Commit a5ac0290 authored by yangguo's avatar yangguo Committed by Commit bot

Start migrating error message templates to the runtime.

Currently done with two templates, one used from native js, one from runtime.

R=verwaest@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#27864}
parent 0e703bd3
...@@ -201,6 +201,8 @@ action("js2c") { ...@@ -201,6 +201,8 @@ action("js2c") {
inputs = [ "tools/jsmin.py" ] inputs = [ "tools/jsmin.py" ]
sources = [ sources = [
"src/macros.py",
"src/messages.h",
"src/runtime.js", "src/runtime.js",
"src/v8natives.js", "src/v8natives.js",
"src/symbol.js", "src/symbol.js",
...@@ -227,7 +229,6 @@ action("js2c") { ...@@ -227,7 +229,6 @@ action("js2c") {
"src/mirror-debugger.js", "src/mirror-debugger.js",
"src/liveedit-debugger.js", "src/liveedit-debugger.js",
"src/templates.js", "src/templates.js",
"src/macros.py",
] ]
outputs = [ outputs = [
...@@ -263,6 +264,7 @@ action("js2c_experimental") { ...@@ -263,6 +264,7 @@ action("js2c_experimental") {
sources = [ sources = [
"src/macros.py", "src/macros.py",
"src/messages.h",
"src/proxy.js", "src/proxy.js",
"src/generator.js", "src/generator.js",
"src/harmony-array.js", "src/harmony-array.js",
......
...@@ -102,7 +102,7 @@ function SetConstructor(iterable) { ...@@ -102,7 +102,7 @@ function SetConstructor(iterable) {
if (!IS_NULL_OR_UNDEFINED(iterable)) { if (!IS_NULL_OR_UNDEFINED(iterable)) {
var adder = this.add; var adder = this.add;
if (!IS_SPEC_FUNCTION(adder)) { if (!IS_SPEC_FUNCTION(adder)) {
throw MakeTypeError('property_not_function', ['add', this]); throw MakeTypeError(kPropertyNotFunction, ['add', this]);
} }
for (var value of iterable) { for (var value of iterable) {
...@@ -268,7 +268,7 @@ function MapConstructor(iterable) { ...@@ -268,7 +268,7 @@ function MapConstructor(iterable) {
if (!IS_NULL_OR_UNDEFINED(iterable)) { if (!IS_NULL_OR_UNDEFINED(iterable)) {
var adder = this.set; var adder = this.set;
if (!IS_SPEC_FUNCTION(adder)) { if (!IS_SPEC_FUNCTION(adder)) {
throw MakeTypeError('property_not_function', ['set', this]); throw MakeTypeError(kPropertyNotFunction, ['set', this]);
} }
for (var nextItem of iterable) { for (var nextItem of iterable) {
......
...@@ -1080,6 +1080,13 @@ Handle<Object> Factory::NewTypeError(const char* message, ...@@ -1080,6 +1080,13 @@ Handle<Object> Factory::NewTypeError(const char* message,
} }
Handle<Object> Factory::NewTypeError(MessageTemplate::Template template_index,
Handle<Object> arg0, Handle<Object> arg1,
Handle<Object> arg2) {
return NewError("MakeTypeError2", template_index, arg0, arg1, arg2);
}
Handle<Object> Factory::NewTypeError(Handle<String> message) { Handle<Object> Factory::NewTypeError(Handle<String> message) {
return NewError("$TypeError", message); return NewError("$TypeError", message);
} }
...@@ -1138,6 +1145,39 @@ Handle<Object> Factory::NewError(const char* maker, const char* message, ...@@ -1138,6 +1145,39 @@ Handle<Object> Factory::NewError(const char* maker, const char* message,
} }
Handle<Object> Factory::NewError(const char* maker,
MessageTemplate::Template template_index,
Handle<Object> arg0, Handle<Object> arg1,
Handle<Object> arg2) {
HandleScope scope(isolate());
Handle<String> error_maker = InternalizeUtf8String(maker);
Handle<Object> fun_obj = Object::GetProperty(isolate()->js_builtins_object(),
error_maker).ToHandleChecked();
Handle<JSFunction> fun = Handle<JSFunction>::cast(fun_obj);
Handle<Object> message_type(Smi::FromInt(template_index), isolate());
if (arg0.is_null()) arg0 = undefined_value();
if (arg1.is_null()) arg1 = undefined_value();
if (arg2.is_null()) arg2 = undefined_value();
Handle<Object> argv[] = {message_type, arg0, arg1, arg2};
// Invoke the JavaScript factory method. If an exception is thrown while
// running the factory method, use the exception as the result.
Handle<Object> result;
MaybeHandle<Object> exception;
if (!Execution::TryCall(fun, isolate()->js_builtins_object(), arraysize(argv),
argv, &exception).ToHandle(&result)) {
Handle<Object> exception_obj;
if (exception.ToHandle(&exception_obj)) {
result = exception_obj;
} else {
result = undefined_value();
}
}
return scope.CloseAndEscape(result);
}
Handle<Object> Factory::NewEvalError(const char* message, Handle<Object> Factory::NewEvalError(const char* message,
Vector<Handle<Object> > args) { Vector<Handle<Object> > args) {
return NewError("MakeEvalError", message, args); return NewError("MakeEvalError", message, args);
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define V8_FACTORY_H_ #define V8_FACTORY_H_
#include "src/isolate.h" #include "src/isolate.h"
#include "src/messages.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -536,11 +537,20 @@ class Factory FINAL { ...@@ -536,11 +537,20 @@ class Factory FINAL {
Handle<Object> NewError(const char* maker, const char* message, Handle<Object> NewError(const char* maker, const char* message,
Vector<Handle<Object> > args); Vector<Handle<Object> > args);
Handle<Object> NewError(const char* message, Vector<Handle<Object> > args); Handle<Object> NewError(const char* message, Vector<Handle<Object> > args);
Handle<Object> NewError(const char* maker,
MessageTemplate::Template template_index,
Handle<Object> arg0, Handle<Object> arg1,
Handle<Object> arg2);
Handle<Object> NewError(Handle<String> message); Handle<Object> NewError(Handle<String> message);
Handle<Object> NewError(const char* constructor, Handle<String> message); Handle<Object> NewError(const char* constructor, Handle<String> message);
Handle<Object> NewTypeError(const char* message, Handle<Object> NewTypeError(const char* message,
Vector<Handle<Object> > args); Vector<Handle<Object> > args);
Handle<Object> NewTypeError(MessageTemplate::Template template_index,
Handle<Object> arg0 = Handle<Object>(),
Handle<Object> arg1 = Handle<Object>(),
Handle<Object> arg2 = Handle<Object>());
Handle<Object> NewTypeError(Handle<String> message); Handle<Object> NewTypeError(Handle<String> message);
Handle<Object> NewRangeError(const char* message, Handle<Object> NewRangeError(const char* message,
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "src/execution.h" #include "src/execution.h"
#include "src/heap/spaces-inl.h" #include "src/heap/spaces-inl.h"
#include "src/messages.h" #include "src/messages.h"
#include "src/string-builder.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -162,4 +163,39 @@ SmartArrayPointer<char> MessageHandler::GetLocalizedMessage( ...@@ -162,4 +163,39 @@ SmartArrayPointer<char> MessageHandler::GetLocalizedMessage(
} }
MaybeHandle<String> MessageTemplate::FormatMessage(int template_index,
Handle<String> arg0,
Handle<String> arg1,
Handle<String> arg2) {
const char* template_string;
switch (template_index) {
#define CASE(NAME, STRING) \
case k##NAME: \
template_string = STRING; \
break;
MESSAGE_TEMPLATES(CASE)
#undef CASE
case kLastMessage:
default:
UNREACHABLE();
template_string = "";
break;
}
Isolate* isolate = arg0->GetIsolate();
IncrementalStringBuilder builder(isolate);
int i = 0;
Handle<String> args[] = {arg0, arg1, arg2};
for (const char* c = template_string; *c != '\0'; c++) {
if (*c == '%') {
builder.AppendString(args[i++]);
DCHECK(i < arraysize(args));
} else {
builder.AppendCharacter(*c);
}
}
return builder.Finish();
}
} } // namespace v8::internal } } // namespace v8::internal
...@@ -10,8 +10,6 @@ ...@@ -10,8 +10,6 @@
#ifndef V8_MESSAGES_H_ #ifndef V8_MESSAGES_H_
#define V8_MESSAGES_H_ #define V8_MESSAGES_H_
#include "src/handles-inl.h"
// Forward declaration of MessageLocation. // Forward declaration of MessageLocation.
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -89,6 +87,25 @@ class MessageHandler { ...@@ -89,6 +87,25 @@ class MessageHandler {
Handle<Object> data); Handle<Object> data);
}; };
#define MESSAGE_TEMPLATES(T) \
T(PropertyNotFunction, "Property '%' of object % is not a function") \
T(WithExpression, "% has no properties")
class MessageTemplate {
public:
enum Template {
#define TEMPLATE(NAME, STRING) k##NAME,
MESSAGE_TEMPLATES(TEMPLATE)
#undef TEMPLATE
kLastMessage
};
static MaybeHandle<String> FormatMessage(int template_index,
Handle<String> arg0,
Handle<String> arg1,
Handle<String> arg2);
};
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_MESSAGES_H_ #endif // V8_MESSAGES_H_
...@@ -39,7 +39,6 @@ var kMessages = { ...@@ -39,7 +39,6 @@ var kMessages = {
stack_trace: ["Stack Trace:\n", "%0"], stack_trace: ["Stack Trace:\n", "%0"],
called_non_callable: ["%0", " is not a function"], called_non_callable: ["%0", " is not a function"],
undefined_method: ["Object ", "%1", " has no method '", "%0", "'"], undefined_method: ["Object ", "%1", " has no method '", "%0", "'"],
property_not_function: ["Property '", "%0", "' of object ", "%1", " is not a function"],
cannot_convert_to_primitive: ["Cannot convert object to primitive value"], cannot_convert_to_primitive: ["Cannot convert object to primitive value"],
not_constructor: ["%0", " is not a constructor"], not_constructor: ["%0", " is not a constructor"],
not_defined: ["%0", " is not defined"], not_defined: ["%0", " is not defined"],
...@@ -47,7 +46,6 @@ var kMessages = { ...@@ -47,7 +46,6 @@ var kMessages = {
unsupported_super: ["Unsupported reference to 'super'"], unsupported_super: ["Unsupported reference to 'super'"],
non_object_property_load: ["Cannot read property '", "%0", "' of ", "%1"], non_object_property_load: ["Cannot read property '", "%0", "' of ", "%1"],
non_object_property_store: ["Cannot set property '", "%0", "' of ", "%1"], non_object_property_store: ["Cannot set property '", "%0", "' of ", "%1"],
with_expression: ["%0", " has no properties"],
illegal_invocation: ["Illegal invocation"], illegal_invocation: ["Illegal invocation"],
no_setter_in_callback: ["Cannot set property ", "%0", " of ", "%1", " which has only a getter"], no_setter_in_callback: ["Cannot set property ", "%0", " of ", "%1", " which has only a getter"],
apply_non_function: ["Function.prototype.apply was called on ", "%0", ", which is a ", "%1", " and not a function"], apply_non_function: ["Function.prototype.apply was called on ", "%0", ", which is a ", "%1", " and not a function"],
...@@ -325,6 +323,11 @@ function MakeGenericError(constructor, type, args) { ...@@ -325,6 +323,11 @@ function MakeGenericError(constructor, type, args) {
} }
function MakeGenericError2(constructor, type, arg0, arg1, arg2) {
return new constructor(FormatMessage(type, arg0, arg1, arg2));
}
/** /**
* Set up the Script function and constructor. * Set up the Script function and constructor.
*/ */
...@@ -338,10 +341,21 @@ function MakeGenericError(constructor, type, args) { ...@@ -338,10 +341,21 @@ function MakeGenericError(constructor, type, args) {
// Helper functions; called from the runtime system. // Helper functions; called from the runtime system.
function FormatMessage(type, args) { 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 "";
}
}
// TODO(yangguo): remove this code path once we migrated all messages.
var format = kMessages[type]; var format = kMessages[type];
if (!format) return "<unknown message " + type + ">"; if (!format) return "<unknown message " + type + ">";
return FormatString(format, args); return FormatString(format, arg0);
} }
...@@ -371,6 +385,12 @@ function MakeTypeError(type, args) { ...@@ -371,6 +385,12 @@ function MakeTypeError(type, args) {
} }
// TODO(yangguo): rename this once we migrated all messages.
function MakeTypeError2(type, arg0, arg1, arg2) {
return MakeGenericError2($TypeError, type, arg0, arg1, arg2);
}
function MakeRangeError(type, args) { function MakeRangeError(type, args) {
return MakeGenericError($RangeError, type, args); return MakeGenericError($RangeError, type, args);
} }
......
...@@ -305,6 +305,21 @@ RUNTIME_FUNCTION(Runtime_MessageGetScript) { ...@@ -305,6 +305,21 @@ RUNTIME_FUNCTION(Runtime_MessageGetScript) {
} }
RUNTIME_FUNCTION(Runtime_FormatMessageString) {
HandleScope scope(isolate);
DCHECK(args.length() == 4);
CONVERT_INT32_ARG_CHECKED(template_index, 0);
CONVERT_ARG_HANDLE_CHECKED(String, arg0, 1);
CONVERT_ARG_HANDLE_CHECKED(String, arg1, 2);
CONVERT_ARG_HANDLE_CHECKED(String, arg2, 3);
Handle<String> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
MessageTemplate::FormatMessage(template_index, arg0, arg1, arg2));
return *result;
}
RUNTIME_FUNCTION(Runtime_IS_VAR) { RUNTIME_FUNCTION(Runtime_IS_VAR) {
UNREACHABLE(); // implemented as macro in the parser UNREACHABLE(); // implemented as macro in the parser
return NULL; return NULL;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "src/accessors.h" #include "src/accessors.h"
#include "src/arguments.h" #include "src/arguments.h"
#include "src/frames-inl.h" #include "src/frames-inl.h"
#include "src/messages.h"
#include "src/runtime/runtime-utils.h" #include "src/runtime/runtime-utils.h"
#include "src/scopeinfo.h" #include "src/scopeinfo.h"
#include "src/scopes.h" #include "src/scopes.h"
...@@ -662,7 +663,7 @@ RUNTIME_FUNCTION(Runtime_PushWithContext) { ...@@ -662,7 +663,7 @@ RUNTIME_FUNCTION(Runtime_PushWithContext) {
if (!maybe_object.ToHandle(&extension_object)) { if (!maybe_object.ToHandle(&extension_object)) {
Handle<Object> handle = args.at<Object>(0); Handle<Object> handle = args.at<Object>(0);
THROW_NEW_ERROR_RETURN_FAILURE( THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError("with_expression", HandleVector(&handle, 1))); isolate, NewTypeError(MessageTemplate::kWithExpression, handle));
} }
} }
......
...@@ -287,6 +287,7 @@ namespace internal { ...@@ -287,6 +287,7 @@ namespace internal {
F(GetFromCacheRT, 2, 1) \ F(GetFromCacheRT, 2, 1) \
F(MessageGetStartPosition, 1, 1) \ F(MessageGetStartPosition, 1, 1) \
F(MessageGetScript, 1, 1) \ F(MessageGetScript, 1, 1) \
F(FormatMessageString, 4, 1) \
F(IS_VAR, 1, 1) \ F(IS_VAR, 1, 1) \
F(GetFromCache, 2, 1) \ F(GetFromCache, 2, 1) \
F(IncrementStatsCounter, 1, 1) \ F(IncrementStatsCounter, 1, 1) \
......
...@@ -25,7 +25,7 @@ function WeakMapConstructor(iterable) { ...@@ -25,7 +25,7 @@ function WeakMapConstructor(iterable) {
if (!IS_NULL_OR_UNDEFINED(iterable)) { if (!IS_NULL_OR_UNDEFINED(iterable)) {
var adder = this.set; var adder = this.set;
if (!IS_SPEC_FUNCTION(adder)) { if (!IS_SPEC_FUNCTION(adder)) {
throw MakeTypeError('property_not_function', ['set', this]); throw MakeTypeError(kPropertyNotFunction, ['set', this]);
} }
for (var nextItem of iterable) { for (var nextItem of iterable) {
if (!IS_SPEC_OBJECT(nextItem)) { if (!IS_SPEC_OBJECT(nextItem)) {
...@@ -116,7 +116,7 @@ function WeakSetConstructor(iterable) { ...@@ -116,7 +116,7 @@ function WeakSetConstructor(iterable) {
if (!IS_NULL_OR_UNDEFINED(iterable)) { if (!IS_NULL_OR_UNDEFINED(iterable)) {
var adder = this.add; var adder = this.add;
if (!IS_SPEC_FUNCTION(adder)) { if (!IS_SPEC_FUNCTION(adder)) {
throw MakeTypeError('property_not_function', ['add', this]); throw MakeTypeError(kPropertyNotFunction, ['add', this]);
} }
for (var value of iterable) { for (var value of iterable) {
%_CallFunction(this, value, adder); %_CallFunction(this, value, adder);
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "src/api.h" #include "src/api.h"
#include "src/factory.h" #include "src/factory.h"
#include "src/messages.h"
#include "src/objects.h" #include "src/objects.h"
#include "src/unicode-decoder.h" #include "src/unicode-decoder.h"
#include "test/cctest/cctest.h" #include "test/cctest/cctest.h"
...@@ -1459,3 +1460,20 @@ INVALID_STRING_TEST(NewStringFromUtf8, char) ...@@ -1459,3 +1460,20 @@ INVALID_STRING_TEST(NewStringFromUtf8, char)
INVALID_STRING_TEST(NewStringFromOneByte, uint8_t) INVALID_STRING_TEST(NewStringFromOneByte, uint8_t)
#undef INVALID_STRING_TEST #undef INVALID_STRING_TEST
TEST(FormatMessage) {
CcTest::InitializeVM();
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
Handle<String> arg0 = isolate->factory()->NewStringFromAsciiChecked("arg0");
Handle<String> arg1 = isolate->factory()->NewStringFromAsciiChecked("arg1");
Handle<String> arg2 = isolate->factory()->NewStringFromAsciiChecked("arg2");
Handle<String> result =
MessageTemplate::FormatMessage(MessageTemplate::kPropertyNotFunction,
arg0, arg1, arg2).ToHandleChecked();
Handle<String> expected = isolate->factory()->NewStringFromAsciiChecked(
"Property 'arg0' of object arg1 is not a function");
CHECK(String::Equals(result, expected));
}
...@@ -1686,6 +1686,8 @@ ...@@ -1686,6 +1686,8 @@
], ],
'variables': { 'variables': {
'library_files': [ 'library_files': [
'../../src/macros.py',
'../../src/messages.h',
'../../src/runtime.js', '../../src/runtime.js',
'../../src/v8natives.js', '../../src/v8natives.js',
'../../src/symbol.js', '../../src/symbol.js',
...@@ -1712,10 +1714,10 @@ ...@@ -1712,10 +1714,10 @@
'../../src/mirror-debugger.js', '../../src/mirror-debugger.js',
'../../src/liveedit-debugger.js', '../../src/liveedit-debugger.js',
'../../src/templates.js', '../../src/templates.js',
'../../src/macros.py',
], ],
'experimental_library_files': [ 'experimental_library_files': [
'../../src/macros.py', '../../src/macros.py',
'../../src/messages.h',
'../../src/proxy.js', '../../src/proxy.js',
'../../src/generator.js', '../../src/generator.js',
'../../src/harmony-array.js', '../../src/harmony-array.js',
......
...@@ -69,6 +69,7 @@ def ReadFile(filename): ...@@ -69,6 +69,7 @@ def ReadFile(filename):
EVAL_PATTERN = re.compile(r'\beval\s*\(') EVAL_PATTERN = re.compile(r'\beval\s*\(')
WITH_PATTERN = re.compile(r'\bwith\s*\(') WITH_PATTERN = re.compile(r'\bwith\s*\(')
INVALID_ERROR_MESSAGE_PATTERN = re.compile(r'Make\w*Error\((k\w+),')
def Validate(lines): def Validate(lines):
# Because of simplified context setup, eval and with is not # Because of simplified context setup, eval and with is not
...@@ -77,7 +78,9 @@ def Validate(lines): ...@@ -77,7 +78,9 @@ def Validate(lines):
raise Error("Eval disallowed in natives.") raise Error("Eval disallowed in natives.")
if WITH_PATTERN.search(lines): if WITH_PATTERN.search(lines):
raise Error("With statements disallowed in natives.") raise Error("With statements disallowed in natives.")
invalid_error = INVALID_ERROR_MESSAGE_PATTERN.search(lines)
if invalid_error:
raise Error("Unknown error message template '%s'" % invalid_error.group(1))
# Pass lines through unchanged. # Pass lines through unchanged.
return lines return lines
...@@ -188,6 +191,21 @@ def ReadMacros(lines): ...@@ -188,6 +191,21 @@ def ReadMacros(lines):
raise Error("Illegal line: " + line) raise Error("Illegal line: " + line)
return (constants, macros) return (constants, macros)
TEMPLATE_PATTERN = re.compile(r'^\s+T\(([a-zA-Z]+), ".+"\)')
def ReadMessageTemplates(lines):
templates = []
index = 0
for line in lines.split('\n'):
template_match = TEMPLATE_PATTERN.match(line)
if template_match:
name = "k%s" % template_match.group(1)
value = index
index = index + 1
templates.append((re.compile("\\b%s\\b" % name), value))
return templates
INLINE_MACRO_PATTERN = re.compile(r'macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*\n') INLINE_MACRO_PATTERN = re.compile(r'macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*\n')
INLINE_MACRO_END_PATTERN = re.compile(r'endmacro\s*\n') INLINE_MACRO_END_PATTERN = re.compile(r'endmacro\s*\n')
...@@ -311,7 +329,7 @@ GET_SCRIPT_NAME_CASE = """\ ...@@ -311,7 +329,7 @@ GET_SCRIPT_NAME_CASE = """\
""" """
def BuildFilterChain(macro_filename): def BuildFilterChain(macro_filename, message_template_file):
"""Build the chain of filter functions to be applied to the sources. """Build the chain of filter functions to be applied to the sources.
Args: Args:
...@@ -327,6 +345,10 @@ def BuildFilterChain(macro_filename): ...@@ -327,6 +345,10 @@ def BuildFilterChain(macro_filename):
filter_chain.append(lambda l: ExpandConstants(l, consts)) filter_chain.append(lambda l: ExpandConstants(l, consts))
filter_chain.append(lambda l: ExpandMacros(l, macros)) filter_chain.append(lambda l: ExpandMacros(l, macros))
if message_template_file:
message_templates = ReadMessageTemplates(ReadFile(message_template_file))
filter_chain.append(lambda l: ExpandConstants(l, message_templates))
filter_chain.extend([ filter_chain.extend([
RemoveCommentsAndTrailingWhitespace, RemoveCommentsAndTrailingWhitespace,
ExpandInlineMacros, ExpandInlineMacros,
...@@ -354,6 +376,9 @@ def IsDebuggerFile(filename): ...@@ -354,6 +376,9 @@ def IsDebuggerFile(filename):
def IsMacroFile(filename): def IsMacroFile(filename):
return filename.endswith("macros.py") return filename.endswith("macros.py")
def IsMessageTemplateFile(filename):
return filename.endswith("messages.h")
def PrepareSources(source_files): def PrepareSources(source_files):
"""Read, prepare and assemble the list of source files. """Read, prepare and assemble the list of source files.
...@@ -372,7 +397,14 @@ def PrepareSources(source_files): ...@@ -372,7 +397,14 @@ def PrepareSources(source_files):
source_files.remove(macro_files[0]) source_files.remove(macro_files[0])
macro_file = macro_files[0] macro_file = macro_files[0]
filters = BuildFilterChain(macro_file) message_template_file = None
message_template_files = filter(IsMessageTemplateFile, source_files)
assert len(message_template_files) in [0, 1]
if message_template_files:
source_files.remove(message_template_files[0])
message_template_file = message_template_files[0]
filters = BuildFilterChain(macro_file, message_template_file)
# Sort 'debugger' sources first. # Sort 'debugger' sources first.
source_files = sorted(source_files, source_files = sorted(source_files,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment