Commit f3ee83b6 authored by dslomov's avatar dslomov Committed by Commit bot

Introduce "expression classifier" to the parser.

R=marja@chromium.org,rossberg@chromium.org

Review URL: https://codereview.chromium.org/1065983005

Cr-Commit-Position: refs/heads/master@{#28005}
parent 9bb8b585
......@@ -1672,6 +1672,7 @@ EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_computed_property_names)
EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_rest_parameters)
EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_reflect)
EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_spreadcalls)
EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_destructuring)
void Genesis::InstallNativeFunctions_harmony_proxies() {
......@@ -1700,6 +1701,7 @@ EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_unicode)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_computed_property_names)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_rest_parameters)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_spreadcalls)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_destructuring)
void Genesis::InitializeGlobal_harmony_regexps() {
Handle<JSObject> builtins(native_context()->builtins());
......@@ -2304,27 +2306,28 @@ bool Genesis::InstallNatives() {
bool Genesis::InstallExperimentalNatives() {
static const char* harmony_arrays_natives[] = {
"native harmony-array.js", "native harmony-typedarray.js", NULL};
"native harmony-array.js", "native harmony-typedarray.js", nullptr};
static const char* harmony_array_includes_natives[] = {
"native harmony-array-includes.js", NULL};
static const char* harmony_proxies_natives[] = {"native proxy.js", NULL};
static const char* harmony_classes_natives[] = {NULL};
static const char* harmony_modules_natives[] = {NULL};
static const char* harmony_object_literals_natives[] = {NULL};
static const char* harmony_regexps_natives[] = {
"native harmony-regexp.js", NULL};
static const char* harmony_arrow_functions_natives[] = {NULL};
"native harmony-array-includes.js", nullptr};
static const char* harmony_proxies_natives[] = {"native proxy.js", nullptr};
static const char* harmony_classes_natives[] = {nullptr};
static const char* harmony_modules_natives[] = {nullptr};
static const char* harmony_object_literals_natives[] = {nullptr};
static const char* harmony_regexps_natives[] = {"native harmony-regexp.js",
nullptr};
static const char* harmony_arrow_functions_natives[] = {nullptr};
static const char* harmony_tostring_natives[] = {"native harmony-tostring.js",
NULL};
static const char* harmony_sloppy_natives[] = {NULL};
static const char* harmony_unicode_natives[] = {NULL};
static const char* harmony_unicode_regexps_natives[] = {NULL};
static const char* harmony_computed_property_names_natives[] = {NULL};
static const char* harmony_rest_parameters_natives[] = {NULL};
nullptr};
static const char* harmony_sloppy_natives[] = {nullptr};
static const char* harmony_unicode_natives[] = {nullptr};
static const char* harmony_unicode_regexps_natives[] = {nullptr};
static const char* harmony_computed_property_names_natives[] = {nullptr};
static const char* harmony_rest_parameters_natives[] = {nullptr};
static const char* harmony_reflect_natives[] = {"native harmony-reflect.js",
NULL};
nullptr};
static const char* harmony_spreadcalls_natives[] = {
"native harmony-spread.js", NULL};
"native harmony-spread.js", nullptr};
static const char* harmony_destructuring_natives[] = {nullptr};
for (int i = ExperimentalNatives::GetDebuggerCount();
i < ExperimentalNatives::GetBuiltinsCount(); i++) {
......
......@@ -191,7 +191,8 @@ DEFINE_IMPLICATION(es_staging, harmony)
V(harmony_proxies, "harmony proxies") \
V(harmony_sloppy, "harmony features in sloppy mode") \
V(harmony_unicode_regexps, "harmony unicode regexps") \
V(harmony_reflect, "harmony Reflect API")
V(harmony_reflect, "harmony Reflect API") \
V(harmony_destructuring, "harmony destructuring")
// Features that are complete (but still behind --harmony/es-staging flag).
#define HARMONY_STAGED(V) \
......
......@@ -1146,8 +1146,10 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info,
}
if (ok) {
Expression* expression =
ParseArrowFunctionLiteral(scope, error_locs, has_rest, &ok);
ExpressionClassifier classifier;
Expression* expression = ParseArrowFunctionLiteral(
scope, error_locs, has_rest, &classifier, &ok);
// TODO(dslomov): report error if not a valid expression.
if (ok) {
// Scanning must end at the same position that was recorded
// previously. If not, parsing has been interrupted due to a stack
......@@ -1614,7 +1616,10 @@ Statement* Parser::ParseExportDefault(bool* ok) {
default: {
int pos = peek_position();
Expression* expr = ParseAssignmentExpression(true, CHECK_OK);
ExpressionClassifier classifier;
Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK);
// TODO(dslomov): report error if not a valid expression.
ExpectSemicolon(CHECK_OK);
result = factory()->NewExpressionStatement(expr, pos);
break;
......@@ -2428,7 +2433,10 @@ Block* Parser::ParseVariableDeclarations(
(mode == CONST && !is_for_iteration_variable)) {
Expect(Token::ASSIGN, CHECK_OK);
pos = position();
value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
ExpressionClassifier classifier;
value = ParseAssignmentExpression(var_context != kForStatement,
&classifier, CHECK_OK);
// TODO(dslomov): check that expression is valid.
variable_loc.end_pos = scanner()->location().end_pos;
if (first_initializer_loc && !first_initializer_loc->IsValid()) {
......@@ -2613,11 +2621,13 @@ Statement* Parser::ParseExpressionOrLabelledStatement(
i::IsConstructor(function_state_->kind())) {
bool is_this = peek() == Token::THIS;
Expression* expr;
ExpressionClassifier classifier;
if (is_this) {
expr = ParseStrongInitializationExpression(CHECK_OK);
expr = ParseStrongInitializationExpression(&classifier, CHECK_OK);
} else {
expr = ParseStrongSuperCallExpression(CHECK_OK);
expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK);
}
// TODO(dslomov): report error if not a valid expression.
switch (peek()) {
case Token::SEMICOLON:
Consume(Token::SEMICOLON);
......@@ -4338,7 +4348,9 @@ ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
Expression* extends = NULL;
if (Check(Token::EXTENDS)) {
block_scope->set_start_position(scanner()->location().end_pos);
extends = ParseLeftHandSideExpression(CHECK_OK);
ExpressionClassifier classifier;
extends = ParseLeftHandSideExpression(&classifier, CHECK_OK);
// TODO(dslomov): report error if not a valid expression.
} else {
block_scope->set_start_position(scanner()->location().end_pos);
}
......@@ -4359,9 +4371,11 @@ ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
const bool is_static = false;
bool is_computed_name = false; // Classes do not care about computed
// property names here.
ExpressionClassifier classifier;
ObjectLiteral::Property* property = ParsePropertyDefinition(
&checker, in_class, has_extends, is_static, &is_computed_name,
&has_seen_constructor, CHECK_OK);
&has_seen_constructor, &classifier, CHECK_OK);
// TODO(dslomov): report error if not a valid expression.
if (has_seen_constructor && constructor == NULL) {
constructor = GetPropertyValue(property)->AsFunctionLiteral();
......@@ -4410,7 +4424,10 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
const AstRawString* name = ParseIdentifier(kAllowRestrictedIdentifiers,
CHECK_OK);
Scanner::Location spread_pos;
ZoneList<Expression*>* args = ParseArguments(&spread_pos, CHECK_OK);
ExpressionClassifier classifier;
ZoneList<Expression*>* args =
ParseArguments(&spread_pos, &classifier, CHECK_OK);
// TODO(dslomov): report error if not a valid expression.
DCHECK(!spread_pos.IsValid());
......
......@@ -520,7 +520,10 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
// require initializers for multiple consts.
(is_strict_const && peek() == Token::COMMA)) {
Expect(Token::ASSIGN, CHECK_OK);
ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
ExpressionClassifier classifier;
ParseAssignmentExpression(var_context != kForStatement, &classifier,
CHECK_OK);
// TODO(dslomov): report error if not valid expression.
variable_loc.end_pos = scanner()->location().end_pos;
if (first_initializer_loc && !first_initializer_loc->IsValid()) {
......@@ -559,11 +562,13 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
i::IsConstructor(function_state_->kind())) {
bool is_this = peek() == Token::THIS;
Expression expr = Expression::Default();
ExpressionClassifier classifier;
if (is_this) {
expr = ParseStrongInitializationExpression(CHECK_OK);
expr = ParseStrongInitializationExpression(&classifier, CHECK_OK);
} else {
expr = ParseStrongSuperCallExpression(CHECK_OK);
expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK);
}
// TODO(dslomov): report error if not a valid expression.
switch (peek()) {
case Token::SEMICOLON:
Consume(Token::SEMICOLON);
......@@ -592,7 +597,10 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
}
bool starts_with_identifier = peek_any_identifier();
Expression expr = ParseExpression(true, CHECK_OK);
ExpressionClassifier classifier;
Expression expr = ParseExpression(true, &classifier, CHECK_OK);
// TODO(dslomov): report error if not a valid expression.
// Even if the expression starts with an identifier, it is not necessarily an
// identifier. For example, "foo + bar" starts with an identifier but is not
// an identifier.
......@@ -1081,7 +1089,9 @@ PreParserExpression PreParser::ParseClassLiteral(
bool has_extends = Check(Token::EXTENDS);
if (has_extends) {
ParseLeftHandSideExpression(CHECK_OK);
ExpressionClassifier classifier;
ParseLeftHandSideExpression(&classifier, CHECK_OK);
// TODO(dslomov): report error if not a valid expression.
}
ClassLiteralChecker checker(this);
......@@ -1094,8 +1104,11 @@ PreParserExpression PreParser::ParseClassLiteral(
const bool is_static = false;
bool is_computed_name = false; // Classes do not care about computed
// property names here.
ExpressionClassifier classifier;
ParsePropertyDefinition(&checker, in_class, has_extends, is_static,
&is_computed_name, &has_seen_constructor, CHECK_OK);
&is_computed_name, &has_seen_constructor,
&classifier, CHECK_OK);
// TODO(dslomov): report error if not a valid expression.
}
Expect(Token::RBRACE, CHECK_OK);
......@@ -1115,7 +1128,9 @@ PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
// Allow "eval" or "arguments" for backward compatibility.
ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
Scanner::Location spread_pos;
ParseArguments(&spread_pos, ok);
ExpressionClassifier classifier;
ParseArguments(&spread_pos, &classifier, ok);
// TODO(dslomov): report error if not a valid expression.
DCHECK(!spread_pos.IsValid());
......
This diff is collapsed.
......@@ -355,6 +355,14 @@ class Scanner {
int beg_pos;
int end_pos;
bool inline operator==(const Location& other) const {
return beg_pos == other.beg_pos && end_pos == other.end_pos;
}
bool inline operator!=(const Location& other) const {
return !(*this == other);
}
};
// -1 is outside of the range of any real source code.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment