summaryrefslogtreecommitdiff
path: root/vala/valacodecontext.vala
blob: e04063034ed0974246b9c569fa58330e4ab6bc1a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
/* valacodecontext.vala
 *
 * Copyright (C) 2006-2009  Jürg Billeter
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.

 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 *
 * Author:
 * 	Jürg Billeter <j@bitron.ch>
 */

using GLib;
using Gee;

/**
 * The root of the code tree.
 */
public class Vala.CodeContext {
	/**
	 * Specifies the name of the library to be built.
	 *
	 * Public header files of a library will be assumed to be installed in
	 * a subdirectory named like the library.
	 */
	public string library { get; set; }

	/**
	 * Enable automatic memory management.
	 */
	public bool memory_management { get; set; }

	/**
	 * Enable run-time checks for programming errors.
	 */
	public bool assert { get; set; }

	/**
	 * Enable additional run-time checks such as type checks.
	 */
	public bool checking { get; set; }

	/**
	 * Do not warn when using deprecated features.
	 */
	public bool deprecated { get; set; }

	/**
	 * Do not warn when using experimental features.
	 */
	public bool experimental { get; set; }

	/**
	 * Enable experimental enhancements for non-null types.
	 */
	public bool non_null_experimental { get; set; }

	/**
	 * Enable transformation of D-Bus member names in dynamic client support.
	 */
	public bool dbus_transformation { get; set; }

	/**
	 * Output C code, don't compile to object code.
	 */
	public bool ccode_only { get; set; }

	/**
	 * Output C header file.
	 */
	public string header_filename { get; set; }

	/**
	 * Compile but do not link.
	 */
	public bool compile_only { get; set; }

	/**
	 * Output filename.
	 */
	public string output { get; set; }

	/**
	 * Base source directory.
	 */
	public string basedir { get; set; }

	/**
	 * Code output directory.
	 */
	public string directory { get; set; }

	/**
	 * Generate a C header file per Vala source file.
	 */
	public bool legacy_headers {
		get { return header_filename == null; }
	}

	/**
	 * Produce debug information.
	 */
	public bool debug { get; set; }

	/**
	 * Optimization level.
	 */
	public int optlevel { get; set; }

	/**
	 * Enable multithreading support.
	 */
	public bool thread { get; set; }

	/**
	 * Specifies the optional module initialization method.
	 */
	public Method module_init_method { get; set; }

	/**
	 * Keep temporary files produced by the compiler.
	 */
	public bool save_temps { get; set; }

	/**
	 * Target major version number of glib for code generation.
	 */
	public int target_glib_major { get; set; }

	/**
	 * Target minor version number of glib for code generation.
	 */
	public int target_glib_minor { get; set; }

	/**
	 * Returns true if the target version of glib is greater than or 
	 * equal to the specified version.
	 */
	public bool require_glib_version (int major, int minor) {
		return (target_glib_major > major) || (target_glib_major == major && target_glib_minor >= minor);
	}

	public bool save_csources {
		get { return save_temps; }
	}

	public bool save_cheaders {
		get { return save_csources || null != library; }
	}

	public Report report { get; set; default = new Report ();}

	private Gee.List<SourceFile> source_files = new ArrayList<SourceFile> ();
	private Gee.List<string> c_source_files = new ArrayList<string> ();
	private Namespace _root = new Namespace (null);

	private Gee.List<string> packages = new ArrayList<string> (str_equal);

	static StaticPrivate context_stack_key = StaticPrivate ();

	/**
	 * The root namespace of the symbol tree.
	 *
	 * @return root namespace
	 */
	public Namespace root {
		get { return _root; }
	}

	/**
	 * The selected code generator.
	 */
	public CodeGenerator codegen { get; set; default = new CodeGenerator (); }

	public CodeContext () {
	}

	/**
	 * Return the topmost context from the context stack.
	 */
	public static CodeContext get () {
		Gee.List<CodeContext>* context_stack = context_stack_key.get ();

		return context_stack->get (context_stack->size - 1);
	}

	/**
	 * Push the specified context to the context stack.
	 */
	public static void push (CodeContext context) {
		Gee.List<CodeContext>* context_stack = context_stack_key.get ();
		if (context_stack == null) {
			context_stack = new ArrayList<CodeContext> ();
			context_stack_key.set (context_stack, null);
		}

		context_stack->add (context);
	}

	/**
	 * Remove the topmost context from the context stack.
	 */
	public static void pop () {
		Gee.List<CodeContext>* context_stack = context_stack_key.get ();

		context_stack->remove_at (context_stack->size - 1);
	}

	/**
	 * Returns a copy of the list of source files.
	 *
	 * @return list of source files
	 */
	public Gee.List<SourceFile> get_source_files () {
		return new ReadOnlyList<SourceFile> (source_files);
	}

	/**
	 * Returns a copy of the list of C source files.
	 *
	 * @return list of C source files
	 */
	public Gee.List<string> get_c_source_files () {
		return new ReadOnlyList<string> (c_source_files);
	}
	
	/**
	 * Adds the specified file to the list of source files.
	 *
	 * @param file a source file
	 */
	public void add_source_file (SourceFile file) {
		source_files.add (file);
	}

	/**
	 * Adds the specified file to the list of C source files.
	 *
	 * @param file a C source file
	 */
	public void add_c_source_file (string file) {
		c_source_files.add (file);
	}

	/**
	 * Returns a copy of the list of used packages.
	 *
	 * @return list of used packages
	 */
	public Gee.List<string> get_packages () {
		return new ReadOnlyList<string> (packages);
	}

	/**
	 * Returns whether the specified package is being used.
	 *
	 * @param pkg a package name
	 * @return    true if the specified package is being used
	 */
	public bool has_package (string pkg) {
		return packages.contains (pkg);
	}

	/**
	 * Adds the specified package to the list of used packages.
	 *
	 * @param pkg a package name
	 */
	public void add_package (string pkg) {
		packages.add (pkg);
	}

	/**
	 * Visits the complete code tree file by file.
	 *
	 * @param visitor the visitor to be called when traversing
	 */
	public void accept (CodeVisitor visitor) {
		root.accept (visitor);

		foreach (SourceFile file in source_files) {
			file.accept (visitor);
		}
	}

	public string? get_package_path (string pkg, string[] vapi_directories) {
		string basename = "%s.vapi".printf (pkg);
		string filename = null;

		if (vapi_directories != null) {
			foreach (string vapidir in vapi_directories) {
				filename = Path.build_filename (vapidir, basename);
				if (FileUtils.test (filename, FileTest.EXISTS)) {
					return filename;
				}
			}
		}

		filename = Path.build_filename (Config.PACKAGE_DATADIR, "vapi", basename);
		if (FileUtils.test (filename, FileTest.EXISTS)) {
			return filename;
		}

		foreach (string vapidir in Environment.get_system_data_dirs ()) {
			filename = Path.build_filename (vapidir, "vala/vapi", basename);
			if (FileUtils.test (filename, FileTest.EXISTS)) {
				return filename;
			}
		}

		return null;
	}
}