Commit 30063af8 authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter

Move attribute processing to semantic analyzer

2008-11-02  Jürg Billeter  <j@bitron.ch>

	* vala/Makefile.am:
	* vala/valaattributeprocessor.vala:
	* vala/valaclass.vala:
	* vala/valaenum.vala:
	* vala/valasemanticanalyzer.vala:
	* vala/valastruct.vala:
	* compiler/valacompiler.vala:
	* vapigen/valagidlparser.vala:
	* vapigen/valavapigen.vala:

	Move attribute processing to semantic analyzer

svn path=/trunk/; revision=1950
parent abd1d899
2008-11-02 Jürg Billeter <j@bitron.ch>
* vala/Makefile.am:
* vala/valaattributeprocessor.vala:
* vala/valaclass.vala:
* vala/valaenum.vala:
* vala/valasemanticanalyzer.vala:
* vala/valastruct.vala:
* compiler/valacompiler.vala:
* vapigen/valagidlparser.vala:
* vapigen/valavapigen.vala:
Move attribute processing to semantic analyzer
2008-11-01 Jürg Billeter <j@bitron.ch>
* vala/valamethod.vala:
......
......@@ -239,13 +239,6 @@ class Vala.Compiler {
return quit ();
}
var attributeprocessor = new AttributeProcessor ();
attributeprocessor.process (context);
if (Report.get_errors () > 0) {
return quit ();
}
var resolver = new SymbolResolver ();
resolver.resolve (context);
......
......@@ -22,7 +22,6 @@ libvalacore_la_VALASOURCES = \
valaarraytype.vala \
valaassignment.vala \
valaattribute.vala \
valaattributeprocessor.vala \
valabaseaccess.vala \
valabasicblock.vala \
valabinaryexpression.vala \
......
/* valaattributeprocessor.vala
*
* Copyright (C) 2006-2008 Jürg Billeter, Raffaele Sandrini
*
* 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>
* Raffaele Sandrini <raffaele@sandrini.ch>
*/
using GLib;
/**
* Code visitor processing attributes associated with code nodes.
*/
public class Vala.AttributeProcessor : CodeVisitor {
/**
* Process all attributes found in specified code context.
*
* @param context a code context
*/
public void process (CodeContext context) {
context.accept (this);
}
public override void visit_source_file (SourceFile source_file) {
source_file.accept_children (this);
}
public override void visit_namespace (Namespace ns) {
ns.process_attributes ();
foreach (Namespace ns in ns.get_namespaces ()) {
ns.accept (this);
}
}
public override void visit_class (Class cl) {
cl.process_attributes ();
cl.accept_children (this);
}
public override void visit_struct (Struct st) {
st.process_attributes ();
st.accept_children (this);
}
public override void visit_interface (Interface iface) {
iface.process_attributes ();
iface.accept_children (this);
}
public override void visit_enum (Enum en) {
en.process_attributes ();
en.accept_children (this);
}
public override void visit_enum_value (EnumValue ev) {
ev.process_attributes ();
}
public override void visit_error_domain (ErrorDomain edomain) {
edomain.process_attributes ();
}
public override void visit_method (Method m) {
m.process_attributes ();
m.accept_children (this);
}
public override void visit_creation_method (CreationMethod m) {
m.process_attributes ();
m.accept_children (this);
}
public override void visit_formal_parameter (FormalParameter p) {
p.process_attributes ();
}
public override void visit_property (Property prop) {
prop.process_attributes ();
prop.accept_children (this);
}
public override void visit_property_accessor (PropertyAccessor p) {
p.process_attributes ();
}
public override void visit_delegate (Delegate d) {
d.process_attributes ();
d.accept_children (this);
}
public override void visit_constant (Constant c) {
c.process_attributes ();
}
public override void visit_field (Field f) {
f.process_attributes ();
}
public override void visit_signal (Signal sig) {
sig.process_attributes ();
sig.accept_children (this);
}
}
......@@ -197,7 +197,11 @@ public class Vala.Class : ObjectTypeSymbol {
/**
* Specifies whether this class denotes an error base.
*/
public bool is_error_base { get; set ; }
public bool is_error_base {
get {
return get_attribute ("ErrorBase") != null;
}
}
Destructor? _destructor;
......@@ -507,7 +511,13 @@ public class Vala.Class : ObjectTypeSymbol {
}
if (cname == null) {
cname = get_default_cname ();
var attr = get_attribute ("CCode");
if (attr != null) {
cname = attr.get_string ("cname");
}
if (cname == null) {
cname = get_default_cname ();
}
}
return cname;
}
......@@ -599,9 +609,6 @@ public class Vala.Class : ObjectTypeSymbol {
set_value_function = a.get_string ("set_value_function");
}
if (a.has_argument ("cname")) {
set_cname (a.get_string ("cname"));
}
if (a.has_argument ("const_cname")) {
const_cname = a.get_string ("const_cname");
}
......@@ -636,8 +643,6 @@ public class Vala.Class : ObjectTypeSymbol {
foreach (Attribute a in attributes) {
if (a.name == "CCode") {
process_ccode_attribute (a);
} else if (a.name == "ErrorBase") {
is_error_base = true;
} else if (a.name == "Compact") {
is_compact = true;
} else if (a.name == "Immutable") {
......
......@@ -121,7 +121,13 @@ public class Vala.Enum : TypeSymbol {
public override string get_cname (bool const_type = false) {
if (cname == null) {
cname = "%s%s".printf (parent_symbol.get_cprefix (), name);
var attr = get_attribute ("CCode");
if (attr != null) {
cname = attr.get_string ("cname");
}
if (cname == null) {
cname = "%s%s".printf (parent_symbol.get_cprefix (), name);
}
}
return cname;
}
......@@ -183,9 +189,6 @@ public class Vala.Enum : TypeSymbol {
}
private void process_ccode_attribute (Attribute a) {
if (a.has_argument ("cname")) {
set_cname (a.get_string ("cname"));
}
if (a.has_argument ("cprefix")) {
set_cprefix (a.get_string ("cprefix"));
}
......
......@@ -138,7 +138,13 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
current_using_directives = null;
}
public override void visit_namespace (Namespace ns) {
ns.process_attributes ();
}
public override void visit_class (Class cl) {
cl.process_attributes ();
current_symbol = cl;
current_class = cl;
......@@ -313,12 +319,14 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
}
public override void visit_struct (Struct st) {
st.process_attributes ();
current_symbol = st;
current_struct = st;
st.accept_children (this);
if (!st.external && st.get_base_types ().size == 0 && st.get_fields ().size == 0) {
if (!st.external && !st.external_package && st.get_base_types ().size == 0 && st.get_fields ().size == 0) {
Report.error (st.source_reference, "structs cannot be empty");
}
......@@ -327,6 +335,8 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
}
public override void visit_interface (Interface iface) {
iface.process_attributes ();
current_symbol = iface;
foreach (DataType prerequisite_reference in iface.get_prerequisites ()) {
......@@ -367,22 +377,32 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
}
public override void visit_enum (Enum en) {
en.process_attributes ();
en.accept_children (this);
}
public override void visit_enum_value (EnumValue ev) {
ev.process_attributes ();
ev.accept_children (this);
}
public override void visit_error_domain (ErrorDomain ed) {
ed.process_attributes ();
ed.accept_children (this);
}
public override void visit_delegate (Delegate d) {
d.process_attributes ();
d.accept_children (this);
}
public override void visit_constant (Constant c) {
c.process_attributes ();
c.type_reference.accept (this);
if (!c.external_package) {
......@@ -398,6 +418,8 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
}
public override void visit_field (Field f) {
f.process_attributes ();
if (f.initializer != null) {
f.initializer.target_type = f.field_type;
}
......@@ -428,6 +450,8 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
}
public override void visit_method (Method m) {
m.process_attributes ();
if (m.is_abstract) {
if (m.parent_symbol is Class) {
var cl = (Class) m.parent_symbol;
......@@ -467,7 +491,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
Report.error (m.source_reference, "Abstract methods cannot have bodies");
} else if (m.external && m.body != null) {
Report.error (m.source_reference, "Extern methods cannot have bodies");
} else if (!m.is_abstract && !m.external && m.body == null) {
} else if (!m.is_abstract && !m.external && !m.external_package && m.body == null) {
Report.error (m.source_reference, "Non-abstract, non-extern methods must have bodies");
}
......@@ -566,6 +590,8 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
}
public override void visit_creation_method (CreationMethod m) {
m.process_attributes ();
if (m.type_name != null && m.type_name != current_symbol.name) {
// type_name is null for constructors generated by GIdlParser
Report.error (m.source_reference, "missing return type in method `%s.%s´".printf (current_symbol.get_full_name (), m.type_name));
......@@ -594,6 +620,8 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
}
public override void visit_formal_parameter (FormalParameter p) {
p.process_attributes ();
p.check (this);
}
......@@ -612,10 +640,14 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
}
public override void visit_property (Property prop) {
prop.process_attributes ();
prop.check (this);
}
public override void visit_property_accessor (PropertyAccessor acc) {
acc.process_attributes ();
var old_return_type = current_return_type;
if (acc.readable) {
current_return_type = acc.prop.property_type;
......@@ -657,6 +689,8 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
}
public override void visit_signal (Signal sig) {
sig.process_attributes ();
sig.accept_children (this);
}
......
......@@ -48,7 +48,6 @@ public class Vala.Struct : TypeSymbol {
private string get_value_function;
private string set_value_function;
private string default_value = null;
private bool simple_type;
private string? type_signature;
private string copy_function;
private string destroy_function;
......@@ -203,7 +202,13 @@ public class Vala.Struct : TypeSymbol {
}
if (cname == null) {
cname = get_default_cname ();
var attr = get_attribute ("CCode");
if (attr != null) {
cname = attr.get_string ("cname");
}
if (cname == null) {
cname = get_default_cname ();
}
}
return cname;
}
......@@ -305,9 +310,6 @@ public class Vala.Struct : TypeSymbol {
}
private void process_ccode_attribute (Attribute a) {
if (a.has_argument ("cname")) {
set_cname (a.get_string ("cname"));
}
if (a.has_argument ("const_cname")) {
set_const_cname (a.get_string ("const_cname"));
}
......@@ -367,8 +369,6 @@ public class Vala.Struct : TypeSymbol {
foreach (Attribute a in attributes) {
if (a.name == "CCode") {
process_ccode_attribute (a);
} else if (a.name == "SimpleType") {
simple_type = true;
} else if (a.name == "IntegerType") {
process_integer_type_attribute (a);
} else if (a.name == "FloatingType") {
......@@ -385,7 +385,7 @@ public class Vala.Struct : TypeSymbol {
return st.get_type_id ();;
}
}
if (simple_type) {
if (is_simple_type ()) {
Report.error (source_reference, "The type `%s` doesn't declare a type id".printf (get_full_name ()));
} else {
return "G_TYPE_POINTER";
......@@ -406,7 +406,7 @@ public class Vala.Struct : TypeSymbol {
return st.get_marshaller_type_name ();
}
}
if (simple_type) {
if (is_simple_type ()) {
Report.error (source_reference, "The type `%s` doesn't declare a marshaller type name".printf (get_full_name ()));
} else {
return "POINTER";
......@@ -427,7 +427,7 @@ public class Vala.Struct : TypeSymbol {
return st.get_get_value_function ();
}
}
if (simple_type) {
if (is_simple_type ()) {
Report.error (source_reference, "The value type `%s` doesn't declare a GValue get function".printf (get_full_name ()));
return null;
} else {
......@@ -446,7 +446,7 @@ public class Vala.Struct : TypeSymbol {
return st.get_set_value_function ();
}
}
if (simple_type) {
if (is_simple_type ()) {
Report.error (source_reference, "The value type `%s` doesn't declare a GValue set function".printf (get_full_name ()));
return null;
} else {
......@@ -527,7 +527,7 @@ public class Vala.Struct : TypeSymbol {
return true;
}
}
return simple_type;
return get_attribute ("SimpleType") != null;
}
/**
......@@ -535,7 +535,7 @@ public class Vala.Struct : TypeSymbol {
* value.
*/
public void set_simple_type (bool simple_type) {
this.simple_type = simple_type;
attributes.append (new Attribute ("SimpleType"));
}
public override void replace_type (DataType old_type, DataType new_type) {
......
......@@ -198,6 +198,7 @@ public class Vala.GIdlParser : CodeVisitor {
if (sym is Namespace) {
ns = (Namespace) sym;
if (ns.external_package) {
ns.attributes = null;
ns.source_reference = current_source_reference;
}
} else {
......@@ -817,7 +818,7 @@ public class Vala.GIdlParser : CodeVisitor {
}
if (is_errordomain) {
var ed = new ErrorDomain (en.name);
var ed = new ErrorDomain (en.name, current_source_reference);
ed.access = SymbolAccessibility.PUBLIC;
ed.set_cprefix (common_prefix);
......
......@@ -137,7 +137,7 @@ class Vala.VAPIGen : Object {
foreach (string source in sources) {
if (FileUtils.test (source, FileTest.EXISTS)) {
context.add_source_file (new SourceFile (context, source));
context.add_source_file (new SourceFile (context, source, true));
} else {
Report.error (null, "%s not found".printf (source));
}
......@@ -155,13 +155,6 @@ class Vala.VAPIGen : Object {
return quit ();
}
var attributeprocessor = new AttributeProcessor ();
attributeprocessor.process (context);
if (Report.get_errors () > 0) {
return quit ();
}
var girparser = new GirParser ();
if (metadata_filename != null) {
girparser.parse_metadata (metadata_filename);
......@@ -182,11 +175,25 @@ class Vala.VAPIGen : Object {
var resolver = new SymbolResolver ();
resolver.resolve (context);
if (Report.get_errors () > 0) {
return quit ();
}
var analyzer = new SemanticAnalyzer ();
analyzer.analyze (context);
if (Report.get_errors () > 0) {
return quit ();
}
if (library != null) {
// interface writer ignores external packages
foreach (SourceFile file in context.get_source_files ()) {
if (!file.filename.has_suffix (".vapi")) {
file.external_package = false;
}
}
var interface_writer = new InterfaceWriter ();
interface_writer.write_file (context, "%s.vapi".printf (library));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment