1
0
forked from aniani/vim

patch 9.0.2084: Vim9: abstract static methods are possible

Problem:  Vim9: abstract static methods are possible
Solution: Disallow abstract static methods

fixes: #13462
closes: #13466

Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Yegappan Lakshmanan 2023-11-02 20:43:57 +01:00 committed by Christian Brabandt
parent 1858e2b22a
commit ef9e3f8924
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09
5 changed files with 25 additions and 26 deletions

View File

@ -411,6 +411,8 @@ prefix when defining the method: >
abstract static def SetColor() abstract static def SetColor()
endclass endclass
< <
A static method in an abstract class cannot be an abstract method.
*E1373* *E1373*
A class extending the abstract class must implement all the abstract methods. A class extending the abstract class must implement all the abstract methods.
The signature (arguments, argument types and return type) must be exactly the The signature (arguments, argument types and return type) must be exactly the

View File

@ -3494,8 +3494,8 @@ EXTERN char e_duplicate_variable_str[]
INIT(= N_("E1369: Duplicate variable: %s")); INIT(= N_("E1369: Duplicate variable: %s"));
EXTERN char e_cannot_define_new_method_as_static[] EXTERN char e_cannot_define_new_method_as_static[]
INIT(= N_("E1370: Cannot define a \"new\" method as static")); INIT(= N_("E1370: Cannot define a \"new\" method as static"));
EXTERN char e_abstract_must_be_followed_by_def_or_static[] EXTERN char e_abstract_must_be_followed_by_def[]
INIT(= N_("E1371: Abstract must be followed by \"def\" or \"static\"")); INIT(= N_("E1371: Abstract must be followed by \"def\""));
EXTERN char e_abstract_method_in_concrete_class[] EXTERN char e_abstract_method_in_concrete_class[]
INIT(= N_("E1372: Abstract method \"%s\" cannot be defined in a concrete class")); INIT(= N_("E1372: Abstract method \"%s\" cannot be defined in a concrete class"));
EXTERN char e_abstract_method_str_not_found[] EXTERN char e_abstract_method_str_not_found[]

View File

@ -35,7 +35,7 @@ def Test_class_basic()
END END
v9.CheckSourceFailure(lines, 'E475: Invalid argument: noclass Something', 2) v9.CheckSourceFailure(lines, 'E475: Invalid argument: noclass Something', 2)
# Only the completed word "class" should be recognized # Only the complete word "class" should be recognized
lines =<< trim END lines =<< trim END
vim9script vim9script
abstract classy Something abstract classy Something
@ -4186,8 +4186,8 @@ enddef
def Test_lockvar_islocked() def Test_lockvar_islocked()
# Can't lock class/object variable # Can't lock class/object variable
# Lock class/object variable's value # Lock class/object variable's value
# Lock item of variabl's value (a list item) # Lock item of variable's value (a list item)
# varible is at index 1 within class/object # variable is at index 1 within class/object
var lines =<< trim END var lines =<< trim END
vim9script vim9script
@ -5585,7 +5585,7 @@ def Test_abstract_method()
abstract this.val = 10 abstract this.val = 10
endclass endclass
END END
v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def" or "static"', 3) v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
# Use a static abstract method # Use a static abstract method
lines =<< trim END lines =<< trim END
@ -5593,14 +5593,8 @@ def Test_abstract_method()
abstract class A abstract class A
abstract static def Foo(): number abstract static def Foo(): number
endclass endclass
class B extends A
static def Foo(): number
return 4
enddef
endclass
assert_equal(4, B.Foo())
END END
v9.CheckSourceSuccess(lines) v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
# Type mismatch between abstract method and concrete method # Type mismatch between abstract method and concrete method
lines =<< trim END lines =<< trim END
@ -5616,17 +5610,6 @@ def Test_abstract_method()
END END
v9.CheckSourceFailure(lines, 'E1383: Method "Foo": type mismatch, expected func(string, number): list<number> but got func(number, string): list<string>', 9) v9.CheckSourceFailure(lines, 'E1383: Method "Foo": type mismatch, expected func(string, number): list<number> but got func(number, string): list<string>', 9)
# Use an abstract class to invoke an abstract method
# FIXME: This should fail
lines =<< trim END
vim9script
abstract class A
abstract static def Foo()
endclass
A.Foo()
END
v9.CheckSourceSuccess(lines)
# Invoke an abstract method from a def function # Invoke an abstract method from a def function
lines =<< trim END lines =<< trim END
vim9script vim9script
@ -5645,6 +5628,18 @@ def Test_abstract_method()
Bar(b) Bar(b)
END END
v9.CheckSourceSuccess(lines) v9.CheckSourceSuccess(lines)
# Use a static method in an abstract class
lines =<< trim END
vim9script
abstract class A
static def Foo(): string
return 'foo'
enddef
endclass
assert_equal('foo', A.Foo())
END
v9.CheckSourceSuccess(lines)
enddef enddef
" Test for calling a class method from a subclass " Test for calling a class method from a subclass

View File

@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
2084,
/**/ /**/
2083, 2083,
/**/ /**/

View File

@ -1571,9 +1571,9 @@ early_ret:
abstract_method = TRUE; abstract_method = TRUE;
p = skipwhite(pa + 8); p = skipwhite(pa + 8);
if (STRNCMP(p, "def", 3) != 0 && STRNCMP(p, "static", 6) != 0) if (STRNCMP(p, "def", 3) != 0)
{ {
emsg(_(e_abstract_must_be_followed_by_def_or_static)); emsg(_(e_abstract_must_be_followed_by_def));
break; break;
} }
} }