[vala] GENIE: Updated genie to include fixes from vala parser
- From: Jamie McCracken <jamiemcc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala] GENIE: Updated genie to include fixes from vala parser
- Date: Sat, 15 Sep 2012 16:58:20 +0000 (UTC)
commit 1607046ae82c1b71817dd4bf03fd203cd246fdb1
Author: Jamie McCracken <jamie mccrack gmail com>
Date: Sat Sep 15 12:57:48 2012 -0400
GENIE: Updated genie to include fixes from vala parser
vala/valagenieparser.vala | 368 +++++++++++++++++++++++++-----------------
vala/valageniescanner.vala | 91 +++++++----
vala/valagenietokentype.vala | 10 +-
3 files changed, 280 insertions(+), 189 deletions(-)
---
diff --git a/vala/valagenieparser.vala b/vala/valagenieparser.vala
index 77fbd1c..d4d9d3f 100644
--- a/vala/valagenieparser.vala
+++ b/vala/valagenieparser.vala
@@ -1,6 +1,6 @@
/* valagenieparser.vala
*
- * Copyright (C) 2008 Jamie McCracken, JÃrg Billeter
+ * Copyright (C) 2008-2012 Jamie McCracken, JÃrg Billeter
* Based on code by JÃrg Billeter
*
* This library is free software; you can redistribute it and/or
@@ -67,7 +67,8 @@ public class Vala.Genie.Parser : CodeVisitor {
STATIC = 1 << 6,
VIRTUAL = 1 << 7,
PRIVATE = 1 << 8,
- ASYNC = 1 << 9
+ ASYNC = 1 << 9,
+ SEALED = 1 << 10
}
public Parser () {
@@ -281,6 +282,7 @@ public class Vala.Genie.Parser : CodeVisitor {
case TokenType.REF:
case TokenType.REQUIRES:
case TokenType.RETURN:
+ case TokenType.SEALED:
case TokenType.SET:
case TokenType.SIZEOF:
case TokenType.STATIC:
@@ -426,21 +428,23 @@ public class Vala.Genie.Parser : CodeVisitor {
}
void skip_type () throws ParseError {
- if (accept (TokenType.VOID)) {
- while (accept (TokenType.STAR)) {
- }
- return;
- }
+
accept (TokenType.DYNAMIC);
accept (TokenType.OWNED);
accept (TokenType.UNOWNED);
accept (TokenType.WEAK);
+
+
if (accept (TokenType.ARRAY) || accept (TokenType.LIST) || accept (TokenType.DICT)) {
accept (TokenType.OF);
}
- skip_symbol_name ();
- skip_type_argument_list ();
+ if (accept (TokenType.VOID)) {
+ } else {
+ skip_symbol_name ();
+ skip_type_argument_list ();
+ }
+
while (accept (TokenType.OPEN_BRACKET)) {
do {
if (current () != TokenType.COMMA && current () != TokenType.CLOSE_BRACKET) {
@@ -463,25 +467,22 @@ public class Vala.Genie.Parser : CodeVisitor {
return expr;
}
- DataType parse_type (bool owned_by_default = true) throws ParseError {
+ DataType parse_type (bool owned_by_default, bool can_weak_ref) throws ParseError {
var begin = get_location ();
- if (accept (TokenType.VOID)) {
- DataType type = new VoidType ();
- while (accept (TokenType.STAR)) {
- type = new PointerType (type);
- }
- return type;
- }
-
List<DataType> type_arg_list = null;
UnresolvedSymbol sym = null;
bool is_dynamic = accept (TokenType.DYNAMIC);
bool value_owned = owned_by_default;
+
if (owned_by_default) {
- if (accept (TokenType.UNOWNED)
- || accept (TokenType.WEAK)) {
+ if (accept (TokenType.UNOWNED)) {
+ value_owned = false;
+ } else if (accept (TokenType.WEAK)) {
+ if (!can_weak_ref && !context.deprecated) {
+ Report.warning (get_src (begin), "deprecated syntax, use `unowned` modifier");
+ }
value_owned = false;
}
} else {
@@ -514,25 +515,32 @@ public class Vala.Genie.Parser : CodeVisitor {
is_dict = true;
}
- if (is_list) {
- var sym_parent = new UnresolvedSymbol (null, "Gee", get_src (begin));
- sym = new UnresolvedSymbol (sym_parent, "ArrayList", get_src (begin));
- } else if (is_dict) {
- var sym_parent = new UnresolvedSymbol (null, "Gee", get_src (begin));
- sym = new UnresolvedSymbol (sym_parent, "HashMap", get_src (begin));
- } else {
- sym = parse_symbol_name ();
- }
+ DataType type;
- type_arg_list = parse_type_argument_list (false);
+ if (!is_dynamic && value_owned == owned_by_default && accept (TokenType.VOID)) {
+ type = new VoidType (get_src (begin));
+ } else {
+
+ if (is_list) {
+ var sym_parent = new UnresolvedSymbol (null, "Gee", get_src (begin));
+ sym = new UnresolvedSymbol (sym_parent, "ArrayList", get_src (begin));
+ } else if (is_dict) {
+ var sym_parent = new UnresolvedSymbol (null, "Gee", get_src (begin));
+ sym = new UnresolvedSymbol (sym_parent, "HashMap", get_src (begin));
+ } else {
+ sym = parse_symbol_name ();
+ }
+
+ type_arg_list = parse_type_argument_list (false);
- DataType type = new UnresolvedType.from_symbol (sym, get_src (begin));
- if (type_arg_list != null) {
- foreach (DataType type_arg in type_arg_list) {
- type.add_type_argument (type_arg);
+ type = new UnresolvedType.from_symbol (sym, get_src (begin));
+ if (type_arg_list != null) {
+ foreach (DataType type_arg in type_arg_list) {
+ type.add_type_argument (type_arg);
+ }
}
}
-
+
while (accept (TokenType.STAR)) {
type = new PointerType (type, get_src (begin));
}
@@ -562,8 +570,7 @@ public class Vala.Genie.Parser : CodeVisitor {
// only used for parsing, reject use as real type
invalid_array = true;
}
- }
- while (accept (TokenType.COMMA));
+ } while (accept (TokenType.COMMA));
expect (TokenType.CLOSE_BRACKET);
type.value_owned = true;
@@ -581,6 +588,10 @@ public class Vala.Genie.Parser : CodeVisitor {
value_owned = accept (TokenType.HASH);
}
+ if (type is PointerType) {
+ value_owned = false;
+ }
+
type.is_dynamic = is_dynamic;
type.value_owned = value_owned;
return type;
@@ -903,6 +914,7 @@ public class Vala.Genie.Parser : CodeVisitor {
expect (TokenType.OPEN_PARENS);
var arg_list = parse_argument_list ();
expect (TokenType.CLOSE_PARENS);
+
var init_list = parse_object_initializer ();
if (init_list.size > 0 && inner is MemberAccess) {
@@ -985,23 +997,23 @@ public class Vala.Genie.Parser : CodeVisitor {
if (accept (TokenType.ARRAY)) {
expect (TokenType.OF);
- var mtype = parse_type ();
+ var mtype = parse_type (true, false);
var expr = parse_array_creation_expression (begin, mtype);
return expr;
}
if (accept (TokenType.LIST)) {
expect (TokenType.OF);
- var mtype = parse_type ();
+ var mtype = parse_type (true, false);
var expr = parse_list_creation_expression (begin, mtype);
return expr;
}
if (accept (TokenType.DICT)) {
expect (TokenType.OF);
- var mtype1 = parse_type ();
+ var mtype1 = parse_type (true, false);
expect (TokenType.COMMA);
- var mtype2 = parse_type ();
+ var mtype2 = parse_type (true, false);
var expr = parse_dict_creation_expression (begin, mtype1, mtype2);
return expr;
}
@@ -1138,24 +1150,31 @@ public class Vala.Genie.Parser : CodeVisitor {
}
Expression parse_yield_expression () throws ParseError {
- var begin = get_location ();
expect (TokenType.YIELD);
- Expression base_expr = null;
- if (current () == TokenType.SUPER) {
- base_expr = parse_base_access ();
- expect (TokenType.DOT);
+
+ var expr = parse_expression ();
+
+ var call = expr as MethodCall;
+ var object_creation = expr as ObjectCreationExpression;
+ if (call == null && object_creation == null) {
+ Report.error (expr.source_reference, "syntax error, expected method call");
+ throw new ParseError.SYNTAX ("expected method call");
+ }
+
+ if (call != null) {
+ call.is_yield_expression = true;
+ } else if (object_creation != null) {
+ object_creation.is_yield_expression = true;
}
- var member = parse_member_name (base_expr);
- var call = (MethodCall) parse_method_call (begin, member);
- call.is_yield_expression = true;
- return call;
+
+ return expr;
}
Expression parse_sizeof_expression () throws ParseError {
var begin = get_location ();
expect (TokenType.SIZEOF);
expect (TokenType.OPEN_PARENS);
- var type = parse_type ();
+ var type = parse_type (true, false);
expect (TokenType.CLOSE_PARENS);
return new SizeofExpression (type, get_src (begin));
@@ -1165,7 +1184,7 @@ public class Vala.Genie.Parser : CodeVisitor {
var begin = get_location ();
expect (TokenType.TYPEOF);
expect (TokenType.OPEN_PARENS);
- var type = parse_type ();
+ var type = parse_type (true, false);
expect (TokenType.CLOSE_PARENS);
return new TypeofExpression (type, get_src (begin));
@@ -1179,7 +1198,7 @@ public class Vala.Genie.Parser : CodeVisitor {
case TokenType.TILDE: return UnaryOperator.BITWISE_COMPLEMENT;
case TokenType.OP_INC: return UnaryOperator.INCREMENT;
case TokenType.OP_DEC: return UnaryOperator.DECREMENT;
- default: return UnaryOperator.NONE;
+ default: return UnaryOperator.NONE;
}
}
@@ -1193,6 +1212,9 @@ public class Vala.Genie.Parser : CodeVisitor {
}
switch (current ()) {
case TokenType.HASH:
+ if (!context.deprecated) {
+ Report.warning (get_src (begin), "deprecated syntax, use `(owned)` cast");
+ }
next ();
var op = parse_unary_expression ();
return new ReferenceTransferExpression (op, get_src (begin));
@@ -1213,7 +1235,7 @@ public class Vala.Genie.Parser : CodeVisitor {
case TokenType.ARRAY:
case TokenType.LIST:
case TokenType.DICT:
- var type = parse_type ();
+ var type = parse_type (true, false);
if (accept (TokenType.CLOSE_PARENS)) {
// check follower to decide whether to create cast expression
switch (current ()) {
@@ -1237,6 +1259,7 @@ public class Vala.Genie.Parser : CodeVisitor {
case TokenType.TYPEOF:
case TokenType.IDENTIFIER:
case TokenType.PARAMS:
+ case TokenType.YIELD:
var inner = parse_unary_expression ();
return new CastExpression (inner, type, get_src (begin), false);
default:
@@ -1277,10 +1300,10 @@ public class Vala.Genie.Parser : CodeVisitor {
BinaryOperator get_binary_operator (TokenType token_type) {
switch (token_type) {
- case TokenType.STAR: return BinaryOperator.MUL;
- case TokenType.DIV: return BinaryOperator.DIV;
+ case TokenType.STAR: return BinaryOperator.MUL;
+ case TokenType.DIV: return BinaryOperator.DIV;
case TokenType.PERCENT: return BinaryOperator.MOD;
- case TokenType.PLUS: return BinaryOperator.PLUS;
+ case TokenType.PLUS: return BinaryOperator.PLUS;
case TokenType.MINUS: return BinaryOperator.MINUS;
case TokenType.OP_LT: return BinaryOperator.LESS_THAN;
case TokenType.OP_GT: return BinaryOperator.GREATER_THAN;
@@ -1296,7 +1319,7 @@ public class Vala.Genie.Parser : CodeVisitor {
prev ();
return BinaryOperator.EQUALITY;
case TokenType.OP_NE: return BinaryOperator.INEQUALITY;
- default: return BinaryOperator.NONE;
+ default: return BinaryOperator.NONE;
}
}
@@ -1405,12 +1428,12 @@ public class Vala.Genie.Parser : CodeVisitor {
switch (current ()) {
case TokenType.ISA:
next ();
- var type = parse_type ();
+ var type = parse_type (true, false);
left = new TypeCheck (left, type, get_src (begin));
break;
case TokenType.AS:
next ();
- var type = parse_type ();
+ var type = parse_type (true, false);
left = new CastExpression (left, type, get_src (begin), true);
break;
default:
@@ -1520,6 +1543,22 @@ public class Vala.Genie.Parser : CodeVisitor {
}
}
+ Parameter parse_lambda_parameter () throws ParseError {
+ var begin = get_location ();
+ var direction = ParameterDirection.IN;
+ if (accept (TokenType.OUT)) {
+ direction = ParameterDirection.OUT;
+ } else if (accept (TokenType.REF)) {
+ direction = ParameterDirection.REF;
+ }
+
+ string id = parse_identifier ();
+
+ var param = new Parameter (id, null, get_src (begin));
+ param.direction = direction;
+ return param;
+ }
+
Expression parse_lambda_expression () throws ParseError {
var begin = get_location ();
List<Parameter> params = new ArrayList<Parameter> ();
@@ -1529,18 +1568,16 @@ public class Vala.Genie.Parser : CodeVisitor {
if (accept (TokenType.OPEN_PARENS)) {
if (current () != TokenType.CLOSE_PARENS) {
do {
- var param = new Parameter (parse_identifier (), null, get_src (get_location ()));
- params.add (param);
+ params.add (parse_lambda_parameter ());
} while (accept (TokenType.COMMA));
}
expect (TokenType.CLOSE_PARENS);
} else {
- var param = new Parameter (parse_identifier (), null, get_src (get_location ()));
- params.add (param);
+ params.add (parse_lambda_parameter ());
}
-
LambdaExpression lambda;
+
if (accept_block ()) {
var block = parse_block ();
lambda = new LambdaExpression.with_statement_body (block, get_src (begin));
@@ -1560,17 +1597,17 @@ public class Vala.Genie.Parser : CodeVisitor {
AssignmentOperator get_assignment_operator (TokenType token_type) {
switch (token_type) {
- case TokenType.ASSIGN: return AssignmentOperator.SIMPLE;
- case TokenType.ASSIGN_ADD: return AssignmentOperator.ADD;
- case TokenType.ASSIGN_SUB: return AssignmentOperator.SUB;
- case TokenType.ASSIGN_BITWISE_OR: return AssignmentOperator.BITWISE_OR;
- case TokenType.ASSIGN_BITWISE_AND: return AssignmentOperator.BITWISE_AND;
- case TokenType.ASSIGN_BITWISE_XOR: return AssignmentOperator.BITWISE_XOR;
- case TokenType.ASSIGN_DIV: return AssignmentOperator.DIV;
- case TokenType.ASSIGN_MUL: return AssignmentOperator.MUL;
- case TokenType.ASSIGN_PERCENT: return AssignmentOperator.PERCENT;
- case TokenType.ASSIGN_SHIFT_LEFT: return AssignmentOperator.SHIFT_LEFT;
- default: return AssignmentOperator.NONE;
+ case TokenType.ASSIGN: return AssignmentOperator.SIMPLE;
+ case TokenType.ASSIGN_ADD: return AssignmentOperator.ADD;
+ case TokenType.ASSIGN_SUB: return AssignmentOperator.SUB;
+ case TokenType.ASSIGN_BITWISE_OR: return AssignmentOperator.BITWISE_OR;
+ case TokenType.ASSIGN_BITWISE_AND: return AssignmentOperator.BITWISE_AND;
+ case TokenType.ASSIGN_BITWISE_XOR: return AssignmentOperator.BITWISE_XOR;
+ case TokenType.ASSIGN_DIV: return AssignmentOperator.DIV;
+ case TokenType.ASSIGN_MUL: return AssignmentOperator.MUL;
+ case TokenType.ASSIGN_PERCENT: return AssignmentOperator.PERCENT;
+ case TokenType.ASSIGN_SHIFT_LEFT: return AssignmentOperator.SHIFT_LEFT;
+ default: return AssignmentOperator.NONE;
}
}
@@ -1579,6 +1616,8 @@ public class Vala.Genie.Parser : CodeVisitor {
var lambda = parse_lambda_expression ();
current_expr_is_lambda = true;
return lambda;
+ } else {
+ current_expr_is_lambda = false;
}
var begin = get_location ();
@@ -1636,8 +1675,8 @@ public class Vala.Genie.Parser : CodeVisitor {
void parse_statements (Block block) throws ParseError {
while (current () != TokenType.DEDENT
- && current () != TokenType.WHEN
- && current () != TokenType.DEFAULT) {
+ && current () != TokenType.WHEN
+ && current () != TokenType.DEFAULT) {
try {
Statement stmt = null;
bool is_decl = false;
@@ -1810,20 +1849,36 @@ public class Vala.Genie.Parser : CodeVisitor {
switch (current ()) {
case TokenType.PASS:
case TokenType.SEMICOLON: return parse_empty_statement ();
- case TokenType.IF: return parse_if_statement ();
- case TokenType.CASE: return parse_switch_statement ();
- case TokenType.WHILE: return parse_while_statement ();
- case TokenType.DO: return parse_do_statement ();
- case TokenType.FOR: return get_for_statement_type ();
- case TokenType.BREAK: return parse_break_statement ();
+ case TokenType.IF: return parse_if_statement ();
+ case TokenType.CASE: return parse_switch_statement ();
+ case TokenType.WHILE: return parse_while_statement ();
+ case TokenType.DO: return parse_do_statement ();
+ case TokenType.FOR: return get_for_statement_type ();
+ case TokenType.BREAK: return parse_break_statement ();
case TokenType.CONTINUE: return parse_continue_statement ();
- case TokenType.RETURN: return parse_return_statement ();
- case TokenType.YIELD: return parse_yield_statement ();
- case TokenType.RAISE: return parse_throw_statement ();
- case TokenType.TRY: return parse_try_statement ();
- case TokenType.LOCK: return parse_lock_statement ();
- case TokenType.DELETE: return parse_delete_statement ();
- default: return parse_expression_statement ();
+ case TokenType.RETURN: return parse_return_statement ();
+ case TokenType.YIELD: return parse_yield_statement ();
+ case TokenType.RAISE: return parse_throw_statement ();
+ case TokenType.TRY: return parse_try_statement ();
+ case TokenType.LOCK: return parse_lock_statement ();
+ case TokenType.DELETE: return parse_delete_statement ();
+ case TokenType.VAR:
+ case TokenType.CONST:
+ throw new ParseError.SYNTAX (get_error ("embedded statement cannot be declaration "));
+ case TokenType.OP_INC:
+ case TokenType.OP_DEC:
+ case TokenType.SUPER:
+ case TokenType.THIS:
+ case TokenType.OPEN_PARENS:
+ case TokenType.STAR:
+ case TokenType.NEW:
+ return parse_expression_statement ();
+ default:
+ if (is_expression ()) {
+ return parse_expression_statement ();
+ } else {
+ throw new ParseError.SYNTAX (get_error ("embedded statement cannot be declaration"));
+ }
}
}
@@ -1890,7 +1945,7 @@ public class Vala.Genie.Parser : CodeVisitor {
expect (TokenType.COLON);
- variable_type = parse_type ();
+ variable_type = parse_type (true, true);
var type = parse_inline_array_type (variable_type);
foreach (string id in id_list) {
@@ -2067,7 +2122,7 @@ public class Vala.Genie.Parser : CodeVisitor {
} else {
id = parse_identifier ();
expect (TokenType.COLON);
- variable_type = parse_type ();
+ variable_type = parse_type (true, true);
}
DataType type_copy = null;
@@ -2137,7 +2192,7 @@ public class Vala.Genie.Parser : CodeVisitor {
} else {
id = parse_identifier ();
if (accept (TokenType.COLON)) {
- type = parse_type ();
+ type = parse_type (true, true);
}
}
@@ -2229,7 +2284,7 @@ public class Vala.Genie.Parser : CodeVisitor {
if (!accept (TokenType.EOL)) {
id = parse_identifier ();
expect (TokenType.COLON);
- type = parse_type ();
+ type = parse_type (true, true);
expect (TokenType.EOL);
}
@@ -2320,6 +2375,9 @@ public class Vala.Genie.Parser : CodeVisitor {
void set_attributes (CodeNode node, List<Attribute>? attributes) {
if (attributes != null) {
foreach (Attribute attr in (List<Attribute>) attributes) {
+ if (node.get_attribute (attr.name) != null) {
+ Report.error (attr.source_reference, "duplicate attribute `%s`".printf (attr.name));
+ }
node.attributes.append (attr);
}
}
@@ -2572,12 +2630,12 @@ public class Vala.Genie.Parser : CodeVisitor {
var type_param_list = parse_type_parameter_list ();
var base_types = new ArrayList<DataType> ();
if (accept (TokenType.COLON)) {
- var type1 = parse_type ();
+ var type1 = parse_type (true, false);
base_types.add (type1);
if (accept (TokenType.IMPLEMENTS)) {
do {
- var type2 = parse_type ();
+ var type2 = parse_type (true, true);
base_types.add (type2);
} while (accept (TokenType.COMMA));
}
@@ -2615,7 +2673,7 @@ public class Vala.Genie.Parser : CodeVisitor {
// ensure there is always a default construction method
if (scanner.source_file.file_type == SourceFileType.SOURCE
- && cl.default_construction_method == null) {
+ && cl.default_construction_method == null) {
var m = new CreationMethod (cl.name, null, cl.source_reference);
m.access = SymbolAccessibility.PUBLIC;
m.body = new Block (cl.source_reference);
@@ -2709,7 +2767,7 @@ public class Vala.Genie.Parser : CodeVisitor {
string id = parse_identifier ();
expect (TokenType.COLON);
- var type = parse_type (false);
+ var type = parse_type (false, false);
type = parse_inline_array_type (type);
Expression initializer = null;
@@ -2745,7 +2803,7 @@ public class Vala.Genie.Parser : CodeVisitor {
var flags = parse_member_declaration_modifiers ();
- var type = parse_type ();
+ var type = parse_type (true, true);
type = parse_inline_array_type (type);
@@ -2753,7 +2811,7 @@ public class Vala.Genie.Parser : CodeVisitor {
if (ModifierFlags.ABSTRACT in flags || ModifierFlags.VIRTUAL in flags || ModifierFlags.OVERRIDE in flags) {
Report.error (f.source_reference, "abstract, virtual, and override modifiers are not applicable to fields");
- }
+ }
if (ModifierFlags.PRIVATE in flags) {
f.access = SymbolAccessibility.PRIVATE;
@@ -2861,7 +2919,7 @@ public class Vala.Genie.Parser : CodeVisitor {
/* deal with return value */
if (accept (TokenType.COLON)) {
- type = parse_type ();
+ type = parse_type (true, false);
}
var type_param_list = parse_type_parameter_list ();
@@ -2887,7 +2945,7 @@ public class Vala.Genie.Parser : CodeVisitor {
if (accept (TokenType.RAISES)) {
do {
- method.add_error_type (parse_type ());
+ method.add_error_type (parse_type (true, false));
} while (accept (TokenType.COMMA));
}
@@ -2916,14 +2974,14 @@ public class Vala.Genie.Parser : CodeVisitor {
method.overrides = true;
}
if ((method.is_abstract && method.is_virtual)
- || (method.is_abstract && method.overrides)
- || (method.is_virtual && method.overrides)) {
+ || (method.is_abstract && method.overrides)
+ || (method.is_virtual && method.overrides)) {
throw new ParseError.SYNTAX (get_error ("only one of `abstract', `virtual', or `override' may be specified"));
}
} else {
if (ModifierFlags.ABSTRACT in flags
- || ModifierFlags.VIRTUAL in flags
- || ModifierFlags.OVERRIDE in flags) {
+ || ModifierFlags.VIRTUAL in flags
+ || ModifierFlags.OVERRIDE in flags) {
throw new ParseError.SYNTAX (get_error ("the modifiers `abstract', `virtual', and `override' are not valid for static methods"));
}
}
@@ -3001,7 +3059,7 @@ public class Vala.Genie.Parser : CodeVisitor {
string id = parse_identifier ();
expect (TokenType.COLON);
- var type = parse_type (false);
+ var type = parse_type (true, true);
var prop = new Property (id, type, null, null, get_src (begin), comment);
if (ModifierFlags.PRIVATE in flags) {
@@ -3152,7 +3210,7 @@ public class Vala.Genie.Parser : CodeVisitor {
expect (TokenType.CLOSE_PARENS);
if (accept (TokenType.COLON)) {
- type = parse_type ();
+ type = parse_type (true, false);
} else {
type = new VoidType ();
}
@@ -3225,7 +3283,7 @@ public class Vala.Genie.Parser : CodeVisitor {
var type_param_list = parse_type_parameter_list ();
DataType base_type = null;
if (accept (TokenType.COLON)) {
- base_type = parse_type ();
+ base_type = parse_type (true, false);
}
var st = new Struct (sym.name, get_src (begin), comment);
@@ -3268,6 +3326,8 @@ public class Vala.Genie.Parser : CodeVisitor {
st.add_field ((Field) sym);
} else if (sym is Constant) {
st.add_constant ((Constant) sym);
+ } else if (sym is Property) {
+ st.add_property ((Property) sym);
} else {
Report.error (sym.source_reference, "unexpected declaration in struct");
}
@@ -3283,7 +3343,7 @@ public class Vala.Genie.Parser : CodeVisitor {
var base_types = new ArrayList<DataType> ();
if (accept (TokenType.COLON)) {
do {
- var type = parse_type ();
+ var type = parse_type (true, false);
base_types.add (type);
} while (accept (TokenType.COMMA));
}
@@ -3370,7 +3430,7 @@ public class Vala.Genie.Parser : CodeVisitor {
expect (TokenType.EOL);
expect (TokenType.INDENT);
do {
- if (current () == TokenType.DEDENT) {
+ if (current () == TokenType.DEDENT && en.get_values ().size > 0) {
// allow trailing comma
break;
}
@@ -3427,7 +3487,7 @@ public class Vala.Genie.Parser : CodeVisitor {
expect (TokenType.INDENT);
do {
- if (current () == TokenType.DEDENT) {
+ if (current () == TokenType.DEDENT && ed.get_codes ().size > 0) {
// allow trailing comma
break;
}
@@ -3524,6 +3584,10 @@ public class Vala.Genie.Parser : CodeVisitor {
next ();
flags |= ModifierFlags.OVERRIDE;
break;
+ case TokenType.SEALED:
+ next ();
+ flags |= ModifierFlags.SEALED;
+ break;
case TokenType.STATIC:
next ();
flags |= ModifierFlags.STATIC;
@@ -3563,9 +3627,13 @@ public class Vala.Genie.Parser : CodeVisitor {
DataType type;
if (direction == ParameterDirection.IN) {
- type = parse_type (false);
+ type = parse_type (false, false);
+ } else if (direction == ParameterDirection.REF) {
+ // ref parameters own the value by default
+ type = parse_type (true, true);
} else {
- type = parse_type (true);
+ // out parameters own the value by default
+ type = parse_type (true, false);
}
var param = new Parameter (id, type, get_src (begin));
@@ -3612,7 +3680,7 @@ public class Vala.Genie.Parser : CodeVisitor {
expect (TokenType.CLOSE_PARENS);
if (accept (TokenType.RAISES)) {
do {
- method.add_error_type (parse_type ());
+ method.add_error_type (parse_type (true, false));
} while (accept (TokenType.COMMA));
}
method.access = SymbolAccessibility.PUBLIC;
@@ -3656,7 +3724,7 @@ public class Vala.Genie.Parser : CodeVisitor {
expect (TokenType.CLOSE_PARENS);
if (accept (TokenType.COLON)) {
- type = parse_type ();
+ type = parse_type (true, false);
} else {
type = new VoidType ();
@@ -3666,7 +3734,7 @@ public class Vala.Genie.Parser : CodeVisitor {
if (accept (TokenType.RAISES)) {
do {
- d.add_error_type (parse_type ());
+ d.add_error_type (parse_type (true, false));
} while (accept (TokenType.COMMA));
}
@@ -3732,20 +3800,20 @@ public class Vala.Genie.Parser : CodeVisitor {
void skip_type_argument_list () throws ParseError {
if (accept (TokenType.OF)) {
- if (accept (TokenType.OPEN_PARENS)) {
- do {
- skip_type ();
- } while (accept (TokenType.COMMA));
- expect (TokenType.CLOSE_PARENS);
- } else {
- do {
- skip_type ();
- } while (accept (TokenType.COMMA));
+ if (accept (TokenType.OPEN_PARENS)) {
+ do {
+ skip_type ();
+ } while (accept (TokenType.COMMA));
+ expect (TokenType.CLOSE_PARENS);
+ } else {
+ do {
+ skip_type ();
+ } while (accept (TokenType.COMMA));
}
}
}
-
+
// try to parse type argument list
List<DataType>? parse_type_argument_list (bool maybe_expression) throws ParseError {
var begin = get_location ();
@@ -3756,28 +3824,28 @@ public class Vala.Genie.Parser : CodeVisitor {
// Optional parens allow multi arg types in function signature: "dict of (int, string)"
// See: https://bugzilla.gnome.org/show_bug.cgi?id=611191
if (accept (TokenType.OPEN_PARENS)) {
- inParens = true;
- }
-
- do {
- switch (current ()) {
- case TokenType.VOID:
- case TokenType.DYNAMIC:
- case TokenType.UNOWNED:
- case TokenType.WEAK:
- case TokenType.IDENTIFIER:
- var type = parse_type ();
-
- list.add (type);
- break;
- default:
- rollback (begin);
- return null;
- }
- } while (accept (TokenType.COMMA));
-
- if (inParens) {
- expect (TokenType.CLOSE_PARENS);
+ inParens = true;
+ }
+
+ do {
+ switch (current ()) {
+ case TokenType.VOID:
+ case TokenType.DYNAMIC:
+ case TokenType.UNOWNED:
+ case TokenType.WEAK:
+ case TokenType.IDENTIFIER:
+ var type = parse_type (true, true);
+
+ list.add (type);
+ break;
+ default:
+ rollback (begin);
+ return null;
+ }
+ } while (accept (TokenType.COMMA));
+
+ if (inParens) {
+ expect (TokenType.CLOSE_PARENS);
}
return list;
diff --git a/vala/valageniescanner.vala b/vala/valageniescanner.vala
index 5f73ba4..e2c5466 100644
--- a/vala/valageniescanner.vala
+++ b/vala/valageniescanner.vala
@@ -283,7 +283,7 @@ public class Vala.Genie.Scanner {
state_stack = null;
}
- TokenType get_identifier_or_keyword (char* begin, int len) {
+ public static TokenType get_identifier_or_keyword (char* begin, int len) {
switch (len) {
case 2:
switch (begin[0]) {
@@ -538,6 +538,9 @@ public class Vala.Genie.Scanner {
break;
case 's':
switch (begin[1]) {
+ case 'e':
+ if (matches (begin, "sealed")) return TokenType.SEALED;
+ break;
case 'i':
if (matches (begin, "sizeof")) return TokenType.SIZEOF;
break;
@@ -736,7 +739,10 @@ public class Vala.Genie.Scanner {
break;
}
} else if (current[0] == '\n') {
- break;
+ current++;
+ line++;
+ column = 1;
+ token_length_in_chars = 1;
} else {
unichar u = ((string) current).get_char_validated ((long) (end - current));
if (u != (unichar) (-1)) {
@@ -748,7 +754,7 @@ public class Vala.Genie.Scanner {
}
}
}
- if (current >= end || current[0] == '\n') {
+ if (current >= end) {
Report.error (get_source_reference (token_length_in_chars), "syntax error, expected \"");
state_stack.length--;
return read_token (out token_begin, out token_end);
@@ -817,7 +823,7 @@ public class Vala.Genie.Scanner {
/* handle automatic line continuations (when inside parens or braces) */
while (current < end && current[0] == '\n' && (open_parens_count > 0 || open_brace_count > 0)) {
- current++;
+ current++;
line++;
skip_space_tabs ();
}
@@ -941,7 +947,7 @@ public class Vala.Genie.Scanner {
}
type = TokenType.REAL_LITERAL;
} else if (current < end && current == begin + 1
- && begin[0] == '0' && begin[1] == 'x' && begin[2].isxdigit ()) {
+ && begin[0] == '0' && begin[1] == 'x' && begin[2].isxdigit ()) {
// hexadecimal integer literal
current++;
while (current < end && current[0].isxdigit ()) {
@@ -1176,7 +1182,6 @@ public class Vala.Genie.Scanner {
case TokenType.COMMA:
case TokenType.MINUS:
case TokenType.OP_AND:
- case TokenType.OP_DEC:
case TokenType.OP_EQ:
case TokenType.OP_GE:
case TokenType.OP_GT:
@@ -1222,7 +1227,7 @@ public class Vala.Genie.Scanner {
token_length_in_chars = 6;
current += 3;
while (current < end - 4) {
- if (current[0] == '"' && current[1] == '"' && current[2] == '"') {
+ if (current[0] == '"' && current[1] == '"' && current[2] == '"' && current[3] != '"') {
break;
} else if (current[0] == '\n') {
current++;
@@ -1285,7 +1290,10 @@ public class Vala.Genie.Scanner {
break;
}
} else if (current[0] == '\n') {
- break;
+ current++;
+ line++;
+ column = 1;
+ token_length_in_chars = 1;
} else {
unichar u = ((string) current).get_char_validated ((long) (end - current));
if (u != (unichar) (-1)) {
@@ -1296,8 +1304,12 @@ public class Vala.Genie.Scanner {
Report.error (get_source_reference (token_length_in_chars), "invalid UTF-8 character");
}
}
+ if (current < end && begin[0] == '\'' && current[0] != '\'') {
+ // multiple characters in single character literal
+ Report.error (get_source_reference (token_length_in_chars), "invalid character literal");
+ }
}
- if (current < end && current[0] != '\n') {
+ if (current < end) {
current++;
} else {
Report.error (get_source_reference (token_length_in_chars), "syntax error, expected %c".printf (begin[0]));
@@ -1313,7 +1325,6 @@ public class Vala.Genie.Scanner {
Report.error (get_source_reference (0), "invalid UTF-8 character");
}
column++;
- last_token = TokenType.STRING_LITERAL;
return read_token (out token_begin, out token_end);
}
}
@@ -1363,7 +1374,7 @@ public class Vala.Genie.Scanner {
return tab_count;
}
- bool matches (char* begin, string keyword) {
+ static bool matches (char* begin, string keyword) {
char* keyword_array = (char *) keyword;
long len = keyword.length;
for (int i = 0; i < len; i++) {
@@ -1416,9 +1427,10 @@ public class Vala.Genie.Scanner {
}
bool comment (bool file_comment = false) {
- if (current > end - 2
- || current[0] != '/'
- || (current[1] != '/' && current[1] != '*')) {
+ if (current == null
+ || current > end - 2
+ || current[0] != '/'
+ || (current[1] != '/' && current[1] != '*')) {
return false;
}
@@ -1457,7 +1469,7 @@ public class Vala.Genie.Scanner {
return false;
}
- if (current[2] == '*' || file_comment) {
+ if (current[2] == '*' || file_comment) {
source_reference = get_source_reference (0);
}
@@ -1465,7 +1477,7 @@ public class Vala.Genie.Scanner {
char* begin = current;
while (current < end - 1
- && (current[0] != '*' || current[1] != '/')) {
+ && (current[0] != '*' || current[1] != '/')) {
if (current[0] == '\n') {
line++;
column = 0;
@@ -1512,7 +1524,7 @@ public class Vala.Genie.Scanner {
}
}
- public void parse_file_comments () {
+ public void parse_file_comments () {
while (whitespace () || comment (true)) {
}
@@ -1520,6 +1532,10 @@ public class Vala.Genie.Scanner {
void push_comment (string comment_item, SourceReference source_reference, bool file_comment) {
if (comment_item[0] == '*') {
+ if (_comment != null) {
+ // extra doc comment, add it to source file comments
+ source_file.add_comment (_comment);
+ }
_comment = new Comment (comment_item, source_reference);
}
@@ -1554,12 +1570,17 @@ public class Vala.Genie.Scanner {
return found;
}
+ void pp_space () {
+ while (pp_whitespace () || comment ()) {
+ }
+ }
+
void pp_directive () {
// hash sign
current++;
column++;
- pp_whitespace ();
+ pp_space ();
char* begin = current;
int len = 0;
@@ -1582,11 +1603,11 @@ public class Vala.Genie.Scanner {
}
if (conditional_stack.length > 0
- && conditional_stack[conditional_stack.length - 1].skip_section) {
+ && conditional_stack[conditional_stack.length - 1].skip_section) {
// skip lines until next preprocessing directive
bool bol = false;
while (current < end) {
- if (bol && current[0] == '#') {
+ if (bol && current < end && current[0] == '#') {
// go back to begin of line
current -= (column - 1);
column = 1;
@@ -1606,14 +1627,14 @@ public class Vala.Genie.Scanner {
}
void pp_eol () {
- pp_whitespace ();
+ pp_space ();
if (current >= end || current[0] != '\n') {
Report.error (get_source_reference (0), "syntax error, expected newline");
}
}
void parse_pp_if () {
- pp_whitespace ();
+ pp_space ();
bool condition = parse_pp_expression ();
@@ -1631,7 +1652,7 @@ public class Vala.Genie.Scanner {
}
void parse_pp_elif () {
- pp_whitespace ();
+ pp_space ();
bool condition = parse_pp_expression ();
@@ -1643,7 +1664,7 @@ public class Vala.Genie.Scanner {
}
if (condition && !conditional_stack[conditional_stack.length - 1].matched
- && (conditional_stack.length == 1 || !conditional_stack[conditional_stack.length - 2].skip_section)) {
+ && (conditional_stack.length == 1 || !conditional_stack[conditional_stack.length - 2].skip_section)) {
// condition true => process code within if
conditional_stack[conditional_stack.length - 1].matched = true;
conditional_stack[conditional_stack.length - 1].skip_section = false;
@@ -1662,7 +1683,7 @@ public class Vala.Genie.Scanner {
}
if (!conditional_stack[conditional_stack.length - 1].matched
- && (conditional_stack.length == 1 || !conditional_stack[conditional_stack.length - 2].skip_section)) {
+ && (conditional_stack.length == 1 || !conditional_stack[conditional_stack.length - 2].skip_section)) {
// condition true => process code within if
conditional_stack[conditional_stack.length - 1].matched = true;
conditional_stack[conditional_stack.length - 1].skip_section = false;
@@ -1717,9 +1738,9 @@ public class Vala.Genie.Scanner {
} else if (current[0] == '(') {
current++;
column++;
- pp_whitespace ();
+ pp_space ();
bool result = parse_pp_expression ();
- pp_whitespace ();
+ pp_space ();
if (current < end && current[0] == ')') {
current++;
column++;
@@ -1737,7 +1758,7 @@ public class Vala.Genie.Scanner {
if (current < end && current[0] == '!') {
current++;
column++;
- pp_whitespace ();
+ pp_space ();
return !parse_pp_unary_expression ();
}
@@ -1746,18 +1767,18 @@ public class Vala.Genie.Scanner {
bool parse_pp_equality_expression () {
bool left = parse_pp_unary_expression ();
- pp_whitespace ();
+ pp_space ();
while (true) {
if (current < end - 1 && current[0] == '=' && current[1] == '=') {
current += 2;
column += 2;
- pp_whitespace ();
+ pp_space ();
bool right = parse_pp_unary_expression ();
left = (left == right);
} else if (current < end - 1 && current[0] == '!' && current[1] == '=') {
current += 2;
column += 2;
- pp_whitespace ();
+ pp_space ();
bool right = parse_pp_unary_expression ();
left = (left != right);
} else {
@@ -1769,11 +1790,11 @@ public class Vala.Genie.Scanner {
bool parse_pp_and_expression () {
bool left = parse_pp_equality_expression ();
- pp_whitespace ();
+ pp_space ();
while (current < end - 1 && current[0] == '&' && current[1] == '&') {
current += 2;
column += 2;
- pp_whitespace ();
+ pp_space ();
bool right = parse_pp_equality_expression ();
left = left && right;
}
@@ -1782,11 +1803,11 @@ public class Vala.Genie.Scanner {
bool parse_pp_or_expression () {
bool left = parse_pp_and_expression ();
- pp_whitespace ();
+ pp_space ();
while (current < end - 1 && current[0] == '|' && current[1] == '|') {
current += 2;
column += 2;
- pp_whitespace ();
+ pp_space ();
bool right = parse_pp_and_expression ();
left = left || right;
}
diff --git a/vala/valagenietokentype.vala b/vala/valagenietokentype.vala
index fb8f54f..920a96a 100644
--- a/vala/valagenietokentype.vala
+++ b/vala/valagenietokentype.vala
@@ -1,6 +1,6 @@
/* valagenietokentype.vala
*
- * Copyright (C) 2008 Jamie McCracken, JÃrg Billeter
+ * Copyright (C) 2008-2012 Jamie McCracken, JÃrg Billeter
* Based on code by JÃrg Billeter
*
* This library is free software; you can redistribute it and/or
@@ -137,12 +137,13 @@ public enum Vala.Genie.TokenType {
PUBLIC,
RAISE,
RAISES,
- REAL_LITERAL,
READONLY,
+ REAL_LITERAL,
REF,
REGEX_LITERAL,
REQUIRES,
RETURN,
+ SEALED,
SEMICOLON,
SET,
SIZEOF,
@@ -253,7 +254,7 @@ public enum Vala.Genie.TokenType {
case NULL: return "`null'";
case OF: return "`of'";
case OUT: return "`out'";
- case OP_AND: return "`&&'";
+ case OP_AND: return "`and'";
case OP_DEC: return "`--'";
case OP_EQ: return "`=='";
case OP_GE: return "`>='";
@@ -263,7 +264,7 @@ public enum Vala.Genie.TokenType {
case OP_LT: return "`<'";
case OP_NE: return "`!='";
case OP_NEG: return "`!'";
- case OP_OR: return "`||'";
+ case OP_OR: return "`or'";
case OP_PTR: return "`->'";
case OP_SHIFT_LEFT: return "`<<'";
case OPEN_BRACE: return "`{'";
@@ -289,6 +290,7 @@ public enum Vala.Genie.TokenType {
case REGEX_LITERAL: return "regex literal";
case REQUIRES: return "`requires'";
case RETURN: return "`return'";
+ case SEALED: return "`sealed'";
case SEMICOLON: return "`;'";
case SET: return "`set'";
case SIZEOF: return "`sizeof'";
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]