forked from aniani/vim
patch 9.0.1909: Vim9: problem calling class method from other class
Problem: Vim9: problem calling class method from other class
Solution: Fix this problem, fix readonly object access, update error
messages.
Calling a class method from another method without the class name prefix
doesn't work properly.
A readonly object variable is modifiable outside the class using a
nested object assignment.
Remove the unused E1338 error message.
Update error messages.
closes: #13116
Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
This commit is contained in:
committed by
Christian Brabandt
parent
d25021cf03
commit
00cd18222e
@@ -4418,13 +4418,11 @@ E1325 vim9class.txt /*E1325*
|
||||
E1326 vim9class.txt /*E1326*
|
||||
E1327 vim9class.txt /*E1327*
|
||||
E1328 vim9class.txt /*E1328*
|
||||
E1329 vim9class.txt /*E1329*
|
||||
E133 userfunc.txt /*E133*
|
||||
E1330 vim9class.txt /*E1330*
|
||||
E1331 vim9class.txt /*E1331*
|
||||
E1332 vim9class.txt /*E1332*
|
||||
E1333 vim9class.txt /*E1333*
|
||||
E1334 vim9class.txt /*E1334*
|
||||
E1335 vim9class.txt /*E1335*
|
||||
E1336 options.txt /*E1336*
|
||||
E1337 vim9class.txt /*E1337*
|
||||
@@ -4458,9 +4456,27 @@ E1361 syntax.txt /*E1361*
|
||||
E1362 vim9class.txt /*E1362*
|
||||
E1363 vim9class.txt /*E1363*
|
||||
E1364 recover.txt /*E1364*
|
||||
E1365 vim9class.txt /*E1365*
|
||||
E1366 vim9class.txt /*E1366*
|
||||
E1367 vim9class.txt /*E1367*
|
||||
E1368 vim9class.txt /*E1368*
|
||||
E1369 vim9class.txt /*E1369*
|
||||
E137 starting.txt /*E137*
|
||||
E1370 vim9class.txt /*E1370*
|
||||
E1371 vim9class.txt /*E1371*
|
||||
E1372 vim9class.txt /*E1372*
|
||||
E1373 vim9class.txt /*E1373*
|
||||
E1374 vim9class.txt /*E1374*
|
||||
E1375 vim9class.txt /*E1375*
|
||||
E1376 vim9class.txt /*E1376*
|
||||
E1377 vim9class.txt /*E1377*
|
||||
E1378 vim9class.txt /*E1378*
|
||||
E1379 vim9class.txt /*E1379*
|
||||
E138 starting.txt /*E138*
|
||||
E1380 vim9class.txt /*E1380*
|
||||
E1381 vim9class.txt /*E1381*
|
||||
E1382 vim9class.txt /*E1382*
|
||||
E1383 vim9class.txt /*E1383*
|
||||
E139 message.txt /*E139*
|
||||
E140 message.txt /*E140*
|
||||
E1400 builtin.txt /*E1400*
|
||||
@@ -6367,7 +6383,7 @@ cino-{ indent.txt /*cino-{*
|
||||
cino-} indent.txt /*cino-}*
|
||||
cinoptions-values indent.txt /*cinoptions-values*
|
||||
class vim9class.txt /*class*
|
||||
class-function vim9class.txt /*class-function*
|
||||
class-method vim9class.txt /*class-method*
|
||||
clear-undo undo.txt /*clear-undo*
|
||||
clearmatches() builtin.txt /*clearmatches()*
|
||||
client-server remote.txt /*client-server*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*vim9class.txt* For Vim version 9.0. Last change: 2023 Mar 22
|
||||
*vim9class.txt* For Vim version 9.0. Last change: 2023 Sep 18
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -11,7 +11,7 @@ Vim9 classes, objects, interfaces, types and enums.
|
||||
|
||||
1. Overview |Vim9-class-overview|
|
||||
2. A simple class |Vim9-simple-class|
|
||||
3. Class members and functions |Vim9-class-member|
|
||||
3. Class variables and methods |Vim9-class-member|
|
||||
4. Using an abstract class |Vim9-abstract-class|
|
||||
5. Using an interface |Vim9-using-interface|
|
||||
6. More class details |Vim9-class|
|
||||
@@ -139,11 +139,13 @@ changed at any time, you can make it public: >
|
||||
|
||||
Now you don't need the SetLnum(), SetCol() and SetPosition() methods, setting
|
||||
"pos.lnum" directly above will no longer give an error.
|
||||
*E1334*
|
||||
*E1326*
|
||||
If you try to set an object member that doesn't exist you get an error: >
|
||||
pos.other = 9
|
||||
< E1334: Object member not found: other ~
|
||||
< E1326: Member not found on object "TextPosition": other ~
|
||||
|
||||
*E1376*
|
||||
A object member cannot be accessed using the class name.
|
||||
|
||||
Private members ~
|
||||
*E1332* *E1333*
|
||||
@@ -176,9 +178,9 @@ number to the total number of lines: >
|
||||
endif
|
||||
return this._lnum
|
||||
enddef
|
||||
|
||||
|
||||
<
|
||||
Private methods ~
|
||||
*E1366*
|
||||
If you want object methods to be accessible only from other methods of the
|
||||
same class and not used from outside the class, then you can make them
|
||||
private. This is done by prefixing the method name with an underscore: >
|
||||
@@ -252,16 +254,17 @@ If the class extends a parent class, the same thing happens. In the second
|
||||
step the members of the parent class are done first. There is no need to call
|
||||
"super()" or "new()" on the parent.
|
||||
|
||||
*E1365*
|
||||
When defining the new() method the return type should not be specified. It
|
||||
always returns an object of the class.
|
||||
|
||||
==============================================================================
|
||||
|
||||
3. class members and functions *Vim9-class-member*
|
||||
3. Class Variables and Methods *Vim9-class-member*
|
||||
|
||||
*:static* *E1337* *E1338*
|
||||
*:static* *E1337* *E1338* *E1368*
|
||||
Class members are declared with "static". They are used by the name without a
|
||||
prefix: >
|
||||
prefix in the class where they are defined: >
|
||||
|
||||
class OtherThing
|
||||
this.size: number
|
||||
@@ -275,6 +278,10 @@ prefix: >
|
||||
Since the name is used as-is, shadowing the name by a function argument name
|
||||
or local variable name is not allowed.
|
||||
|
||||
*E1374* *E1375*
|
||||
To access a class member outside of the class where it is defined, the class
|
||||
name prefix must be used. A class member cannot be accessed using an object.
|
||||
|
||||
Just like object members the access can be made private by using an underscore
|
||||
as the first character in the name, and it can be made public by prefixing
|
||||
"public": >
|
||||
@@ -285,10 +292,11 @@ as the first character in the name, and it can be made public by prefixing
|
||||
public static result: number # anybody can read and write
|
||||
endclass
|
||||
<
|
||||
*class-function*
|
||||
Class functions are also declared with "static". They have no access to
|
||||
object members, they cannot use the "this" keyword. >
|
||||
|
||||
*class-method*
|
||||
Class methods are also declared with "static". They can use the class
|
||||
variables but they have no access to the object variables, they cannot use the
|
||||
"this" keyword.
|
||||
>
|
||||
class OtherThing
|
||||
this.size: number
|
||||
static totalSize: number
|
||||
@@ -301,8 +309,9 @@ object members, they cannot use the "this" keyword. >
|
||||
enddef
|
||||
endclass
|
||||
|
||||
Inside the class the function can be called by name directly, outside the
|
||||
class the class name must be prefixed: `OtherThing.ClearTotalSize()`.
|
||||
Inside the class the class method can be called by name directly, outside the
|
||||
class the class name must be prefixed: `OtherThing.ClearTotalSize()`. To use
|
||||
a super class method in a child class, the class name must be prefixed.
|
||||
|
||||
Just like object methods the access can be made private by using an underscore
|
||||
as the first character in the method name: >
|
||||
@@ -312,7 +321,7 @@ as the first character in the method name: >
|
||||
echo "Foo"
|
||||
enddef
|
||||
def Bar()
|
||||
OtherThing._Foo()
|
||||
_Foo()
|
||||
enddef
|
||||
endclass
|
||||
<
|
||||
@@ -320,6 +329,31 @@ as the first character in the method name: >
|
||||
Note that constructors cannot be declared as "static", because they always
|
||||
are.
|
||||
|
||||
To access the class methods and class variables of a super class in an
|
||||
extended class, the class name prefix should be used just as from anywhere
|
||||
outside of the defining class: >
|
||||
|
||||
vim9script
|
||||
class Vehicle
|
||||
static nextID: number = 1000
|
||||
static def GetID(): number
|
||||
nextID += 1
|
||||
return nextID
|
||||
enddef
|
||||
endclass
|
||||
class Car extends Vehicle
|
||||
this.myID: number
|
||||
def new()
|
||||
this.myID = Vehicle.GetID()
|
||||
enddef
|
||||
endclass
|
||||
<
|
||||
Class variables and methods are not inherited by a child class. A child class
|
||||
can declare a static variable or a method with the same name as the one in the
|
||||
super class. Depending on the class where the member is used the
|
||||
corresponding class member will be used. The type of the class member in a
|
||||
child class can be different from that in the super class.
|
||||
|
||||
==============================================================================
|
||||
|
||||
4. Using an abstract class *Vim9-abstract-class*
|
||||
@@ -358,16 +392,19 @@ class, for which objects can be created. Example: >
|
||||
An abstract class is defined the same way as a normal class, except that it
|
||||
does not have any new() method. *E1359*
|
||||
|
||||
*abstract-method*
|
||||
*abstract-method* *E1371* *E1372*
|
||||
An abstract method can be defined in an abstract class by using the "abstract"
|
||||
prefix when defining the function: >
|
||||
|
||||
abstract class Shape
|
||||
abstract def Draw()
|
||||
abstract static def SetColor()
|
||||
endclass
|
||||
|
||||
<
|
||||
*E1373*
|
||||
A class extending the abstract class must implement all the abstract methods.
|
||||
Class methods in an abstract class can also be abstract methods.
|
||||
The signature (arguments, argument types and return type) must be exactly the
|
||||
same. Class methods in an abstract class can also be abstract methods.
|
||||
|
||||
==============================================================================
|
||||
|
||||
@@ -409,9 +446,10 @@ a number. This example extends the one above: >
|
||||
return this.base * this.height / 2
|
||||
enddef
|
||||
endclass
|
||||
|
||||
<
|
||||
*E1348* *E1349* *E1367* *E1382* *E1383*
|
||||
If a class declares to implement an interface, all the items specified in the
|
||||
interface must appear in the class, with the same types. *E1348* *E1349*
|
||||
interface must appear in the class, with the same types.
|
||||
|
||||
The interface name can be used as a type: >
|
||||
|
||||
@@ -422,7 +460,14 @@ The interface name can be used as a type: >
|
||||
for shape in shapes
|
||||
echo $'the surface is {shape.Surface()}'
|
||||
endfor
|
||||
<
|
||||
*E1378* *E1379* *E1380*
|
||||
An interface can have only instance variables (read-only and read-write
|
||||
access) and methods. An interface cannot contain private variables, private
|
||||
methods, class variables and class methods.
|
||||
|
||||
An interface can extend another interface using "extends". The sub-interface
|
||||
inherits all the instance variables and methods from the super interface.
|
||||
|
||||
==============================================================================
|
||||
|
||||
@@ -464,9 +509,12 @@ once. They can appear in any order, although this order is recommended: >
|
||||
extends ClassName
|
||||
implements InterfaceName, OtherInterface
|
||||
specifies SomeInterface
|
||||
< *E1355*
|
||||
< *E1355* *E1369*
|
||||
Each member and function name can be used only once. It is not possible to
|
||||
define a function with the same name and different type of arguments.
|
||||
define a function with the same name and different type of arguments. It is
|
||||
not possible to use a public and private member variable with the same name.
|
||||
A object variable name used in a super class cannot be reused in a child
|
||||
class.
|
||||
|
||||
|
||||
Member Initialization ~
|
||||
@@ -491,6 +539,10 @@ Object methods of the base class can be overruled. The signature (arguments,
|
||||
argument types and return type) must be exactly the same. The method of the
|
||||
base class can be called by prefixing "super.".
|
||||
|
||||
*E1377*
|
||||
The access level of a method (public or private) in a child class should be
|
||||
the same as the super class.
|
||||
|
||||
Other object methods of the base class are taken over by the child class.
|
||||
|
||||
Class functions, including functions starting with "new", can be overruled,
|
||||
@@ -523,18 +575,26 @@ interface, which is often done in many languages, especially Java.
|
||||
|
||||
|
||||
Items in a class ~
|
||||
*E1318* *E1325* *E1326*
|
||||
*E1318* *E1325*
|
||||
Inside a class, in between `:class` and `:endclass`, these items can appear:
|
||||
- An object member declaration: >
|
||||
this._memberName: memberType
|
||||
this.memberName: memberType
|
||||
public this.memberName: memberType
|
||||
this._privateMemberName: memberType
|
||||
this.readonlyMemberName: memberType
|
||||
public this.readwriteMemberName: memberType
|
||||
- A class member declaration: >
|
||||
static this._privateMemberName: memberType
|
||||
static this.readonlyMemberName: memberType
|
||||
static public this.readwriteMemberName: memberType
|
||||
- A constructor method: >
|
||||
def new(arguments)
|
||||
def newName(arguments)
|
||||
- A class method: >
|
||||
static def SomeMethod(arguments)
|
||||
static def _PrivateMethod(arguments)
|
||||
- An object method: >
|
||||
def SomeMethod(arguments)
|
||||
< *E1329*
|
||||
def _PrivateMethod(arguments)
|
||||
|
||||
For the object member the type must be specified. The best way is to do this
|
||||
explicitly with ": {type}". For simple types you can also use an initializer,
|
||||
such as "= 123", and Vim will see that the type is a number. Avoid doing this
|
||||
@@ -573,6 +633,8 @@ An interface name must start with an uppercase letter. *E1343*
|
||||
The "Has" prefix can be used to make it easier to guess this is an interface
|
||||
name, with a hint about what it provides.
|
||||
An interface can only be defined in a |Vim9| script file. *E1342*
|
||||
An interface cannot "implement" another interface but it can "extend" another
|
||||
interface. *E1381*
|
||||
|
||||
|
||||
null object ~
|
||||
|
||||
Reference in New Issue
Block a user