| Index: tools/gn/template.cc
|
| diff --git a/tools/gn/template.cc b/tools/gn/template.cc
|
| index fa0ccf31c64c4e3a43b5a4a8b1e24d51e87deea6..bf4eb6187804c08f4e2586ba9d9046151cc04aad 100644
|
| --- a/tools/gn/template.cc
|
| +++ b/tools/gn/template.cc
|
| @@ -8,6 +8,7 @@
|
| #include "tools/gn/functions.h"
|
| #include "tools/gn/parse_tree.h"
|
| #include "tools/gn/scope.h"
|
| +#include "tools/gn/scope_per_file_provider.h"
|
| #include "tools/gn/value.h"
|
|
|
| Template::Template(const Scope* scope, const FunctionCallNode* def)
|
| @@ -50,17 +51,24 @@ Value Template::Invoke(Scope* scope,
|
| if (err->has_error())
|
| return Value();
|
|
|
| - // Set up the scope to run the template. This should be dependent on the
|
| - // closure, but have the "invoker" and "target_name" values injected, and the
|
| - // current dir matching the invoker. We jump through some hoops to avoid
|
| - // copying the invocation scope when setting it in the template scope (since
|
| - // the invocation scope may have large lists of source files in it and could
|
| - // be expensive to copy).
|
| + // Set up the scope to run the template and set the current directory for the
|
| + // template (which ScopePerFileProvider uses to base the target-related
|
| + // variables target_gen_dir and target_out_dir on) to be that of the invoker.
|
| + // This way, files don't have to be rebased and target_*_dir works the way
|
| + // people expect (otherwise its to easy to be putting generated files in the
|
| + // gen dir corresponding to an imported file).
|
| + Scope template_scope(closure_.get());
|
| + template_scope.set_source_dir(scope->GetSourceDir());
|
| +
|
| + ScopePerFileProvider per_file_provider(&template_scope, true);
|
| +
|
| + // We jump through some hoops to avoid copying the invocation scope when
|
| + // setting it in the template scope (since the invocation scope may have
|
| + // large lists of source files in it and could be expensive to copy).
|
| //
|
| // Scope.SetValue will copy the value which will in turn copy the scope, but
|
| // if we instead create a value and then set the scope on it, the copy can
|
| // be avoided.
|
| - Scope template_scope(closure_.get());
|
| const char kInvoker[] = "invoker";
|
| template_scope.SetValue(kInvoker, Value(NULL, scoped_ptr<Scope>()),
|
| invocation);
|
| @@ -73,11 +81,11 @@ Value Template::Invoke(Scope* scope,
|
| Value(invocation, args[0].string_value()),
|
| invocation);
|
|
|
| - // Run the template code. Don't check for unused variables since the
|
| - // template could be executed in many different ways and it could be that
|
| - // not all executions use all values in the closure.
|
| + // Actually run the template code.
|
| Value result =
|
| definition_->block()->ExecuteBlockInScope(&template_scope, err);
|
| + if (err->has_error())
|
| + return Value();
|
|
|
| // Check for unused variables in the invocation scope. This will find typos
|
| // of things the caller meant to pass to the template but the template didn't
|
|
|