Migrate error messages, part 12.
Review URL: https://codereview.chromium.org/1130133003 Cr-Commit-Position: refs/heads/master@{#28439}
This commit is contained in:
parent
03131f8a4a
commit
fc65e55116
@ -1560,7 +1560,8 @@ Local<Script> UnboundScript::BindToCurrentContext() {
|
||||
pending_error_handler_.ReportMessageAt(
|
||||
scope_info->StrongModeFreeVariableStartPosition(i),
|
||||
scope_info->StrongModeFreeVariableEndPosition(i),
|
||||
"strong_unbound_global", name_string, i::kReferenceError);
|
||||
i::MessageTemplate::kStrongUnboundGlobal, name_string,
|
||||
i::kReferenceError);
|
||||
i::Handle<i::Script> script(i::Script::cast(function_info->script()));
|
||||
pending_error_handler_.ThrowPendingError(isolate, script);
|
||||
isolate->ReportPendingMessages();
|
||||
|
@ -250,9 +250,9 @@ class AstValue : public ZoneObject {
|
||||
F(is_construct_call, "_IsConstructCall") \
|
||||
F(is_spec_object, "_IsSpecObject") \
|
||||
F(let, "let") \
|
||||
F(make_reference_error, "MakeReferenceErrorEmbedded") \
|
||||
F(make_syntax_error, "MakeSyntaxErrorEmbedded") \
|
||||
F(make_type_error, "MakeTypeErrorEmbedded") \
|
||||
F(make_reference_error, "MakeReferenceError") \
|
||||
F(make_syntax_error, "MakeSyntaxError") \
|
||||
F(make_type_error, "MakeTypeError") \
|
||||
F(native, "native") \
|
||||
F(new_target, "new.target") \
|
||||
F(next, "next") \
|
||||
|
@ -669,8 +669,8 @@ bool Debug::CompileDebuggerScript(Isolate* isolate, int index) {
|
||||
MessageLocation computed_location;
|
||||
isolate->ComputeLocation(&computed_location);
|
||||
Handle<Object> message = MessageHandler::MakeMessageObject(
|
||||
isolate, "error_loading_debugger", &computed_location,
|
||||
Vector<Handle<Object> >::empty(), Handle<JSArray>());
|
||||
isolate, MessageTemplate::kDebuggerLoading, &computed_location,
|
||||
isolate->factory()->undefined_value(), Handle<JSArray>());
|
||||
DCHECK(!isolate->has_pending_exception());
|
||||
Handle<Object> exception;
|
||||
if (maybe_exception.ToHandle(&exception)) {
|
||||
|
@ -2140,24 +2140,21 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
|
||||
|
||||
|
||||
Handle<JSMessageObject> Factory::NewJSMessageObject(
|
||||
Handle<String> type,
|
||||
Handle<JSArray> arguments,
|
||||
int start_position,
|
||||
int end_position,
|
||||
Handle<Object> script,
|
||||
MessageTemplate::Template message, Handle<Object> argument,
|
||||
int start_position, int end_position, Handle<Object> script,
|
||||
Handle<Object> stack_frames) {
|
||||
Handle<Map> map = message_object_map();
|
||||
Handle<JSMessageObject> message = New<JSMessageObject>(map, NEW_SPACE);
|
||||
message->set_properties(*empty_fixed_array(), SKIP_WRITE_BARRIER);
|
||||
message->initialize_elements();
|
||||
message->set_elements(*empty_fixed_array(), SKIP_WRITE_BARRIER);
|
||||
message->set_type(*type);
|
||||
message->set_arguments(*arguments);
|
||||
message->set_start_position(start_position);
|
||||
message->set_end_position(end_position);
|
||||
message->set_script(*script);
|
||||
message->set_stack_frames(*stack_frames);
|
||||
return message;
|
||||
Handle<JSMessageObject> message_obj = New<JSMessageObject>(map, NEW_SPACE);
|
||||
message_obj->set_properties(*empty_fixed_array(), SKIP_WRITE_BARRIER);
|
||||
message_obj->initialize_elements();
|
||||
message_obj->set_elements(*empty_fixed_array(), SKIP_WRITE_BARRIER);
|
||||
message_obj->set_type(message);
|
||||
message_obj->set_argument(*argument);
|
||||
message_obj->set_start_position(start_position);
|
||||
message_obj->set_end_position(end_position);
|
||||
message_obj->set_script(*script);
|
||||
message_obj->set_stack_frames(*stack_frames);
|
||||
return message_obj;
|
||||
}
|
||||
|
||||
|
||||
|
@ -549,8 +549,9 @@ class Factory final {
|
||||
|
||||
Handle<Object> NewError(const char* maker,
|
||||
MessageTemplate::Template template_index,
|
||||
Handle<Object> arg0, Handle<Object> arg1,
|
||||
Handle<Object> arg2);
|
||||
Handle<Object> arg0 = Handle<Object>(),
|
||||
Handle<Object> arg1 = Handle<Object>(),
|
||||
Handle<Object> arg2 = Handle<Object>());
|
||||
|
||||
Handle<Object> NewError(MessageTemplate::Template template_index,
|
||||
Handle<Object> arg0 = Handle<Object>(),
|
||||
@ -656,13 +657,12 @@ class Factory final {
|
||||
Handle<TypeFeedbackVector> NewTypeFeedbackVector(const Spec* spec);
|
||||
|
||||
// Allocates a new JSMessageObject object.
|
||||
Handle<JSMessageObject> NewJSMessageObject(
|
||||
Handle<String> type,
|
||||
Handle<JSArray> arguments,
|
||||
int start_position,
|
||||
int end_position,
|
||||
Handle<Object> script,
|
||||
Handle<Object> stack_frames);
|
||||
Handle<JSMessageObject> NewJSMessageObject(MessageTemplate::Template message,
|
||||
Handle<Object> argument,
|
||||
int start_position,
|
||||
int end_position,
|
||||
Handle<Object> script,
|
||||
Handle<Object> stack_frames);
|
||||
|
||||
Handle<DebugInfo> NewDebugInfo(Handle<SharedFunctionInfo> shared);
|
||||
|
||||
|
@ -1381,9 +1381,9 @@ Handle<JSMessageObject> Isolate::CreateMessage(Handle<Object> exception,
|
||||
factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("exception"));
|
||||
}
|
||||
}
|
||||
return MessageHandler::MakeMessageObject(this, "uncaught_exception", location,
|
||||
HandleVector<Object>(&exception, 1),
|
||||
stack_trace_object);
|
||||
return MessageHandler::MakeMessageObject(
|
||||
this, MessageTemplate::kUncaughtException, location, exception,
|
||||
stack_trace_object);
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,20 +35,9 @@ void MessageHandler::DefaultMessageReport(Isolate* isolate,
|
||||
|
||||
|
||||
Handle<JSMessageObject> MessageHandler::MakeMessageObject(
|
||||
Isolate* isolate,
|
||||
const char* type,
|
||||
MessageLocation* loc,
|
||||
Vector< Handle<Object> > args,
|
||||
Handle<JSArray> stack_frames) {
|
||||
Isolate* isolate, MessageTemplate::Template message, MessageLocation* loc,
|
||||
Handle<Object> argument, Handle<JSArray> stack_frames) {
|
||||
Factory* factory = isolate->factory();
|
||||
Handle<String> type_handle = factory->InternalizeUtf8String(type);
|
||||
Handle<FixedArray> arguments_elements =
|
||||
factory->NewFixedArray(args.length());
|
||||
for (int i = 0; i < args.length(); i++) {
|
||||
arguments_elements->set(i, *args[i]);
|
||||
}
|
||||
Handle<JSArray> arguments_handle =
|
||||
factory->NewJSArrayWithElements(arguments_elements);
|
||||
|
||||
int start = 0;
|
||||
int end = 0;
|
||||
@ -63,15 +52,10 @@ Handle<JSMessageObject> MessageHandler::MakeMessageObject(
|
||||
? Handle<Object>::cast(factory->undefined_value())
|
||||
: Handle<Object>::cast(stack_frames);
|
||||
|
||||
Handle<JSMessageObject> message =
|
||||
factory->NewJSMessageObject(type_handle,
|
||||
arguments_handle,
|
||||
start,
|
||||
end,
|
||||
script_handle,
|
||||
stack_frames_handle);
|
||||
Handle<JSMessageObject> message_obj = factory->NewJSMessageObject(
|
||||
message, argument, start, end, script_handle, stack_frames_handle);
|
||||
|
||||
return message;
|
||||
return message_obj;
|
||||
}
|
||||
|
||||
|
||||
@ -129,29 +113,9 @@ void MessageHandler::ReportMessage(Isolate* isolate,
|
||||
|
||||
Handle<String> MessageHandler::GetMessage(Isolate* isolate,
|
||||
Handle<Object> data) {
|
||||
Factory* factory = isolate->factory();
|
||||
Handle<String> fmt_str =
|
||||
factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("$formatMessage"));
|
||||
Handle<JSFunction> fun = Handle<JSFunction>::cast(Object::GetProperty(
|
||||
isolate->js_builtins_object(), fmt_str).ToHandleChecked());
|
||||
Handle<JSMessageObject> message = Handle<JSMessageObject>::cast(data);
|
||||
Handle<Object> argv[] = { Handle<Object>(message->type(), isolate),
|
||||
Handle<Object>(message->arguments(), isolate) };
|
||||
|
||||
MaybeHandle<Object> maybe_result = Execution::TryCall(
|
||||
fun, isolate->js_builtins_object(), arraysize(argv), argv);
|
||||
Handle<Object> result;
|
||||
if (!maybe_result.ToHandle(&result) || !result->IsString()) {
|
||||
return factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("<error>"));
|
||||
}
|
||||
Handle<String> result_string = Handle<String>::cast(result);
|
||||
// A string that has been obtained from JS code in this way is
|
||||
// likely to be a complicated ConsString of some sort. We flatten it
|
||||
// here to improve the efficiency of converting it to a C string and
|
||||
// other operations that are likely to take place (see GetLocalizedMessage
|
||||
// for example).
|
||||
result_string = String::Flatten(result_string);
|
||||
return result_string;
|
||||
Handle<Object> arg = Handle<Object>(message->argument(), isolate);
|
||||
return MessageTemplate::FormatMessage(isolate, message->type(), arg);
|
||||
}
|
||||
|
||||
|
||||
@ -312,6 +276,38 @@ bool CallSite::IsConstructor(Isolate* isolate) {
|
||||
}
|
||||
|
||||
|
||||
Handle<String> MessageTemplate::FormatMessage(Isolate* isolate,
|
||||
int template_index,
|
||||
Handle<Object> arg) {
|
||||
Factory* factory = isolate->factory();
|
||||
Handle<String> fmt_str = factory->InternalizeOneByteString(
|
||||
STATIC_CHAR_VECTOR("$noSideEffectToString"));
|
||||
Handle<JSFunction> fun = Handle<JSFunction>::cast(
|
||||
Object::GetProperty(isolate->js_builtins_object(), fmt_str)
|
||||
.ToHandleChecked());
|
||||
|
||||
MaybeHandle<Object> maybe_result =
|
||||
Execution::TryCall(fun, isolate->js_builtins_object(), 1, &arg);
|
||||
Handle<Object> result;
|
||||
if (!maybe_result.ToHandle(&result) || !result->IsString()) {
|
||||
return factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("<error>"));
|
||||
}
|
||||
MaybeHandle<String> maybe_result_string = MessageTemplate::FormatMessage(
|
||||
template_index, Handle<String>::cast(result), factory->empty_string(),
|
||||
factory->empty_string());
|
||||
Handle<String> result_string;
|
||||
if (!maybe_result_string.ToHandle(&result_string)) {
|
||||
return factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("<error>"));
|
||||
}
|
||||
// A string that has been obtained from JS code in this way is
|
||||
// likely to be a complicated ConsString of some sort. We flatten it
|
||||
// here to improve the efficiency of converting it to a C string and
|
||||
// other operations that are likely to take place (see GetLocalizedMessage
|
||||
// for example).
|
||||
return String::Flatten(result_string);
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<String> MessageTemplate::FormatMessage(int template_index,
|
||||
Handle<String> arg0,
|
||||
Handle<String> arg1,
|
||||
@ -338,8 +334,14 @@ MaybeHandle<String> MessageTemplate::FormatMessage(int template_index,
|
||||
Handle<String> args[] = {arg0, arg1, arg2};
|
||||
for (const char* c = template_string; *c != '\0'; c++) {
|
||||
if (*c == '%') {
|
||||
DCHECK(i < arraysize(args));
|
||||
builder.AppendString(args[i++]);
|
||||
// %% results in verbatim %.
|
||||
if (*(c + 1) == '%') {
|
||||
c++;
|
||||
builder.AppendCharacter('%');
|
||||
} else {
|
||||
DCHECK(i < arraysize(args));
|
||||
builder.AppendString(args[i++]);
|
||||
}
|
||||
} else {
|
||||
builder.AppendCharacter(*c);
|
||||
}
|
||||
|
169
src/messages.h
169
src/messages.h
@ -62,32 +62,6 @@ class MessageLocation {
|
||||
};
|
||||
|
||||
|
||||
// A message handler is a convenience interface for accessing the list
|
||||
// of message listeners registered in an environment
|
||||
class MessageHandler {
|
||||
public:
|
||||
// Returns a message object for the API to use.
|
||||
static Handle<JSMessageObject> MakeMessageObject(
|
||||
Isolate* isolate,
|
||||
const char* type,
|
||||
MessageLocation* loc,
|
||||
Vector< Handle<Object> > args,
|
||||
Handle<JSArray> stack_frames);
|
||||
|
||||
// Report a formatted message (needs JS allocation).
|
||||
static void ReportMessage(Isolate* isolate,
|
||||
MessageLocation* loc,
|
||||
Handle<Object> message);
|
||||
|
||||
static void DefaultMessageReport(Isolate* isolate,
|
||||
const MessageLocation* loc,
|
||||
Handle<Object> message_obj);
|
||||
static Handle<String> GetMessage(Isolate* isolate, Handle<Object> data);
|
||||
static SmartArrayPointer<char> GetLocalizedMessage(Isolate* isolate,
|
||||
Handle<Object> data);
|
||||
};
|
||||
|
||||
|
||||
class CallSite {
|
||||
public:
|
||||
CallSite(Handle<Object> receiver, Handle<JSFunction> fun, int pos)
|
||||
@ -115,8 +89,11 @@ class CallSite {
|
||||
|
||||
#define MESSAGE_TEMPLATES(T) \
|
||||
/* Error */ \
|
||||
T(None, "") \
|
||||
T(CyclicProto, "Cyclic __proto__ value") \
|
||||
T(DebuggerLoading, "Error loading debugger") \
|
||||
T(DefaultOptionsMissing, "Internal % error. Default options are missing.") \
|
||||
T(UncaughtException, "Uncaught %") \
|
||||
T(Unsupported, "Not supported") \
|
||||
T(WrongServiceType, "Internal error, wrong service type: %") \
|
||||
T(WrongValueType, "Internal error. Wrong value type.") \
|
||||
@ -264,6 +241,11 @@ class CallSite {
|
||||
/* ReferenceError */ \
|
||||
T(NonMethod, "'super' is referenced from non-method") \
|
||||
T(NotDefined, "% is not defined") \
|
||||
T(StrongSuperCallMissing, \
|
||||
"In strong mode, invoking the super constructor in a subclass is " \
|
||||
"required") \
|
||||
T(StrongUnboundGlobal, \
|
||||
"In strong mode, using an undeclared global variable '%' is not allowed") \
|
||||
T(UnsupportedSuper, "Unsupported reference to 'super'") \
|
||||
/* RangeError */ \
|
||||
T(ArrayLengthOutOfRange, "defineProperty() array length out of range") \
|
||||
@ -298,13 +280,124 @@ class CallSite {
|
||||
T(UnsupportedTimeZone, "Unsupported time zone specified %") \
|
||||
T(ValueOutOfRange, "Value % out of range for % options property %") \
|
||||
/* SyntaxError */ \
|
||||
T(BadGetterArity, "Getter must not have any formal parameters.") \
|
||||
T(BadSetterArity, "Setter must have exactly one formal parameter.") \
|
||||
T(ConstructorIsAccessor, "Class constructor may not be an accessor") \
|
||||
T(ConstructorIsGenerator, "Class constructor may not be a generator") \
|
||||
T(DerivedConstructorReturn, \
|
||||
"Derived constructors may only return object or undefined") \
|
||||
T(DuplicateArrawFunFormalParam, \
|
||||
"Arrow function may not have duplicate parameter names") \
|
||||
T(DuplicateConstructor, "A class may only have one constructor") \
|
||||
T(DuplicateExport, "Duplicate export of '%'") \
|
||||
T(DuplicateProto, \
|
||||
"Duplicate __proto__ fields are not allowed in object literals") \
|
||||
T(ForInLoopInitializer, \
|
||||
"for-in loop variable declaration may not have an initializer.") \
|
||||
T(ForInOfLoopMultiBindings, \
|
||||
"Invalid left-hand side in % loop: Must have a single binding.") \
|
||||
T(ForOfLoopInitializer, \
|
||||
"for-of loop variable declaration may not have an initializer.") \
|
||||
T(IllegalAccess, "Illegal access") \
|
||||
T(IllegalBreak, "Illegal break statement") \
|
||||
T(IllegalContinue, "Illegal continue statement") \
|
||||
T(IllegalReturn, "Illegal return statement") \
|
||||
T(InvalidLhsInAssignment, "Invalid left-hand side in assignment") \
|
||||
T(InvalidLhsInFor, "Invalid left-hand side in for-loop") \
|
||||
T(InvalidLhsInPostfixOp, \
|
||||
"Invalid left-hand side expression in postfix operation") \
|
||||
T(InvalidLhsInPrefixOp, \
|
||||
"Invalid left-hand side expression in prefix operation") \
|
||||
T(InvalidRegExpFlags, "Invalid flags supplied to RegExp constructor '%'") \
|
||||
T(LabelRedeclaration, "Label '%' has already been declared") \
|
||||
T(MalformedArrowFunParamList, "Malformed arrow function parameter list") \
|
||||
T(MalformedRegExp, "Invalid regular expression: /%/: %") \
|
||||
T(MalformedRegExpFlags, "Invalid regular expression flags") \
|
||||
T(ModuleExportUndefined, "Export '%' is not defined in module") \
|
||||
T(MultipleDefaultsInSwitch, \
|
||||
"More than one default clause in switch statement") \
|
||||
T(NewlineAfterThrow, "Illegal newline after throw") \
|
||||
T(NoCatchOrFinally, "Missing catch or finally after try") \
|
||||
T(NotIsvar, "builtin %%IS_VAR: not a variable") \
|
||||
T(ParamAfterRest, "Rest parameter must be last formal parameter") \
|
||||
T(ParenthesisInArgString, "Function arg string contains parenthesis") \
|
||||
T(SingleFunctionLiteral, "Single function literal required") \
|
||||
T(SloppyLexical, \
|
||||
"Block-scoped declarations (let, const, function, class) not yet " \
|
||||
"supported outside strict mode") \
|
||||
T(StrictDelete, "Delete of an unqualified identifier in strict mode.") \
|
||||
T(StrictEvalArguments, "Unexpected eval or arguments in strict mode") \
|
||||
T(StrictFunction, \
|
||||
"In strict mode code, functions can only be declared at top level or " \
|
||||
"immediately within another function.") \
|
||||
T(StrictOctalLiteral, "Octal literals are not allowed in strict mode.") \
|
||||
T(StrictParamDupe, \
|
||||
"Strict mode function may not have duplicate parameter names") \
|
||||
T(StrictWith, "Strict mode code may not include a with statement") \
|
||||
T(StrongArguments, \
|
||||
"In strong mode, 'arguments' is deprecated, use '...args' instead") \
|
||||
T(StrongConstructorReturnMisplaced, \
|
||||
"In strong mode, returning from a constructor before its super " \
|
||||
"constructor invocation or all assignments to 'this' is deprecated") \
|
||||
T(StrongConstructorReturnValue, \
|
||||
"In strong mode, returning a value from a constructor is deprecated") \
|
||||
T(StrongConstructorSuper, \
|
||||
"In strong mode, 'super' can only be used to invoke the super " \
|
||||
"constructor, and cannot be nested inside another statement or " \
|
||||
"expression") \
|
||||
T(StrongConstructorThis, \
|
||||
"In strong mode, 'this' can only be used to initialize properties, and " \
|
||||
"cannot be nested inside another statement or expression") \
|
||||
T(StrongDelete, \
|
||||
"In strong mode, 'delete' is deprecated, use maps or sets instead") \
|
||||
T(StrongDirectEval, "In strong mode, direct calls to eval are deprecated") \
|
||||
T(StrongEllision, \
|
||||
"In strong mode, arrays with holes are deprecated, use maps instead") \
|
||||
T(StrongEmpty, \
|
||||
"In strong mode, empty sub-statements are deprecated, make them explicit " \
|
||||
"with '{}' instead") \
|
||||
T(StrongEqual, \
|
||||
"In strong mode, '==' and '!=' are deprecated, use '===' and '!==' " \
|
||||
"instead") \
|
||||
T(StrongForIn, \
|
||||
"In strong mode, 'for'-'in' loops are deprecated, use 'for'-'of' instead") \
|
||||
T(StrongSuperCallDuplicate, \
|
||||
"In strong mode, invoking the super constructor multiple times is " \
|
||||
"deprecated") \
|
||||
T(StrongSuperCallMisplaced, \
|
||||
"In strong mode, the super constructor must be invoked before any " \
|
||||
"assignment to 'this'") \
|
||||
T(StrongSwitchFallthrough, \
|
||||
"In strong mode, switch fall-through is deprecated, terminate each case " \
|
||||
"with 'break', 'continue', 'return' or 'throw'") \
|
||||
T(StrongUndefined, \
|
||||
"In strong mode, binding or assigning to 'undefined' is deprecated") \
|
||||
T(StrongUseBeforeDeclaration, \
|
||||
"In strong mode, declaring variable '%' before its use is required") \
|
||||
T(StrongVar, \
|
||||
"In strong mode, 'var' is deprecated, use 'let' or 'const' instead") \
|
||||
T(TemplateOctalLiteral, \
|
||||
"Octal literals are not allowed in template strings.") \
|
||||
T(ThisFormalParameter, "'this' is not a valid formal parameter name") \
|
||||
T(TooManyArguments, \
|
||||
"Too many arguments in function call (only 65535 allowed)") \
|
||||
T(TooManyParameters, \
|
||||
"Too many parameters in function definition (only 65535 allowed)") \
|
||||
T(TooManyVariables, "Too many variables declared (only 4194303 allowed)") \
|
||||
T(UnexpectedEOS, "Unexpected end of input") \
|
||||
T(UnexpectedReserved, "Unexpected reserved word") \
|
||||
T(UnexpectedStrictReserved, "Unexpected strict mode reserved word") \
|
||||
T(UnexpectedSuper, "'super' keyword unexpected here") \
|
||||
T(UnexpectedTemplateString, "Unexpected template string") \
|
||||
T(UnexpectedToken, "Unexpected token %") \
|
||||
T(UnexpectedTokenIdentifier, "Unexpected identifier") \
|
||||
T(UnexpectedTokenNumber, "Unexpected number") \
|
||||
T(UnexpectedTokenString, "Unexpected string") \
|
||||
T(UnknownLabel, "Undefined label '%'") \
|
||||
T(UnterminatedArgList, "missing ) after argument list") \
|
||||
T(UnterminatedRegExp, "Invalid regular expression: missing /") \
|
||||
T(UnterminatedTemplate, "Unterminated template literal") \
|
||||
T(UnterminatedTemplateExpr, "Missing } in template expression") \
|
||||
/* EvalError */ \
|
||||
T(CodeGenFromStrings, "%") \
|
||||
/* URIError */ \
|
||||
@ -323,6 +416,30 @@ class MessageTemplate {
|
||||
Handle<String> arg0,
|
||||
Handle<String> arg1,
|
||||
Handle<String> arg2);
|
||||
|
||||
static Handle<String> FormatMessage(Isolate* isolate, int template_index,
|
||||
Handle<Object> arg);
|
||||
};
|
||||
|
||||
|
||||
// A message handler is a convenience interface for accessing the list
|
||||
// of message listeners registered in an environment
|
||||
class MessageHandler {
|
||||
public:
|
||||
// Returns a message object for the API to use.
|
||||
static Handle<JSMessageObject> MakeMessageObject(
|
||||
Isolate* isolate, MessageTemplate::Template type, MessageLocation* loc,
|
||||
Handle<Object> argument, Handle<JSArray> stack_frames);
|
||||
|
||||
// Report a formatted message (needs JS allocation).
|
||||
static void ReportMessage(Isolate* isolate, MessageLocation* loc,
|
||||
Handle<Object> message);
|
||||
|
||||
static void DefaultMessageReport(Isolate* isolate, const MessageLocation* loc,
|
||||
Handle<Object> message_obj);
|
||||
static Handle<String> GetMessage(Isolate* isolate, Handle<Object> data);
|
||||
static SmartArrayPointer<char> GetLocalizedMessage(Isolate* isolate,
|
||||
Handle<Object> data);
|
||||
};
|
||||
} } // namespace v8::internal
|
||||
|
||||
|
159
src/messages.js
159
src/messages.js
@ -5,11 +5,11 @@
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
var $errorToString;
|
||||
var $formatMessage;
|
||||
var $getStackTraceLine;
|
||||
var $messageGetPositionInLine;
|
||||
var $messageGetLineNumber;
|
||||
var $messageGetSourceLine;
|
||||
var $noSideEffectToString;
|
||||
var $stackOverflowBoilerplate;
|
||||
var $stackTraceSymbol;
|
||||
var $toDetailString;
|
||||
@ -51,127 +51,6 @@ var GlobalSyntaxError;
|
||||
var GlobalReferenceError;
|
||||
var GlobalEvalError;
|
||||
|
||||
var kMessages = {
|
||||
// Error
|
||||
constructor_is_generator: ["Class constructor may not be a generator"],
|
||||
constructor_is_accessor: ["Class constructor may not be an accessor"],
|
||||
// TypeError
|
||||
unexpected_token: ["Unexpected token ", "%0"],
|
||||
unexpected_token_number: ["Unexpected number"],
|
||||
unexpected_token_string: ["Unexpected string"],
|
||||
unexpected_token_identifier: ["Unexpected identifier"],
|
||||
unexpected_reserved: ["Unexpected reserved word"],
|
||||
unexpected_strict_reserved: ["Unexpected strict mode reserved word"],
|
||||
unexpected_eos: ["Unexpected end of input"],
|
||||
unexpected_template_string: ["Unexpected template string"],
|
||||
malformed_regexp_flags: ["Invalid regular expression flags"],
|
||||
unterminated_regexp: ["Invalid regular expression: missing /"],
|
||||
unterminated_template: ["Unterminated template literal"],
|
||||
unterminated_template_expr: ["Missing } in template expression"],
|
||||
unterminated_arg_list: ["missing ) after argument list"],
|
||||
multiple_defaults_in_switch: ["More than one default clause in switch statement"],
|
||||
newline_after_throw: ["Illegal newline after throw"],
|
||||
label_redeclaration: ["Label '", "%0", "' has already been declared"],
|
||||
var_redeclaration: ["Identifier '", "%0", "' has already been declared"],
|
||||
no_catch_or_finally: ["Missing catch or finally after try"],
|
||||
unknown_label: ["Undefined label '", "%0", "'"],
|
||||
uncaught_exception: ["Uncaught ", "%0"],
|
||||
undefined_method: ["Object ", "%1", " has no method '", "%0", "'"],
|
||||
non_object_property_store: ["Cannot set property '", "%0", "' of ", "%1"],
|
||||
value_and_accessor: ["Invalid property. A property cannot both have accessors and be writable or have a value, ", "%0"],
|
||||
proto_object_or_null: ["Object prototype may only be an Object or null: ", "%0"],
|
||||
// ReferenceError
|
||||
invalid_lhs_in_assignment: ["Invalid left-hand side in assignment"],
|
||||
invalid_lhs_in_for: ["Invalid left-hand side in for-loop"],
|
||||
invalid_lhs_in_postfix_op: ["Invalid left-hand side expression in postfix operation"],
|
||||
invalid_lhs_in_prefix_op: ["Invalid left-hand side expression in prefix operation"],
|
||||
// SyntaxError
|
||||
not_isvar: ["builtin %IS_VAR: not a variable"],
|
||||
single_function_literal: ["Single function literal required"],
|
||||
illegal_break: ["Illegal break statement"],
|
||||
illegal_continue: ["Illegal continue statement"],
|
||||
illegal_return: ["Illegal return statement"],
|
||||
error_loading_debugger: ["Error loading debugger"],
|
||||
array_indexof_not_defined: ["Array.getIndexOf: Argument undefined"],
|
||||
illegal_access: ["Illegal access"],
|
||||
static_prototype: ["Classes may not have static property named prototype"],
|
||||
strict_mode_with: ["Strict mode code may not include a with statement"],
|
||||
strict_eval_arguments: ["Unexpected eval or arguments in strict mode"],
|
||||
too_many_arguments: ["Too many arguments in function call (only 65535 allowed)"],
|
||||
too_many_parameters: ["Too many parameters in function definition (only 65535 allowed)"],
|
||||
too_many_variables: ["Too many variables declared (only 4194303 allowed)"],
|
||||
strict_param_dupe: ["Strict mode function may not have duplicate parameter names"],
|
||||
strict_octal_literal: ["Octal literals are not allowed in strict mode."],
|
||||
template_octal_literal: ["Octal literals are not allowed in template strings."],
|
||||
strict_delete: ["Delete of an unqualified identifier in strict mode."],
|
||||
strict_function: ["In strict mode code, functions can only be declared at top level or immediately within another function." ],
|
||||
strict_caller: ["Illegal access to a strict mode caller function."],
|
||||
strong_ellision: ["In strong mode, arrays with holes are deprecated, use maps instead"],
|
||||
strong_arguments: ["In strong mode, 'arguments' is deprecated, use '...args' instead"],
|
||||
strong_undefined: ["In strong mode, binding or assigning to 'undefined' is deprecated"],
|
||||
strong_direct_eval: ["In strong mode, direct calls to eval are deprecated"],
|
||||
strong_switch_fallthrough : ["In strong mode, switch fall-through is deprecated, terminate each case with 'break', 'continue', 'return' or 'throw'"],
|
||||
strong_equal: ["In strong mode, '==' and '!=' are deprecated, use '===' and '!==' instead"],
|
||||
strong_delete: ["In strong mode, 'delete' is deprecated, use maps or sets instead"],
|
||||
strong_var: ["In strong mode, 'var' is deprecated, use 'let' or 'const' instead"],
|
||||
strong_for_in: ["In strong mode, 'for'-'in' loops are deprecated, use 'for'-'of' instead"],
|
||||
strong_empty: ["In strong mode, empty sub-statements are deprecated, make them explicit with '{}' instead"],
|
||||
strong_use_before_declaration: ["In strong mode, declaring variable '", "%0", "' before its use is required"],
|
||||
strong_unbound_global: ["In strong mode, using an undeclared global variable '", "%0", "' is not allowed"],
|
||||
strong_super_call_missing: ["In strong mode, invoking the super constructor in a subclass is required"],
|
||||
strong_super_call_duplicate: ["In strong mode, invoking the super constructor multiple times is deprecated"],
|
||||
strong_super_call_misplaced: ["In strong mode, the super constructor must be invoked before any assignment to 'this'"],
|
||||
strong_constructor_super: ["In strong mode, 'super' can only be used to invoke the super constructor, and cannot be nested inside another statement or expression"],
|
||||
strong_constructor_this: ["In strong mode, 'this' can only be used to initialize properties, and cannot be nested inside another statement or expression"],
|
||||
strong_constructor_return_value: ["In strong mode, returning a value from a constructor is deprecated"],
|
||||
strong_constructor_return_misplaced: ["In strong mode, returning from a constructor before its super constructor invocation or all assignments to 'this' is deprecated"],
|
||||
sloppy_lexical: ["Block-scoped declarations (let, const, function, class) not yet supported outside strict mode"],
|
||||
malformed_arrow_function_parameter_list: ["Malformed arrow function parameter list"],
|
||||
module_export_undefined: ["Export '", "%0", "' is not defined in module"],
|
||||
duplicate_export: ["Duplicate export of '", "%0", "'"],
|
||||
unexpected_super: ["'super' keyword unexpected here"],
|
||||
duplicate_constructor: ["A class may only have one constructor"],
|
||||
super_constructor_call: ["A 'super' constructor call may only appear as the first statement of a function, and its arguments may not access 'this'. Other forms are not yet supported."],
|
||||
duplicate_proto: ["Duplicate __proto__ fields are not allowed in object literals"],
|
||||
param_after_rest: ["Rest parameter must be last formal parameter"],
|
||||
derived_constructor_return: ["Derived constructors may only return object or undefined"],
|
||||
for_in_loop_initializer: ["for-in loop variable declaration may not have an initializer."],
|
||||
for_of_loop_initializer: ["for-of loop variable declaration may not have an initializer."],
|
||||
for_inof_loop_multi_bindings: ["Invalid left-hand side in ", "%0", " loop: Must have a single binding."],
|
||||
bad_getter_arity: ["Getter must not have any formal parameters."],
|
||||
bad_setter_arity: ["Setter must have exactly one formal parameter."],
|
||||
this_formal_parameter: ["'this' is not a valid formal parameter name"],
|
||||
duplicate_arrow_function_formal_parameter: ["Arrow function may not have duplicate parameter names"]
|
||||
};
|
||||
|
||||
|
||||
function FormatString(format, args) {
|
||||
var result = "";
|
||||
var arg_num = 0;
|
||||
for (var i = 0; i < format.length; i++) {
|
||||
var str = format[i];
|
||||
if (str.length == 2 && %_StringCharCodeAt(str, 0) == 0x25) {
|
||||
// Two-char string starts with "%".
|
||||
var arg_num = (%_StringCharCodeAt(str, 1) - 0x30) >>> 0;
|
||||
if (arg_num < 4) {
|
||||
// str is one of %0, %1, %2 or %3.
|
||||
try {
|
||||
str = NoSideEffectToString(args[arg_num]);
|
||||
} catch (e) {
|
||||
if (%IsJSModule(args[arg_num]))
|
||||
str = "module";
|
||||
else if (IS_SPEC_OBJECT(args[arg_num]))
|
||||
str = "object";
|
||||
else
|
||||
str = "#<error>";
|
||||
}
|
||||
}
|
||||
}
|
||||
result += str;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
function NoSideEffectsObjectToString() {
|
||||
if (IS_UNDEFINED(this) && !IS_UNDETECTABLE(this)) return "[object Undefined]";
|
||||
@ -281,20 +160,14 @@ function MakeGenericError(constructor, type, arg0, arg1, arg2) {
|
||||
|
||||
// Helper functions; called from the runtime system.
|
||||
function FormatMessage(type, arg0, arg1, arg2) {
|
||||
if (IS_NUMBER(type)) {
|
||||
var arg0 = NoSideEffectToString(arg0);
|
||||
var arg1 = NoSideEffectToString(arg1);
|
||||
var arg2 = NoSideEffectToString(arg2);
|
||||
try {
|
||||
return %FormatMessageString(type, arg0, arg1, arg2);
|
||||
} catch (e) {
|
||||
return "";
|
||||
}
|
||||
var arg0 = NoSideEffectToString(arg0);
|
||||
var arg1 = NoSideEffectToString(arg1);
|
||||
var arg2 = NoSideEffectToString(arg2);
|
||||
try {
|
||||
return %FormatMessageString(type, arg0, arg1, arg2);
|
||||
} catch (e) {
|
||||
return "<error>";
|
||||
}
|
||||
// TODO(yangguo): remove this code path once we migrated all messages.
|
||||
var format = kMessages[type];
|
||||
if (!format) return "<unknown message " + type + ">";
|
||||
return FormatString(format, arg0);
|
||||
}
|
||||
|
||||
|
||||
@ -1151,11 +1024,11 @@ $installFunctions(GlobalError.prototype, DONT_ENUM,
|
||||
['toString', ErrorToString]);
|
||||
|
||||
$errorToString = ErrorToString;
|
||||
$formatMessage = FormatMessage;
|
||||
$getStackTraceLine = GetStackTraceLine;
|
||||
$messageGetPositionInLine = GetPositionInLine;
|
||||
$messageGetLineNumber = GetLineNumber;
|
||||
$messageGetSourceLine = GetSourceLine;
|
||||
$noSideEffectToString = NoSideEffectToString;
|
||||
$toDetailString = ToDetailString;
|
||||
|
||||
$Error = GlobalError;
|
||||
@ -1194,20 +1067,6 @@ MakeURIError = function() {
|
||||
return MakeGenericError(GlobalURIError, kURIMalformed);
|
||||
}
|
||||
|
||||
// The embedded versions are called from unoptimized code, with embedded
|
||||
// arguments. Those arguments cannot be arrays, which are context-dependent.
|
||||
MakeSyntaxErrorEmbedded = function(type, arg) {
|
||||
return MakeGenericError(GlobalSyntaxError, type, [arg]);
|
||||
}
|
||||
|
||||
MakeReferenceErrorEmbedded = function(type, arg) {
|
||||
return MakeGenericError(GlobalReferenceError, type, [arg]);
|
||||
}
|
||||
|
||||
MakeTypeErrorEmbedded = function(type, arg) {
|
||||
return MakeGenericError(GlobalTypeError, type, [arg]);
|
||||
}
|
||||
|
||||
//Boilerplate for exceptions for stack overflows. Used from
|
||||
//Isolate::StackOverflow().
|
||||
$stackOverflowBoilerplate = MakeRangeError(kStackOverflow);
|
||||
|
@ -493,8 +493,6 @@ void JSDate::JSDateVerify() {
|
||||
|
||||
void JSMessageObject::JSMessageObjectVerify() {
|
||||
CHECK(IsJSMessageObject());
|
||||
CHECK(type()->IsString());
|
||||
CHECK(arguments()->IsJSArray());
|
||||
VerifyObjectField(kStartPositionOffset);
|
||||
VerifyObjectField(kEndPositionOffset);
|
||||
VerifyObjectField(kArgumentsOffset);
|
||||
|
@ -6323,8 +6323,8 @@ ACCESSORS(JSDate, min, Object, kMinOffset)
|
||||
ACCESSORS(JSDate, sec, Object, kSecOffset)
|
||||
|
||||
|
||||
ACCESSORS(JSMessageObject, type, String, kTypeOffset)
|
||||
ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
|
||||
SMI_ACCESSORS(JSMessageObject, type, kTypeOffset)
|
||||
ACCESSORS(JSMessageObject, argument, Object, kArgumentsOffset)
|
||||
ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
|
||||
ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
|
||||
SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
|
||||
|
@ -547,8 +547,8 @@ void JSValue::JSValuePrint(std::ostream& os) { // NOLINT
|
||||
|
||||
void JSMessageObject::JSMessageObjectPrint(std::ostream& os) { // NOLINT
|
||||
HeapObject::PrintHeader(os, "JSMessageObject");
|
||||
os << " - type: " << Brief(type());
|
||||
os << "\n - arguments: " << Brief(arguments());
|
||||
os << " - type: " << type();
|
||||
os << "\n - arguments: " << Brief(argument());
|
||||
os << "\n - start_position: " << start_position();
|
||||
os << "\n - end_position: " << end_position();
|
||||
os << "\n - script: " << Brief(script());
|
||||
|
@ -8002,10 +8002,11 @@ class JSDate: public JSObject {
|
||||
class JSMessageObject: public JSObject {
|
||||
public:
|
||||
// [type]: the type of error message.
|
||||
DECL_ACCESSORS(type, String)
|
||||
inline int type() const;
|
||||
inline void set_type(int value);
|
||||
|
||||
// [arguments]: the arguments for formatting the error message.
|
||||
DECL_ACCESSORS(arguments, JSArray)
|
||||
DECL_ACCESSORS(argument, Object)
|
||||
|
||||
// [script]: the script from which the error message originated.
|
||||
DECL_ACCESSORS(script, Object)
|
||||
@ -10548,7 +10549,7 @@ class AccessorInfo: public Struct {
|
||||
// Bit positions in flag.
|
||||
static const int kAllCanReadBit = 0;
|
||||
static const int kAllCanWriteBit = 1;
|
||||
class AttributesField: public BitField<PropertyAttributes, 2, 3> {};
|
||||
class AttributesField : public BitField<PropertyAttributes, 2, 3> {};
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo);
|
||||
};
|
||||
|
156
src/parser.cc
156
src/parser.cc
@ -636,35 +636,35 @@ Expression* ParserTraits::BuildUnaryExpression(Expression* expression,
|
||||
}
|
||||
|
||||
|
||||
Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) {
|
||||
Expression* ParserTraits::NewThrowReferenceError(
|
||||
MessageTemplate::Template message, int pos) {
|
||||
return NewThrowError(
|
||||
parser_->ast_value_factory()->make_reference_error_string(), message,
|
||||
parser_->ast_value_factory()->empty_string(), pos);
|
||||
}
|
||||
|
||||
|
||||
Expression* ParserTraits::NewThrowSyntaxError(
|
||||
const char* message, const AstRawString* arg, int pos) {
|
||||
Expression* ParserTraits::NewThrowSyntaxError(MessageTemplate::Template message,
|
||||
const AstRawString* arg,
|
||||
int pos) {
|
||||
return NewThrowError(parser_->ast_value_factory()->make_syntax_error_string(),
|
||||
message, arg, pos);
|
||||
}
|
||||
|
||||
|
||||
Expression* ParserTraits::NewThrowTypeError(
|
||||
const char* message, const AstRawString* arg, int pos) {
|
||||
Expression* ParserTraits::NewThrowTypeError(MessageTemplate::Template message,
|
||||
const AstRawString* arg, int pos) {
|
||||
return NewThrowError(parser_->ast_value_factory()->make_type_error_string(),
|
||||
message, arg, pos);
|
||||
}
|
||||
|
||||
|
||||
Expression* ParserTraits::NewThrowError(
|
||||
const AstRawString* constructor, const char* message,
|
||||
const AstRawString* arg, int pos) {
|
||||
Expression* ParserTraits::NewThrowError(const AstRawString* constructor,
|
||||
MessageTemplate::Template message,
|
||||
const AstRawString* arg, int pos) {
|
||||
Zone* zone = parser_->zone();
|
||||
const AstRawString* type =
|
||||
parser_->ast_value_factory()->GetOneByteString(message);
|
||||
ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone);
|
||||
args->Add(parser_->factory()->NewStringLiteral(type, pos), zone);
|
||||
args->Add(parser_->factory()->NewSmiLiteral(message, pos), zone);
|
||||
args->Add(parser_->factory()->NewStringLiteral(arg, pos), zone);
|
||||
CallRuntime* call_constructor =
|
||||
parser_->factory()->NewCallRuntime(constructor, NULL, args, pos);
|
||||
@ -673,8 +673,8 @@ Expression* ParserTraits::NewThrowError(
|
||||
|
||||
|
||||
void ParserTraits::ReportMessageAt(Scanner::Location source_location,
|
||||
const char* message, const char* arg,
|
||||
ParseErrorType error_type) {
|
||||
MessageTemplate::Template message,
|
||||
const char* arg, ParseErrorType error_type) {
|
||||
if (parser_->stack_overflow()) {
|
||||
// Suppress the error message (syntax error or such) in the presence of a
|
||||
// stack overflow. The isolate allows only one pending exception at at time
|
||||
@ -687,14 +687,15 @@ void ParserTraits::ReportMessageAt(Scanner::Location source_location,
|
||||
}
|
||||
|
||||
|
||||
void ParserTraits::ReportMessage(const char* message, const char* arg,
|
||||
ParseErrorType error_type) {
|
||||
void ParserTraits::ReportMessage(MessageTemplate::Template message,
|
||||
const char* arg, ParseErrorType error_type) {
|
||||
Scanner::Location source_location = parser_->scanner()->location();
|
||||
ReportMessageAt(source_location, message, arg, error_type);
|
||||
}
|
||||
|
||||
|
||||
void ParserTraits::ReportMessage(const char* message, const AstRawString* arg,
|
||||
void ParserTraits::ReportMessage(MessageTemplate::Template message,
|
||||
const AstRawString* arg,
|
||||
ParseErrorType error_type) {
|
||||
Scanner::Location source_location = parser_->scanner()->location();
|
||||
ReportMessageAt(source_location, message, arg, error_type);
|
||||
@ -702,7 +703,8 @@ void ParserTraits::ReportMessage(const char* message, const AstRawString* arg,
|
||||
|
||||
|
||||
void ParserTraits::ReportMessageAt(Scanner::Location source_location,
|
||||
const char* message, const AstRawString* arg,
|
||||
MessageTemplate::Template message,
|
||||
const AstRawString* arg,
|
||||
ParseErrorType error_type) {
|
||||
if (parser_->stack_overflow()) {
|
||||
// Suppress the error message (syntax error or such) in the presence of a
|
||||
@ -1022,7 +1024,7 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
|
||||
!body->at(0)->IsExpressionStatement() ||
|
||||
!body->at(0)->AsExpressionStatement()->
|
||||
expression()->IsFunctionLiteral()) {
|
||||
ReportMessage("single_function_literal");
|
||||
ReportMessage(MessageTemplate::kSingleFunctionLiteral);
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
@ -1220,13 +1222,13 @@ void* Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token,
|
||||
Scanner::Location super_loc = function_state_->super_location();
|
||||
if (this_loc.beg_pos != old_this_loc.beg_pos &&
|
||||
this_loc.beg_pos != token_loc.beg_pos) {
|
||||
ReportMessageAt(this_loc, "strong_constructor_this");
|
||||
ReportMessageAt(this_loc, MessageTemplate::kStrongConstructorThis);
|
||||
*ok = false;
|
||||
return nullptr;
|
||||
}
|
||||
if (super_loc.beg_pos != old_super_loc.beg_pos &&
|
||||
super_loc.beg_pos != token_loc.beg_pos) {
|
||||
ReportMessageAt(super_loc, "strong_constructor_super");
|
||||
ReportMessageAt(super_loc, MessageTemplate::kStrongConstructorSuper);
|
||||
*ok = false;
|
||||
return nullptr;
|
||||
}
|
||||
@ -1380,7 +1382,8 @@ void* Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) {
|
||||
// TODO(adamk): Pass both local_name and export_name once ParserTraits
|
||||
// supports multiple arg error messages.
|
||||
// Also try to report this at a better location.
|
||||
ParserTraits::ReportMessage("module_export_undefined", it.local_name());
|
||||
ParserTraits::ReportMessage(MessageTemplate::kModuleExportUndefined,
|
||||
it.local_name());
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
@ -1477,15 +1480,15 @@ ZoneList<ImportDeclaration*>* Parser::ParseNamedImports(int pos, bool* ok) {
|
||||
}
|
||||
if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false)) {
|
||||
*ok = false;
|
||||
ReportMessage("unexpected_reserved");
|
||||
ReportMessage(MessageTemplate::kUnexpectedReserved);
|
||||
return NULL;
|
||||
} else if (IsEvalOrArguments(local_name)) {
|
||||
*ok = false;
|
||||
ReportMessage("strict_eval_arguments");
|
||||
ReportMessage(MessageTemplate::kStrictEvalArguments);
|
||||
return NULL;
|
||||
} else if (is_strong(language_mode()) && IsUndefined(local_name)) {
|
||||
*ok = false;
|
||||
ReportMessage("strong_undefined");
|
||||
ReportMessage(MessageTemplate::kStrongUndefined);
|
||||
return NULL;
|
||||
}
|
||||
VariableProxy* proxy = NewUnresolved(local_name, IMPORT);
|
||||
@ -1629,8 +1632,8 @@ Statement* Parser::ParseExportDefault(bool* ok) {
|
||||
if (names.length() == 1) {
|
||||
scope_->module()->AddLocalExport(default_string, names.first(), zone(), ok);
|
||||
if (!*ok) {
|
||||
ParserTraits::ReportMessageAt(default_loc, "duplicate_export",
|
||||
default_string);
|
||||
ParserTraits::ReportMessageAt(
|
||||
default_loc, MessageTemplate::kDuplicateExport, default_string);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
@ -1693,7 +1696,7 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
|
||||
} else if (reserved_loc.IsValid()) {
|
||||
// No FromClause, so reserved words are invalid in ExportClause.
|
||||
*ok = false;
|
||||
ReportMessageAt(reserved_loc, "unexpected_reserved");
|
||||
ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
|
||||
return NULL;
|
||||
}
|
||||
ExpectSemicolon(CHECK_OK);
|
||||
@ -1706,7 +1709,8 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
|
||||
zone(), ok);
|
||||
if (!*ok) {
|
||||
ParserTraits::ReportMessageAt(export_locations[i],
|
||||
"duplicate_export", export_names[i]);
|
||||
MessageTemplate::kDuplicateExport,
|
||||
export_names[i]);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -1746,7 +1750,7 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
|
||||
descriptor->AddLocalExport(names[i], names[i], zone(), ok);
|
||||
if (!*ok) {
|
||||
// TODO(adamk): Possibly report this error at the right place.
|
||||
ParserTraits::ReportMessage("duplicate_export", names[i]);
|
||||
ParserTraits::ReportMessage(MessageTemplate::kDuplicateExport, names[i]);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -1801,7 +1805,8 @@ Statement* Parser::ParseSubStatement(ZoneList<const AstRawString*>* labels,
|
||||
|
||||
case Token::SEMICOLON:
|
||||
if (is_strong(language_mode())) {
|
||||
ReportMessageAt(scanner()->peek_location(), "strong_empty");
|
||||
ReportMessageAt(scanner()->peek_location(),
|
||||
MessageTemplate::kStrongEmpty);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
@ -1858,7 +1863,8 @@ Statement* Parser::ParseSubStatement(ZoneList<const AstRawString*>* labels,
|
||||
// Statement:
|
||||
// GeneratorDeclaration
|
||||
if (is_strict(language_mode())) {
|
||||
ReportMessageAt(scanner()->peek_location(), "strict_function");
|
||||
ReportMessageAt(scanner()->peek_location(),
|
||||
MessageTemplate::kStrictFunction);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
@ -1982,12 +1988,12 @@ Variable* Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
|
||||
if (is_strict(language_mode())) {
|
||||
// In harmony we treat re-declarations as early errors. See
|
||||
// ES5 16 for a definition of early errors.
|
||||
ParserTraits::ReportMessage("var_redeclaration", name);
|
||||
ParserTraits::ReportMessage(MessageTemplate::kVarRedeclaration, name);
|
||||
*ok = false;
|
||||
return nullptr;
|
||||
}
|
||||
Expression* expression = NewThrowTypeError(
|
||||
"var_redeclaration", name, declaration->position());
|
||||
MessageTemplate::kVarRedeclaration, name, declaration->position());
|
||||
declaration_scope->SetIllegalRedeclaration(expression);
|
||||
} else if (mode == VAR) {
|
||||
var->set_maybe_assigned();
|
||||
@ -2164,7 +2170,7 @@ Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
|
||||
|
||||
Expect(Token::CLASS, CHECK_OK);
|
||||
if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
|
||||
ReportMessage("sloppy_lexical");
|
||||
ReportMessage(MessageTemplate::kSloppyLexical);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
@ -2350,7 +2356,7 @@ void Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
|
||||
if (peek() == Token::VAR) {
|
||||
if (is_strong(language_mode())) {
|
||||
Scanner::Location location = scanner()->peek_location();
|
||||
ReportMessageAt(location, "strong_var");
|
||||
ReportMessageAt(location, MessageTemplate::kStrongVar);
|
||||
*ok = false;
|
||||
return;
|
||||
}
|
||||
@ -2530,8 +2536,9 @@ Statement* Parser::ParseExpressionOrLabelledStatement(
|
||||
default:
|
||||
if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
|
||||
ReportMessageAt(function_state_->this_location(),
|
||||
is_this ? "strong_constructor_this"
|
||||
: "strong_constructor_super");
|
||||
is_this
|
||||
? MessageTemplate::kStrongConstructorThis
|
||||
: MessageTemplate::kStrongConstructorSuper);
|
||||
*ok = false;
|
||||
return nullptr;
|
||||
}
|
||||
@ -2562,7 +2569,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(
|
||||
// structured. However, these are probably changes we want to
|
||||
// make later anyway so we should go back and fix this then.
|
||||
if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
|
||||
ParserTraits::ReportMessage("label_redeclaration", label);
|
||||
ParserTraits::ReportMessage(MessageTemplate::kLabelRedeclaration, label);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
@ -2595,7 +2602,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(
|
||||
if (peek() == Token::IDENTIFIER && expr->AsVariableProxy() != NULL &&
|
||||
expr->AsVariableProxy()->raw_name() ==
|
||||
ast_value_factory()->let_string()) {
|
||||
ReportMessage("sloppy_lexical", NULL);
|
||||
ReportMessage(MessageTemplate::kSloppyLexical, NULL);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
@ -2643,9 +2650,9 @@ Statement* Parser::ParseContinueStatement(bool* ok) {
|
||||
IterationStatement* target = LookupContinueTarget(label, CHECK_OK);
|
||||
if (target == NULL) {
|
||||
// Illegal continue statement.
|
||||
const char* message = "illegal_continue";
|
||||
MessageTemplate::Template message = MessageTemplate::kIllegalContinue;
|
||||
if (label != NULL) {
|
||||
message = "unknown_label";
|
||||
message = MessageTemplate::kUnknownLabel;
|
||||
}
|
||||
ParserTraits::ReportMessage(message, label);
|
||||
*ok = false;
|
||||
@ -2680,9 +2687,9 @@ Statement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels,
|
||||
target = LookupBreakTarget(label, CHECK_OK);
|
||||
if (target == NULL) {
|
||||
// Illegal break statement.
|
||||
const char* message = "illegal_break";
|
||||
MessageTemplate::Template message = MessageTemplate::kIllegalBreak;
|
||||
if (label != NULL) {
|
||||
message = "unknown_label";
|
||||
message = MessageTemplate::kUnknownLabel;
|
||||
}
|
||||
ParserTraits::ReportMessage(message, label);
|
||||
*ok = false;
|
||||
@ -2721,7 +2728,7 @@ Statement* Parser::ParseReturnStatement(bool* ok) {
|
||||
i::IsConstructor(function_state_->kind())) {
|
||||
int pos = peek_position();
|
||||
ReportMessageAt(Scanner::Location(pos, pos + 1),
|
||||
"strong_constructor_return_value");
|
||||
MessageTemplate::kStrongConstructorReturnValue);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
@ -2745,7 +2752,7 @@ Statement* Parser::ParseReturnStatement(bool* ok) {
|
||||
Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
|
||||
|
||||
Expression* throw_expression =
|
||||
NewThrowTypeError("derived_constructor_return",
|
||||
NewThrowTypeError(MessageTemplate::kDerivedConstructorReturn,
|
||||
ast_value_factory()->empty_string(), pos);
|
||||
|
||||
// %_IsSpecObject(temp)
|
||||
@ -2787,7 +2794,7 @@ Statement* Parser::ParseReturnStatement(bool* ok) {
|
||||
|
||||
Scope* decl_scope = scope_->DeclarationScope();
|
||||
if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) {
|
||||
ReportMessageAt(loc, "illegal_return");
|
||||
ReportMessageAt(loc, MessageTemplate::kIllegalReturn);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
@ -2804,7 +2811,7 @@ Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels,
|
||||
int pos = position();
|
||||
|
||||
if (is_strict(language_mode())) {
|
||||
ReportMessage("strict_mode_with");
|
||||
ReportMessage(MessageTemplate::kStrictWith);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
@ -2837,7 +2844,7 @@ CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
|
||||
} else {
|
||||
Expect(Token::DEFAULT, CHECK_OK);
|
||||
if (*default_seen_ptr) {
|
||||
ReportMessage("multiple_defaults_in_switch");
|
||||
ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
@ -2856,7 +2863,8 @@ CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
|
||||
}
|
||||
if (is_strong(language_mode()) && stat != NULL && !stat->IsJump() &&
|
||||
peek() != Token::RBRACE) {
|
||||
ReportMessageAt(scanner()->location(), "strong_switch_fallthrough");
|
||||
ReportMessageAt(scanner()->location(),
|
||||
MessageTemplate::kStrongSwitchFallthrough);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
@ -2899,7 +2907,7 @@ Statement* Parser::ParseThrowStatement(bool* ok) {
|
||||
Expect(Token::THROW, CHECK_OK);
|
||||
int pos = position();
|
||||
if (scanner()->HasAnyLineTerminatorBeforeNext()) {
|
||||
ReportMessage("newline_after_throw");
|
||||
ReportMessage(MessageTemplate::kNewlineAfterThrow);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
@ -2930,7 +2938,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
|
||||
|
||||
Token::Value tok = peek();
|
||||
if (tok != Token::CATCH && tok != Token::FINALLY) {
|
||||
ReportMessage("no_catch_or_finally");
|
||||
ReportMessage(MessageTemplate::kNoCatchOrFinally);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
@ -3412,9 +3420,9 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
|
||||
if (num_decl != 1) {
|
||||
const char* loop_type =
|
||||
mode == ForEachStatement::ITERATE ? "for-of" : "for-in";
|
||||
ParserTraits::ReportMessageAt(parsing_result.bindings_loc,
|
||||
"for_inof_loop_multi_bindings",
|
||||
loop_type);
|
||||
ParserTraits::ReportMessageAt(
|
||||
parsing_result.bindings_loc,
|
||||
MessageTemplate::kForInOfLoopMultiBindings, loop_type);
|
||||
*ok = false;
|
||||
return nullptr;
|
||||
}
|
||||
@ -3422,11 +3430,11 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
|
||||
(is_strict(language_mode()) || mode == ForEachStatement::ITERATE)) {
|
||||
if (mode == ForEachStatement::ITERATE) {
|
||||
ReportMessageAt(parsing_result.first_initializer_loc,
|
||||
"for_of_loop_initializer");
|
||||
MessageTemplate::kForOfLoopInitializer);
|
||||
} else {
|
||||
// TODO(caitp): This should be an error in sloppy mode too.
|
||||
ReportMessageAt(parsing_result.first_initializer_loc,
|
||||
"for_in_loop_initializer");
|
||||
MessageTemplate::kForInLoopInitializer);
|
||||
}
|
||||
*ok = false;
|
||||
return nullptr;
|
||||
@ -3475,9 +3483,9 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
|
||||
if (num_decl != 1) {
|
||||
const char* loop_type =
|
||||
mode == ForEachStatement::ITERATE ? "for-of" : "for-in";
|
||||
ParserTraits::ReportMessageAt(parsing_result.bindings_loc,
|
||||
"for_inof_loop_multi_bindings",
|
||||
loop_type);
|
||||
ParserTraits::ReportMessageAt(
|
||||
parsing_result.bindings_loc,
|
||||
MessageTemplate::kForInOfLoopMultiBindings, loop_type);
|
||||
*ok = false;
|
||||
return nullptr;
|
||||
}
|
||||
@ -3485,10 +3493,10 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
|
||||
(is_strict(language_mode()) || mode == ForEachStatement::ITERATE)) {
|
||||
if (mode == ForEachStatement::ITERATE) {
|
||||
ReportMessageAt(parsing_result.first_initializer_loc,
|
||||
"for_of_loop_initializer");
|
||||
MessageTemplate::kForOfLoopInitializer);
|
||||
} else {
|
||||
ReportMessageAt(parsing_result.first_initializer_loc,
|
||||
"for_in_loop_initializer");
|
||||
MessageTemplate::kForInLoopInitializer);
|
||||
}
|
||||
*ok = false;
|
||||
return nullptr;
|
||||
@ -3559,7 +3567,8 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
|
||||
if (CheckInOrOf(accept_OF, &mode, ok)) {
|
||||
if (!*ok) return nullptr;
|
||||
expression = this->CheckAndRewriteReferenceExpression(
|
||||
expression, lhs_location, "invalid_lhs_in_for", CHECK_OK);
|
||||
expression, lhs_location, MessageTemplate::kInvalidLhsInFor,
|
||||
CHECK_OK);
|
||||
|
||||
ForEachStatement* loop =
|
||||
factory()->NewForEachStatement(mode, labels, stmt_pos);
|
||||
@ -3591,7 +3600,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
|
||||
// Detect attempts at 'let' declarations in sloppy mode.
|
||||
if (peek() == Token::IDENTIFIER && is_sloppy(language_mode()) &&
|
||||
is_let_identifier_expression) {
|
||||
ReportMessage("sloppy_lexical", NULL);
|
||||
ReportMessage(MessageTemplate::kSloppyLexical, NULL);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
@ -3722,7 +3731,7 @@ void ParserTraits::DeclareArrowFunctionParameters(
|
||||
Scope* scope, Expression* expr, const Scanner::Location& params_loc,
|
||||
Scanner::Location* duplicate_loc, bool* ok) {
|
||||
if (scope->num_parameters() >= Code::kMaxArguments) {
|
||||
ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list");
|
||||
ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
|
||||
*ok = false;
|
||||
return;
|
||||
}
|
||||
@ -3989,7 +3998,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
||||
if (is_strong(language_mode()) && IsSubclassConstructor(kind)) {
|
||||
if (!function_state.super_location().IsValid()) {
|
||||
ReportMessageAt(function_name_location,
|
||||
"strong_super_call_missing", kReferenceError);
|
||||
MessageTemplate::kStrongSuperCallMissing,
|
||||
kReferenceError);
|
||||
*ok = false;
|
||||
return nullptr;
|
||||
}
|
||||
@ -4253,17 +4263,18 @@ ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
|
||||
bool* ok) {
|
||||
// All parts of a ClassDeclaration and ClassExpression are strict code.
|
||||
if (name_is_strict_reserved) {
|
||||
ReportMessageAt(class_name_location, "unexpected_strict_reserved");
|
||||
ReportMessageAt(class_name_location,
|
||||
MessageTemplate::kUnexpectedStrictReserved);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
if (IsEvalOrArguments(name)) {
|
||||
ReportMessageAt(class_name_location, "strict_eval_arguments");
|
||||
ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
if (is_strong(language_mode()) && IsUndefined(name)) {
|
||||
ReportMessageAt(class_name_location, "strong_undefined");
|
||||
ReportMessageAt(class_name_location, MessageTemplate::kStrongUndefined);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
@ -4392,7 +4403,7 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
|
||||
if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
|
||||
return args->at(0);
|
||||
} else {
|
||||
ReportMessage("not_isvar");
|
||||
ReportMessage(MessageTemplate::kNotIsvar);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
@ -4402,14 +4413,14 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
|
||||
if (function != NULL &&
|
||||
function->nargs != -1 &&
|
||||
function->nargs != args->length()) {
|
||||
ReportMessage("illegal_access");
|
||||
ReportMessage(MessageTemplate::kIllegalAccess);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Check that the function is defined if it's an inline runtime call.
|
||||
if (function == NULL && name->FirstCharacter() == '_') {
|
||||
ParserTraits::ReportMessage("not_defined", name);
|
||||
ParserTraits::ReportMessage(MessageTemplate::kNotDefined, name);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
@ -4434,7 +4445,8 @@ void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
|
||||
Scanner::Location location = position == RelocInfo::kNoPosition
|
||||
? Scanner::Location::invalid()
|
||||
: Scanner::Location(position, position + 1);
|
||||
ParserTraits::ReportMessageAt(location, "var_redeclaration", name);
|
||||
ParserTraits::ReportMessageAt(location, MessageTemplate::kVarRedeclaration,
|
||||
name);
|
||||
*ok = false;
|
||||
}
|
||||
}
|
||||
|
27
src/parser.h
27
src/parser.h
@ -659,33 +659,36 @@ class ParserTraits {
|
||||
int pos, AstNodeFactory* factory);
|
||||
|
||||
// Generate AST node that throws a ReferenceError with the given type.
|
||||
Expression* NewThrowReferenceError(const char* type, int pos);
|
||||
Expression* NewThrowReferenceError(MessageTemplate::Template message,
|
||||
int pos);
|
||||
|
||||
// Generate AST node that throws a SyntaxError with the given
|
||||
// type. The first argument may be null (in the handle sense) in
|
||||
// which case no arguments are passed to the constructor.
|
||||
Expression* NewThrowSyntaxError(
|
||||
const char* type, const AstRawString* arg, int pos);
|
||||
Expression* NewThrowSyntaxError(MessageTemplate::Template message,
|
||||
const AstRawString* arg, int pos);
|
||||
|
||||
// Generate AST node that throws a TypeError with the given
|
||||
// type. Both arguments must be non-null (in the handle sense).
|
||||
Expression* NewThrowTypeError(const char* type, const AstRawString* arg,
|
||||
int pos);
|
||||
Expression* NewThrowTypeError(MessageTemplate::Template message,
|
||||
const AstRawString* arg, int pos);
|
||||
|
||||
// Generic AST generator for throwing errors from compiled code.
|
||||
Expression* NewThrowError(
|
||||
const AstRawString* constructor, const char* type,
|
||||
const AstRawString* arg, int pos);
|
||||
Expression* NewThrowError(const AstRawString* constructor,
|
||||
MessageTemplate::Template message,
|
||||
const AstRawString* arg, int pos);
|
||||
|
||||
// Reporting errors.
|
||||
void ReportMessageAt(Scanner::Location source_location, const char* message,
|
||||
void ReportMessageAt(Scanner::Location source_location,
|
||||
MessageTemplate::Template message,
|
||||
const char* arg = NULL,
|
||||
ParseErrorType error_type = kSyntaxError);
|
||||
void ReportMessage(const char* message, const char* arg = NULL,
|
||||
void ReportMessage(MessageTemplate::Template message, const char* arg = NULL,
|
||||
ParseErrorType error_type = kSyntaxError);
|
||||
void ReportMessage(const char* message, const AstRawString* arg,
|
||||
void ReportMessage(MessageTemplate::Template message, const AstRawString* arg,
|
||||
ParseErrorType error_type = kSyntaxError);
|
||||
void ReportMessageAt(Scanner::Location source_location, const char* message,
|
||||
void ReportMessageAt(Scanner::Location source_location,
|
||||
MessageTemplate::Template message,
|
||||
const AstRawString* arg,
|
||||
ParseErrorType error_type = kSyntaxError);
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "src/ast.h"
|
||||
#include "src/messages.h"
|
||||
#include "src/parser.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -61,7 +62,7 @@ void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
|
||||
|
||||
if (descriptor_->declaration_scope->num_var_or_const() >
|
||||
kMaxNumFunctionLocals) {
|
||||
parser->ReportMessage("too_many_variables");
|
||||
parser->ReportMessage(MessageTemplate::kTooManyVariables);
|
||||
*ok_ = false;
|
||||
return;
|
||||
}
|
||||
|
@ -17,29 +17,27 @@ void PendingCompilationErrorHandler::ThrowPendingError(Isolate* isolate,
|
||||
if (!has_pending_error_) return;
|
||||
MessageLocation location(script, start_position_, end_position_);
|
||||
Factory* factory = isolate->factory();
|
||||
bool has_arg = arg_ != NULL || char_arg_ != NULL || !handle_arg_.is_null();
|
||||
Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0);
|
||||
Handle<String> argument;
|
||||
if (arg_ != NULL) {
|
||||
Handle<String> arg_string = arg_->string();
|
||||
elements->set(0, *arg_string);
|
||||
argument = arg_->string();
|
||||
} else if (char_arg_ != NULL) {
|
||||
Handle<String> arg_string =
|
||||
argument =
|
||||
factory->NewStringFromUtf8(CStrVector(char_arg_)).ToHandleChecked();
|
||||
elements->set(0, *arg_string);
|
||||
} else if (!handle_arg_.is_null()) {
|
||||
elements->set(0, *handle_arg_);
|
||||
argument = handle_arg_;
|
||||
}
|
||||
isolate->debug()->OnCompileError(script);
|
||||
|
||||
Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
|
||||
Handle<Object> error;
|
||||
|
||||
switch (error_type_) {
|
||||
case kReferenceError:
|
||||
error = factory->NewError("MakeReferenceError", message_, array);
|
||||
error = factory->NewError("MakeReferenceError", message_, argument);
|
||||
break;
|
||||
case kSyntaxError:
|
||||
error = factory->NewError("MakeSyntaxError", message_, array);
|
||||
error = factory->NewError("MakeSyntaxError", message_, argument);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "src/base/macros.h"
|
||||
#include "src/globals.h"
|
||||
#include "src/handles.h"
|
||||
#include "src/messages.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -24,13 +25,14 @@ class PendingCompilationErrorHandler {
|
||||
: has_pending_error_(false),
|
||||
start_position_(-1),
|
||||
end_position_(-1),
|
||||
message_(nullptr),
|
||||
message_(MessageTemplate::kNone),
|
||||
arg_(nullptr),
|
||||
char_arg_(nullptr),
|
||||
error_type_(kSyntaxError) {}
|
||||
|
||||
void ReportMessageAt(int start_position, int end_position,
|
||||
const char* message, const char* arg = nullptr,
|
||||
MessageTemplate::Template message,
|
||||
const char* arg = nullptr,
|
||||
ParseErrorType error_type = kSyntaxError) {
|
||||
if (has_pending_error_) return;
|
||||
has_pending_error_ = true;
|
||||
@ -43,7 +45,8 @@ class PendingCompilationErrorHandler {
|
||||
}
|
||||
|
||||
void ReportMessageAt(int start_position, int end_position,
|
||||
const char* message, const AstRawString* arg,
|
||||
MessageTemplate::Template message,
|
||||
const AstRawString* arg,
|
||||
ParseErrorType error_type = kSyntaxError) {
|
||||
if (has_pending_error_) return;
|
||||
has_pending_error_ = true;
|
||||
@ -56,7 +59,7 @@ class PendingCompilationErrorHandler {
|
||||
}
|
||||
|
||||
void ReportMessageAt(int start_position, int end_position,
|
||||
const char* message, Handle<String> arg,
|
||||
MessageTemplate::Template message, Handle<String> arg,
|
||||
ParseErrorType error_type = kSyntaxError) {
|
||||
if (has_pending_error_) return;
|
||||
has_pending_error_ = true;
|
||||
@ -77,7 +80,7 @@ class PendingCompilationErrorHandler {
|
||||
bool has_pending_error_;
|
||||
int start_position_;
|
||||
int end_position_;
|
||||
const char* message_;
|
||||
MessageTemplate::Template message_;
|
||||
const AstRawString* arg_;
|
||||
const char* char_arg_;
|
||||
Handle<String> handle_arg_;
|
||||
|
@ -28,7 +28,8 @@ struct PreparseDataConstants {
|
||||
static const int kMessageEndPos = 1;
|
||||
static const int kMessageArgCountPos = 2;
|
||||
static const int kParseErrorTypePos = 3;
|
||||
static const int kMessageTextPos = 4;
|
||||
static const int kMessageTemplatePos = 4;
|
||||
static const int kMessageArgPos = 5;
|
||||
|
||||
static const unsigned char kNumberTerminator = 0x80u;
|
||||
};
|
||||
|
@ -29,7 +29,7 @@ CompleteParserRecorder::CompleteParserRecorder() {
|
||||
|
||||
|
||||
void CompleteParserRecorder::LogMessage(int start_pos, int end_pos,
|
||||
const char* message,
|
||||
MessageTemplate::Template message,
|
||||
const char* arg_opt,
|
||||
ParseErrorType error_type) {
|
||||
if (HasError()) return;
|
||||
@ -43,8 +43,9 @@ void CompleteParserRecorder::LogMessage(int start_pos, int end_pos,
|
||||
function_store_.Add((arg_opt == NULL) ? 0 : 1);
|
||||
STATIC_ASSERT(PreparseDataConstants::kParseErrorTypePos == 3);
|
||||
function_store_.Add(error_type);
|
||||
STATIC_ASSERT(PreparseDataConstants::kMessageTextPos == 4);
|
||||
WriteString(CStrVector(message));
|
||||
STATIC_ASSERT(PreparseDataConstants::kMessageTemplatePos == 4);
|
||||
function_store_.Add(static_cast<unsigned>(message));
|
||||
STATIC_ASSERT(PreparseDataConstants::kMessageArgPos == 5);
|
||||
if (arg_opt != NULL) WriteString(CStrVector(arg_opt));
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "src/allocation.h"
|
||||
#include "src/hashmap.h"
|
||||
#include "src/messages.h"
|
||||
#include "src/preparse-data-format.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -58,7 +59,7 @@ class ParserRecorder {
|
||||
// Logs an error message and marks the log as containing an error.
|
||||
// Further logging will be ignored, and ExtractData will return a vector
|
||||
// representing the error only.
|
||||
virtual void LogMessage(int start, int end, const char* message,
|
||||
virtual void LogMessage(int start, int end, MessageTemplate::Template message,
|
||||
const char* argument_opt,
|
||||
ParseErrorType error_type) = 0;
|
||||
|
||||
@ -90,7 +91,7 @@ class SingletonLogger : public ParserRecorder {
|
||||
// Logs an error message and marks the log as containing an error.
|
||||
// Further logging will be ignored, and ExtractData will return a vector
|
||||
// representing the error only.
|
||||
virtual void LogMessage(int start, int end, const char* message,
|
||||
virtual void LogMessage(int start, int end, MessageTemplate::Template message,
|
||||
const char* argument_opt, ParseErrorType error_type) {
|
||||
if (has_error_) return;
|
||||
has_error_ = true;
|
||||
@ -125,7 +126,7 @@ class SingletonLogger : public ParserRecorder {
|
||||
DCHECK(has_error_);
|
||||
return error_type_;
|
||||
}
|
||||
const char* message() {
|
||||
MessageTemplate::Template message() {
|
||||
DCHECK(has_error_);
|
||||
return message_;
|
||||
}
|
||||
@ -144,7 +145,7 @@ class SingletonLogger : public ParserRecorder {
|
||||
LanguageMode language_mode_;
|
||||
bool scope_uses_super_property_;
|
||||
// For error messages.
|
||||
const char* message_;
|
||||
MessageTemplate::Template message_;
|
||||
const char* argument_opt_;
|
||||
ParseErrorType error_type_;
|
||||
};
|
||||
@ -174,7 +175,7 @@ class CompleteParserRecorder : public ParserRecorder {
|
||||
// Logs an error message and marks the log as containing an error.
|
||||
// Further logging will be ignored, and ExtractData will return a vector
|
||||
// representing the error only.
|
||||
virtual void LogMessage(int start, int end, const char* message,
|
||||
virtual void LogMessage(int start, int end, MessageTemplate::Template message,
|
||||
const char* argument_opt, ParseErrorType error_type);
|
||||
ScriptData* GetScriptData();
|
||||
|
||||
@ -189,9 +190,6 @@ class CompleteParserRecorder : public ParserRecorder {
|
||||
private:
|
||||
void WriteString(Vector<const char> str);
|
||||
|
||||
// Write a non-negative number to the symbol store.
|
||||
void WriteNumber(int number);
|
||||
|
||||
Collector<unsigned> function_store_;
|
||||
unsigned preamble_[PreparseDataConstants::kHeaderSize];
|
||||
|
||||
|
@ -21,14 +21,16 @@ namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
void PreParserTraits::ReportMessageAt(Scanner::Location location,
|
||||
const char* message, const char* arg,
|
||||
MessageTemplate::Template message,
|
||||
const char* arg,
|
||||
ParseErrorType error_type) {
|
||||
ReportMessageAt(location.beg_pos, location.end_pos, message, arg, error_type);
|
||||
}
|
||||
|
||||
|
||||
void PreParserTraits::ReportMessageAt(int start_pos, int end_pos,
|
||||
const char* message, const char* arg,
|
||||
MessageTemplate::Template message,
|
||||
const char* arg,
|
||||
ParseErrorType error_type) {
|
||||
pre_parser_->log_->LogMessage(start_pos, end_pos, message, arg, error_type);
|
||||
}
|
||||
@ -132,7 +134,8 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
|
||||
if (is_strong(scope_->language_mode()) && IsSubclassConstructor(kind)) {
|
||||
if (!function_state.super_location().IsValid()) {
|
||||
ReportMessageAt(Scanner::Location(start_position, start_position + 1),
|
||||
"strong_super_call_missing", kReferenceError);
|
||||
MessageTemplate::kStrongSuperCallMissing,
|
||||
kReferenceError);
|
||||
return kPreParseSuccess;
|
||||
}
|
||||
}
|
||||
@ -229,13 +232,13 @@ void PreParser::ParseStatementList(int end_token, bool* ok,
|
||||
Scanner::Location super_loc = function_state_->super_location();
|
||||
if (this_loc.beg_pos != old_this_loc.beg_pos &&
|
||||
this_loc.beg_pos != token_loc.beg_pos) {
|
||||
ReportMessageAt(this_loc, "strong_constructor_this");
|
||||
ReportMessageAt(this_loc, MessageTemplate::kStrongConstructorThis);
|
||||
*ok = false;
|
||||
return;
|
||||
}
|
||||
if (super_loc.beg_pos != old_super_loc.beg_pos &&
|
||||
super_loc.beg_pos != token_loc.beg_pos) {
|
||||
ReportMessageAt(super_loc, "strong_constructor_super");
|
||||
ReportMessageAt(super_loc, MessageTemplate::kStrongConstructorSuper);
|
||||
*ok = false;
|
||||
return;
|
||||
}
|
||||
@ -323,7 +326,7 @@ PreParser::Statement PreParser::ParseSubStatement(bool* ok) {
|
||||
case Token::SEMICOLON:
|
||||
if (is_strong(language_mode())) {
|
||||
PreParserTraits::ReportMessageAt(scanner()->peek_location(),
|
||||
"strong_empty");
|
||||
MessageTemplate::kStrongEmpty);
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
}
|
||||
@ -370,7 +373,7 @@ PreParser::Statement PreParser::ParseSubStatement(bool* ok) {
|
||||
if (is_strict(language_mode())) {
|
||||
PreParserTraits::ReportMessageAt(start_location.beg_pos,
|
||||
end_location.end_pos,
|
||||
"strict_function");
|
||||
MessageTemplate::kStrictFunction);
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
} else {
|
||||
@ -423,7 +426,7 @@ PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
|
||||
PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) {
|
||||
Expect(Token::CLASS, CHECK_OK);
|
||||
if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
|
||||
ReportMessage("sloppy_lexical");
|
||||
ReportMessage(MessageTemplate::kSloppyLexical);
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
}
|
||||
@ -499,7 +502,7 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
|
||||
if (peek() == Token::VAR) {
|
||||
if (is_strong(language_mode())) {
|
||||
Scanner::Location location = scanner()->peek_location();
|
||||
ReportMessageAt(location, "strong_var");
|
||||
ReportMessageAt(location, MessageTemplate::kStrongVar);
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
}
|
||||
@ -617,8 +620,9 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
|
||||
default:
|
||||
if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
|
||||
ReportMessageAt(function_state_->this_location(),
|
||||
is_this ? "strong_constructor_this"
|
||||
: "strong_constructor_super");
|
||||
is_this
|
||||
? MessageTemplate::kStrongConstructorThis
|
||||
: MessageTemplate::kStrongConstructorSuper);
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
}
|
||||
@ -659,7 +663,7 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
|
||||
// Detect attempts at 'let' declarations in sloppy mode.
|
||||
if (peek() == Token::IDENTIFIER && is_sloppy(language_mode()) &&
|
||||
expr.IsIdentifier() && expr.AsIdentifier().IsLet()) {
|
||||
ReportMessage("sloppy_lexical", NULL);
|
||||
ReportMessage(MessageTemplate::kSloppyLexical, NULL);
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
}
|
||||
@ -749,7 +753,7 @@ PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
|
||||
i::IsConstructor(function_state_->kind())) {
|
||||
int pos = peek_position();
|
||||
ReportMessageAt(Scanner::Location(pos, pos + 1),
|
||||
"strong_constructor_return_value");
|
||||
MessageTemplate::kStrongConstructorReturnValue);
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
}
|
||||
@ -765,7 +769,7 @@ PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
|
||||
// 'with' '(' Expression ')' Statement
|
||||
Expect(Token::WITH, CHECK_OK);
|
||||
if (is_strict(language_mode())) {
|
||||
ReportMessageAt(scanner()->location(), "strict_mode_with");
|
||||
ReportMessageAt(scanner()->location(), MessageTemplate::kStrictWith);
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
}
|
||||
@ -809,7 +813,8 @@ PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
|
||||
}
|
||||
if (is_strong(language_mode()) && !statement.IsJumpStatement() &&
|
||||
token != Token::RBRACE) {
|
||||
ReportMessageAt(scanner()->location(), "strong_switch_fallthrough");
|
||||
ReportMessageAt(scanner()->location(),
|
||||
MessageTemplate::kStrongSwitchFallthrough);
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
}
|
||||
@ -872,17 +877,20 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
|
||||
const char* loop_type =
|
||||
mode == ForEachStatement::ITERATE ? "for-of" : "for-in";
|
||||
PreParserTraits::ReportMessageAt(
|
||||
bindings_loc, "for_inof_loop_multi_bindings", loop_type);
|
||||
bindings_loc, MessageTemplate::kForInOfLoopMultiBindings,
|
||||
loop_type);
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
}
|
||||
if (first_initializer_loc.IsValid() &&
|
||||
(is_strict(language_mode()) || mode == ForEachStatement::ITERATE)) {
|
||||
if (mode == ForEachStatement::ITERATE) {
|
||||
ReportMessageAt(first_initializer_loc, "for_of_loop_initializer");
|
||||
ReportMessageAt(first_initializer_loc,
|
||||
MessageTemplate::kForOfLoopInitializer);
|
||||
} else {
|
||||
// TODO(caitp): This should be an error in sloppy mode, too.
|
||||
ReportMessageAt(first_initializer_loc, "for_in_loop_initializer");
|
||||
ReportMessageAt(first_initializer_loc,
|
||||
MessageTemplate::kForInLoopInitializer);
|
||||
}
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
@ -910,7 +918,7 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
|
||||
// Detect attempts at 'let' declarations in sloppy mode.
|
||||
if (peek() == Token::IDENTIFIER && is_sloppy(language_mode()) &&
|
||||
is_let_identifier_expression) {
|
||||
ReportMessage("sloppy_lexical", NULL);
|
||||
ReportMessage(MessageTemplate::kSloppyLexical, NULL);
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
}
|
||||
@ -937,7 +945,7 @@ PreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
|
||||
|
||||
Expect(Token::THROW, CHECK_OK);
|
||||
if (scanner()->HasAnyLineTerminatorBeforeNext()) {
|
||||
ReportMessageAt(scanner()->location(), "newline_after_throw");
|
||||
ReportMessageAt(scanner()->location(), MessageTemplate::kNewlineAfterThrow);
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
}
|
||||
@ -965,7 +973,7 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
|
||||
|
||||
Token::Value tok = peek();
|
||||
if (tok != Token::CATCH && tok != Token::FINALLY) {
|
||||
ReportMessageAt(scanner()->location(), "no_catch_or_finally");
|
||||
ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally);
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
}
|
||||
@ -1073,7 +1081,8 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
|
||||
|
||||
if (is_strong(language_mode()) && IsSubclassConstructor(kind)) {
|
||||
if (!function_state.super_location().IsValid()) {
|
||||
ReportMessageAt(function_name_location, "strong_super_call_missing",
|
||||
ReportMessageAt(function_name_location,
|
||||
MessageTemplate::kStrongSuperCallMissing,
|
||||
kReferenceError);
|
||||
*ok = false;
|
||||
return Expression::Default();
|
||||
@ -1106,18 +1115,19 @@ PreParserExpression PreParser::ParseClassLiteral(
|
||||
bool name_is_strict_reserved, int pos, bool* ok) {
|
||||
// All parts of a ClassDeclaration and ClassExpression are strict code.
|
||||
if (name_is_strict_reserved) {
|
||||
ReportMessageAt(class_name_location, "unexpected_strict_reserved");
|
||||
ReportMessageAt(class_name_location,
|
||||
MessageTemplate::kUnexpectedStrictReserved);
|
||||
*ok = false;
|
||||
return EmptyExpression();
|
||||
}
|
||||
if (IsEvalOrArguments(name)) {
|
||||
ReportMessageAt(class_name_location, "strict_eval_arguments");
|
||||
ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments);
|
||||
*ok = false;
|
||||
return EmptyExpression();
|
||||
}
|
||||
LanguageMode class_language_mode = language_mode();
|
||||
if (is_strong(class_language_mode) && IsUndefined(name)) {
|
||||
ReportMessageAt(class_name_location, "strong_undefined");
|
||||
ReportMessageAt(class_name_location, MessageTemplate::kStrongUndefined);
|
||||
*ok = false;
|
||||
return EmptyExpression();
|
||||
}
|
||||
|
248
src/preparser.h
248
src/preparser.h
@ -10,6 +10,7 @@
|
||||
#include "src/bailout-reason.h"
|
||||
#include "src/func-name-inferrer.h"
|
||||
#include "src/hashmap.h"
|
||||
#include "src/messages.h"
|
||||
#include "src/scanner.h"
|
||||
#include "src/scopes.h"
|
||||
#include "src/token.h"
|
||||
@ -445,7 +446,7 @@ class ParserBase : public Traits {
|
||||
bool accept_OF, ForEachStatement::VisitMode* visit_mode, bool* ok) {
|
||||
if (Check(Token::IN)) {
|
||||
if (is_strong(language_mode())) {
|
||||
ReportMessageAt(scanner()->location(), "strong_for_in");
|
||||
ReportMessageAt(scanner()->location(), MessageTemplate::kStrongForIn);
|
||||
*ok = false;
|
||||
} else {
|
||||
*visit_mode = ForEachStatement::ENUMERATE;
|
||||
@ -460,23 +461,25 @@ class ParserBase : public Traits {
|
||||
|
||||
// Checks whether an octal literal was last seen between beg_pos and end_pos.
|
||||
// If so, reports an error. Only called for strict mode and template strings.
|
||||
void CheckOctalLiteral(int beg_pos, int end_pos, const char* error,
|
||||
bool* ok) {
|
||||
void CheckOctalLiteral(int beg_pos, int end_pos,
|
||||
MessageTemplate::Template message, bool* ok) {
|
||||
Scanner::Location octal = scanner()->octal_position();
|
||||
if (octal.IsValid() && beg_pos <= octal.beg_pos &&
|
||||
octal.end_pos <= end_pos) {
|
||||
ReportMessageAt(octal, error);
|
||||
ReportMessageAt(octal, message);
|
||||
scanner()->clear_octal_position();
|
||||
*ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
|
||||
CheckOctalLiteral(beg_pos, end_pos, "strict_octal_literal", ok);
|
||||
CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral,
|
||||
ok);
|
||||
}
|
||||
|
||||
inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) {
|
||||
CheckOctalLiteral(beg_pos, end_pos, "template_octal_literal", ok);
|
||||
CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral,
|
||||
ok);
|
||||
}
|
||||
|
||||
// Checking the name of a function literal. This has to be done after parsing
|
||||
@ -492,17 +495,20 @@ class ParserBase : public Traits {
|
||||
if (is_sloppy(language_mode)) return;
|
||||
|
||||
if (this->IsEvalOrArguments(function_name)) {
|
||||
Traits::ReportMessageAt(function_name_loc, "strict_eval_arguments");
|
||||
Traits::ReportMessageAt(function_name_loc,
|
||||
MessageTemplate::kStrictEvalArguments);
|
||||
*ok = false;
|
||||
return;
|
||||
}
|
||||
if (function_name_is_strict_reserved) {
|
||||
Traits::ReportMessageAt(function_name_loc, "unexpected_strict_reserved");
|
||||
Traits::ReportMessageAt(function_name_loc,
|
||||
MessageTemplate::kUnexpectedStrictReserved);
|
||||
*ok = false;
|
||||
return;
|
||||
}
|
||||
if (is_strong(language_mode) && this->IsUndefined(function_name)) {
|
||||
Traits::ReportMessageAt(function_name_loc, "strong_undefined");
|
||||
Traits::ReportMessageAt(function_name_loc,
|
||||
MessageTemplate::kStrongUndefined);
|
||||
*ok = false;
|
||||
return;
|
||||
}
|
||||
@ -523,13 +529,14 @@ class ParserBase : public Traits {
|
||||
bool is_generator() const { return function_state_->is_generator(); }
|
||||
|
||||
// Report syntax errors.
|
||||
void ReportMessage(const char* message, const char* arg = NULL,
|
||||
void ReportMessage(MessageTemplate::Template message, const char* arg = NULL,
|
||||
ParseErrorType error_type = kSyntaxError) {
|
||||
Scanner::Location source_location = scanner()->location();
|
||||
Traits::ReportMessageAt(source_location, message, arg, error_type);
|
||||
}
|
||||
|
||||
void ReportMessageAt(Scanner::Location location, const char* message,
|
||||
void ReportMessageAt(Scanner::Location location,
|
||||
MessageTemplate::Template message,
|
||||
ParseErrorType error_type = kSyntaxError) {
|
||||
Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0),
|
||||
error_type);
|
||||
@ -543,11 +550,11 @@ class ParserBase : public Traits {
|
||||
struct Error {
|
||||
Error()
|
||||
: location(Scanner::Location::invalid()),
|
||||
message(nullptr),
|
||||
message(MessageTemplate::kNone),
|
||||
arg(nullptr) {}
|
||||
|
||||
Scanner::Location location;
|
||||
const char* message;
|
||||
MessageTemplate::Template message;
|
||||
const char* arg;
|
||||
|
||||
bool HasError() const { return location.IsValid(); }
|
||||
@ -612,7 +619,8 @@ class ParserBase : public Traits {
|
||||
}
|
||||
|
||||
void RecordExpressionError(const Scanner::Location& loc,
|
||||
const char* message, const char* arg = nullptr) {
|
||||
MessageTemplate::Template message,
|
||||
const char* arg = nullptr) {
|
||||
if (!is_valid_expression()) return;
|
||||
expression_error_.location = loc;
|
||||
expression_error_.message = message;
|
||||
@ -620,7 +628,7 @@ class ParserBase : public Traits {
|
||||
}
|
||||
|
||||
void RecordBindingPatternError(const Scanner::Location& loc,
|
||||
const char* message,
|
||||
MessageTemplate::Template message,
|
||||
const char* arg = nullptr) {
|
||||
if (!is_valid_binding_pattern()) return;
|
||||
binding_pattern_error_.location = loc;
|
||||
@ -629,7 +637,7 @@ class ParserBase : public Traits {
|
||||
}
|
||||
|
||||
void RecordAssignmentPatternError(const Scanner::Location& loc,
|
||||
const char* message,
|
||||
MessageTemplate::Template message,
|
||||
const char* arg = nullptr) {
|
||||
if (!is_valid_assignment_pattern()) return;
|
||||
assignment_pattern_error_.location = loc;
|
||||
@ -638,7 +646,7 @@ class ParserBase : public Traits {
|
||||
}
|
||||
|
||||
void RecordArrowFormalParametersError(const Scanner::Location& loc,
|
||||
const char* message,
|
||||
MessageTemplate::Template message,
|
||||
const char* arg = nullptr) {
|
||||
if (!is_valid_arrow_formal_parameters()) return;
|
||||
arrow_formal_parameters_error_.location = loc;
|
||||
@ -649,7 +657,8 @@ class ParserBase : public Traits {
|
||||
void RecordDuplicateFormalParameterError(const Scanner::Location& loc) {
|
||||
if (!is_valid_formal_parameter_list_without_duplicates()) return;
|
||||
duplicate_formal_parameter_error_.location = loc;
|
||||
duplicate_formal_parameter_error_.message = "strict_param_dupe";
|
||||
duplicate_formal_parameter_error_.message =
|
||||
MessageTemplate::kStrictParamDupe;
|
||||
duplicate_formal_parameter_error_.arg = nullptr;
|
||||
}
|
||||
|
||||
@ -657,7 +666,7 @@ class ParserBase : public Traits {
|
||||
// is not the same as StrictFormalParameterList, which simply forbids
|
||||
// duplicate bindings.
|
||||
void RecordStrictModeFormalParameterError(const Scanner::Location& loc,
|
||||
const char* message,
|
||||
MessageTemplate::Template message,
|
||||
const char* arg = nullptr) {
|
||||
if (!is_valid_strict_mode_formal_parameters()) return;
|
||||
strict_mode_formal_parameter_error_.location = loc;
|
||||
@ -666,7 +675,7 @@ class ParserBase : public Traits {
|
||||
}
|
||||
|
||||
void RecordStrongModeFormalParameterError(const Scanner::Location& loc,
|
||||
const char* message,
|
||||
MessageTemplate::Template message,
|
||||
const char* arg = nullptr) {
|
||||
if (!is_valid_strong_mode_formal_parameters()) return;
|
||||
strong_mode_formal_parameter_error_.location = loc;
|
||||
@ -783,7 +792,8 @@ class ParserBase : public Traits {
|
||||
if (classifier->is_valid_binding_pattern()) {
|
||||
// A simple arrow formal parameter: IDENTIFIER => BODY.
|
||||
if (!this->IsIdentifier(expr)) {
|
||||
Traits::ReportMessageAt(scanner()->location(), "unexpected_token",
|
||||
Traits::ReportMessageAt(scanner()->location(),
|
||||
MessageTemplate::kUnexpectedToken,
|
||||
Token::String(scanner()->current_token()));
|
||||
*ok = false;
|
||||
}
|
||||
@ -794,13 +804,15 @@ class ParserBase : public Traits {
|
||||
}
|
||||
|
||||
void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) {
|
||||
classifier->RecordBindingPatternError(
|
||||
scanner()->peek_location(), "unexpected_token", Token::String(peek()));
|
||||
classifier->RecordBindingPatternError(scanner()->peek_location(),
|
||||
MessageTemplate::kUnexpectedToken,
|
||||
Token::String(peek()));
|
||||
}
|
||||
|
||||
void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) {
|
||||
classifier->RecordArrowFormalParametersError(
|
||||
scanner()->peek_location(), "unexpected_token", Token::String(peek()));
|
||||
scanner()->peek_location(), MessageTemplate::kUnexpectedToken,
|
||||
Token::String(peek()));
|
||||
}
|
||||
|
||||
// Recursive descent functions:
|
||||
@ -887,8 +899,8 @@ class ParserBase : public Traits {
|
||||
// left-hand side of assignments). Although ruled out by ECMA as early errors,
|
||||
// we allow calls for web compatibility and rewrite them to a runtime throw.
|
||||
ExpressionT CheckAndRewriteReferenceExpression(
|
||||
ExpressionT expression,
|
||||
Scanner::Location location, const char* message, bool* ok);
|
||||
ExpressionT expression, Scanner::Location location,
|
||||
MessageTemplate::Template message, bool* ok);
|
||||
|
||||
// Used to validate property names in object literals and class literals
|
||||
enum PropertyKind {
|
||||
@ -1603,23 +1615,26 @@ class PreParserTraits {
|
||||
return PreParserExpression::Default();
|
||||
}
|
||||
|
||||
PreParserExpression NewThrowReferenceError(const char* type, int pos) {
|
||||
PreParserExpression NewThrowReferenceError(MessageTemplate::Template message,
|
||||
int pos) {
|
||||
return PreParserExpression::Default();
|
||||
}
|
||||
PreParserExpression NewThrowSyntaxError(
|
||||
const char* type, Handle<Object> arg, int pos) {
|
||||
PreParserExpression NewThrowSyntaxError(MessageTemplate::Template message,
|
||||
Handle<Object> arg, int pos) {
|
||||
return PreParserExpression::Default();
|
||||
}
|
||||
PreParserExpression NewThrowTypeError(
|
||||
const char* type, Handle<Object> arg, int pos) {
|
||||
PreParserExpression NewThrowTypeError(MessageTemplate::Template message,
|
||||
Handle<Object> arg, int pos) {
|
||||
return PreParserExpression::Default();
|
||||
}
|
||||
|
||||
// Reporting errors.
|
||||
void ReportMessageAt(Scanner::Location location, const char* message,
|
||||
void ReportMessageAt(Scanner::Location location,
|
||||
MessageTemplate::Template message,
|
||||
const char* arg = NULL,
|
||||
ParseErrorType error_type = kSyntaxError);
|
||||
void ReportMessageAt(int start_pos, int end_pos, const char* message,
|
||||
void ReportMessageAt(int start_pos, int end_pos,
|
||||
MessageTemplate::Template message,
|
||||
const char* arg = NULL,
|
||||
ParseErrorType error_type = kSyntaxError);
|
||||
|
||||
@ -2023,32 +2038,37 @@ void ParserBase<Traits>::ReportUnexpectedTokenAt(
|
||||
// Four of the tokens are treated specially
|
||||
switch (token) {
|
||||
case Token::EOS:
|
||||
return ReportMessageAt(source_location, "unexpected_eos");
|
||||
return ReportMessageAt(source_location, MessageTemplate::kUnexpectedEOS);
|
||||
case Token::SMI:
|
||||
case Token::NUMBER:
|
||||
return ReportMessageAt(source_location, "unexpected_token_number");
|
||||
return ReportMessageAt(source_location,
|
||||
MessageTemplate::kUnexpectedTokenNumber);
|
||||
case Token::STRING:
|
||||
return ReportMessageAt(source_location, "unexpected_token_string");
|
||||
return ReportMessageAt(source_location,
|
||||
MessageTemplate::kUnexpectedTokenString);
|
||||
case Token::IDENTIFIER:
|
||||
return ReportMessageAt(source_location, "unexpected_token_identifier");
|
||||
return ReportMessageAt(source_location,
|
||||
MessageTemplate::kUnexpectedTokenIdentifier);
|
||||
case Token::FUTURE_RESERVED_WORD:
|
||||
return ReportMessageAt(source_location, "unexpected_reserved");
|
||||
return ReportMessageAt(source_location,
|
||||
MessageTemplate::kUnexpectedReserved);
|
||||
case Token::LET:
|
||||
case Token::STATIC:
|
||||
case Token::YIELD:
|
||||
case Token::FUTURE_STRICT_RESERVED_WORD:
|
||||
return ReportMessageAt(source_location,
|
||||
is_strict(language_mode())
|
||||
? "unexpected_strict_reserved"
|
||||
: "unexpected_token_identifier");
|
||||
? MessageTemplate::kUnexpectedStrictReserved
|
||||
: MessageTemplate::kUnexpectedTokenIdentifier);
|
||||
case Token::TEMPLATE_SPAN:
|
||||
case Token::TEMPLATE_TAIL:
|
||||
return Traits::ReportMessageAt(source_location,
|
||||
"unexpected_template_string");
|
||||
return Traits::ReportMessageAt(
|
||||
source_location, MessageTemplate::kUnexpectedTemplateString);
|
||||
default:
|
||||
const char* name = Token::String(token);
|
||||
DCHECK(name != NULL);
|
||||
Traits::ReportMessageAt(source_location, "unexpected_token", name);
|
||||
Traits::ReportMessageAt(source_location,
|
||||
MessageTemplate::kUnexpectedToken, name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2088,35 +2108,35 @@ ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
|
||||
// must detect because we know we're in strict mode, we also record any
|
||||
// error that we might make in the future once we know the language mode.
|
||||
if (this->IsEval(name)) {
|
||||
classifier->RecordStrictModeFormalParameterError(scanner()->location(),
|
||||
"strict_eval_arguments");
|
||||
classifier->RecordStrictModeFormalParameterError(
|
||||
scanner()->location(), MessageTemplate::kStrictEvalArguments);
|
||||
if (is_strict(language_mode())) {
|
||||
classifier->RecordBindingPatternError(scanner()->location(),
|
||||
"strict_eval_arguments");
|
||||
classifier->RecordBindingPatternError(
|
||||
scanner()->location(), MessageTemplate::kStrictEvalArguments);
|
||||
}
|
||||
}
|
||||
if (this->IsArguments(name)) {
|
||||
scope_->RecordArgumentsUsage();
|
||||
classifier->RecordStrictModeFormalParameterError(scanner()->location(),
|
||||
"strict_eval_arguments");
|
||||
classifier->RecordStrictModeFormalParameterError(
|
||||
scanner()->location(), MessageTemplate::kStrictEvalArguments);
|
||||
if (is_strict(language_mode())) {
|
||||
classifier->RecordBindingPatternError(scanner()->location(),
|
||||
"strict_eval_arguments");
|
||||
classifier->RecordBindingPatternError(
|
||||
scanner()->location(), MessageTemplate::kStrictEvalArguments);
|
||||
}
|
||||
if (is_strong(language_mode())) {
|
||||
classifier->RecordExpressionError(scanner()->location(),
|
||||
"strong_arguments");
|
||||
MessageTemplate::kStrongArguments);
|
||||
}
|
||||
}
|
||||
if (this->IsUndefined(name)) {
|
||||
classifier->RecordStrongModeFormalParameterError(scanner()->location(),
|
||||
"strong_undefined");
|
||||
classifier->RecordStrongModeFormalParameterError(
|
||||
scanner()->location(), MessageTemplate::kStrongUndefined);
|
||||
if (is_strong(language_mode())) {
|
||||
// TODO(dslomov): allow 'undefined' in nested patterns.
|
||||
classifier->RecordBindingPatternError(scanner()->location(),
|
||||
"strong_undefined");
|
||||
classifier->RecordAssignmentPatternError(scanner()->location(),
|
||||
"strong_undefined");
|
||||
classifier->RecordBindingPatternError(
|
||||
scanner()->location(), MessageTemplate::kStrongUndefined);
|
||||
classifier->RecordAssignmentPatternError(
|
||||
scanner()->location(), MessageTemplate::kStrongUndefined);
|
||||
}
|
||||
}
|
||||
return name;
|
||||
@ -2125,7 +2145,7 @@ ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
|
||||
next == Token::LET || next == Token::STATIC ||
|
||||
(next == Token::YIELD && !is_generator()))) {
|
||||
classifier->RecordStrictModeFormalParameterError(
|
||||
scanner()->location(), "unexpected_strict_reserved");
|
||||
scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
|
||||
return this->GetSymbol(scanner());
|
||||
} else {
|
||||
this->ReportUnexpectedToken(next);
|
||||
@ -2194,7 +2214,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
|
||||
int pos = peek_position();
|
||||
if (!scanner()->ScanRegExpPattern(seen_equal)) {
|
||||
Next();
|
||||
ReportMessage("unterminated_regexp");
|
||||
ReportMessage(MessageTemplate::kUnterminatedRegExp);
|
||||
*ok = false;
|
||||
return Traits::EmptyExpression();
|
||||
}
|
||||
@ -2204,7 +2224,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
|
||||
IdentifierT js_pattern = this->GetNextSymbol(scanner());
|
||||
if (!scanner()->ScanRegExpFlags()) {
|
||||
Next();
|
||||
ReportMessage("malformed_regexp_flags");
|
||||
ReportMessage(MessageTemplate::kMalformedRegExpFlags);
|
||||
*ok = false;
|
||||
return Traits::EmptyExpression();
|
||||
}
|
||||
@ -2259,7 +2279,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
|
||||
// Constructors' usages of 'this' in strong mode are parsed separately.
|
||||
// TODO(rossberg): this does not work with arrow functions yet.
|
||||
if (i::IsConstructor(function_state_->kind())) {
|
||||
ReportMessage("strong_constructor_this");
|
||||
ReportMessage(MessageTemplate::kStrongConstructorThis);
|
||||
*ok = false;
|
||||
break;
|
||||
}
|
||||
@ -2279,8 +2299,8 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
|
||||
break;
|
||||
case Token::SMI:
|
||||
case Token::NUMBER:
|
||||
classifier->RecordBindingPatternError(scanner()->location(),
|
||||
"unexpected_token_number");
|
||||
classifier->RecordBindingPatternError(
|
||||
scanner()->location(), MessageTemplate::kUnexpectedTokenNumber);
|
||||
Next();
|
||||
result =
|
||||
this->ExpressionFromLiteral(token, beg_pos, scanner(), factory());
|
||||
@ -2299,8 +2319,8 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
|
||||
}
|
||||
|
||||
case Token::STRING: {
|
||||
classifier->RecordBindingPatternError(scanner()->location(),
|
||||
"unexpected_token_string");
|
||||
classifier->RecordBindingPatternError(
|
||||
scanner()->location(), MessageTemplate::kUnexpectedTokenString);
|
||||
Consume(Token::STRING);
|
||||
result = this->ExpressionFromString(beg_pos, scanner(), factory());
|
||||
break;
|
||||
@ -2342,7 +2362,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
|
||||
if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) {
|
||||
// As a primary expression, the only thing that can follow "()" is "=>".
|
||||
classifier->RecordBindingPatternError(scanner()->location(),
|
||||
"unexpected_token",
|
||||
MessageTemplate::kUnexpectedToken,
|
||||
Token::String(Token::RPAREN));
|
||||
Scope* scope = this->NewScope(scope_, ARROW_SCOPE);
|
||||
scope->set_start_position(beg_pos);
|
||||
@ -2363,7 +2383,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
|
||||
BindingPatternUnexpectedToken(classifier);
|
||||
Consume(Token::CLASS);
|
||||
if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
|
||||
ReportMessage("sloppy_lexical");
|
||||
ReportMessage(MessageTemplate::kSloppyLexical);
|
||||
*ok = false;
|
||||
break;
|
||||
}
|
||||
@ -2457,7 +2477,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
|
||||
ExpressionT elem = this->EmptyExpression();
|
||||
if (peek() == Token::COMMA) {
|
||||
if (is_strong(language_mode())) {
|
||||
ReportMessageAt(scanner()->peek_location(), "strong_ellision");
|
||||
ReportMessageAt(scanner()->peek_location(),
|
||||
MessageTemplate::kStrongEllision);
|
||||
*ok = false;
|
||||
return this->EmptyExpression();
|
||||
}
|
||||
@ -2775,7 +2796,7 @@ typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
|
||||
}
|
||||
|
||||
if (result->length() > Code::kMaxArguments) {
|
||||
ReportMessage("too_many_arguments");
|
||||
ReportMessage(MessageTemplate::kTooManyArguments);
|
||||
*ok = false;
|
||||
return this->NullExpressionList();
|
||||
}
|
||||
@ -2786,7 +2807,7 @@ typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
|
||||
}
|
||||
Scanner::Location location = scanner_->location();
|
||||
if (Token::RPAREN != Next()) {
|
||||
ReportMessageAt(location, "unterminated_arg_list");
|
||||
ReportMessageAt(location, MessageTemplate::kUnterminatedArgList);
|
||||
*ok = false;
|
||||
return this->NullExpressionList();
|
||||
}
|
||||
@ -2869,7 +2890,8 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
|
||||
}
|
||||
|
||||
expression = this->CheckAndRewriteReferenceExpression(
|
||||
expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK);
|
||||
expression, lhs_location, MessageTemplate::kInvalidLhsInAssignment,
|
||||
CHECK_OK);
|
||||
expression = this->MarkExpressionAsAssigned(expression);
|
||||
|
||||
Token::Value op = Next(); // Get assignment operator.
|
||||
@ -3017,7 +3039,7 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
|
||||
default: break;
|
||||
}
|
||||
if (cmp == Token::EQ && is_strong(language_mode())) {
|
||||
ReportMessageAt(op_location, "strong_equal");
|
||||
ReportMessageAt(op_location, MessageTemplate::kStrongEqual);
|
||||
*ok = false;
|
||||
return this->EmptyExpression();
|
||||
}
|
||||
@ -3063,12 +3085,12 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
|
||||
|
||||
if (op == Token::DELETE && is_strict(language_mode())) {
|
||||
if (is_strong(language_mode())) {
|
||||
ReportMessage("strong_delete");
|
||||
ReportMessage(MessageTemplate::kStrongDelete);
|
||||
*ok = false;
|
||||
return this->EmptyExpression();
|
||||
} else if (this->IsIdentifier(expression)) {
|
||||
// "delete identifier" is a syntax error in strict mode.
|
||||
ReportMessage("strict_delete");
|
||||
ReportMessage(MessageTemplate::kStrictDelete);
|
||||
*ok = false;
|
||||
return this->EmptyExpression();
|
||||
}
|
||||
@ -3082,7 +3104,8 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
|
||||
Scanner::Location lhs_location = scanner()->peek_location();
|
||||
ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK);
|
||||
expression = this->CheckAndRewriteReferenceExpression(
|
||||
expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK);
|
||||
expression, lhs_location, MessageTemplate::kInvalidLhsInPrefixOp,
|
||||
CHECK_OK);
|
||||
this->MarkExpressionAsAssigned(expression);
|
||||
|
||||
return factory()->NewCountOperation(op,
|
||||
@ -3111,7 +3134,8 @@ ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier,
|
||||
BindingPatternUnexpectedToken(classifier);
|
||||
|
||||
expression = this->CheckAndRewriteReferenceExpression(
|
||||
expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK);
|
||||
expression, lhs_location, MessageTemplate::kInvalidLhsInPostfixOp,
|
||||
CHECK_OK);
|
||||
expression = this->MarkExpressionAsAssigned(expression);
|
||||
|
||||
Token::Value next = Next();
|
||||
@ -3152,7 +3176,7 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
|
||||
|
||||
if (is_strong(language_mode()) && this->IsIdentifier(result) &&
|
||||
this->IsEval(this->AsIdentifier(result))) {
|
||||
ReportMessage("strong_direct_eval");
|
||||
ReportMessage(MessageTemplate::kStrongDirectEval);
|
||||
*ok = false;
|
||||
return this->EmptyExpression();
|
||||
}
|
||||
@ -3364,14 +3388,14 @@ ParserBase<Traits>::ParseStrongInitializationExpression(
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ReportMessage("strong_constructor_this");
|
||||
ReportMessage(MessageTemplate::kStrongConstructorThis);
|
||||
*ok = false;
|
||||
return this->EmptyExpression();
|
||||
}
|
||||
|
||||
if (peek() != Token::ASSIGN) {
|
||||
ReportMessageAt(function_state_->this_location(),
|
||||
"strong_constructor_this");
|
||||
MessageTemplate::kStrongConstructorThis);
|
||||
*ok = false;
|
||||
return this->EmptyExpression();
|
||||
}
|
||||
@ -3396,7 +3420,7 @@ ParserBase<Traits>::ParseStrongInitializationExpression(
|
||||
|
||||
if (function_state_->return_location().IsValid()) {
|
||||
ReportMessageAt(function_state_->return_location(),
|
||||
"strong_constructor_return_misplaced");
|
||||
MessageTemplate::kStrongConstructorReturnMisplaced);
|
||||
*ok = false;
|
||||
return this->EmptyExpression();
|
||||
}
|
||||
@ -3419,7 +3443,7 @@ ParserBase<Traits>::ParseStrongSuperCallExpression(
|
||||
ExpressionT expr = this->SuperReference(scope_, factory());
|
||||
|
||||
if (peek() != Token::LPAREN) {
|
||||
ReportMessage("strong_constructor_super");
|
||||
ReportMessage(MessageTemplate::kStrongConstructorSuper);
|
||||
*ok = false;
|
||||
return this->EmptyExpression();
|
||||
}
|
||||
@ -3430,20 +3454,22 @@ ParserBase<Traits>::ParseStrongSuperCallExpression(
|
||||
|
||||
// TODO(rossberg): This doesn't work with arrow functions yet.
|
||||
if (!IsSubclassConstructor(function_state_->kind())) {
|
||||
ReportMessage("unexpected_super");
|
||||
ReportMessage(MessageTemplate::kUnexpectedSuper);
|
||||
*ok = false;
|
||||
return this->EmptyExpression();
|
||||
} else if (function_state_->super_location().IsValid()) {
|
||||
ReportMessageAt(scanner()->location(), "strong_super_call_duplicate");
|
||||
ReportMessageAt(scanner()->location(),
|
||||
MessageTemplate::kStrongSuperCallDuplicate);
|
||||
*ok = false;
|
||||
return this->EmptyExpression();
|
||||
} else if (function_state_->this_location().IsValid()) {
|
||||
ReportMessageAt(scanner()->location(), "strong_super_call_misplaced");
|
||||
ReportMessageAt(scanner()->location(),
|
||||
MessageTemplate::kStrongSuperCallMisplaced);
|
||||
*ok = false;
|
||||
return this->EmptyExpression();
|
||||
} else if (function_state_->return_location().IsValid()) {
|
||||
ReportMessageAt(function_state_->return_location(),
|
||||
"strong_constructor_return_misplaced");
|
||||
MessageTemplate::kStrongConstructorReturnMisplaced);
|
||||
*ok = false;
|
||||
return this->EmptyExpression();
|
||||
}
|
||||
@ -3484,7 +3510,8 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new,
|
||||
if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) {
|
||||
if (is_strong(language_mode())) {
|
||||
// Super calls in strong mode are parsed separately.
|
||||
ReportMessageAt(scanner()->location(), "strong_constructor_super");
|
||||
ReportMessageAt(scanner()->location(),
|
||||
MessageTemplate::kStrongConstructorSuper);
|
||||
*ok = false;
|
||||
return this->EmptyExpression();
|
||||
}
|
||||
@ -3493,7 +3520,7 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new,
|
||||
}
|
||||
}
|
||||
|
||||
ReportMessageAt(scanner()->location(), "unexpected_super");
|
||||
ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper);
|
||||
*ok = false;
|
||||
return this->EmptyExpression();
|
||||
}
|
||||
@ -3600,7 +3627,7 @@ int ParserBase<Traits>::ParseFormalParameterList(
|
||||
if (peek() != Token::RPAREN) {
|
||||
do {
|
||||
if (++parameter_count > Code::kMaxArguments) {
|
||||
ReportMessage("too_many_parameters");
|
||||
ReportMessage(MessageTemplate::kTooManyParameters);
|
||||
*ok = false;
|
||||
return -1;
|
||||
}
|
||||
@ -3610,7 +3637,8 @@ int ParserBase<Traits>::ParseFormalParameterList(
|
||||
} while (!*is_rest && Check(Token::COMMA));
|
||||
|
||||
if (*is_rest && peek() == Token::COMMA) {
|
||||
ReportMessageAt(scanner()->peek_location(), "param_after_rest");
|
||||
ReportMessageAt(scanner()->peek_location(),
|
||||
MessageTemplate::kParamAfterRest);
|
||||
*ok = false;
|
||||
return -1;
|
||||
}
|
||||
@ -3628,14 +3656,14 @@ void ParserBase<Traits>::CheckArityRestrictions(
|
||||
case FunctionLiteral::GETTER_ARITY:
|
||||
if (param_count != 0) {
|
||||
ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
|
||||
"bad_getter_arity");
|
||||
MessageTemplate::kBadGetterArity);
|
||||
*ok = false;
|
||||
}
|
||||
break;
|
||||
case FunctionLiteral::SETTER_ARITY:
|
||||
if (param_count != 1) {
|
||||
ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
|
||||
"bad_setter_arity");
|
||||
MessageTemplate::kBadSetterArity);
|
||||
*ok = false;
|
||||
}
|
||||
break;
|
||||
@ -3786,13 +3814,13 @@ ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
|
||||
next = peek();
|
||||
if (next == Token::EOS) {
|
||||
ReportMessageAt(Scanner::Location(start, peek_position()),
|
||||
"unterminated_template");
|
||||
MessageTemplate::kUnterminatedTemplate);
|
||||
*ok = false;
|
||||
return Traits::EmptyExpression();
|
||||
} else if (next == Token::ILLEGAL) {
|
||||
Traits::ReportMessageAt(
|
||||
Scanner::Location(position() + 1, peek_position()),
|
||||
"unexpected_token", "ILLEGAL", kSyntaxError);
|
||||
MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
|
||||
*ok = false;
|
||||
return Traits::EmptyExpression();
|
||||
}
|
||||
@ -3803,7 +3831,7 @@ ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
|
||||
|
||||
if (peek() != Token::RBRACE) {
|
||||
ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
|
||||
"unterminated_template_expr");
|
||||
MessageTemplate::kUnterminatedTemplateExpr);
|
||||
*ok = false;
|
||||
return Traits::EmptyExpression();
|
||||
}
|
||||
@ -3815,13 +3843,14 @@ ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
|
||||
pos = position();
|
||||
|
||||
if (next == Token::EOS) {
|
||||
ReportMessageAt(Scanner::Location(start, pos), "unterminated_template");
|
||||
ReportMessageAt(Scanner::Location(start, pos),
|
||||
MessageTemplate::kUnterminatedTemplate);
|
||||
*ok = false;
|
||||
return Traits::EmptyExpression();
|
||||
} else if (next == Token::ILLEGAL) {
|
||||
Traits::ReportMessageAt(
|
||||
Scanner::Location(position() + 1, peek_position()),
|
||||
"unexpected_token", "ILLEGAL", kSyntaxError);
|
||||
MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
|
||||
*ok = false;
|
||||
return Traits::EmptyExpression();
|
||||
}
|
||||
@ -3837,20 +3866,22 @@ ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
|
||||
|
||||
|
||||
template <typename Traits>
|
||||
typename ParserBase<Traits>::ExpressionT ParserBase<
|
||||
Traits>::CheckAndRewriteReferenceExpression(ExpressionT expression,
|
||||
Scanner::Location location,
|
||||
const char* message, bool* ok) {
|
||||
typename ParserBase<Traits>::ExpressionT
|
||||
ParserBase<Traits>::CheckAndRewriteReferenceExpression(
|
||||
ExpressionT expression, Scanner::Location location,
|
||||
MessageTemplate::Template message, bool* ok) {
|
||||
if (this->IsIdentifier(expression)) {
|
||||
if (is_strict(language_mode()) &&
|
||||
this->IsEvalOrArguments(this->AsIdentifier(expression))) {
|
||||
this->ReportMessageAt(location, "strict_eval_arguments", kSyntaxError);
|
||||
this->ReportMessageAt(location, MessageTemplate::kStrictEvalArguments,
|
||||
kSyntaxError);
|
||||
*ok = false;
|
||||
return this->EmptyExpression();
|
||||
}
|
||||
if (is_strong(language_mode()) &&
|
||||
this->IsUndefined(this->AsIdentifier(expression))) {
|
||||
this->ReportMessageAt(location, "strong_undefined", kSyntaxError);
|
||||
this->ReportMessageAt(location, MessageTemplate::kStrongUndefined,
|
||||
kSyntaxError);
|
||||
*ok = false;
|
||||
return this->EmptyExpression();
|
||||
}
|
||||
@ -3886,7 +3917,7 @@ void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
|
||||
|
||||
if (type == kValueProperty && IsProto()) {
|
||||
if (has_seen_proto_) {
|
||||
this->parser()->ReportMessage("duplicate_proto");
|
||||
this->parser()->ReportMessage(MessageTemplate::kDuplicateProto);
|
||||
*ok = false;
|
||||
return;
|
||||
}
|
||||
@ -3906,20 +3937,21 @@ void ParserBase<Traits>::ClassLiteralChecker::CheckProperty(
|
||||
|
||||
if (is_static) {
|
||||
if (IsPrototype()) {
|
||||
this->parser()->ReportMessage("static_prototype");
|
||||
this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
|
||||
*ok = false;
|
||||
return;
|
||||
}
|
||||
} else if (IsConstructor()) {
|
||||
if (is_generator || type == kAccessorProperty) {
|
||||
const char* msg =
|
||||
is_generator ? "constructor_is_generator" : "constructor_is_accessor";
|
||||
MessageTemplate::Template msg =
|
||||
is_generator ? MessageTemplate::kConstructorIsGenerator
|
||||
: MessageTemplate::kConstructorIsAccessor;
|
||||
this->parser()->ReportMessage(msg);
|
||||
*ok = false;
|
||||
return;
|
||||
}
|
||||
if (has_seen_constructor_) {
|
||||
this->parser()->ReportMessage("duplicate_constructor");
|
||||
this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor);
|
||||
*ok = false;
|
||||
return;
|
||||
}
|
||||
|
@ -795,7 +795,8 @@ void Scope::GetNestedScopeChain(Isolate* isolate,
|
||||
|
||||
|
||||
void Scope::ReportMessage(int start_position, int end_position,
|
||||
const char* message, const AstRawString* arg) {
|
||||
MessageTemplate::Template message,
|
||||
const AstRawString* arg) {
|
||||
// Propagate the error to the topmost scope targeted by this scope analysis
|
||||
// phase.
|
||||
Scope* top = this;
|
||||
@ -1219,7 +1220,8 @@ bool Scope::CheckStrongModeDeclaration(VariableProxy* proxy, Variable* var) {
|
||||
eval_for_use == eval_for_declaration) {
|
||||
DCHECK(proxy->end_position() != RelocInfo::kNoPosition);
|
||||
ReportMessage(proxy->position(), proxy->end_position(),
|
||||
"strong_use_before_declaration", proxy->raw_name());
|
||||
MessageTemplate::kStrongUseBeforeDeclaration,
|
||||
proxy->raw_name());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -503,7 +503,8 @@ class Scope: public ZoneObject {
|
||||
}
|
||||
|
||||
// Error handling.
|
||||
void ReportMessage(int start_position, int end_position, const char* message,
|
||||
void ReportMessage(int start_position, int end_position,
|
||||
MessageTemplate::Template message,
|
||||
const AstRawString* arg);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -1333,40 +1333,24 @@ const char* ReadString(unsigned* start) {
|
||||
|
||||
i::Handle<i::String> FormatMessage(i::Vector<unsigned> data) {
|
||||
i::Isolate* isolate = CcTest::i_isolate();
|
||||
i::Factory* factory = isolate->factory();
|
||||
const char* message =
|
||||
ReadString(&data[i::PreparseDataConstants::kMessageTextPos]);
|
||||
i::Handle<i::String> format = v8::Utils::OpenHandle(
|
||||
*v8::String::NewFromUtf8(CcTest::isolate(), message));
|
||||
int message = data[i::PreparseDataConstants::kMessageTemplatePos];
|
||||
int arg_count = data[i::PreparseDataConstants::kMessageArgCountPos];
|
||||
const char* arg = NULL;
|
||||
i::Handle<i::JSArray> args_array;
|
||||
i::Handle<i::Object> arg_object;
|
||||
if (arg_count == 1) {
|
||||
// Position after text found by skipping past length field and
|
||||
// length field content words.
|
||||
int pos = i::PreparseDataConstants::kMessageTextPos + 1 +
|
||||
data[i::PreparseDataConstants::kMessageTextPos];
|
||||
arg = ReadString(&data[pos]);
|
||||
args_array = factory->NewJSArray(1);
|
||||
i::JSArray::SetElement(args_array, 0, v8::Utils::OpenHandle(*v8_str(arg)),
|
||||
NONE, i::SLOPPY).Check();
|
||||
const char* arg =
|
||||
ReadString(&data[i::PreparseDataConstants::kMessageArgPos]);
|
||||
arg_object =
|
||||
v8::Utils::OpenHandle(*v8::String::NewFromUtf8(CcTest::isolate(), arg));
|
||||
i::DeleteArray(arg);
|
||||
} else {
|
||||
CHECK_EQ(0, arg_count);
|
||||
args_array = factory->NewJSArray(0);
|
||||
arg_object = isolate->factory()->undefined_value();
|
||||
}
|
||||
|
||||
i::Handle<i::JSObject> builtins(isolate->js_builtins_object());
|
||||
i::Handle<i::Object> format_fun =
|
||||
i::Object::GetProperty(isolate, builtins, "$formatMessage")
|
||||
.ToHandleChecked();
|
||||
i::Handle<i::Object> arg_handles[] = { format, args_array };
|
||||
i::Handle<i::Object> result = i::Execution::Call(
|
||||
isolate, format_fun, builtins, 2, arg_handles).ToHandleChecked();
|
||||
CHECK(result->IsString());
|
||||
i::DeleteArray(message);
|
||||
i::DeleteArray(arg);
|
||||
data.Dispose();
|
||||
return i::Handle<i::String>::cast(result);
|
||||
return i::MessageTemplate::FormatMessage(isolate, message, arg_object);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user