XSharpPublic icon indicating copy to clipboard operation
XSharpPublic copied to clipboard

VO incompatibility resolving GLOBALs/DEFINEs

Open cpyrgas opened this issue 1 year ago • 2 comments

https://www.xsharp.eu/forum/topic?p=30408#p30408

Following should probably apply only to the VO dialect, and let other dialects handle this differently.

In VO, when there's a name ambiguity, the compiler resolves identifiers used inside a class in this order:

  1. Class fields
  2. GLOBAL/DEFINE
  3. Class ACCESS/ASSIGN

In X#, currently it resolves to ACCESS/ASSIGN before GLOBAL/DEFINE, causing unintended recursive calls

The following code compiles with no errors in VO, except for the two lines that are supposed to produce one. In X#, it's the opposite:

/*
prg(25,3): error XS0154: The property or indexer 'NewTest.dTest2' cannot be used in this context because it lacks the get accessor
prg(26,3): error XS0200: Property or indexer 'NewTest.gTest2' cannot be assigned to -- it is read only
prg(32,3): error XS0154: The property or indexer 'NewTest.dTest2' cannot be used in this context because it lacks the get accessor
prg(33,3): error XS0200: Property or indexer 'NewTest.gTest2' cannot be assigned to -- it is read only
*/

GLOBAL gTest1 := "global"
DEFINE dTest1 := "define"

GLOBAL gTest2 := "global"
DEFINE dTest2 := "define"

CLASS NewTest
	EXPORT gTest1 := "class"
	EXPORT dTest1 := "class"
	METHOD TestMethod()
		? gTest1
		? dTest1
		gTest1 := "class modified"
		? gTest1
		
		dTest1 := "class modified"
		? dTest1
		
		dTest2 := "should report compiler error since it refers to a define" // error in VO, no error in X#
	RETURN NIL
		

	ACCESS gTest2()
		? gTest2
		? dTest2 // error in X#
		gTest2 := "global modified" // error in X#
		? gTest2
	RETURN "access"

	ASSIGN dTest2(u)
		? gTest2
		? dTest2 // error in X#
		gTest2 := "global modified again" // error in X#
		? gTest2
		
		dTest2 := "should report compiler error since it refers to a define" // error in VO, no error in X#
END CLASS

FUNCTION Start() AS VOID
	LOCAL o AS NewTest
	o := NewTest{}
	o:TestMethod()
	? "-----------"
	? o:gTest2
	? "-----------"
	gTest2 := "global"
	o:dTest2 := "test"

cpyrgas avatar Jul 16 '24 21:07 cpyrgas

The fix for this will need to be tested also in conjunction with the /enforceself option. Not that in VO it is always mandatory to use SELF: for accessing methods and access/assigns. but not for class fields!!! In X# when enabling this option it requires SELF: everywhere, and I think we should keep it this way.

cpyrgas avatar Jul 16 '24 21:07 cpyrgas

Also note that GLOBALs/DEFINEs should be resolved before properties (but still after class fields) even if they are defined in a separate library.

cpyrgas avatar Jul 16 '24 21:07 cpyrgas