Page 1 of 1
Warning XS1030 The following method did not include a CLASS declaration
Posted: Tue Mar 03, 2020 4:43 pm
by ic2
After unchecking Remove Class Cause in the VO XPorter, which keeps ...CLASS xxx behind the methods, which is way clearer than having to see that somewhere hidden in the VS screen (see
https://www.xsharp.eu/forum/suggestions ... utput#7360) I have the following problem (not sure however if is completely related to this option):
1 Many errors: Warning XS1030 #warning: 'The following method did not include a CLASS declaration'
A line where it goes wrong is for example:
#warning The following method did not include a CLASS declaration
PARTIAL CLASS RichEdit_external_class INHERIT RichEdit
2 This kind of code seems to be generated for all standard VO classes and it also causes an error like this at any method belonging to one of these standard VO classes, e.g.:
Error XS9016 Class name DataBrowser for method differs from parent class name DataBrowser_external_class
I am converting a separate lib which has dependencies.
How can I prevent about 100 errors and warnings by making the XPorter clear that DataBrowser and other VO classes are just present in the relevant VO DLLs, also preventing this _external_class generation?
Dick
Warning XS1030 The following method did not include a CLASS declaration
Posted: Tue Mar 03, 2020 5:00 pm
by Chris
Hi DIck,
Before you port you are pp, please make sure you have completely read all the topics in the X# help file, under "Migrating apps from VO to X#". Among many other things, those topics explain the issue with this message (it's in the 2nd topic, The VOPAD example).
In short, adding a method on an already baked class in a dll externally is not allowed in .Net and can never work like that. In this particular case, a method has been externally added in VO to the already existing (in the GUI classes) RichEdit class.
In order to fix this problem, you need to either subclass your control, add this method to the subclass and then use the subclass in your code, or use extension methods as described in the help file. The best approach depends on what kind of external methods you have written in VO and what they do (if they access class members that are not public or not). Can you please give us a few examples of such external methods (their complete code), so we can suggest what path you can choose?
Warning XS1030 The following method did not include a CLASS declaration
Posted: Tue Mar 03, 2020 5:44 pm
by ic2
Hello Chris,
That's a very quick reply!
A few examples:
PARTIAL CLASS IC2DBServer_external_class INHERIT IC2DBServer
METHOD ReturnADS CLASS IC2DBServer
//#s Called from Init:IC2dbserver using Send to see if we want ADS 19-09-2007
RETURN ReturnVar("LUSEADS")
Class IC2DBServer, a subclass for dbServer, is defined in another AEF. I would prefer to have an as far as possible working/ compiling project per library before going through the whole project. In that case it would be better to have an empty class generated and even empty methods. Currently I have 4 of these partial "External_class"-es generated in 4 different PRG files plus all these error messages while these would be resolved when I include the AEF where IC2DBServer is defined anyway.
Isn't there a way to avoid these entries?
Most of the other methods are methods added to an existing VO class, like Window, MONTHCALENDAR, RichEdit. As I have subclassed almost everything except some of my oldest code, I see that 75% is obsolete code, already renamed years ago, to something like _RemoveThis_NameOfMethod. So that's a good reason to actually clean that out. But not all, e.g. the method below which I got from Paul Piko (probably via the NG). Yes, I do have a subclassed ListView and probably I don't even use the non subclassed listview. As these are just warnings I can check out if I still use them, and if so, change the code.
This brings me to1 more question: I am now using VS 2019 and I did not see the 'x reference' links above methods, from VS CodeLens. Is this unsupported in X#? A working CodeLens would be very helpful in determining if something is really obsolete or if it's still used. I consider CodeLens one of the (very few) advantages of Visual Studio above VO.
Bottom line: I could best deal with these issues if:
1 XPorter would not generate these external_class- es and either would generate an empty class and empty methods (or allows me to make these manually until I merge the different AEF's)
2 CodeLens would work to quickly tell me if a method with an error is actually used (I suspect however that the Send(#method) and owner:DoSomething constructions might not work with CodeLens?)
3 Some way to allow added methods to existing VO classes. But I guess that great flexibility of VO can't work in .Net :unsure:
METHOD AutoSize() CLASS ListViewColumn
// This method will adjust the width of the column so that the widest item is completely visible
LOCAL dwIndex AS DWORD
LOCAL n AS DWORD
IF oOwner != NULL_OBJECT
dwIndex := oOwner:__GetColumnIndexFromSymbol(SELF:NameSym) - 1
ListView_SetColumnWidth(oOwner:Handle(), INT(dwIndex), SHORTINT(_CAST,LVSCW_AUTOSIZE))
n := DWORD(ListView_GetColumnWidth(oOwner:Handle(), INT(dwIndex)))
ListView_SetColumnWidth(oOwner:Handle(), INT(dwIndex), SHORTINT(_CAST,LVSCW_AUTOSIZE_USEHEADER))
n := Max(n,ListView_GetColumnWidth(oOwner:Handle(), INT(dwIndex)))
ListView_SetColumnWidth(oOwner:Handle(), INT(dwIndex), SHORTINT(n))
ENDIF
RETURN NIL
Dick
Warning XS1030 The following method did not include a CLASS declaration
Posted: Tue Mar 03, 2020 10:24 pm
by Chris
Hi Dick,
Since you have already subclassed DBServer with IC2DBServer in one aef, then why have you not included also the ReturnADS() method in that aef, instead of defining it in a separate one? For this case, simply move the declaration of this method (better do it ialso in the VO code I mean) in the aef where the IC2DBServer is defined, and this problem is solved already.
About the other ones which are also methods extending your other subclasses, again simply move those to the aefs where you have defined your subclasses and those problems will be solved as well.
Regarding the ListViewColumn:AutoSize() method, this is indeed more complicated, but fortunately the fix is easy as well. This method uses only one non-public member of its class (oOwner), but it is very easy to workaround it, by using "Owner" instead, which returns the same thing. So you can simply define (only in the X# version of the code this time) an extension method like this anywhere in one of your base libraries:
Code: Select all
CLASS Extensions
STATIC METHOD AutoSize(SELF oColumn AS ListViewColumn)
// This method will adjust the width of the column so that the widest item is completely visible
LOCAL dwIndex AS DWORD
LOCAL n AS DWORD
IF oColumn:Owner != NULL_OBJECT
dwIndex := oColumn:Owner:__GetColumnIndexFromSymbol(oColumn:NameSym) - 1
ListView_SetColumnWidth(oColumn:Owner:Handle(), INT(dwIndex), SHORTINT(_CAST,LVSCW_AUTOSIZE))
n := DWORD(ListView_GetColumnWidth(oColumn:Owner:Handle(), INT(dwIndex)))
ListView_SetColumnWidth(oColumn:Owner:Handle(), INT(dwIndex), SHORTINT(_CAST,LVSCW_AUTOSIZE_USEHEADER))
n := Max(n,ListView_GetColumnWidth(oColumn:Owner:Handle(), INT(dwIndex)))
ListView_SetColumnWidth(oColumn:Owner:Handle(), INT(dwIndex), SHORTINT(n))
ENDIF
RETURN NIL
END CLASS
also completely remove the class generated by VOXporter, and your existing VO code that uses the AutoSize() method will magically continue to work, without any changes. If you want some more details on how this works, please refer to the help file topic I mentioned.
Regarding the compiler only giving a warning about those classes, this is the half story, because it would also report errors in places when you are actually using those external methods. And making VOXporter not show those entries would only make it more difficult understanding why your code does not compile. But with the workarounds I mentioned above, you should be able to get rid of them all. And yes, this feature of VO (adding externally methods to already existing classes) is very powerful, but is also very "wrong" in the sense that it breaks every programming rule known to man! OK, I am exaggerating a little bit
. but really, being able to expose things that the creator of a class explicitly prohibited from doing so is not a good thing.
About CodeLens, I think it's just not supported yet, but VS features like that should be added in the coming months.
Warning XS1030 The following method did not include a CLASS declaration
Posted: Wed Mar 04, 2020 12:28 am
by ic2
Hi Chris,
Thanks for the extensive remarks.
Unfortunately moving these IC2DBServer methods to where the class is defined is not so easy as it looks. The 3 methods use 2 methods and one variable only available in the library which I am now converting (and these can't nbe moved to the dbServer containing AEF for sure). I won't say there is nothing I can move, perhaps I can, but I am sure most of these issues can't be solved like this - and in VO they needn't be solved because you can have methods of a class everywhere, only constraint is sometimes that you can't strong type dislocated methods.
The Extensions solution is very smart and will certainly solve some issues.
The additions to existing classes is hopefully a minority. Just not sure if I would want to invest in changing that in VO....
Just to see if things would improve I XPorted my complete repository which was done impressively fast. Unfortunately the solution compiles with 13296 errors and 254 warnings, although many are generated from the Word and Excel base classes:
Error XS9090 The _DLL syntax for Methods, Accesses and Assigns is not supported and not needed in .Net. You should add a reference to the assembly
If I remove these 2 libraries + the Report Pro and Graphics4VO Base libraries only a few 100 errors remain but most errors just don't show (the library which I separated has only one error left at the moment and even if now the XS1030 isn't issued because it should be able to find the classes in other prg's I think it's not the full story.
So I think my best approach is still to get individual libraries working. I then need to manually remove all the generated classes causing the XS1030, which will be 100x more time consuming in VS than it would be in VO, and manually add the missing classes until I know the rest of the code per library is correct. I'll let you know the results of this approach!
Dick
Warning XS1030 The following method did not include a CLASS declaration
Posted: Wed Mar 04, 2020 9:15 am
by Chris
Hi Dick,
The other method you showed has this code:
Code: Select all
METHOD ReturnADS CLASS IC2DBServer
//#s Called from Init:IC2dbserver using Send to see if we want ADS 19-09-2007
RETURN ReturnVar("LUSEADS")
Do you mean you cannot move it to another aef, because the ReturnVar() is not available in that aef? In that case, why don't you call the function ReturnVar("LUSEADS") directly, instead of adding a new method to a class and calling it?
But still, if you want it to feel like it's part of the class, you can again simply use an extension method:
Code: Select all
CLASS Extensions
STATIC METHOD ReturnADS(SELF oServer AS IC2DBServer)
//#s Called from Init:IC2dbserver using Send to see if we want ADS 19-09-2007
RETURN ReturnVar("LUSEADS")
END CLASS
Can you please show us also the other external methods, so we can see if it's easy to adjust them, too?
Warning XS1030 The following method did not include a CLASS declaration
Posted: Wed Mar 04, 2020 10:43 am
by ic2
Hello Chris,
Chris wrote:
Do you mean you cannot move it to another aef, because the ReturnVar() is not available in that aef? In that case, why don't you call the function ReturnVar("LUSEADS") directly, instead of adding a new method to a class and calling it?
Yes, that's what I mean. And indeed, in this case it would work to call ReturnVar directly as the method has only one line of code, calling a function, and this function ReturnVar happens to be in the library I am trying to convert. But the same call to the IC2DBServer method is used in other libraries too where ReturnVar is not available. In this case I wanted a clear method of IC2DBServer which tells me what I am doing instead of a call to a function. But other cases are different.
I can't check if the Extensions solution would work currently, see next posting.
Dick