From: Jamie McCracken Date: Sat, 15 Sep 2012 16:57:48 +0000 (-0400) Subject: GENIE: Updated genie to include fixes from vala parser X-Git-Tag: 0.17.7~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1607046ae82c1b71817dd4bf03fd203cd246fdb1;p=thirdparty%2Fvala.git GENIE: Updated genie to include fixes from vala parser --- diff --git a/vala/valagenieparser.vala b/vala/valagenieparser.vala index 77fbd1c5d..d4d9d3fde 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 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 params = new ArrayList (); @@ -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? attributes) { if (attributes != null) { foreach (Attribute attr in (List) 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 (); 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 (); 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? 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 5f73ba483..e2c5466b5 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 fb8f54f6e..920a96af8 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'";