Index: src/preparser.h |
diff --git a/src/preparser.h b/src/preparser.h |
index 4ff1a0c07afc588b1d6d5e59fd6b2a9f6ab7ef6d..263e16aab8910925dec24d3ac121710344fb3929 100644 |
--- a/src/preparser.h |
+++ b/src/preparser.h |
@@ -8,6 +8,7 @@ |
#include "src/v8.h" |
#include "src/bailout-reason.h" |
+#include "src/expression-classifier.h" |
#include "src/func-name-inferrer.h" |
#include "src/hashmap.h" |
#include "src/messages.h" |
@@ -18,7 +19,6 @@ |
namespace v8 { |
namespace internal { |
- |
// Common base class shared between parser and pre-parser. Traits encapsulate |
// the differences between Parser and PreParser: |
@@ -54,7 +54,6 @@ namespace internal { |
// typedef ExpressionList; |
// typedef PropertyList; |
// typedef FormalParameter; |
-// typedef FormalParameterScope; |
// // For constructing objects returned by the traversing functions. |
// typedef Factory; |
// }; |
@@ -68,7 +67,6 @@ class ParserBase : public Traits { |
typedef typename Traits::Type::Expression ExpressionT; |
typedef typename Traits::Type::Identifier IdentifierT; |
typedef typename Traits::Type::FormalParameter FormalParameterT; |
- typedef typename Traits::Type::FormalParameterScope FormalParameterScopeT; |
typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; |
typedef typename Traits::Type::Literal LiteralT; |
typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; |
@@ -506,238 +504,8 @@ class ParserBase : public Traits { |
void ReportUnexpectedToken(Token::Value token); |
void ReportUnexpectedTokenAt(Scanner::Location location, Token::Value token); |
- class ExpressionClassifier { |
- public: |
- struct Error { |
- Error() |
- : location(Scanner::Location::invalid()), |
- message(MessageTemplate::kNone), |
- arg(nullptr) {} |
- |
- Scanner::Location location; |
- MessageTemplate::Template message; |
- const char* arg; |
- }; |
- |
- enum TargetProduction { |
- ExpressionProduction = 1 << 0, |
- BindingPatternProduction = 1 << 1, |
- AssignmentPatternProduction = 1 << 2, |
- DistinctFormalParametersProduction = 1 << 3, |
- StrictModeFormalParametersProduction = 1 << 4, |
- StrongModeFormalParametersProduction = 1 << 5, |
- ArrowFormalParametersProduction = 1 << 6, |
- |
- PatternProductions = |
- (BindingPatternProduction | AssignmentPatternProduction), |
- FormalParametersProductions = (DistinctFormalParametersProduction | |
- StrictModeFormalParametersProduction | |
- StrongModeFormalParametersProduction), |
- StandardProductions = ExpressionProduction | PatternProductions, |
- AllProductions = (StandardProductions | FormalParametersProductions | |
- ArrowFormalParametersProduction) |
- }; |
- |
- ExpressionClassifier() : invalid_productions_(0) {} |
- |
- bool is_valid(unsigned productions) const { |
- return (invalid_productions_ & productions) == 0; |
- } |
- |
- bool is_valid_expression() const { return is_valid(ExpressionProduction); } |
- |
- bool is_valid_binding_pattern() const { |
- return is_valid(BindingPatternProduction); |
- } |
- |
- bool is_valid_assignment_pattern() const { |
- return is_valid(AssignmentPatternProduction); |
- } |
- |
- bool is_valid_arrow_formal_parameters() const { |
- return is_valid(ArrowFormalParametersProduction); |
- } |
- bool is_valid_formal_parameter_list_without_duplicates() const { |
- return is_valid(DistinctFormalParametersProduction); |
- } |
- |
- // Note: callers should also check |
- // is_valid_formal_parameter_list_without_duplicates(). |
- bool is_valid_strict_mode_formal_parameters() const { |
- return is_valid(StrictModeFormalParametersProduction); |
- } |
- |
- // Note: callers should also check is_valid_strict_mode_formal_parameters() |
- // and is_valid_formal_parameter_list_without_duplicates(). |
- bool is_valid_strong_mode_formal_parameters() const { |
- return is_valid(StrongModeFormalParametersProduction); |
- } |
- |
- const Error& expression_error() const { return expression_error_; } |
- |
- const Error& binding_pattern_error() const { |
- return binding_pattern_error_; |
- } |
- |
- const Error& assignment_pattern_error() const { |
- return assignment_pattern_error_; |
- } |
- |
- const Error& arrow_formal_parameters_error() const { |
- return arrow_formal_parameters_error_; |
- } |
- |
- const Error& duplicate_formal_parameter_error() const { |
- return duplicate_formal_parameter_error_; |
- } |
- |
- const Error& strict_mode_formal_parameter_error() const { |
- return strict_mode_formal_parameter_error_; |
- } |
- |
- const Error& strong_mode_formal_parameter_error() const { |
- return strong_mode_formal_parameter_error_; |
- } |
- |
- void RecordExpressionError(const Scanner::Location& loc, |
- MessageTemplate::Template message, |
- const char* arg = nullptr) { |
- if (!is_valid_expression()) return; |
- invalid_productions_ |= ExpressionProduction; |
- expression_error_.location = loc; |
- expression_error_.message = message; |
- expression_error_.arg = arg; |
- } |
- |
- void RecordBindingPatternError(const Scanner::Location& loc, |
- MessageTemplate::Template message, |
- const char* arg = nullptr) { |
- if (!is_valid_binding_pattern()) return; |
- invalid_productions_ |= BindingPatternProduction; |
- binding_pattern_error_.location = loc; |
- binding_pattern_error_.message = message; |
- binding_pattern_error_.arg = arg; |
- } |
- |
- void RecordAssignmentPatternError(const Scanner::Location& loc, |
- MessageTemplate::Template message, |
- const char* arg = nullptr) { |
- if (!is_valid_assignment_pattern()) return; |
- invalid_productions_ |= AssignmentPatternProduction; |
- assignment_pattern_error_.location = loc; |
- assignment_pattern_error_.message = message; |
- assignment_pattern_error_.arg = arg; |
- } |
- |
- void RecordArrowFormalParametersError(const Scanner::Location& loc, |
- MessageTemplate::Template message, |
- const char* arg = nullptr) { |
- if (!is_valid_arrow_formal_parameters()) return; |
- invalid_productions_ |= ArrowFormalParametersProduction; |
- arrow_formal_parameters_error_.location = loc; |
- arrow_formal_parameters_error_.message = message; |
- arrow_formal_parameters_error_.arg = arg; |
- } |
- |
- void RecordDuplicateFormalParameterError(const Scanner::Location& loc) { |
- if (!is_valid_formal_parameter_list_without_duplicates()) return; |
- invalid_productions_ |= DistinctFormalParametersProduction; |
- duplicate_formal_parameter_error_.location = loc; |
- duplicate_formal_parameter_error_.message = |
- MessageTemplate::kStrictParamDupe; |
- duplicate_formal_parameter_error_.arg = nullptr; |
- } |
- |
- // Record a binding that would be invalid in strict mode. Confusingly this |
- // is not the same as StrictFormalParameterList, which simply forbids |
- // duplicate bindings. |
- void RecordStrictModeFormalParameterError(const Scanner::Location& loc, |
- MessageTemplate::Template message, |
- const char* arg = nullptr) { |
- if (!is_valid_strict_mode_formal_parameters()) return; |
- invalid_productions_ |= StrictModeFormalParametersProduction; |
- strict_mode_formal_parameter_error_.location = loc; |
- strict_mode_formal_parameter_error_.message = message; |
- strict_mode_formal_parameter_error_.arg = arg; |
- } |
- |
- void RecordStrongModeFormalParameterError(const Scanner::Location& loc, |
- MessageTemplate::Template message, |
- const char* arg = nullptr) { |
- if (!is_valid_strong_mode_formal_parameters()) return; |
- invalid_productions_ |= StrongModeFormalParametersProduction; |
- strong_mode_formal_parameter_error_.location = loc; |
- strong_mode_formal_parameter_error_.message = message; |
- strong_mode_formal_parameter_error_.arg = arg; |
- } |
- |
- void Accumulate(const ExpressionClassifier& inner, |
- unsigned productions = StandardProductions) { |
- // Propagate errors from inner, but don't overwrite already recorded |
- // errors. |
- unsigned non_arrow_inner_invalid_productions = |
- inner.invalid_productions_ & ~ArrowFormalParametersProduction; |
- if (non_arrow_inner_invalid_productions == 0) return; |
- unsigned non_arrow_productions = |
- productions & ~ArrowFormalParametersProduction; |
- unsigned errors = |
- non_arrow_productions & non_arrow_inner_invalid_productions; |
- errors &= ~invalid_productions_; |
- if (errors != 0) { |
- invalid_productions_ |= errors; |
- if (errors & ExpressionProduction) |
- expression_error_ = inner.expression_error_; |
- if (errors & BindingPatternProduction) |
- binding_pattern_error_ = inner.binding_pattern_error_; |
- if (errors & AssignmentPatternProduction) |
- assignment_pattern_error_ = inner.assignment_pattern_error_; |
- if (errors & DistinctFormalParametersProduction) |
- duplicate_formal_parameter_error_ = |
- inner.duplicate_formal_parameter_error_; |
- if (errors & StrictModeFormalParametersProduction) |
- strict_mode_formal_parameter_error_ = |
- inner.strict_mode_formal_parameter_error_; |
- if (errors & StrongModeFormalParametersProduction) |
- strong_mode_formal_parameter_error_ = |
- inner.strong_mode_formal_parameter_error_; |
- } |
- |
- // As an exception to the above, the result continues to be a valid arrow |
- // formal parameters if the inner expression is a valid binding pattern. |
- if (productions & ArrowFormalParametersProduction && |
- is_valid_arrow_formal_parameters() && |
- !inner.is_valid_binding_pattern()) { |
- invalid_productions_ |= ArrowFormalParametersProduction; |
- arrow_formal_parameters_error_ = inner.binding_pattern_error_; |
- } |
- } |
- |
- void AccumulateReclassifyingAsPattern(const ExpressionClassifier& inner) { |
- Accumulate(inner, AllProductions & ~PatternProductions); |
- if (!inner.is_valid_expression()) { |
- if (is_valid_binding_pattern()) { |
- binding_pattern_error_ = inner.expression_error(); |
- } |
- if (is_valid_assignment_pattern()) { |
- assignment_pattern_error_ = inner.expression_error(); |
- } |
- } |
- } |
- |
- private: |
- unsigned invalid_productions_; |
- Error expression_error_; |
- Error binding_pattern_error_; |
- Error assignment_pattern_error_; |
- Error arrow_formal_parameters_error_; |
- Error duplicate_formal_parameter_error_; |
- Error strict_mode_formal_parameter_error_; |
- Error strong_mode_formal_parameter_error_; |
- }; |
- |
- void ReportClassifierError( |
- const typename ExpressionClassifier::Error& error) { |
+ void ReportClassifierError(const ExpressionClassifier::Error& error) { |
Traits::ReportMessageAt(error.location, error.message, error.arg, |
kSyntaxError); |
} |
@@ -890,9 +658,9 @@ class ParserBase : public Traits { |
ExpressionT ParseStrongSuperCallExpression(ExpressionClassifier* classifier, |
bool* ok); |
- void ParseFormalParameter(FormalParameterScopeT* scope, bool is_rest, |
+ void ParseFormalParameter(Scope* scope, bool is_rest, |
ExpressionClassifier* classifier, bool* ok); |
- int ParseFormalParameterList(FormalParameterScopeT* scope, bool* has_rest, |
+ int ParseFormalParameterList(Scope* scope, bool* has_rest, |
ExpressionClassifier* classifier, bool* ok); |
void CheckArityRestrictions( |
int param_count, FunctionLiteral::ArityRestriction arity_restriction, |
@@ -1509,7 +1277,6 @@ class PreParserTraits { |
typedef PreParserExpressionList ExpressionList; |
typedef PreParserExpressionList PropertyList; |
typedef PreParserIdentifier FormalParameter; |
- typedef DuplicateFinder FormalParameterScope; |
typedef PreParserStatementList StatementList; |
// For constructing objects returned by the traversing functions. |
@@ -1788,9 +1555,8 @@ class PreParserTraits { |
return !tag.IsNoTemplateTag(); |
} |
- V8_INLINE bool DeclareFormalParameter(DuplicateFinder* scope, |
- PreParserIdentifier param, |
- bool is_rest); |
+ void DeclareFormalParameter(Scope* scope, PreParserIdentifier param, |
+ ExpressionClassifier* classifier, bool is_rest) {} |
void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} |
@@ -1984,13 +1750,6 @@ PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, |
} |
-bool PreParserTraits::DeclareFormalParameter( |
- DuplicateFinder* duplicate_finder, PreParserIdentifier current_identifier, |
- bool is_rest) { |
- return pre_parser_->scanner()->FindSymbol(duplicate_finder, 1) != 0; |
-} |
- |
- |
void PreParserTraits::ParseArrowFunctionFormalParameters( |
Scope* scope, PreParserExpression params, |
const Scanner::Location& params_loc, bool* is_rest, |
@@ -2163,6 +1922,11 @@ ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, |
scanner()->location(), MessageTemplate::kStrongUndefined); |
} |
} |
+ |
+ if (classifier->duplicate_finder() != nullptr && |
+ scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
+ classifier->RecordDuplicateFormalParameterError(scanner()->location()); |
+ } |
return name; |
} else if (is_sloppy(language_mode()) && |
(next == Token::FUTURE_STRICT_RESERVED_WORD || |
@@ -3682,8 +3446,7 @@ ParserBase<Traits>::ParseMemberExpressionContinuation( |
template <class Traits> |
-void ParserBase<Traits>::ParseFormalParameter(FormalParameterScopeT* scope, |
- bool is_rest, |
+void ParserBase<Traits>::ParseFormalParameter(Scope* scope, bool is_rest, |
ExpressionClassifier* classifier, |
bool* ok) { |
// FormalParameter[Yield,GeneratorParameter] : |
@@ -3691,17 +3454,13 @@ void ParserBase<Traits>::ParseFormalParameter(FormalParameterScopeT* scope, |
IdentifierT name = ParseAndClassifyIdentifier(classifier, ok); |
if (!*ok) return; |
- bool was_declared = Traits::DeclareFormalParameter(scope, name, is_rest); |
- if (was_declared) { |
- classifier->RecordDuplicateFormalParameterError(scanner()->location()); |
- } |
+ Traits::DeclareFormalParameter(scope, name, classifier, is_rest); |
} |
template <class Traits> |
int ParserBase<Traits>::ParseFormalParameterList( |
- FormalParameterScopeT* scope, bool* is_rest, |
- ExpressionClassifier* classifier, bool* ok) { |
+ Scope* scope, bool* is_rest, ExpressionClassifier* classifier, bool* ok) { |
// FormalParameters[Yield,GeneratorParameter] : |
// [empty] |
// FormalParameterList[?Yield, ?GeneratorParameter] |