summaryrefslogtreecommitdiff
path: root/chromium/v8/src/parsing/expression-scope.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8/src/parsing/expression-scope.h')
-rw-r--r--chromium/v8/src/parsing/expression-scope.h92
1 files changed, 77 insertions, 15 deletions
diff --git a/chromium/v8/src/parsing/expression-scope.h b/chromium/v8/src/parsing/expression-scope.h
index 5a6ef376a8a..ba931d36dab 100644
--- a/chromium/v8/src/parsing/expression-scope.h
+++ b/chromium/v8/src/parsing/expression-scope.h
@@ -5,6 +5,8 @@
#ifndef V8_PARSING_EXPRESSION_SCOPE_H_
#define V8_PARSING_EXPRESSION_SCOPE_H_
+#include <utility>
+
#include "src/ast/scopes.h"
#include "src/common/message-template.h"
#include "src/objects/function-kind.h"
@@ -82,6 +84,12 @@ class ExpressionScope {
AsExpressionParsingScope()->ClearExpressionError();
}
+ void ValidateAsExpression() {
+ if (!CanBeExpression()) return;
+ AsExpressionParsingScope()->ValidateExpression();
+ AsExpressionParsingScope()->ClearPatternError();
+ }
+
// Record async arrow parameters errors in all ambiguous async arrow scopes in
// the chain up to the first unambiguous scope.
void RecordAsyncArrowParametersError(const Scanner::Location& loc,
@@ -173,6 +181,18 @@ class ExpressionScope {
return IsInRange(type_, kParameterDeclaration, kLexicalDeclaration);
}
+ int SetInitializers(int variable_index, int peek_position) {
+ if (CanBeExpression()) {
+ return AsExpressionParsingScope()->SetInitializers(variable_index,
+ peek_position);
+ }
+ return variable_index;
+ }
+
+ bool has_possible_arrow_parameter_in_scope_chain() const {
+ return has_possible_arrow_parameter_in_scope_chain_;
+ }
+
protected:
enum ScopeType : uint8_t {
// Expression or assignment target.
@@ -201,7 +221,11 @@ class ExpressionScope {
type_(type),
has_possible_parameter_in_scope_chain_(
CanBeParameterDeclaration() ||
- (parent_ && parent_->has_possible_parameter_in_scope_chain_)) {
+ (parent_ && parent_->has_possible_parameter_in_scope_chain_)),
+ has_possible_arrow_parameter_in_scope_chain_(
+ CanBeArrowParameterDeclaration() ||
+ (parent_ &&
+ parent_->has_possible_arrow_parameter_in_scope_chain_)) {
parser->expression_scope_ = this;
}
@@ -265,6 +289,10 @@ class ExpressionScope {
return IsInRange(type_, kMaybeArrowParameterDeclaration,
kParameterDeclaration);
}
+ bool CanBeArrowParameterDeclaration() const {
+ return IsInRange(type_, kMaybeArrowParameterDeclaration,
+ kMaybeAsyncArrowParameterDeclaration);
+ }
bool IsCertainlyParameterDeclaration() const {
return type_ == kParameterDeclaration;
}
@@ -273,6 +301,7 @@ class ExpressionScope {
ExpressionScope<Types>* parent_;
ScopeType type_;
bool has_possible_parameter_in_scope_chain_;
+ bool has_possible_arrow_parameter_in_scope_chain_;
DISALLOW_COPY_AND_ASSIGN(ExpressionScope);
};
@@ -458,8 +487,8 @@ class ExpressionParsingScope : public ExpressionScope<Types> {
ExpressionScopeT::Report(Scanner::Location(begin, end),
MessageTemplate::kInvalidDestructuringTarget);
}
- for (VariableProxy* proxy : variable_list_) {
- proxy->set_is_assigned();
+ for (auto& variable_initializer_pair : variable_list_) {
+ variable_initializer_pair.first->set_is_assigned();
}
}
@@ -471,18 +500,46 @@ class ExpressionParsingScope : public ExpressionScope<Types> {
clear(kExpressionIndex);
}
+ void ClearPatternError() {
+ DCHECK(verified_);
+#ifdef DEBUG
+ verified_ = false;
+#endif
+ clear(kPatternIndex);
+ }
+
void TrackVariable(VariableProxy* variable) {
if (!this->CanBeDeclaration()) {
this->parser()->scope()->AddUnresolved(variable);
}
- variable_list_.Add(variable);
+ variable_list_.Add({variable, kNoSourcePosition});
}
void MarkIdentifierAsAssigned() {
// It's possible we're parsing a syntax error. In that case it's not
// guaranteed that there's a variable in the list.
if (variable_list_.length() == 0) return;
- variable_list_.at(variable_list_.length() - 1)->set_is_assigned();
+ variable_list_.at(variable_list_.length() - 1).first->set_is_assigned();
+ }
+
+ int SetInitializers(int first_variable_index, int position) {
+ int len = variable_list_.length();
+ if (len == 0) return 0;
+
+ int end = len - 1;
+ // Loop backwards and abort as soon as we see one that's already set to
+ // avoid a loop on expressions like a,b,c,d,e,f,g (outside of an arrowhead).
+ // TODO(delphick): Look into removing this loop.
+ for (int i = end; i >= first_variable_index &&
+ variable_list_.at(i).second == kNoSourcePosition;
+ --i) {
+ variable_list_.at(i).second = position;
+ }
+ return end;
+ }
+
+ ScopedList<std::pair<VariableProxy*, int>>* variable_list() {
+ return &variable_list_;
}
protected:
@@ -496,8 +553,6 @@ class ExpressionParsingScope : public ExpressionScope<Types> {
void ValidatePattern() { Validate(kPatternIndex); }
- ScopedPtrList<VariableProxy>* variable_list() { return &variable_list_; }
-
private:
friend class AccumulationScope<Types>;
@@ -542,7 +597,7 @@ class ExpressionParsingScope : public ExpressionScope<Types> {
bool verified_ = false;
#endif
- ScopedPtrList<VariableProxy> variable_list_;
+ ScopedList<std::pair<VariableProxy*, int>> variable_list_;
MessageTemplate messages_[kNumberOfErrors];
Scanner::Location locations_[kNumberOfErrors];
bool has_async_arrow_in_scope_chain_;
@@ -665,7 +720,8 @@ class ArrowHeadParsingScope : public ExpressionParsingScope<Types> {
// references.
this->parser()->next_arrow_function_info_.ClearStrictParameterError();
ExpressionParsingScope<Types>::ValidateExpression();
- for (VariableProxy* proxy : *this->variable_list()) {
+ for (auto& proxy_initializer_pair : *this->variable_list()) {
+ VariableProxy* proxy = proxy_initializer_pair.first;
this->parser()->scope()->AddUnresolved(proxy);
}
}
@@ -683,21 +739,27 @@ class ArrowHeadParsingScope : public ExpressionParsingScope<Types> {
VariableKind kind = PARAMETER_VARIABLE;
VariableMode mode =
has_simple_parameter_list_ ? VariableMode::kVar : VariableMode::kLet;
- for (VariableProxy* proxy : *this->variable_list()) {
+ for (auto& proxy_initializer_pair : *this->variable_list()) {
+ VariableProxy* proxy = proxy_initializer_pair.first;
+ int initializer_position = proxy_initializer_pair.second;
+ // Default values for parameters will have been parsed as assignments so
+ // clear the is_assigned bit as they are not actually assignments.
+ proxy->clear_is_assigned();
bool was_added;
- this->parser()->DeclareAndBindVariable(
- proxy, kind, mode, Variable::DefaultInitializationFlag(mode), result,
- &was_added, proxy->position());
+ this->parser()->DeclareAndBindVariable(proxy, kind, mode, result,
+ &was_added, initializer_position);
if (!was_added) {
ExpressionScope<Types>::Report(proxy->location(),
MessageTemplate::kParamDupe);
}
}
- int initializer_position = this->parser()->end_position();
+#ifdef DEBUG
for (auto declaration : *result->declarations()) {
- declaration->var()->set_initializer_position(initializer_position);
+ DCHECK_NE(declaration->var()->initializer_position(), kNoSourcePosition);
}
+#endif // DEBUG
+
if (uses_this_) result->UsesThis();
return result;
}