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

Unified Diff: tools/gn/template.cc

Issue 212933008: Don't dynamically scope GN templates. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/gn/template.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/gn/template.cc
diff --git a/tools/gn/template.cc b/tools/gn/template.cc
new file mode 100644
index 0000000000000000000000000000000000000000..cae5e0c2d092c4439fa1028624d79fc286e2dd5c
--- /dev/null
+++ b/tools/gn/template.cc
@@ -0,0 +1,73 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "tools/gn/template.h"
+
+#include "tools/gn/err.h"
+#include "tools/gn/functions.h"
+#include "tools/gn/parse_tree.h"
+#include "tools/gn/scope.h"
+#include "tools/gn/value.h"
+
+Template::Template(const Scope* scope, const FunctionCallNode* def)
+ : closure_(scope->MakeClosure()),
+ definition_(def) {
+}
+
+Template::Template(scoped_ptr<Scope> scope, const FunctionCallNode* def)
+ : closure_(scope.Pass()),
+ definition_(def) {
+}
+
+Template::~Template() {
+}
+
+scoped_ptr<Template> Template::Clone() const {
+ // We can make a new closure from our closure to copy it.
+ return scoped_ptr<Template>(
+ new Template(closure_->MakeClosure(), definition_));
+}
+
+Value Template::Invoke(Scope* scope,
+ const FunctionCallNode* invocation,
+ const std::vector<Value>& args,
+ BlockNode* block,
+ Err* err) const {
+ // Don't allow templates to be executed from imported files. Imports are for
+ // simple values only.
+ if (!EnsureNotProcessingImport(invocation, scope, err))
+ return Value();
+
+ // First run the invocation's block.
+ Scope invocation_scope(scope);
+ if (!FillTargetBlockScope(scope, invocation,
+ invocation->function().value().as_string(),
+ block, args, &invocation_scope, err))
+ return Value();
+ block->ExecuteBlockInScope(&invocation_scope, err);
+ 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.
+ Scope template_scope(closure_.get());
+ template_scope.SetValue("invoker", Value(NULL, &invocation_scope),
+ invocation);
+ template_scope.set_source_dir(scope->GetSourceDir());
+
+ const base::StringPiece target_name("target_name");
+ template_scope.SetValue(target_name,
+ 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.
+ return definition_->block()->ExecuteBlockInScope(&template_scope, err);
+}
+
+LocationRange Template::GetDefinitionRange() const {
+ return definition_->GetRange();
+}
« no previous file with comments | « tools/gn/template.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698