Commit 53b8098f authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter

use continue statements to decrease indentation levels add interface

2006-07-07  Jürg Billeter  <j@bitron.ch>

	* vala/valacodecontext.vala: use continue statements to decrease
	  indentation levels
	* vala/valasymbolbuilder.vala, vala/valasymbolresolver.vala,
	  vala/valasemanticanalyzer.vala, vala/valamemorymanager.vala,
	  vala/valacodegenerator.vala, vala/valaconditionalexpression.vala,
	  vala/valaconstant.vala: add interface documentation, use implicit
	  namespace specification
	* vala/valasemanticanalyzer.vala: check that if, while, for, and
	  conditional expression conditions are boolean
	* vala/valaclass.vala: remove dummy accessor, breaks build with old
	  vala compiler
	* compiler/valacompiler.vala: use implicit namespace specification
	* tests/test-016.vala: test conditional expressions
	* tests/Makefile.am: update

svn path=/trunk/; revision=68
parent 7b280c7d
2006-07-07 Jürg Billeter <j@bitron.ch>
* vala/valacodecontext.vala: use continue statements to decrease
indentation levels
* vala/valasymbolbuilder.vala, vala/valasymbolresolver.vala,
vala/valasemanticanalyzer.vala, vala/valamemorymanager.vala,
vala/valacodegenerator.vala, vala/valaconditionalexpression.vala,
vala/valaconstant.vala: add interface documentation, use implicit
namespace specification
* vala/valasemanticanalyzer.vala: check that if, while, for, and
conditional expression conditions are boolean
* vala/valaclass.vala: remove dummy accessor, breaks build with old
vala compiler
* compiler/valacompiler.vala: use implicit namespace specification
* tests/test-016.vala: test conditional expressions
* tests/Makefile.am: update
2006-07-07 Jürg Billeter <j@bitron.ch>
* vala/valacodecontext.vala: add interface documentation, use implicit
......
......@@ -22,192 +22,190 @@
using GLib;
namespace Vala {
class Compiler {
static string directory;
static bool version;
static string[] sources;
static string[] vapi_directories;
static string library;
static string[] packages;
static bool disable_memory_management;
CodeContext context;
class Vala.Compiler {
static string directory;
static bool version;
static string[] sources;
static string[] vapi_directories;
static string library;
static string[] packages;
static bool disable_memory_management;
CodeContext context;
const OptionEntry[] options = {
{ "vapidir", 0, 0, OptionArg.FILENAME_ARRAY, out vapi_directories, "Look for package bindings in DIRECTORY", "DIRECTORY..." },
{ "pkg", 0, 0, OptionArg.STRING_ARRAY, out packages, "Include binding for PACKAGE", "PACKAGE..." },
{ "library", 0, 0, OptionArg.STRING, out library, "Library name", "NAME" },
{ "directory", 'd', 0, OptionArg.FILENAME, out directory, "Output directory", "DIRECTORY" },
{ "version", 0, 0, OptionArg.NONE, ref version, "Display version number", null },
{ "disable-memory-management", 0, 0, OptionArg.NONE, ref disable_memory_management, "Disable memory management", null },
{ "", 0, 0, OptionArg.FILENAME_ARRAY, out sources, null, "FILE..." },
{ null }
};
const OptionEntry[] options = {
{ "vapidir", 0, 0, OptionArg.FILENAME_ARRAY, out vapi_directories, "Look for package bindings in DIRECTORY", "DIRECTORY..." },
{ "pkg", 0, 0, OptionArg.STRING_ARRAY, out packages, "Include binding for PACKAGE", "PACKAGE..." },
{ "library", 0, 0, OptionArg.STRING, out library, "Library name", "NAME" },
{ "directory", 'd', 0, OptionArg.FILENAME, out directory, "Output directory", "DIRECTORY" },
{ "version", 0, 0, OptionArg.NONE, ref version, "Display version number", null },
{ "disable-memory-management", 0, 0, OptionArg.NONE, ref disable_memory_management, "Disable memory management", null },
{ "", 0, 0, OptionArg.FILENAME_ARRAY, out sources, null, "FILE..." },
{ null }
};
private int quit () {
if (Report.get_errors () == 0) {
stdout.printf ("Compilation succeeded - %d warning(s)\n", Report.get_warnings ());
return 0;
} else {
stdout.printf ("Compilation failed: %d error(s), %d warning(s)\n", Report.get_errors (), Report.get_warnings ());
return 1;
private int quit () {
if (Report.get_errors () == 0) {
stdout.printf ("Compilation succeeded - %d warning(s)\n", Report.get_warnings ());
return 0;
} else {
stdout.printf ("Compilation failed: %d error(s), %d warning(s)\n", Report.get_errors (), Report.get_warnings ());
return 1;
}
}
private ref string get_package_path (string! pkg) {
var basename = "%s.vala".printf (pkg);
if (vapi_directories != null) {
foreach (string vapidir in vapi_directories) {
var filename = Path.build_filename (vapidir, basename, null);
if (File.test (filename, FileTest.EXISTS)) {
return filename;
}
}
vapi_directories = null;
}
private ref string get_package_path (string! pkg) {
var basename = "%s.vala".printf (pkg);
var filename = Path.build_filename ("/usr/share/vala/vapi", basename, null);
if (File.test (filename, FileTest.EXISTS)) {
return filename;
}
if (vapi_directories != null) {
foreach (string vapidir in vapi_directories) {
var filename = Path.build_filename (vapidir, basename, null);
if (File.test (filename, FileTest.EXISTS)) {
return filename;
}
}
vapi_directories = null;
}
var filename = Path.build_filename ("/usr/share/vala/vapi", basename, null);
if (File.test (filename, FileTest.EXISTS)) {
return filename;
}
return null;
return null;
}
private bool add_package (string! pkg) {
var package_path = get_package_path (pkg);
if (package_path == null) {
return false;
}
private bool add_package (string! pkg) {
var package_path = get_package_path (pkg);
if (package_path == null) {
return false;
}
context.add_source_file (new SourceFile (filename = package_path, pkg = true));
return true;
context.add_source_file (new SourceFile (filename = package_path, pkg = true));
return true;
}
private int run () {
context = new CodeContext ();
/* default package */
if (!add_package ("glib-2.0")) {
Report.error (null, "glib-2.0 not found in specified Vala API directories");
}
private int run () {
context = new CodeContext ();
/* default package */
if (!add_package ("glib-2.0")) {
Report.error (null, "glib-2.0 not found in specified Vala API directories");
}
if (packages != null) {
foreach (string package in packages) {
if (!add_package (package)) {
Report.error (null, "%s not found in specified Vala API directories".printf (package));
}
}
packages = null;
}
if (Report.get_errors () > 0) {
return quit ();
}
foreach (string source in sources) {
if (File.test (source, FileTest.EXISTS)) {
context.add_source_file (new SourceFile (filename = source));
} else {
Report.error (null, "%s not found".printf (source));
if (packages != null) {
foreach (string package in packages) {
if (!add_package (package)) {
Report.error (null, "%s not found in specified Vala API directories".printf (package));
}
}
sources = null;
if (Report.get_errors () > 0) {
return quit ();
}
var parser = new Parser ();
parser.parse (context);
if (Report.get_errors () > 0) {
return quit ();
}
var builder = new SymbolBuilder ();
builder.build (context);
if (Report.get_errors () > 0) {
return quit ();
}
var attributeprocessor = new AttributeProcessor ();
attributeprocessor.process (context);
if (Report.get_errors () > 0) {
return quit ();
}
var resolver = new SymbolResolver ();
resolver.resolve (context);
if (Report.get_errors () > 0) {
return quit ();
}
var analyzer = new SemanticAnalyzer (memory_management = !disable_memory_management);
analyzer.analyze (context);
if (Report.get_errors () > 0) {
return quit ();
}
if (!disable_memory_management) {
var memory_manager = new MemoryManager ();
memory_manager.analyze (context);
if (Report.get_errors () > 0) {
return quit ();
}
packages = null;
}
if (Report.get_errors () > 0) {
return quit ();
}
foreach (string source in sources) {
if (File.test (source, FileTest.EXISTS)) {
context.add_source_file (new SourceFile (filename = source));
} else {
Report.error (null, "%s not found".printf (source));
}
var code_generator = new CodeGenerator (memory_management = !disable_memory_management);
code_generator.emit (context);
}
sources = null;
if (Report.get_errors () > 0) {
return quit ();
}
var parser = new Parser ();
parser.parse (context);
if (Report.get_errors () > 0) {
return quit ();
}
var builder = new SymbolBuilder ();
builder.build (context);
if (Report.get_errors () > 0) {
return quit ();
}
var attributeprocessor = new AttributeProcessor ();
attributeprocessor.process (context);
if (Report.get_errors () > 0) {
return quit ();
}
var resolver = new SymbolResolver ();
resolver.resolve (context);
if (Report.get_errors () > 0) {
return quit ();
}
var analyzer = new SemanticAnalyzer (memory_management = !disable_memory_management);
analyzer.analyze (context);
if (Report.get_errors () > 0) {
return quit ();
}
if (!disable_memory_management) {
var memory_manager = new MemoryManager ();
memory_manager.analyze (context);
if (Report.get_errors () > 0) {
return quit ();
}
if (library != null) {
var interface_writer = new InterfaceWriter ();
interface_writer.write_file (context, "%s.vala".printf (library));
library = null;
}
return quit ();
}
static int main (int argc, string[] argv) {
Error err = null;
var code_generator = new CodeGenerator (memory_management = !disable_memory_management);
code_generator.emit (context);
var opt_context = OptionContext.@new ("- Vala Compiler");
opt_context.set_help_enabled (true);
opt_context.add_main_entries (options, null);
opt_context.parse (ref argc, out argv, out err);
if (err != null) {
return 1;
}
if (Report.get_errors () > 0) {
return quit ();
}
if (library != null) {
var interface_writer = new InterfaceWriter ();
interface_writer.write_file (context, "%s.vala".printf (library));
if (sources == null) {
stderr.printf ("No source file specified.\n");
library = null;
}
return quit ();
}
static int main (int argc, string[] argv) {
Error err = null;
var opt_context = OptionContext.@new ("- Vala Compiler");
opt_context.set_help_enabled (true);
opt_context.add_main_entries (options, null);
opt_context.parse (ref argc, out argv, out err);
if (err != null) {
return 1;
}
if (sources == null) {
stderr.printf ("No source file specified.\n");
return 1;
}
foreach (string source in sources) {
if (!source.has_suffix (".vala")) {
stderr.printf ("Only .vala source files supported.\n");
return 1;
}
foreach (string source in sources) {
if (!source.has_suffix (".vala")) {
stderr.printf ("Only .vala source files supported.\n");
return 1;
}
}
var compiler = new Compiler ();
return compiler.run ();
}
var compiler = new Compiler ();
return compiler.run ();
}
}
......@@ -16,4 +16,5 @@ EXTRA_DIST = \
test-013.vala \
test-014.vala \
test-015.vala \
test-016.vala \
$(NULL)
using GLib;
class Maman.Bar {
static int main (int argc, string[] argv) {
stdout.printf ("Conditional Expression Test: 1");
stdout.printf (" %d", false ? -1 : 2);
stdout.printf (" 3\n");
return 0;
}
}
......@@ -44,9 +44,6 @@ public class Vala.Class : DataType {
get {
return _has_private_fields;
}
set {
/* FIXME: dummy accessor due to vala compiler bug */
}
}
private string cname;
......
......@@ -76,10 +76,12 @@ public class Vala.CodeContext {
/* find cycles in dependencies between source files */
foreach (SourceFile file in source_files) {
/* we're only interested in internal source files */
if (!file.pkg) {
if (file.mark == 0) {
visit (file, null);
}
if (file.pkg) {
continue;
}
if (file.mark == 0) {
visit (file, null);
}
}
......@@ -96,18 +98,20 @@ public class Vala.CodeContext {
*/
foreach (SourceFile file2 in source_files) {
/* we're only interested in internal source files */
if (!file2.pkg) {
foreach (SourceFile dep in file2.header_internal_dependencies) {
if (file2.cycle != null && dep.cycle == file2.cycle) {
/* in the same cycle */
if (!file2.is_cycle_head) {
/* include header of cycle head */
file2.header_internal_includes.append (file2.cycle.head.get_cheader_filename ());
}
} else {
/* we can just include the headers if they are not in a cycle or not in the same cycle as the current file */
file2.header_internal_includes.append (dep.get_cheader_filename ());
if (file2.pkg) {
continue;
}
foreach (SourceFile dep in file2.header_internal_dependencies) {
if (file2.cycle != null && dep.cycle == file2.cycle) {
/* in the same cycle */
if (!file2.is_cycle_head) {
/* include header of cycle head */
file2.header_internal_includes.append (file2.cycle.head.get_cheader_filename ());
}
} else {
/* we can just include the headers if they are not in a cycle or not in the same cycle as the current file */
file2.header_internal_includes.append (dep.get_cheader_filename ());
}
}
}
......@@ -143,60 +147,69 @@ public class Vala.CodeContext {
file.mark = 1;
foreach (SourceFile dep in file.header_internal_dependencies) {
if (file != dep) {
if (dep.mark == 1) {
/* found cycle */
if (file == dep) {
continue;
}
if (dep.mark == 1) {
/* found cycle */
var cycle = new SourceFileCycle ();
cycles.append (cycle);
bool cycle_start_found = false;
foreach (SourceFile cycle_file in l) {
ref SourceFileCycle ref_cycle_file_cycle = cycle_file.cycle;
if (!cycle_start_found) {
if (cycle_file == dep) {
cycle_start_found = true;
}
}
var cycle = new SourceFileCycle ();
cycles.append (cycle);
if (!cycle_start_found) {
continue;
}
bool cycle_start_found = false;
foreach (SourceFile cycle_file in l) {
ref SourceFileCycle ref_cycle_file_cycle = cycle_file.cycle;
if (!cycle_start_found) {
if (cycle_file == dep) {
cycle_start_found = true;
if (cycle_file.cycle != null) {
/* file already in a cycle */
if (cycle_file.cycle == cycle) {
/* file is in the same cycle, nothing to do */
continue;
}
/* file is in an other cycle, merge the two cycles */
/* broken memory management cycles.remove (cycle_file.cycle); */
ref List<ref SourceFileCycle> newlist = null;
foreach (SourceFileCycle oldcycle in cycles) {
if (oldcycle != cycle_file.cycle) {
newlist.append (oldcycle);
}
}
if (cycle_start_found) {
if (cycle_file.cycle != null) {
/* file already in a cycle */
if (cycle_file.cycle != cycle) {
/* file is in an other cycle, merge the two cycles */
/* broken memory management cycles.remove (cycle_file.cycle); */
ref List<ref SourceFileCycle> newlist = null;
foreach (SourceFileCycle oldcycle in cycles) {
if (oldcycle != cycle_file.cycle) {
newlist.append (oldcycle);
}
}
cycles = null;
foreach (SourceFileCycle newcycle in newlist) {
cycles.append (newcycle);
}
newlist = null;
/* end workaround for broken memory management */
foreach (SourceFile inner_cycle_file in cycle_file.cycle.files) {
if (inner_cycle_file.cycle != cycle) {
/* file in inner cycle not yet added to outer cycle */
cycle.files.append (inner_cycle_file);
inner_cycle_file.cycle = cycle;
}
}
}
} else {
cycle.files.append (cycle_file);
cycle_file.cycle = cycle;
cycles = null;
foreach (SourceFileCycle newcycle in newlist) {
cycles.append (newcycle);
}
newlist = null;
/* end workaround for broken memory management */
foreach (SourceFile inner_cycle_file in cycle_file.cycle.files) {
if (inner_cycle_file.cycle != cycle) {
/* file in inner cycle not yet added to outer cycle */
cycle.files.append (inner_cycle_file);
inner_cycle_file.cycle = cycle;
}
}
} else {
cycle.files.append (cycle_file);
cycle_file.cycle = cycle;
}
} else if (dep.mark == 0) {
/* found not yet visited file */
visit (dep, l);
}
} else if (dep.mark == 0) {
/* found not yet visited file */
visit (dep, l);
}
}
......
This diff is collapsed.
......@@ -22,22 +22,42 @@
using GLib;
namespace Vala {
public class ConditionalExpression : Expression {
public Expression condition { get; construct; }
public Expression true_expression { get; construct; }
public Expression false_expression { get; construct; }
public static ref ConditionalExpression new (Expression cond, Expression true_expr, Expression false_expr, SourceReference source) {
return (new ConditionalExpression (condition = cond, true_expression = true_expr, false_expression = false_expr, source_reference = source));
}
public override void accept (CodeVisitor visitor) {
condition.accept (visitor);
true_expression.accept (visitor);
false_expression.accept (visitor);
/**
* Represents a conditional expression in the source code.
*/
public class Vala.ConditionalExpression : Expression {
/**
* The condition.
*/
public Expression! condition { get; set construct; }
/**
* The expression to be evaluated if the condition holds.
*/
public Expression! true_expression { get; set construct; }
/**
* The expression to be evaluated if the condition doesn't hold.
*/
public Expression! false_expression { get; set construct; }
/**
* Creates a new conditional expression.
*
* @param cond a condition
* @param true_expr expression to be evaluated if condition is true
* @param false_expr expression to be evaluated if condition is false
* @return newly created conditional expression
*/
public static ref ConditionalExpression! new (Expression! cond, Expression! true_expr, Expression! false_expr, SourceReference source) {
return (new ConditionalExpression (condition = cond, true_expression = true_expr, false_expression = false_expr, source_reference = source));
}
public override void accept (CodeVisitor! visitor) {
condition.accept (visitor);
true_expression.accept (visitor);
false_expression.accept (visitor);
visitor.visit_conditional_expression (this);
}
visitor.visit_conditional_expression (this);
}
}
......@@ -22,37 +22,63 @@
using GLib;
namespace Vala {
public class Constant : CodeNode {
public string name { get; construct; }
public TypeReference type_reference { get; construct; }
public Expression initializer { get; construct; }
public SourceReference source_reference { get; construct; }
public static ref Constant new (string name, TypeReference type, Expression init, SourceReference source) {
return (new Constant (name = name, type_reference = type, initializer = init, source_reference = source));
}
public override void accept (CodeVisitor visitor) {
type_reference.accept (visitor);
initializer.accept (visitor);
/**
* Represents a type member with a constant value.
*/
public class Vala.Constant : CodeNode {
/**
* The symbol name of this constant.
*/
public string! name { get; set construct; }
visitor.visit_constant (this);
}
/**
* The data type of this constant.
*/
public TypeReference! type_reference { get; set construct; }
/**
* The value of this constant.
*/
public Expression! initializer { get; set construct; }
private string cname;
/**
* Creates a new constant.
*
* @param name constant name
* @param type constant type
* @param init constant value
* @param source reference to source code
* @return newly created constant
*/
public static ref Constant! new (string! name, TypeReference! type, Expression! init, SourceReference source) {
return (new Constant (name = name, type_reference = type, initializer = init, source_reference = source));
}
public override void accept (CodeVisitor visitor) {
type_reference.accept (visitor);
string cname;
public string get_cname () {
if (cname == null) {
if (symbol.parent_symbol.node is DataType) {
var t = (DataType) symbol.parent_symbol.node;
cname = "%s_%s".printf (t.get_upper_case_cname (null), name);
} else {
var ns = (Namespace) symbol.parent_symbol.node;
cname = "%s%s".printf (ns.get_cprefix ().up (), name);
}
initializer.accept (visitor);
visitor.visit_constant (this);
}
/**
* Returns the name of this constant as it is used in C code.
*
* @return the name to be used in C code
*/
public string! get_cname () {
if (cname == null) {
if (symbol.parent_symbol.node is DataType) {
var t = (DataType) symbol.parent_symbol.node;
cname = "%s_%s".printf (t.get_upper_case_cname (null), name);
} else {
var ns = (Namespace) symbol.parent_symbol.node;
cname = "%s%s".printf (ns.get_cprefix ().up (), name);