feat(resolver): add error to prevent returning value from init
This commit is contained in:
@@ -7,6 +7,7 @@ from src.ast.expr import Expr, LogicalExpr, VariableExpr, LiteralExpr, GroupingE
|
|||||||
AssignExpr, GetExpr, SetExpr, ThisExpr
|
AssignExpr, GetExpr, SetExpr, ThisExpr
|
||||||
from src.ast.stmt import Stmt, ForStmt, WhileStmt, LetStmt, ReturnStmt, IfStmt, FunctionStmt, \
|
from src.ast.stmt import Stmt, ForStmt, WhileStmt, LetStmt, ReturnStmt, IfStmt, FunctionStmt, \
|
||||||
ExpressionStmt, BlockStmt, BreakStmt, ContinueStmt, ClassStmt
|
ExpressionStmt, BlockStmt, BreakStmt, ContinueStmt, ClassStmt
|
||||||
|
from src.consts import CONSTRUCTOR_NAME
|
||||||
from src.pebble import Pebble
|
from src.pebble import Pebble
|
||||||
from src.token import Token
|
from src.token import Token
|
||||||
|
|
||||||
@@ -17,6 +18,7 @@ if TYPE_CHECKING:
|
|||||||
class FunctionType(Enum):
|
class FunctionType(Enum):
|
||||||
NONE = auto()
|
NONE = auto()
|
||||||
FUNCTION = auto()
|
FUNCTION = auto()
|
||||||
|
INITIALIZER = auto()
|
||||||
METHOD = auto()
|
METHOD = auto()
|
||||||
|
|
||||||
|
|
||||||
@@ -136,7 +138,10 @@ class Resolver(Expr.Visitor[None], Stmt.Visitor[None]):
|
|||||||
self.scopes[-1]["this"] = True
|
self.scopes[-1]["this"] = True
|
||||||
|
|
||||||
for method in stmt.methods:
|
for method in stmt.methods:
|
||||||
self.resolve_function(method, FunctionType.METHOD)
|
declaration: FunctionType = FunctionType.METHOD
|
||||||
|
if method.name.lexeme == CONSTRUCTOR_NAME:
|
||||||
|
declaration = FunctionType.INITIALIZER
|
||||||
|
self.resolve_function(method, declaration)
|
||||||
|
|
||||||
self.end_scope()
|
self.end_scope()
|
||||||
self.current_class = enclosing_class
|
self.current_class = enclosing_class
|
||||||
@@ -160,6 +165,8 @@ class Resolver(Expr.Visitor[None], Stmt.Visitor[None]):
|
|||||||
Pebble.token_error(stmt.keyword, "Cannot return from top-level scope.")
|
Pebble.token_error(stmt.keyword, "Cannot return from top-level scope.")
|
||||||
|
|
||||||
if stmt.value is not None:
|
if stmt.value is not None:
|
||||||
|
if self.current_func == FunctionType.INITIALIZER:
|
||||||
|
Pebble.token_error(stmt.keyword, "Cannot return a value from an initializer.")
|
||||||
self.resolve(stmt.value)
|
self.resolve(stmt.value)
|
||||||
|
|
||||||
def visit_let_stmt(self, stmt: LetStmt) -> None:
|
def visit_let_stmt(self, stmt: LetStmt) -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user