Always give class literals a block scope
Class methods always have the class scope on their scope chain in order to implement strong mode checks. Previously, that scope wasn't attached to the ClassLiteral for anonymous classes (since the scope contained no bindings). This patch simply puts that same scope on the ClassLiteral, anonymous or not, which simplifies other code that needs to reason about the scope of a class and its methods. Review URL: https://codereview.chromium.org/1413903002 Cr-Commit-Position: refs/heads/master@{#31371}
This commit is contained in:
parent
80df08b59f
commit
cf13dda1ba
@ -1533,20 +1533,15 @@ void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
|
||||
|
||||
|
||||
void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) {
|
||||
if (expr->scope() == NULL) {
|
||||
// Visit class literal in the same scope, no declarations.
|
||||
// Visit declarations and class literal in a block scope.
|
||||
if (expr->scope()->ContextLocalCount() > 0) {
|
||||
Node* context = BuildLocalBlockContext(expr->scope());
|
||||
ContextScope scope(this, expr->scope(), context);
|
||||
VisitDeclarations(expr->scope()->declarations());
|
||||
VisitClassLiteralContents(expr);
|
||||
} else {
|
||||
// Visit declarations and class literal in a block scope.
|
||||
if (expr->scope()->ContextLocalCount() > 0) {
|
||||
Node* context = BuildLocalBlockContext(expr->scope());
|
||||
ContextScope scope(this, expr->scope(), context);
|
||||
VisitDeclarations(expr->scope()->declarations());
|
||||
VisitClassLiteralContents(expr);
|
||||
} else {
|
||||
VisitDeclarations(expr->scope()->declarations());
|
||||
VisitClassLiteralContents(expr);
|
||||
}
|
||||
VisitDeclarations(expr->scope()->declarations());
|
||||
VisitClassLiteralContents(expr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1644,8 +1639,7 @@ void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) {
|
||||
literal = NewNode(op, literal, proto);
|
||||
|
||||
// Assign to class variable.
|
||||
if (expr->scope() != NULL) {
|
||||
DCHECK_NOT_NULL(expr->class_variable_proxy());
|
||||
if (expr->class_variable_proxy() != nullptr) {
|
||||
Variable* var = expr->class_variable_proxy()->var();
|
||||
FrameStateBeforeAndAfter states(this, BailoutId::None());
|
||||
VectorSlotPair feedback = CreateVectorSlotPair(
|
||||
|
@ -1273,8 +1273,7 @@ void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) {
|
||||
|
||||
EmitClassDefineProperties(lit);
|
||||
|
||||
if (lit->scope() != NULL) {
|
||||
DCHECK_NOT_NULL(lit->class_variable_proxy());
|
||||
if (lit->class_variable_proxy() != nullptr) {
|
||||
EmitVariableAssignment(lit->class_variable_proxy()->var(),
|
||||
Token::INIT_CONST, lit->ProxySlot());
|
||||
}
|
||||
|
@ -4895,15 +4895,13 @@ ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
|
||||
block_scope->language_mode());
|
||||
}
|
||||
|
||||
// Note that we do not finalize this block scope because strong
|
||||
// mode uses it as a sentinel value indicating an anonymous class.
|
||||
block_scope->set_end_position(end_pos);
|
||||
|
||||
if (name != NULL) {
|
||||
DCHECK_NOT_NULL(proxy);
|
||||
proxy->var()->set_initializer_position(end_pos);
|
||||
} else {
|
||||
// Unnamed classes should not have scopes (the scope will be empty).
|
||||
DCHECK_EQ(block_scope->num_var_or_const(), 0);
|
||||
block_scope = nullptr;
|
||||
}
|
||||
|
||||
return factory()->NewClassLiteral(name, block_scope, proxy, extends,
|
||||
|
Loading…
Reference in New Issue
Block a user