Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Unified Diff: src/preparser.h

Issue 1170153003: [destructuring] Refactor duplicate parameter name detection. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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]
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698