Reviewers: rossberg,
Message:
rossberg, here's another potential simplification, wdyt?
(This way, we wouldn't need to store the "corresponding outer class var"
into
the ScopeInfo (idk even how to exactly), but it would be enough to store
only
the declaration group...
Description:
[strong] Simplify the classes-referring-to-classes check.
Follow up for r28032.
We don't need to store the "corresponding outer scope class variables", it's
enough if we transmit the declaration group start to the inner class
variable.
[email protected]
BUG=v8:3956
LOG=N
Please review this at https://codereview.chromium.org/1102903002/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+42, -52 lines):
M src/parser.cc
M src/scopes.cc
M src/variables.h
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index
f97174136887ae5be63b81dc44b3a8eea62b9da2..af186270ee87307f13fd3694bf7c9de8aa78c9b3
100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -2199,6 +2199,10 @@ Statement*
Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
scope_->class_declaration_group_start());
Variable* outer_class_variable = Declare(declaration, true, CHECK_OK);
proxy->var()->set_initializer_position(position());
+ // This is needed because a class ("class Name { }") creates two
bindings (one
+ // in the outer scope, and one in the class scope). The method is a
function
+ // scope inside the inner scope (class scope). The consecutive class
+ // declarations are in the outer scope.
if (value->class_variable_proxy() &&
value->class_variable_proxy()->var() &&
outer_class_variable->is_class()) {
// In some cases, the outer variable is not detected as a class
variable;
@@ -2208,8 +2212,8 @@ Statement*
Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
value->class_variable_proxy()
->var()
->AsClassVariable()
- ->set_corresponding_outer_class_variable(
- outer_class_variable->AsClassVariable());
+ ->set_declaration_group_start(
+
outer_class_variable->AsClassVariable()->declaration_group_start());
}
Token::Value init_op =
Index: src/scopes.cc
diff --git a/src/scopes.cc b/src/scopes.cc
index
86c75ad8d7c23b91200ff4d3c78d1f982d2f261c..8b623f90ce908ac548bfd8ea46bdcf088121bbcf
100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -1168,48 +1168,40 @@ bool
Scope::CheckStrongModeDeclaration(VariableProxy* proxy, Variable* var) {
for (scope = this; scope && scope != var->scope();
scope = scope->outer_scope()) {
ClassVariable* class_var = scope->ClassVariableForMethod();
- if (class_var) {
- // A method is referring to some other class, possibly declared
- // later. Referring to a class declared earlier is always OK and
covered
- // by the code outside this if. Here we only need to allow special
cases
- // for referring to a class which is declared later.
-
- // Referring to a class C declared later is OK under the following
- // circumstances:
-
- // 1. The class declarations are in a consecutive group with no
other
- // declarations or statements in between, and
-
- // 2. There is no dependency cycle where the first edge is an
- // initialization time dependency (computed property name or
extends
- // clause) from C to something that depends on this class directly
or
- // transitively.
-
- // This is needed because a class ("class Name { }") creates two
- // bindings (one in the outer scope, and one in the class scope).
The
- // method is a function scope inside the inner scope (class
scope). The
- // consecutive class declarations are in the outer scope.
- class_var = class_var->corresponding_outer_class_variable();
- if (class_var &&
- class_var->declaration_group_start() ==
- var->AsClassVariable()->declaration_group_start()) {
- return true;
- }
-
- // TODO(marja,rossberg): implement the dependency cycle detection.
Here
- // we undershoot the target and allow referring to any class in
the same
- // consectuive declaration group.
-
- // The cycle detection can work roughly like this: 1) detect
init-time
- // references here (they are free variables which are inside the
class
- // scope but not inside a method scope - no parser changes needed
to
- // detect them) 2) if we encounter an init-time reference here,
allow
- // it, but record it for a later dependency cycle check 3) also
record
- // non-init-time references here 4) after scope analysis is done,
- // analyse the dependency cycles: an illegal cycle is one starting
with
- // an init-time reference and leading back to the starting point
with
- // either non-init-time and init-time references.
+ // A method is referring to some other class, possibly declared
+ // later. Referring to a class declared earlier is always OK and
covered
+ // by the code outside this if. Here we only need to allow special
cases
+ // for referring to a class which is declared later.
+
+ // Referring to a class C declared later is OK under the following
+ // circumstances:
+
+ // 1. The class declarations are in a consecutive group with no other
+ // declarations or statements in between, and
+
+ // 2. There is no dependency cycle where the first edge is an
+ // initialization time dependency (computed property name or extends
+ // clause) from C to something that depends on this class directly or
+ // transitively.
+ if (class_var &&
+ class_var->declaration_group_start() ==
+ var->AsClassVariable()->declaration_group_start()) {
+ return true;
}
+
+ // TODO(marja,rossberg): implement the dependency cycle detection.
Here we
+ // undershoot the target and allow referring to any class in the same
+ // consectuive declaration group.
+
+ // The cycle detection can work roughly like this: 1) detect
init-time
+ // references here (they are free variables which are inside the
class
+ // scope but not inside a method scope - no parser changes needed to
+ // detect them) 2) if we encounter an init-time reference here,
allow it,
+ // but record it for a later dependency cycle check 3) also record
+ // non-init-time references here 4) after scope analysis is done,
analyse
+ // the dependency cycles: an illegal cycle is one starting with an
+ // init-time reference and leading back to the starting point with
either
+ // non-init-time and init-time references.
}
}
Index: src/variables.h
diff --git a/src/variables.h b/src/variables.h
index
31bfe42dc098e43fa4b6deabdfda076a96ee7596..384a8859545045ac502c5f80cc7a8229ddd81d75
100644
--- a/src/variables.h
+++ b/src/variables.h
@@ -192,16 +192,11 @@ class ClassVariable : public Variable {
int declaration_group_start = -1)
: Variable(scope, name, mode, Variable::CLASS, initialization_flag,
maybe_assigned_flag),
- declaration_group_start_(declaration_group_start),
- corresponding_outer_class_variable_(nullptr) {}
+ declaration_group_start_(declaration_group_start) {}
int declaration_group_start() const { return declaration_group_start_; }
-
- ClassVariable* corresponding_outer_class_variable() const {
- return corresponding_outer_class_variable_;
- }
- void set_corresponding_outer_class_variable(ClassVariable* var) {
- corresponding_outer_class_variable_ = var;
+ void set_declaration_group_start(int declaration_group_start) {
+ declaration_group_start_ = declaration_group_start;
}
private:
@@ -209,7 +204,6 @@ class ClassVariable : public Variable {
// needed for strong mode scoping checks. TODO(marja, rossberg):
Implement
// checks for functions too.
int declaration_group_start_;
- ClassVariable* corresponding_outer_class_variable_;
};
} } // namespace v8::internal
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.