Hi when I load a class whose superclass is not in the image I have the impression that the system create a subclass from ProtoObject and I would like to be able to control the superclass. ProtoObject subclass: #Adaptor1Example instanceVariableNames: 'customers accountID address name phoneNumber' classVariableNames: '' poolDictionaries: '' category: 'Examples-Cookbook' Any idea where to look? Stef
Well if the class does not exists it calls the method on UndefinedObject (UndeclaredBinding). And you have: UndefinedObject>>subclass: nameOfClass instanceVariableNames: instVarNames classVariableNames: classVarNames poolDictionaries: poolDictnames category: category "Calling this method is now considered an accident. If you really want to create a class with a nil superclass, then create the class and then set the superclass using #superclass:" self traceCr: ('Attempt to create ', nameOfClass, ' as a subclass of nil. Possibly a class is being loaded before its superclass.'). ^ProtoObject subclass: nameOfClass instanceVariableNames: instVarNames classVariableNames: classVarNames poolDictionaries: poolDictnames category: category The best is to set manually the superclass after with #superclass: 2013/12/2 Stéphane Ducasse <stephane.ducasse@inria.fr>
Hi
when I load a class whose superclass is not in the image I have the impression that the system create a subclass from ProtoObject and I would like to be able to control the superclass.
ProtoObject subclass: #Adaptor1Example instanceVariableNames: 'customers accountID address name phoneNumber' classVariableNames: '' poolDictionaries: '' category: 'Examples-Cookbook'
Any idea where to look?
Stef
Well if the class does not exists it calls the method on UndefinedObject (UndeclaredBinding). And you have:
I will check and see if I can set up a hook because having classes subclasses of protoobject is not a good idea when loading broken code.
UndefinedObject>>subclass: nameOfClass instanceVariableNames: instVarNames classVariableNames: classVarNames poolDictionaries: poolDictnames category: category "Calling this method is now considered an accident. If you really want to create a class with a nil superclass, then create the class and then set the superclass using #superclass:" self traceCr: ('Attempt to create ', nameOfClass, ' as a subclass of nil. Possibly a class is being loaded before its superclass.'). ^ProtoObject subclass: nameOfClass instanceVariableNames: instVarNames classVariableNames: classVarNames poolDictionaries: poolDictnames category: category
The best is to set manually the superclass after with #superclass:
No because I have no idea what are the classes whose superclasses are not in the image. With a proper hook I could just say if the superclass is unknow please use the "StubRootClass" of my framework. else let the system handles it. Stef
Then for your project replace ProtoObject by StubRootClass in UndefinedObject>>subclass:instanceVariableNames:classVariableNames: poolDictionaries:category: it will work. An alternative is to catch OCSemanticWarning or its subclass OCUndeclaredVariableWarning while loading the new classes and execute another code instead of the default action in the exception handling block 2013/12/3 Stéphane Ducasse <stephane.ducasse@inria.fr>
Well if the class does not exists it calls the method on UndefinedObject (UndeclaredBinding). And you have:
I will check and see if I can set up a hook because having classes subclasses of protoobject is not a good idea when loading broken code.
UndefinedObject>>subclass: nameOfClass instanceVariableNames: instVarNames classVariableNames: classVarNames poolDictionaries: poolDictnames category: category "Calling this method is now considered an accident. If you really want to create a class with a nil superclass, then create the class and then set the superclass using #superclass:" self traceCr: ('Attempt to create ', nameOfClass, ' as a subclass of nil. Possibly a class is being loaded before its superclass.'). ^ProtoObject subclass: nameOfClass instanceVariableNames: instVarNames classVariableNames: classVarNames poolDictionaries: poolDictnames category: category
The best is to set manually the superclass after with #superclass:
No because I have no idea what are the classes whose superclasses are not in the image. With a proper hook I could just say if the superclass is unknow please use the "StubRootClass" of my framework. else let the system handles it.
Stef
On Dec 3, 2013, at 11:20 AM, Clément Bera <bera.clement@gmail.com> wrote:
Then for your project replace ProtoObject by StubRootClass in UndefinedObject>>subclass:instanceVariableNames:classVariableNames:poolDictionaries:category: it will work.
yes but this is ugly because I do not want override. So I will introduce an exception so that we can do that in a clean way.
An alternative is to catch OCSemanticWarning or its subclass OCUndeclaredVariableWarning while loading the new classes and execute another code instead of the default action in the exception handling block
do you know if the OCUndeclaredVariable is raised for unknown superclass? How to undefined and OCUndeclaredVariableWarning relate? Stef
2013/12/3 Stéphane Ducasse <stephane.ducasse@inria.fr>
Well if the class does not exists it calls the method on UndefinedObject (UndeclaredBinding). And you have:
I will check and see if I can set up a hook because having classes subclasses of protoobject is not a good idea when loading broken code.
UndefinedObject>>subclass: nameOfClass instanceVariableNames: instVarNames classVariableNames: classVarNames poolDictionaries: poolDictnames category: category "Calling this method is now considered an accident. If you really want to create a class with a nil superclass, then create the class and then set the superclass using #superclass:" self traceCr: ('Attempt to create ', nameOfClass, ' as a subclass of nil. Possibly a class is being loaded before its superclass.'). ^ProtoObject subclass: nameOfClass instanceVariableNames: instVarNames classVariableNames: classVarNames poolDictionaries: poolDictnames category: category
The best is to set manually the superclass after with #superclass:
No because I have no idea what are the classes whose superclasses are not in the image. With a proper hook I could just say if the superclass is unknow please use the "StubRootClass" of my framework. else let the system handles it.
Stef
*do you know if the OCUndeclaredVariable is raised for unknown superclass?* this code: AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: 'customers accountID address name phoneNumber' classVariableNames: '' poolDictionaries: '' category: 'Examples-Cookbook' is run as a Do It. In Do It, unknown variables (as here AnUnknownClass) raise an OCUndeclaredVariableWarning. For example, running: AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: 'customers accountID address name phoneNumber' classVariableNames: '' poolDictionaries: '' category: 'Examples-Cookbook' executes the default action for OCUndeclaredVariableWarning, which is opening a pop-up titled: "Unknown variable ...". Here the error is raised at *compilation time, *therefore it would have* no effect to wrap this with a #on:do: * [ AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: 'customers accountID address name phoneNumber' classVariableNames: '' poolDictionaries: '' category: 'Examples-Cookbook' ] on: OCSemanticWarning do: [ ] ==> same problem. Now if you do: [ OpalCompiler new evaluate: 'AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: ''customers accountID address name phoneNumber'' classVariableNames: '''' poolDictionaries: '''' category: ''Examples-Cookbook''' ] on: OCSemanticWarning do: [ :e | e halt ] Here we catch the error, and you can handle it. Now it is not easily possible to resume the error, because you want a global instead and Opal expects a temp (there are way to resume but with very deep stack manipulation that I do not want to show to young pharoers present on this mailing list). So the best is to retry it. One solution is therefore: [ OpalCompiler new evaluate: 'AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: ''customers accountID address phoneNumber'' classVariableNames: '''' poolDictionaries: '''' category: ''Examples-Cookbook''' ] on: OCSemanticWarning do: [ :e | Smalltalk at: e node name put: StubRootClass. e retry ] with e node name answering #AnUnknownClass here. Now you need to make sure that the exception block is executed for the case of a missing superclass and not something else or you will end up creating loads of globals. The exception block should be something similar to: [ :e | e node name first isUppercase and: [ "some condition" ] ifTrue: [ Smalltalk at: e node name put: StubRootClass. ^ e retry ]. e pass ] *How to undefined and OCUndeclaredVariableWarning relate?* In your case, while loading from Monticello the code is compiled and evaluated in non interactive mode. Therefore it cannot trigger the default action of OCUndeclaredVariableWarning which is a UI event. So it sets by default the unknown global to: Undeclared at: varName asSymbol put: nil. OCUndeclaredVariable new name: varName asSymbol in: OCUndeclaredVariableWarning >>defaultAction which then later triggers the code in UndefinedObject. 2013/12/3 Stéphane Ducasse <stephane.ducasse@inria.fr>
On Dec 3, 2013, at 11:20 AM, Clément Bera <bera.clement@gmail.com> wrote:
Then for your project replace ProtoObject by StubRootClass in UndefinedObject>>subclass:instanceVariableNames:classVariableNames: poolDictionaries:category: it will work.
yes but this is ugly because I do not want override. So I will introduce an exception so that we can do that in a clean way.
An alternative is to catch OCSemanticWarning or its subclass OCUndeclaredVariableWarning while loading the new classes and execute another code instead of the default action in the exception handling block
do you know if the OCUndeclaredVariable is raised for unknown superclass? How to undefined and OCUndeclaredVariableWarning relate?
Stef
2013/12/3 Stéphane Ducasse <stephane.ducasse@inria.fr>
Well if the class does not exists it calls the method on UndefinedObject (UndeclaredBinding). And you have:
I will check and see if I can set up a hook because having classes subclasses of protoobject is not a good idea when loading broken code.
UndefinedObject>>subclass: nameOfClass instanceVariableNames: instVarNames classVariableNames: classVarNames poolDictionaries: poolDictnames category: category "Calling this method is now considered an accident. If you really want to create a class with a nil superclass, then create the class and then set the superclass using #superclass:" self traceCr: ('Attempt to create ', nameOfClass, ' as a subclass of nil. Possibly a class is being loaded before its superclass.'). ^ProtoObject subclass: nameOfClass instanceVariableNames: instVarNames classVariableNames: classVarNames poolDictionaries: poolDictnames category: category
The best is to set manually the superclass after with #superclass:
No because I have no idea what are the classes whose superclasses are not in the image. With a proper hook I could just say if the superclass is unknow please use the "StubRootClass" of my framework. else let the system handles it.
Stef
thanks for your analysis I will have a look at it. I was thinking to check if I should redefine UndefinedObject>>subclass: to raise an error Stef On Dec 3, 2013, at 3:17 PM, Clément Bera <bera.clement@gmail.com> wrote:
do you know if the OCUndeclaredVariable is raised for unknown superclass?
this code:
AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: 'customers accountID address name phoneNumber' classVariableNames: '' poolDictionaries: '' category: 'Examples-Cookbook'
is run as a Do It. In Do It, unknown variables (as here AnUnknownClass) raise an OCUndeclaredVariableWarning. For example, running:
AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: 'customers accountID address name phoneNumber' classVariableNames: '' poolDictionaries: '' category: 'Examples-Cookbook'
executes the default action for OCUndeclaredVariableWarning, which is opening a pop-up titled: "Unknown variable ...". Here the error is raised at compilation time, therefore it would have no effect to wrap this with a #on:do:
[ AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: 'customers accountID address name phoneNumber' classVariableNames: '' poolDictionaries: '' category: 'Examples-Cookbook' ] on: OCSemanticWarning do: [ ]
==> same problem.
Now if you do:
[ OpalCompiler new evaluate: 'AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: ''customers accountID address name phoneNumber'' classVariableNames: '''' poolDictionaries: '''' category: ''Examples-Cookbook''' ] on: OCSemanticWarning do: [ :e | e halt ]
Here we catch the error, and you can handle it. Now it is not easily possible to resume the error, because you want a global instead and Opal expects a temp (there are way to resume but with very deep stack manipulation that I do not want to show to young pharoers present on this mailing list). So the best is to retry it. One solution is therefore:
[ OpalCompiler new evaluate: 'AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: ''customers accountID address phoneNumber'' classVariableNames: '''' poolDictionaries: '''' category: ''Examples-Cookbook''' ] on: OCSemanticWarning do: [ :e | Smalltalk at: e node name put: StubRootClass. e retry ]
with e node name answering #AnUnknownClass here. Now you need to make sure that the exception block is executed for the case of a missing superclass and not something else or you will end up creating loads of globals.
The exception block should be something similar to:
[ :e | e node name first isUppercase and: [ "some condition" ] ifTrue: [ Smalltalk at: e node name put: StubRootClass. ^ e retry ]. e pass ]
How to undefined and OCUndeclaredVariableWarning relate?
In your case, while loading from Monticello the code is compiled and evaluated in non interactive mode. Therefore it cannot trigger the default action of OCUndeclaredVariableWarning which is a UI event. So it sets by default the unknown global to:
Undeclared at: varName asSymbol put: nil. OCUndeclaredVariable new name: varName asSymbol
in: OCUndeclaredVariableWarning >>defaultAction
which then later triggers the code in UndefinedObject.
2013/12/3 Stéphane Ducasse <stephane.ducasse@inria.fr>
On Dec 3, 2013, at 11:20 AM, Clément Bera <bera.clement@gmail.com> wrote:
Then for your project replace ProtoObject by StubRootClass in UndefinedObject>>subclass:instanceVariableNames:classVariableNames:poolDictionaries:category: it will work.
yes but this is ugly because I do not want override. So I will introduce an exception so that we can do that in a clean way.
An alternative is to catch OCSemanticWarning or its subclass OCUndeclaredVariableWarning while loading the new classes and execute another code instead of the default action in the exception handling block
do you know if the OCUndeclaredVariable is raised for unknown superclass? How to undefined and OCUndeclaredVariableWarning relate?
Stef
2013/12/3 Stéphane Ducasse <stephane.ducasse@inria.fr>
Well if the class does not exists it calls the method on UndefinedObject (UndeclaredBinding). And you have:
I will check and see if I can set up a hook because having classes subclasses of protoobject is not a good idea when loading broken code.
UndefinedObject>>subclass: nameOfClass instanceVariableNames: instVarNames classVariableNames: classVarNames poolDictionaries: poolDictnames category: category "Calling this method is now considered an accident. If you really want to create a class with a nil superclass, then create the class and then set the superclass using #superclass:" self traceCr: ('Attempt to create ', nameOfClass, ' as a subclass of nil. Possibly a class is being loaded before its superclass.'). ^ProtoObject subclass: nameOfClass instanceVariableNames: instVarNames classVariableNames: classVarNames poolDictionaries: poolDictnames category: category
The best is to set manually the superclass after with #superclass:
No because I have no idea what are the classes whose superclasses are not in the image. With a proper hook I could just say if the superclass is unknow please use the "StubRootClass" of my framework. else let the system handles it.
Stef
AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: 'customers accountID address name phoneNumber' classVariableNames: '' poolDictionaries: '' category: 'Examples-Cookbook'
executes the default action for OCUndeclaredVariableWarning, which is opening a pop-up titled: "Unknown variable ...". Here the error is raised at compilation time, therefore it would have no effect to wrap this with a #on:do:
I do not understand why if an exception is raised why I cannot trap it. [AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: 'customers accountID address name phoneNumber' classVariableNames: '' poolDictionaries: '' category: 'Examples-Cookbook'] on: OCUndeclaredVariableWarning do: [ self halt.] does not halt. The fact that is is at compilation time does not mean anything to me. So why? I'm totally confused by this bad and unexpected behavior. Do you imply that the warning is already trapped and that I cannot take precedence? Probably but this has nothing to do with compilation time. Then to me OCSemanticWarning should be enhanced so that we do not get these silly menus. An exception should work and clients should be able to customise it to (for example introduce menu and dialog with the users but they should not be the only default. We see again this plague of interactive environment not being rethought in the 2013 age. defaultAction self errorNotification ifFalse: [ ^nil ]. ^self openMenuIn: [:labels :lines :caption | UIManager default chooseFrom: labels lines: lines title: caption] but that we could specify the action to be executed instead. to me CompilerException should have nothing to do with UI and popup. Then we should be able to pass objects that knows how to handle the errors in interactive way or not. As a clear example, this is just bad that each time we want to change the UI message we have to change the compiler exception. ugly at wish. I have no cycle to fix that now. I will check if I can get something in UndefinedObject so that I can continue to work on my task. Stef
[ OpalCompiler new evaluate: 'AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: ''customers accountID address name phoneNumber'' classVariableNames: '''' poolDictionaries: '''' category: ''Examples-Cookbook''' ] on: OCSemanticWarning do: [ :e | e halt ]
Here we catch the error, and you can handle it. Now it is not easily possible to resume the error, because you want a global instead and Opal expects a temp (there are way to resume but with very deep stack manipulation that I do not want to show to young pharoers present on this mailing list). So the best is to retry it. One solution is therefore:
[ OpalCompiler new evaluate: 'AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: ''customers accountID address phoneNumber'' classVariableNames: '''' poolDictionaries: '''' category: ''Examples-Cookbook''' ] on: OCSemanticWarning do: [ :e | Smalltalk at: e node name put: StubRootClass. e retry ]
with e node name answering #AnUnknownClass here. Now you need to make sure that the exception block is executed for the case of a missing superclass and not something else or you will end up creating loads of globals.
The exception block should be something similar to:
[ :e | e node name first isUppercase and: [ "some condition" ] ifTrue: [ Smalltalk at: e node name put: StubRootClass. ^ e retry ]. e pass ]
How to undefined and OCUndeclaredVariableWarning relate?
In your case, while loading from Monticello the code is compiled and evaluated in non interactive mode. Therefore it cannot trigger the default action of OCUndeclaredVariableWarning which is a UI event. So it sets by default the unknown global to:
Undeclared at: varName asSymbol put: nil. OCUndeclaredVariable new name: varName asSymbol
in: OCUndeclaredVariableWarning >>defaultAction
which then later triggers the code in UndefinedObject.
On 04 Dec 2013, at 20:02, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote:
AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: 'customers accountID address name phoneNumber' classVariableNames: '' poolDictionaries: '' category: 'Examples-Cookbook'
executes the default action for OCUndeclaredVariableWarning, which is opening a pop-up titled: "Unknown variable ...". Here the error is raised at compilation time, therefore it would have no effect to wrap this with a #on:do:
I to me CompilerException should have nothing to do with UI and popup. Then we should be able to pass objects that knows how to handle the errors in interactive way or not.
As a clear example, this is just bad that each time we want to change the UI message we have to change the compiler exception. ugly at wish.
I have no cycle to fix that now. I will check if I can get something in UndefinedObject so that I can continue to work on my task.
The whole exception / error handling of the compiler needs to be deeply rethought. Sadly I have no cycles free in my brain to even start to think about it, and, even more important, we should wait until the old Compiler is removed⦠Marcus
As a clear example, this is just bad that each time we want to change the UI message we have to change the compiler exception. ugly at wish.
I have no cycle to fix that now. I will check if I can get something in UndefinedObject so that I can continue to work on my task.
The whole exception / error handling of the compiler needs to be deeply rethought. Sadly I have no cycles free in my brain to even start to think about it, and, even more important, we should wait until the old Compiler is removedâ¦
Ok I will check something on UndefinedObject to start with. Then it would be fun to prototype a kind of strategy hiearchy on the side (extracted from also) behavior of OCSemanticsError It was nice to see it and since now I'm ok to have a look at the compiler code it was interesting. Stef
Marcus
On 04 Dec 2013, at 20:34, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote:
As a clear example, this is just bad that each time we want to change the UI message we have to change the compiler exception. ugly at wish.
I have no cycle to fix that now. I will check if I can get something in UndefinedObject so that I can continue to work on my task.
The whole exception / error handling of the compiler needs to be deeply rethought. Sadly I have no cycles free in my brain to even start to think about it, and, even more important, we should wait until the old Compiler is removedâ¦
Ok I will check something on UndefinedObject to start with. Then it would be fun to prototype a kind of strategy hiearchy on the side (extracted from also) behavior of OCSemanticsError It was nice to see it and since now I'm ok to have a look at the compiler code it was interesting.
The current design is motivated mostly by backward compatibility, not anything else. Marcus
Ok I will check something on UndefinedObject to start with. Then it would be fun to prototype a kind of strategy hiearchy on the side (extracted from also) behavior of OCSemanticsError It was nice to see it and since now I'm ok to have a look at the compiler code it was interesting.
The current design is motivated mostly by backward compatibility, not anything else.
I see :) I would really to see an headless, interactive and scriptable scenarios to be exercised. So this is good it will get better :) Stef
It didn't halt on your machine because you didn't copy and paste the code that halts (i guess I wrote too much code in the mail so it was not clear). You copied the code that I explicitly said that doesn't halt because the error is raised at compilation time. This code halts (copy, paste and run it you will see): [ OpalCompiler new evaluate: 'AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: ''customers accountID address name phoneNumber'' classVariableNames: '''' poolDictionaries: '''' category: ''Examples-Cookbook''' ] on: OCSemanticWarning do: [ :e | e halt ] We can discuss this another day when you have time because seemingly my mail was not clear (you said you couldn't trap the semantic warning). Now I'm really sick today so we can discuss friday or next week. 2013/12/4 Stéphane Ducasse <stephane.ducasse@inria.fr>
Ok I will check something on UndefinedObject to start with. Then it would be fun to prototype a kind of strategy hiearchy on the side (extracted from also) behavior of OCSemanticsError It was nice to see it and since now I'm ok to have a look at the compiler code it was interesting.
The current design is motivated mostly by backward compatibility, not anything else.
I see :) I would really to see an headless, interactive and scriptable scenarios to be exercised. So this is good it will get better :) Stef
On Dec 4, 2013, at 10:02 PM, Clément Bera <bera.clement@gmail.com> wrote:
It didn't halt on your machine because you didn't copy and paste the code that halts (i guess I wrote too much code in the mail so it was not clear). You copied the code that I explicitly said that doesn't halt because the error is raised at compilation time.
I saw it do not worry. I was just shocked by the state of the exceptions.
This code halts (copy, paste and run it you will see):
[ OpalCompiler new evaluate: 'AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: ''customers accountID address name phoneNumber'' classVariableNames: '''' poolDictionaries: '''' category: ''Examples-Cookbook''' ] on: OCSemanticWarning do: [ :e | e halt ]
We can discuss this another day when you have time because seemingly my mail was not clear (you said you couldn't trap the semantic warning). Now I'm really sick today so we can discuss friday or next week.
rest well
2013/12/4 Stéphane Ducasse <stephane.ducasse@inria.fr>
Ok I will check something on UndefinedObject to start with. Then it would be fun to prototype a kind of strategy hiearchy on the side (extracted from also) behavior of OCSemanticsError It was nice to see it and since now I'm ok to have a look at the compiler code it was interesting.
The current design is motivated mostly by backward compatibility, not anything else.
I see :) I would really to see an headless, interactive and scriptable scenarios to be exercised. So this is good it will get better :) Stef
Steph, each time you want to evaluate something, do you agree that this involves - a parse phase of the expression you want to evaluate to create an AST - a code generation phase from AST -> bytecodes to generate a CompiledMethod - the evaluation phase itself which evaluates above CompiledMethod with appropriate receiver (nil generally) I didn't check OPAL, but do you agree that the semantic analysis determining which are those variables you called {'AnUnknownClass'. 'OCUndeclaredVariableWarning'. 'self'} and how to bind them, must happen somewhere between AST and CompiledMethod creation? So if there is a semantic exception, like UndeclaredVariable, how would the CompiledMethod be generated in the first place? If it's not generated, how would it be executed? If it's not executed, how would the message on:do: be sent to a block with 2 arguments? Unless you suggest to attempt executing a ParseTree which is known to be defectuous... 2013/12/4 Stéphane Ducasse <stephane.ducasse@inria.fr>
AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: 'customers accountID address name phoneNumber' classVariableNames: '' poolDictionaries: '' category: 'Examples-Cookbook'
executes the default action for OCUndeclaredVariableWarning, which is opening a pop-up titled: "Unknown variable ...". Here the error is raised at *compilation time, *therefore it would have* no effect to wrap this with a #on:do: *
I do not understand why if an exception is raised why I cannot trap it.
[AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: 'customers accountID address name phoneNumber' classVariableNames: '' poolDictionaries: '' category: 'Examples-Cookbook'] on: OCUndeclaredVariableWarning do: [ self halt.] does not halt.
The fact that is is at compilation time does not mean anything to me. So why? I'm totally confused by this bad and unexpected behavior. Do you imply that the warning is already trapped and that I cannot take precedence? Probably but this has nothing to do with compilation time.
Then to me OCSemanticWarning should be enhanced so that we do not get these silly menus. An exception should work and clients should be able to customise it to (for example introduce menu and dialog with the users but they should not be the only default. We see again this plague of interactive environment not being rethought in the 2013 age.
defaultAction self errorNotification ifFalse: [ ^nil ]. ^self openMenuIn: [:labels :lines :caption | UIManager default chooseFrom: labels lines: lines title: caption]
but that we could specify the action to be executed instead.
to me CompilerException should have nothing to do with UI and popup. Then we should be able to pass objects that knows how to handle the errors in interactive way or not.
As a clear example, this is just bad that each time we want to change the UI message we have to change the compiler exception. ugly at wish.
I have no cycle to fix that now. I will check if I can get something in UndefinedObject so that I can continue to work on my task.
Stef
[ OpalCompiler new evaluate: 'AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: ''customers accountID address name phoneNumber'' classVariableNames: '''' poolDictionaries: '''' category: ''Examples-Cookbook''' ] on: OCSemanticWarning do: [ :e | e halt ]
Here we catch the error, and you can handle it. Now it is not easily possible to resume the error, because you want a global instead and Opal expects a temp (there are way to resume but with very deep stack manipulation that I do not want to show to young pharoers present on this mailing list). So the best is to retry it. One solution is therefore:
[ OpalCompiler new evaluate: 'AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: ''customers accountID address phoneNumber'' classVariableNames: '''' poolDictionaries: '''' category: ''Examples-Cookbook''' ] on: OCSemanticWarning do: [ :e | Smalltalk at: e node name put: StubRootClass. e retry ]
with e node name answering #AnUnknownClass here. Now you need to make sure that the exception block is executed for the case of a missing superclass and not something else or you will end up creating loads of globals.
The exception block should be something similar to:
[ :e | e node name first isUppercase and: [ "some condition" ] ifTrue: [ Smalltalk at: e node name put: StubRootClass. ^ e retry ]. e pass ]
*How to undefined and OCUndeclaredVariableWarning relate?*
In your case, while loading from Monticello the code is compiled and evaluated in non interactive mode. Therefore it cannot trigger the default action of OCUndeclaredVariableWarning which is a UI event. So it sets by default the unknown global to:
Undeclared at: varName asSymbol put: nil. OCUndeclaredVariable new name: varName asSymbol
in: OCUndeclaredVariableWarning >>defaultAction
which then later triggers the code in UndefinedObject.
I forgot to add that the OCUndeclaredVariableWarning was already handled at semantic analysis. Do you suggest that default behavior should be to handle and retry instead of handle and return? One way to achieve what you are asking would be to initialize the Undeclared entry to some kind of ProtoObject that does not understand anything and rethrow a OCUndeclaredVariableWarning instead of a MessageNotUnderstood... (very uneasy to debug, since the Debugger itself is querying the receiver etc... - unless Debugger is using basic mirror primitives) 2013/12/4 Nicolas Cellier <nicolas.cellier.aka.nice@gmail.com>
Steph, each time you want to evaluate something, do you agree that this involves - a parse phase of the expression you want to evaluate to create an AST - a code generation phase from AST -> bytecodes to generate a CompiledMethod - the evaluation phase itself which evaluates above CompiledMethod with appropriate receiver (nil generally)
I didn't check OPAL, but do you agree that the semantic analysis determining which are those variables you called {'AnUnknownClass'. 'OCUndeclaredVariableWarning'. 'self'} and how to bind them, must happen somewhere between AST and CompiledMethod creation?
So if there is a semantic exception, like UndeclaredVariable, how would the CompiledMethod be generated in the first place? If it's not generated, how would it be executed? If it's not executed, how would the message on:do: be sent to a block with 2 arguments?
Unless you suggest to attempt executing a ParseTree which is known to be defectuous...
2013/12/4 Stéphane Ducasse <stephane.ducasse@inria.fr>
AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: 'customers accountID address name phoneNumber' classVariableNames: '' poolDictionaries: '' category: 'Examples-Cookbook'
executes the default action for OCUndeclaredVariableWarning, which is opening a pop-up titled: "Unknown variable ...". Here the error is raised at *compilation time, *therefore it would have* no effect to wrap this with a #on:do: *
I do not understand why if an exception is raised why I cannot trap it.
[AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: 'customers accountID address name phoneNumber' classVariableNames: '' poolDictionaries: '' category: 'Examples-Cookbook'] on: OCUndeclaredVariableWarning do: [ self halt.] does not halt.
The fact that is is at compilation time does not mean anything to me. So why? I'm totally confused by this bad and unexpected behavior. Do you imply that the warning is already trapped and that I cannot take precedence? Probably but this has nothing to do with compilation time.
Then to me OCSemanticWarning should be enhanced so that we do not get these silly menus. An exception should work and clients should be able to customise it to (for example introduce menu and dialog with the users but they should not be the only default. We see again this plague of interactive environment not being rethought in the 2013 age.
defaultAction self errorNotification ifFalse: [ ^nil ]. ^self openMenuIn: [:labels :lines :caption | UIManager default chooseFrom: labels lines: lines title: caption]
but that we could specify the action to be executed instead.
to me CompilerException should have nothing to do with UI and popup. Then we should be able to pass objects that knows how to handle the errors in interactive way or not.
As a clear example, this is just bad that each time we want to change the UI message we have to change the compiler exception. ugly at wish.
I have no cycle to fix that now. I will check if I can get something in UndefinedObject so that I can continue to work on my task.
Stef
[ OpalCompiler new evaluate: 'AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: ''customers accountID address name phoneNumber'' classVariableNames: '''' poolDictionaries: '''' category: ''Examples-Cookbook''' ] on: OCSemanticWarning do: [ :e | e halt ]
Here we catch the error, and you can handle it. Now it is not easily possible to resume the error, because you want a global instead and Opal expects a temp (there are way to resume but with very deep stack manipulation that I do not want to show to young pharoers present on this mailing list). So the best is to retry it. One solution is therefore:
[ OpalCompiler new evaluate: 'AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: ''customers accountID address phoneNumber'' classVariableNames: '''' poolDictionaries: '''' category: ''Examples-Cookbook''' ] on: OCSemanticWarning do: [ :e | Smalltalk at: e node name put: StubRootClass. e retry ]
with e node name answering #AnUnknownClass here. Now you need to make sure that the exception block is executed for the case of a missing superclass and not something else or you will end up creating loads of globals.
The exception block should be something similar to:
[ :e | e node name first isUppercase and: [ "some condition" ] ifTrue: [ Smalltalk at: e node name put: StubRootClass. ^ e retry ]. e pass ]
*How to undefined and OCUndeclaredVariableWarning relate?*
In your case, while loading from Monticello the code is compiled and evaluated in non interactive mode. Therefore it cannot trigger the default action of OCUndeclaredVariableWarning which is a UI event. So it sets by default the unknown global to:
Undeclared at: varName asSymbol put: nil. OCUndeclaredVariable new name: varName asSymbol
in: OCUndeclaredVariableWarning >>defaultAction
which then later triggers the code in UndefinedObject.
2013/12/4 Nicolas Cellier <nicolas.cellier.aka.nice@gmail.com>
I forgot to add that the OCUndeclaredVariableWarning was already handled at semantic analysis.
This is not the case. The OCUndeclaredVariableWarning is handled in the default action. Therefore anyone can catch it. In this case for instance: [ OpalCompiler new evaluate: 'AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: ''customers accountID address name phoneNumber'' classVariableNames: '''' poolDictionaries: '''' category: ''Examples-Cookbook''' ] on: OCSemanticWarning do: [ :e | e halt ] The Semantic warning is caught outside of the semantic analysis and it works perfectly fine. The only thing is that you need to retry the error and not resume it to restart the semantic analysis (or you have an inconsistent execution state in the semantic analysis visitor).
Do you suggest that default behavior should be to handle and retry instead of handle and return?
One way to achieve what you are asking would be to initialize the
Undeclared entry to some kind of ProtoObject that does not understand anything and rethrow a OCUndeclaredVariableWarning instead of a MessageNotUnderstood... (very uneasy to debug, since the Debugger itself is querying the receiver etc... - unless Debugger is using basic mirror primitives)
2013/12/4 Nicolas Cellier <nicolas.cellier.aka.nice@gmail.com>
Steph, each time you want to evaluate something, do you agree that this involves - a parse phase of the expression you want to evaluate to create an AST - a code generation phase from AST -> bytecodes to generate a CompiledMethod - the evaluation phase itself which evaluates above CompiledMethod with appropriate receiver (nil generally)
I didn't check OPAL, but do you agree that the semantic analysis determining which are those variables you called {'AnUnknownClass'. 'OCUndeclaredVariableWarning'. 'self'} and how to bind them, must happen somewhere between AST and CompiledMethod creation?
So if there is a semantic exception, like UndeclaredVariable, how would the CompiledMethod be generated in the first place? If it's not generated, how would it be executed? If it's not executed, how would the message on:do: be sent to a block with 2 arguments?
Unless you suggest to attempt executing a ParseTree which is known to be defectuous...
2013/12/4 Stéphane Ducasse <stephane.ducasse@inria.fr>
AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: 'customers accountID address name phoneNumber' classVariableNames: '' poolDictionaries: '' category: 'Examples-Cookbook'
executes the default action for OCUndeclaredVariableWarning, which is opening a pop-up titled: "Unknown variable ...". Here the error is raised at *compilation time, *therefore it would have* no effect to wrap this with a #on:do: *
I do not understand why if an exception is raised why I cannot trap it.
[AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: 'customers accountID address name phoneNumber' classVariableNames: '' poolDictionaries: '' category: 'Examples-Cookbook'] on: OCUndeclaredVariableWarning do: [ self halt.] does not halt.
The fact that is is at compilation time does not mean anything to me. So why? I'm totally confused by this bad and unexpected behavior. Do you imply that the warning is already trapped and that I cannot take precedence? Probably but this has nothing to do with compilation time.
Then to me OCSemanticWarning should be enhanced so that we do not get these silly menus. An exception should work and clients should be able to customise it to (for example introduce menu and dialog with the users but they should not be the only default. We see again this plague of interactive environment not being rethought in the 2013 age.
defaultAction self errorNotification ifFalse: [ ^nil ]. ^self openMenuIn: [:labels :lines :caption | UIManager default chooseFrom: labels lines: lines title: caption]
but that we could specify the action to be executed instead.
to me CompilerException should have nothing to do with UI and popup. Then we should be able to pass objects that knows how to handle the errors in interactive way or not.
As a clear example, this is just bad that each time we want to change the UI message we have to change the compiler exception. ugly at wish.
I have no cycle to fix that now. I will check if I can get something in UndefinedObject so that I can continue to work on my task.
Stef
[ OpalCompiler new evaluate: 'AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: ''customers accountID address name phoneNumber'' classVariableNames: '''' poolDictionaries: '''' category: ''Examples-Cookbook''' ] on: OCSemanticWarning do: [ :e | e halt ]
Here we catch the error, and you can handle it. Now it is not easily possible to resume the error, because you want a global instead and Opal expects a temp (there are way to resume but with very deep stack manipulation that I do not want to show to young pharoers present on this mailing list). So the best is to retry it. One solution is therefore:
[ OpalCompiler new evaluate: 'AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: ''customers accountID address phoneNumber'' classVariableNames: '''' poolDictionaries: '''' category: ''Examples-Cookbook''' ] on: OCSemanticWarning do: [ :e | Smalltalk at: e node name put: StubRootClass. e retry ]
with e node name answering #AnUnknownClass here. Now you need to make sure that the exception block is executed for the case of a missing superclass and not something else or you will end up creating loads of globals.
The exception block should be something similar to:
[ :e | e node name first isUppercase and: [ "some condition" ] ifTrue: [ Smalltalk at: e node name put: StubRootClass. ^ e retry ]. e pass ]
*How to undefined and OCUndeclaredVariableWarning relate?*
In your case, while loading from Monticello the code is compiled and evaluated in non interactive mode. Therefore it cannot trigger the default action of OCUndeclaredVariableWarning which is a UI event. So it sets by default the unknown global to:
Undeclared at: varName asSymbol put: nil. OCUndeclaredVariable new name: varName asSymbol
in: OCUndeclaredVariableWarning >>defaultAction
which then later triggers the code in UndefinedObject.
Hi nicolas
I forgot to add that the OCUndeclaredVariableWarning was already handled at semantic analysis. Do you suggest that default behavior should be to handle and retry instead of handle and return?
I suggest that we can define what is the behavior of handling an exceptional cases.
One way to achieve what you are asking would be to initialize the Undeclared entry to some kind of ProtoObject that does not understand anything and rethrow a OCUndeclaredVariableWarning instead of a MessageNotUnderstood... (very uneasy to debug, since the Debugger itself is querying the receiver etc... - unless Debugger is using basic mirror primitives)
we should be able to say: when you encounter an undefined do that when you enconter a syntax error do that We should have a list of hooks and exceptional situations and be able to define the actions we want to be performed. This way the compiler would not depend on the UI also :). I love these "layers" from the past. When you have a UI then you specify new actions which involves popup and other niceties. and in particular exception should not hardcode the popup of menu and other UI related things. So this is not linked to the phases of compilation, this is linked to offering customisable error. Stef
2013/12/4 Nicolas Cellier <nicolas.cellier.aka.nice@gmail.com> Steph, each time you want to evaluate something, do you agree that this involves - a parse phase of the expression you want to evaluate to create an AST - a code generation phase from AST -> bytecodes to generate a CompiledMethod - the evaluation phase itself which evaluates above CompiledMethod with appropriate receiver (nil generally)
I didn't check OPAL, but do you agree that the semantic analysis determining which are those variables you called {'AnUnknownClass'. 'OCUndeclaredVariableWarning'. 'self'} and how to bind them, must happen somewhere between AST and CompiledMethod creation?
So if there is a semantic exception, like UndeclaredVariable, how would the CompiledMethod be generated in the first place? If it's not generated, how would it be executed? If it's not executed, how would the message on:do: be sent to a block with 2 arguments?
Unless you suggest to attempt executing a ParseTree which is known to be defectuous...
2013/12/4 Stéphane Ducasse <stephane.ducasse@inria.fr>
AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: 'customers accountID address name phoneNumber' classVariableNames: '' poolDictionaries: '' category: 'Examples-Cookbook'
executes the default action for OCUndeclaredVariableWarning, which is opening a pop-up titled: "Unknown variable ...". Here the error is raised at compilation time, therefore it would have no effect to wrap this with a #on:do:
I do not understand why if an exception is raised why I cannot trap it.
[AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: 'customers accountID address name phoneNumber' classVariableNames: '' poolDictionaries: '' category: 'Examples-Cookbook'] on: OCUndeclaredVariableWarning do: [ self halt.] does not halt.
The fact that is is at compilation time does not mean anything to me. So why? I'm totally confused by this bad and unexpected behavior. Do you imply that the warning is already trapped and that I cannot take precedence? Probably but this has nothing to do with compilation time.
Then to me OCSemanticWarning should be enhanced so that we do not get these silly menus. An exception should work and clients should be able to customise it to (for example introduce menu and dialog with the users but they should not be the only default. We see again this plague of interactive environment not being rethought in the 2013 age.
defaultAction
self errorNotification ifFalse: [ ^nil ]. ^self openMenuIn: [:labels :lines :caption | UIManager default chooseFrom: labels lines: lines title: caption]
but that we could specify the action to be executed instead.
to me CompilerException should have nothing to do with UI and popup. Then we should be able to pass objects that knows how to handle the errors in interactive way or not.
As a clear example, this is just bad that each time we want to change the UI message we have to change the compiler exception. ugly at wish.
I have no cycle to fix that now. I will check if I can get something in UndefinedObject so that I can continue to work on my task.
Stef
[ OpalCompiler new evaluate: 'AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: ''customers accountID address name phoneNumber'' classVariableNames: '''' poolDictionaries: '''' category: ''Examples-Cookbook''' ] on: OCSemanticWarning do: [ :e | e halt ]
Here we catch the error, and you can handle it. Now it is not easily possible to resume the error, because you want a global instead and Opal expects a temp (there are way to resume but with very deep stack manipulation that I do not want to show to young pharoers present on this mailing list). So the best is to retry it. One solution is therefore:
[ OpalCompiler new evaluate: 'AnUnknownClass subclass: #Adaptor1Example instanceVariableNames: ''customers accountID address phoneNumber'' classVariableNames: '''' poolDictionaries: '''' category: ''Examples-Cookbook''' ] on: OCSemanticWarning do: [ :e | Smalltalk at: e node name put: StubRootClass. e retry ]
with e node name answering #AnUnknownClass here. Now you need to make sure that the exception block is executed for the case of a missing superclass and not something else or you will end up creating loads of globals.
The exception block should be something similar to:
[ :e | e node name first isUppercase and: [ "some condition" ] ifTrue: [ Smalltalk at: e node name put: StubRootClass. ^ e retry ]. e pass ]
How to undefined and OCUndeclaredVariableWarning relate?
In your case, while loading from Monticello the code is compiled and evaluated in non interactive mode. Therefore it cannot trigger the default action of OCUndeclaredVariableWarning which is a UI event. So it sets by default the unknown global to:
Undeclared at: varName asSymbol put: nil. OCUndeclaredVariable new name: varName asSymbol
in: OCUndeclaredVariableWarning >>defaultAction
which then later triggers the code in UndefinedObject.
participants (5)
-
Clément Bera -
Clément Béra -
Marcus Denker -
Nicolas Cellier -
Stéphane Ducasse