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

Side by Side Diff: tools/gn/file_template.h

Issue 429423002: Refactor GN source expansions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/gn/escape.cc ('k') | tools/gn/file_template.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef TOOLS_GN_FILE_TEMPLATE_H_
6 #define TOOLS_GN_FILE_TEMPLATE_H_
7
8 #include <iosfwd>
9
10 #include "base/basictypes.h"
11 #include "base/containers/stack_container.h"
12 #include "tools/gn/err.h"
13 #include "tools/gn/source_dir.h"
14 #include "tools/gn/value.h"
15
16 struct EscapeOptions;
17 class ParseNode;
18 class Settings;
19 class SourceFile;
20 class Target;
21
22 extern const char kSourceExpansion_Help[];
23
24 // A FileTemplate object implements source expansion for a given "template"
25 // (either outputs or args, depending on the target type).
26 //
27 // There are two ways you can use this. You can make a template and then
28 // apply a source to it to get a list of outputs manually. Or you can do the
29 // actual substitution in Ninja, writing the arguments in a rule and using
30 // variables in build statements to invoke the rule with the right
31 // substitutions.
32 class FileTemplate {
33 public:
34 enum OutputStyle {
35 OUTPUT_ABSOLUTE, // Dirs will be absolute "//foo/bar".
36 OUTPUT_RELATIVE, // Dirs will be relative to a given directory.
37 };
38
39 struct Subrange {
40 // See the help in the .cc file for what these mean.
41 enum Type {
42 LITERAL = 0,
43
44 SOURCE, // {{source}}
45 NAME_PART, // {{source_name_part}}
46 FILE_PART, // {{source_file_part}}
47 SOURCE_DIR, // {{source_dir}}
48 ROOT_RELATIVE_DIR, // {{root_relative_dir}}
49 SOURCE_GEN_DIR, // {{source_gen_dir}}
50 SOURCE_OUT_DIR, // {{source_out_dir}}
51
52 NUM_TYPES // Must be last
53 };
54 Subrange(Type t, const std::string& l = std::string())
55 : type(t),
56 literal(l) {
57 }
58
59 Type type;
60
61 // When type_ == LITERAL, this specifies the literal.
62 std::string literal;
63 };
64
65 // Constructs a template from the given value. On error, the err will be
66 // set. In this case you should not use this object.
67 FileTemplate(const Settings* settings,
68 const Value& t,
69 OutputStyle output_style,
70 const SourceDir& relative_to,
71 Err* err);
72 FileTemplate(const Settings* settings,
73 const std::vector<std::string>& t,
74 OutputStyle output_style,
75 const SourceDir& relative_to);
76 FileTemplate(const Settings* settings,
77 const std::vector<SourceFile>& t,
78 OutputStyle output_style,
79 const SourceDir& relative_to);
80
81 ~FileTemplate();
82
83 // Returns an output template representing the given target's script
84 // outputs.
85 static FileTemplate GetForTargetOutputs(const Target* target);
86
87 // Returns true if the given substitution type is used by this template.
88 bool IsTypeUsed(Subrange::Type type) const;
89
90 // Returns true if there are any substitutions.
91 bool has_substitutions() const { return has_substitutions_; }
92
93 // Applies the template to one source file. The results will be *appended* to
94 // the output.
95 void Apply(const SourceFile& source,
96 std::vector<std::string>* output) const;
97
98 // Writes a string representing the template with Ninja variables for the
99 // substitutions, and the literals escaped for Ninja consumption.
100 //
101 // For example, if the input is "foo{{source_name_part}}bar" this will write
102 // foo${source_name_part}bar. If there are multiple templates (we were
103 // constucted with a list of more than one item) then the values will be
104 // separated by spaces.
105 //
106 // If this template is nonempty, we will first print out a space to separate
107 // it from the previous command.
108 //
109 // The names used for the Ninja variables will be the same ones used by
110 // WriteNinjaVariablesForSubstitution. You would use this to define the Ninja
111 // rule, and then define the variables to substitute for each file using
112 // WriteNinjaVariablesForSubstitution.
113 void WriteWithNinjaExpansions(std::ostream& out) const;
114
115 // Writes to the given stream the variable declarations for extracting the
116 // required parts of the given source file string. The results will be
117 // indented two spaces.
118 //
119 // This is used to set up a build statement to invoke a rule where the rule
120 // contains a representation of this file template to be expanded by Ninja
121 // (see GetWithNinjaExpansions).
122 void WriteNinjaVariablesForSubstitution(
123 std::ostream& out,
124 const SourceFile& source,
125 const EscapeOptions& escape_options) const;
126
127 // Returns the Ninja variable name used by the above Ninja functions to
128 // substitute for the given type.
129 static const char* GetNinjaVariableNameForType(Subrange::Type type);
130
131 // Extracts the given type of substitution from the given source file.
132 // If output_style is OUTPUT_RELATIVE, relative_to indicates the directory
133 // that the relative directories should be relative to, otherwise it is
134 // ignored.
135 static std::string GetSubstitution(const Settings* settings,
136 const SourceFile& source,
137 Subrange::Type type,
138 OutputStyle output_style,
139 const SourceDir& relative_to);
140
141 // Known template types, these include the "{{ }}".
142 // IF YOU ADD NEW ONES: If the expansion expands to something inside the
143 // output directory, also update EnsureStringIsInOutputDir.
144 static const char kSource[];
145 static const char kSourceNamePart[];
146 static const char kSourceFilePart[];
147 static const char kSourceDir[];
148 static const char kRootRelDir[];
149 static const char kSourceGenDir[];
150 static const char kSourceOutDir[];
151
152 private:
153 typedef base::StackVector<Subrange, 8> Template;
154 typedef base::StackVector<Template, 8> TemplateVector;
155
156 void ParseInput(const Value& value, Err* err);
157
158 // Parses a template string and adds it to the templates_ list.
159 void ParseOneTemplateString(const std::string& str);
160
161 const Settings* settings_;
162 OutputStyle output_style_;
163 SourceDir relative_to_;
164
165 TemplateVector templates_;
166
167 // The corresponding value is set to true if the given subrange type is
168 // required. This allows us to precompute these types whem applying them
169 // to a given source file.
170 bool types_required_[Subrange::NUM_TYPES];
171
172 // Set when any of the types_required_ is true. Otherwise, everythins is a
173 // literal (a common case so we can optimize some code paths).
174 bool has_substitutions_;
175 };
176
177 #endif // TOOLS_GN_FILE_TEMPLATE_H_
OLDNEW
« no previous file with comments | « tools/gn/escape.cc ('k') | tools/gn/file_template.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698