feat(resolver): add error for this outside of class

This commit is contained in:
2026-02-06 22:53:48 +01:00
parent 0871c7875a
commit de3d5f3aef

View File

@@ -26,12 +26,18 @@ class LoopType(Enum):
FOR = auto() FOR = auto()
class ClassType(Enum):
NONE = auto()
CLASS = auto()
class Resolver(Expr.Visitor[None], Stmt.Visitor[None]): class Resolver(Expr.Visitor[None], Stmt.Visitor[None]):
def __init__(self, interpreter: Interpreter): def __init__(self, interpreter: Interpreter):
self.interpreter: Interpreter = interpreter self.interpreter: Interpreter = interpreter
self.scopes: list[dict[str, bool]] = [] self.scopes: list[dict[str, bool]] = []
self.current_func: FunctionType = FunctionType.NONE self.current_func: FunctionType = FunctionType.NONE
self.current_loop: LoopType = LoopType.NONE self.current_loop: LoopType = LoopType.NONE
self.current_class: ClassType = ClassType.NONE
def resolve(self, *objects: Expr | Stmt) -> None: def resolve(self, *objects: Expr | Stmt) -> None:
for obj in objects: for obj in objects:
@@ -111,6 +117,8 @@ class Resolver(Expr.Visitor[None], Stmt.Visitor[None]):
self.resolve(expr.object) self.resolve(expr.object)
def visit_this_expr(self, expr: ThisExpr) -> None: def visit_this_expr(self, expr: ThisExpr) -> None:
if self.current_class == ClassType.NONE:
Pebble.token_error(expr.keyword, "Cannot use 'this' outside of a class.")
self.resolve_local(expr, expr.keyword) self.resolve_local(expr, expr.keyword)
def visit_block_stmt(self, stmt: BlockStmt) -> None: def visit_block_stmt(self, stmt: BlockStmt) -> None:
@@ -119,6 +127,8 @@ class Resolver(Expr.Visitor[None], Stmt.Visitor[None]):
self.end_scope() self.end_scope()
def visit_class_stmt(self, stmt: ClassStmt) -> None: def visit_class_stmt(self, stmt: ClassStmt) -> None:
enclosing_class: ClassType = self.current_class
self.current_class = ClassType.CLASS
self.declare(stmt.name) self.declare(stmt.name)
self.define(stmt.name) self.define(stmt.name)
@@ -129,6 +139,7 @@ class Resolver(Expr.Visitor[None], Stmt.Visitor[None]):
self.resolve_function(method, FunctionType.METHOD) self.resolve_function(method, FunctionType.METHOD)
self.end_scope() self.end_scope()
self.current_class = enclosing_class
def visit_expression_stmt(self, stmt: ExpressionStmt) -> None: def visit_expression_stmt(self, stmt: ExpressionStmt) -> None:
self.resolve(stmt.expression) self.resolve(stmt.expression)