LCOV - code coverage report
Current view: top level - vala - valaparser.vala (source / functions) Coverage Total Hit
Test: vala 0.57.0.298-a8cae1 Lines: 97.2 % 2346 2281
Test Date: 2024-04-25 11:34:36 Functions: - 0 0

            Line data    Source code
       1              : /* valaparser.vala
       2              :  *
       3              :  * Copyright (C) 2006-2013  Jürg Billeter
       4              :  *
       5              :  * This library is free software; you can redistribute it and/or
       6              :  * modify it under the terms of the GNU Lesser General Public
       7              :  * License as published by the Free Software Foundation; either
       8              :  * version 2.1 of the License, or (at your option) any later version.
       9              : 
      10              :  * This library is distributed in the hope that it will be useful,
      11              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      12              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13              :  * Lesser General Public License for more details.
      14              : 
      15              :  * You should have received a copy of the GNU Lesser General Public
      16              :  * License along with this library; if not, write to the Free Software
      17              :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
      18              :  *
      19              :  * Author:
      20              :  *      Jürg Billeter <j@bitron.ch>
      21              :  */
      22              : 
      23              : using GLib;
      24              : 
      25              : /**
      26              :  * Code visitor parsing all Vala source files.
      27              :  */
      28         1538 : public class Vala.Parser : CodeVisitor {
      29         1538 :         Scanner scanner;
      30              : 
      31         1538 :         CodeContext context;
      32              : 
      33              :         // token buffer
      34         1538 :         TokenInfo[] tokens;
      35              :         // index of current token in buffer
      36              :         int index;
      37              :         // number of tokens in buffer
      38              :         int size;
      39              : 
      40         1538 :         Comment comment;
      41              : 
      42              :         const int BUFFER_SIZE = 32;
      43              : 
      44              :         static List<TypeParameter> _empty_type_parameter_list;
      45              :         static int next_local_func_id = 0;
      46              : 
      47        16304 :         PartialInfo[] partials;
      48              : 
      49              :         struct TokenInfo {
      50              :                 public TokenType type;
      51              :                 public SourceLocation begin;
      52              :                 public SourceLocation end;
      53              :         }
      54              : 
      55           48 :         struct PartialInfo {
      56           36 :                 public Symbol parent;
      57              :                 public SourceLocation begin;
      58           36 :                 public List<Attribute>? attributes;
      59              :         }
      60              : 
      61              :         [Flags]
      62              :         enum ModifierFlags {
      63              :                 NONE = 0,
      64              :                 ABSTRACT,
      65              :                 CLASS,
      66              :                 EXTERN,
      67              :                 INLINE,
      68              :                 NEW,
      69              :                 OVERRIDE,
      70              :                 STATIC,
      71              :                 VIRTUAL,
      72              :                 ASYNC,
      73              :                 SEALED,
      74              :                 PARTIAL;
      75              : 
      76              :                 public unowned string to_string () {
      77           13 :                         var flags_class = (FlagsClass) typeof(ModifierFlags).class_ref ();
      78           13 :                         return flags_class.get_first_value (this).value_nick;
      79              :                 }
      80              :         }
      81              : 
      82         3076 :         public Parser () {
      83         1538 :                 tokens = new TokenInfo[BUFFER_SIZE];
      84              :         }
      85              : 
      86              :         /**
      87              :          * Parses all .vala and .vapi source files in the specified code
      88              :          * context and builds a code tree.
      89              :          *
      90              :          * @param context a code context
      91              :          */
      92         1538 :         public void parse (CodeContext context) {
      93         1538 :                 this.context = context;
      94         1538 :                 context.accept (this);
      95         1538 :                 this.context = null;
      96              :         }
      97              : 
      98         6761 :         public override void visit_source_file (SourceFile source_file) {
      99         6761 :                 if ((context != null && context.run_output) || source_file.filename.has_suffix (".vala") || source_file.filename.has_suffix (".vapi")) {
     100         6605 :                         parse_file (source_file);
     101              :                 }
     102              :         }
     103              : 
     104    219813547 :         inline bool next () {
     105    219813547 :                 index = (index + 1) % BUFFER_SIZE;
     106    219813547 :                 size--;
     107    219813547 :                 if (size <= 0) {
     108              :                         SourceLocation begin, end;
     109    179617757 :                         TokenType type = scanner.read_token (out begin, out end);
     110    179617757 :                         tokens[index] = { type, begin, end };
     111    179617757 :                         size = 1;
     112              :                 }
     113    219813547 :                 return (tokens[index].type != TokenType.EOF);
     114              :         }
     115              : 
     116        35959 :         inline void prev () {
     117        35959 :                 index = (index - 1 + BUFFER_SIZE) % BUFFER_SIZE;
     118        35959 :                 size++;
     119        35959 :                 assert (size <= BUFFER_SIZE);
     120              :         }
     121              : 
     122           17 :         inline void safe_prev () {
     123           17 :                 switch (previous ()) {
     124              :                 case TokenType.DOT:
     125              :                 case TokenType.DOUBLE_COLON:
     126              :                         break;
     127              :                 default:
     128           17 :                         prev ();
     129           17 :                         break;
     130              :                 }
     131              :         }
     132              : 
     133    971917576 :         inline TokenType current () {
     134    971917576 :                 return tokens[index].type;
     135              :         }
     136              : 
     137       443690 :         inline TokenType previous () {
     138       443690 :                 return tokens[(index - 1 + BUFFER_SIZE) % BUFFER_SIZE].type;
     139              :         }
     140              : 
     141    691294342 :         inline bool accept (TokenType type) {
     142    691294342 :                 if (current () == type) {
     143    101859074 :                         next ();
     144    101859074 :                         return true;
     145              :                 }
     146    691294342 :                 return false;
     147              :         }
     148              : 
     149           59 :         void report_parse_error (ParseError e) {
     150           59 :                 var begin = get_location ();
     151           59 :                 next ();
     152           59 :                 Report.error (get_src (begin), "syntax error, %s", e.message);
     153              :         }
     154              : 
     155     46633046 :         inline bool expect (TokenType type) throws ParseError {
     156     46633046 :                 if (accept (type)) {
     157              :                         return true;
     158              :                 }
     159              : 
     160           79 :                 switch (type) {
     161              :                 case TokenType.CLOSE_BRACE:
     162            1 :                         safe_prev ();
     163            1 :                         report_parse_error (new ParseError.SYNTAX ("following block delimiter %s missing", type.to_string ()));
     164              :                         return true;
     165              :                 case TokenType.CLOSE_BRACKET:
     166              :                 case TokenType.CLOSE_PARENS:
     167              :                 case TokenType.SEMICOLON:
     168           16 :                         safe_prev ();
     169           16 :                         report_parse_error (new ParseError.SYNTAX ("following expression/statement delimiter %s missing", type.to_string ()));
     170              :                         return true;
     171              :                 default:
     172           62 :                         throw new ParseError.SYNTAX ("expected %s", type.to_string ());
     173              :                 }
     174              :         }
     175              : 
     176    186684008 :         inline SourceLocation get_location () {
     177    186684008 :                 return tokens[index].begin;
     178              :         }
     179              : 
     180            0 :         string get_location_string () {
     181            0 :                 var begin = get_location ();
     182            0 :                 return "__VALA_L%d_C%d__".printf (begin.line, begin.column);
     183              :         }
     184              : 
     185           29 :         string get_current_string () {
     186           29 :                 var token = tokens[index];
     187           29 :                 return ((string) token.begin.pos).substring (0, (int) (token.end.pos - token.begin.pos));
     188              :         }
     189              : 
     190     71089672 :         string get_last_string () {
     191     71089672 :                 int last_index = (index + BUFFER_SIZE - 1) % BUFFER_SIZE;
     192     71089672 :                 var token = tokens[last_index];
     193     71089672 :                 return ((string) token.begin.pos).substring (0, (int) (token.end.pos - token.begin.pos));
     194              :         }
     195              : 
     196    101956647 :         SourceReference get_src (SourceLocation begin) {
     197    101956647 :                 int last_index = (index + BUFFER_SIZE - 1) % BUFFER_SIZE;
     198              : 
     199    101956647 :                 return new SourceReference (scanner.source_file, begin, tokens[last_index].end);
     200              :         }
     201              : 
     202            8 :         SourceReference get_current_src () {
     203            8 :                 var token = tokens[index];
     204            8 :                 return new SourceReference (scanner.source_file, token.begin, token.end);
     205              :         }
     206              : 
     207       295603 :         SourceReference get_last_src () {
     208       295603 :                 int last_index = (index + BUFFER_SIZE - 1) % BUFFER_SIZE;
     209       295603 :                 var token = tokens[last_index];
     210       295603 :                 return new SourceReference (scanner.source_file, token.begin, token.end);
     211              :         }
     212              : 
     213     31535643 :         void rollback (SourceLocation location) {
     214     71695668 :                 while (tokens[index].begin.pos != location.pos) {
     215     40160025 :                         index = (index - 1 + BUFFER_SIZE) % BUFFER_SIZE;
     216     40160025 :                         size++;
     217     40160025 :                         if (size > BUFFER_SIZE) {
     218            5 :                                 scanner.seek (location);
     219            5 :                                 size = 0;
     220            5 :                                 index = 0;
     221              : 
     222            5 :                                 next ();
     223              :                         }
     224              :                 }
     225              :         }
     226              : 
     227           12 :         void jump (SourceLocation location) {
     228           19 :                 while (tokens[index].begin.pos != location.pos) {
     229            7 :                         index = (index + 1) % BUFFER_SIZE;
     230            7 :                         size--;
     231            7 :                         if (size <= 0) {
     232            3 :                                 scanner.seek (location);
     233            3 :                                 size = 0;
     234            3 :                                 index = 0;
     235              : 
     236            3 :                                 next ();
     237              :                         }
     238              :                 }
     239              :         }
     240              : 
     241    158953687 :         void skip_identifier () throws ParseError {
     242              :                 // also accept keywords as identifiers where there is no conflict
     243     79476858 :                 switch (current ()) {
     244              :                 case TokenType.ABSTRACT:
     245              :                 case TokenType.AS:
     246              :                 case TokenType.ASYNC:
     247              :                 case TokenType.BASE:
     248              :                 case TokenType.BREAK:
     249              :                 case TokenType.CASE:
     250              :                 case TokenType.CATCH:
     251              :                 case TokenType.CLASS:
     252              :                 case TokenType.CONST:
     253              :                 case TokenType.CONSTRUCT:
     254              :                 case TokenType.CONTINUE:
     255              :                 case TokenType.DEFAULT:
     256              :                 case TokenType.DELEGATE:
     257              :                 case TokenType.DELETE:
     258              :                 case TokenType.DO:
     259              :                 case TokenType.DYNAMIC:
     260              :                 case TokenType.ELSE:
     261              :                 case TokenType.ENUM:
     262              :                 case TokenType.ENSURES:
     263              :                 case TokenType.ERRORDOMAIN:
     264              :                 case TokenType.EXTERN:
     265              :                 case TokenType.FALSE:
     266              :                 case TokenType.FINALLY:
     267              :                 case TokenType.FOR:
     268              :                 case TokenType.FOREACH:
     269              :                 case TokenType.GET:
     270              :                 case TokenType.IDENTIFIER:
     271              :                 case TokenType.IF:
     272              :                 case TokenType.IN:
     273              :                 case TokenType.INLINE:
     274              :                 case TokenType.INTERFACE:
     275              :                 case TokenType.INTERNAL:
     276              :                 case TokenType.IS:
     277              :                 case TokenType.LOCK:
     278              :                 case TokenType.NAMESPACE:
     279              :                 case TokenType.NEW:
     280              :                 case TokenType.NULL:
     281              :                 case TokenType.OUT:
     282              :                 case TokenType.OVERRIDE:
     283              :                 case TokenType.OWNED:
     284              :                 case TokenType.PARAMS:
     285              :                 case TokenType.PARTIAL:
     286              :                 case TokenType.PRIVATE:
     287              :                 case TokenType.PROTECTED:
     288              :                 case TokenType.PUBLIC:
     289              :                 case TokenType.REF:
     290              :                 case TokenType.REQUIRES:
     291              :                 case TokenType.RETURN:
     292              :                 case TokenType.SEALED:
     293              :                 case TokenType.SET:
     294              :                 case TokenType.SIGNAL:
     295              :                 case TokenType.SIZEOF:
     296              :                 case TokenType.STATIC:
     297              :                 case TokenType.STRUCT:
     298              :                 case TokenType.SWITCH:
     299              :                 case TokenType.THIS:
     300              :                 case TokenType.THROW:
     301              :                 case TokenType.THROWS:
     302              :                 case TokenType.TRUE:
     303              :                 case TokenType.TRY:
     304              :                 case TokenType.TYPEOF:
     305              :                 case TokenType.UNLOCK:
     306              :                 case TokenType.UNOWNED:
     307              :                 case TokenType.USING:
     308              :                 case TokenType.VAR:
     309              :                 case TokenType.VIRTUAL:
     310              :                 case TokenType.VOID:
     311              :                 case TokenType.VOLATILE:
     312              :                 case TokenType.WEAK:
     313              :                 case TokenType.WHILE:
     314              :                 case TokenType.WITH:
     315              :                 case TokenType.YIELD:
     316     79238499 :                         next ();
     317     79238499 :                         return;
     318              :                 case TokenType.INTEGER_LITERAL:
     319              :                 case TokenType.REAL_LITERAL:
     320              :                         // also accept integer and real literals
     321              :                         // as long as they contain at least one character
     322              :                         // and no decimal point
     323              :                         // for example, 2D and 3D
     324           29 :                         string id = get_current_string ();
     325           29 :                         if (id[id.length - 1].isalpha () && !("." in id)) {
     326            0 :                                 next ();
     327            0 :                                 return;
     328              :                         }
     329           29 :                         break;
     330              :                 default:
     331       238330 :                         throw new ParseError.SYNTAX ("expected identifier");
     332              :                 }
     333              :         }
     334              : 
     335     61044785 :         string parse_identifier (bool required = false) throws ParseError {
     336     61044785 :                 try {
     337     61044785 :                         skip_identifier ();
     338              :                 } catch (ParseError e) {
     339           17 :                         if (!required && context.keep_going) {
     340            0 :                                 report_parse_error (e);
     341            0 :                                 prev ();
     342            0 :                                 return get_location_string ();
     343              :                         } else {
     344           28 :                                 throw e;
     345              :                         }
     346              :                 }
     347     61044768 :                 return get_last_string ();
     348              :         }
     349              : 
     350      1256125 :         Expression parse_literal () throws ParseError {
     351      1256125 :                 var begin = get_location ();
     352              : 
     353      1256125 :                 switch (current ()) {
     354              :                 case TokenType.TRUE:
     355        27559 :                         next ();
     356        27559 :                         return new BooleanLiteral (true, get_src (begin));
     357              :                 case TokenType.FALSE:
     358        30963 :                         next ();
     359        30963 :                         return new BooleanLiteral (false, get_src (begin));
     360              :                 case TokenType.INTEGER_LITERAL:
     361       269633 :                         next ();
     362       269633 :                         return new IntegerLiteral (get_last_string (), get_src (begin));
     363              :                 case TokenType.REAL_LITERAL:
     364          400 :                         next ();
     365          400 :                         return new RealLiteral (get_last_string (), get_src (begin));
     366              :                 case TokenType.CHARACTER_LITERAL:
     367         5176 :                         next ();
     368              :                         // FIXME validate and unescape here and just pass unichar to CharacterLiteral
     369         5176 :                         var lit = new CharacterLiteral (get_last_string (), get_src (begin));
     370         5176 :                         if (lit.error) {
     371            0 :                                 Report.error (lit.source_reference, "invalid character literal");
     372              :                         }
     373         5176 :                         return lit;
     374              :                 case TokenType.REGEX_LITERAL:
     375           30 :                         next ();
     376           30 :                         string match_part = get_last_string ();
     377           30 :                         SourceReference src_begin = get_src (begin);
     378           30 :                         expect (TokenType.CLOSE_REGEX_LITERAL);
     379           30 :                         string close_token = get_last_string ();
     380           30 :                         return new RegexLiteral ("%s/%s".printf (close_token, match_part), src_begin);
     381              :                 case TokenType.STRING_LITERAL:
     382        92220 :                         next ();
     383        92220 :                         return new StringLiteral (get_last_string (), get_src (begin));
     384              :                 case TokenType.TEMPLATE_STRING_LITERAL:
     385            6 :                         next ();
     386            6 :                         return new StringLiteral ("\"%s\"".printf (get_last_string ()), get_src (begin));
     387              :                 case TokenType.VERBATIM_STRING_LITERAL:
     388           28 :                         next ();
     389           28 :                         string raw_string = get_last_string ();
     390           28 :                         string escaped_string = raw_string.substring (3, raw_string.length - 6).escape ("");
     391           28 :                         return new StringLiteral ("\"%s\"".printf (escaped_string), get_src (begin));
     392              :                 case TokenType.VERBATIM_TEMPLATE_STRING_LITERAL:
     393            6 :                         next ();
     394            6 :                         string raw_string = get_last_string ();
     395            6 :                         string escaped_string = raw_string.escape ("");
     396            6 :                         return new StringLiteral ("\"%s\"".printf (escaped_string), get_src (begin));
     397              :                 case TokenType.NULL:
     398       830104 :                         next ();
     399       830104 :                         return new NullLiteral (get_src (begin));
     400              :                 default:
     401            0 :                         throw new ParseError.SYNTAX ("expected literal");
     402              :                 }
     403              :         }
     404              : 
     405         6605 :         public void parse_file (SourceFile source_file) {
     406         6605 :                 var has_global_context = (context != null);
     407         6605 :                 if (!has_global_context) {
     408            0 :                         context = source_file.context;
     409              :                 }
     410              : 
     411         6605 :                 scanner = new Scanner (source_file);
     412         6605 :                 parse_file_comments ();
     413              : 
     414         6605 :                 tokens = new TokenInfo[BUFFER_SIZE];
     415         6605 :                 index = -1;
     416         6605 :                 size = 0;
     417              : 
     418         6605 :                 next ();
     419              : 
     420              : 
     421         6605 :                 try {
     422         6605 :                         partials = new PartialInfo[] {};
     423         6605 :                         var begin = get_location ();
     424         6605 :                         parse_using_directives (context.root);
     425         6605 :                         parse_declarations (context.root, true);
     426         6605 :                         if (accept (TokenType.CLOSE_BRACE)) {
     427              :                                 // only report error if it's not a secondary error
     428            3 :                                 if (context.report.get_errors () == 0) {
     429            1 :                                         Report.error (get_last_src (), "unexpected `}'");
     430              :                                 }
     431              :                         }
     432         6605 :                         if (partials.length > 0) {
     433            6 :                                 rollback (begin);
     434           18 :                                 foreach (var info in partials) {
     435           12 :                                         jump (info.begin);
     436           12 :                                         parse_class_declaration (info.parent, info.attributes, true);
     437              :                                 }
     438              :                         }
     439         6605 :                         partials = null;
     440              :                 } catch (ParseError e) {
     441            0 :                         report_parse_error (e);
     442              :                 }
     443              : 
     444         6605 :                 scanner = null;
     445         6605 :                 if (!has_global_context) {
     446            0 :                         context = null;
     447              :                 }
     448              :         }
     449              : 
     450         6605 :         void parse_file_comments () {
     451         6605 :                 scanner.parse_file_comments ();
     452              :         }
     453              : 
     454     17053242 :         void skip_symbol_name () throws ParseError {
     455     35008689 :                 do {
     456     18432073 :                         skip_identifier ();
     457     18193760 :                 } while (accept (TokenType.DOT) || accept (TokenType.DOUBLE_COLON));
     458              :         }
     459              : 
     460     24443740 :         UnresolvedSymbol parse_symbol_name () throws ParseError {
     461     24443740 :                 var begin = get_location ();
     462     24443740 :                 UnresolvedSymbol sym = null;
     463     83650230 :                 do {
     464     29603254 :                         string name = parse_identifier ();
     465     29603253 :                         if (name == "global" && accept (TokenType.DOUBLE_COLON)) {
     466              :                                 // global::Name
     467              :                                 // qualified access to global symbol
     468           16 :                                 name = parse_identifier ();
     469           16 :                                 sym = new UnresolvedSymbol (sym, name, get_src (begin));
     470           16 :                                 sym.qualified = true;
     471           16 :                                 continue;
     472              :                         }
     473     29603237 :                         sym = new UnresolvedSymbol (sym, name, get_src (begin));
     474     29603253 :                 } while (accept (TokenType.DOT));
     475     24443739 :                 return sym;
     476              :         }
     477              : 
     478     18997726 :         void skip_type () throws ParseError {
     479     18759413 :                 accept (TokenType.DYNAMIC);
     480     18759413 :                 accept (TokenType.OWNED);
     481     18759413 :                 accept (TokenType.UNOWNED);
     482     18759413 :                 accept (TokenType.WEAK);
     483              : 
     484     18759413 :                 if (is_inner_array_type ()) {
     485        10845 :                         expect (TokenType.OPEN_PARENS);
     486        10845 :                         expect (TokenType.UNOWNED);
     487        10845 :                         skip_type ();
     488        10845 :                         expect (TokenType.CLOSE_PARENS);
     489        10845 :                         expect (TokenType.OPEN_BRACKET);
     490        10845 :                         prev ();
     491              :                 } else {
     492     18748568 :                         if (accept (TokenType.VOID)) {
     493              :                         } else {
     494     16814911 :                                 skip_symbol_name ();
     495     16576598 :                                 skip_type_argument_list ();
     496              :                         }
     497     18721082 :                         while (accept (TokenType.STAR)) {
     498              :                         }
     499     18510255 :                         accept (TokenType.INTERR);
     500              :                 }
     501              : 
     502     18735273 :                 while (accept (TokenType.OPEN_BRACKET)) {
     503       428418 :                         do {
     504              :                                 // required for decision between expression and declaration statement
     505       424459 :                                 if (current () != TokenType.COMMA && current () != TokenType.CLOSE_BRACKET && current () != TokenType.COLON) {
     506         4014 :                                         parse_expression ();
     507              :                                 }
     508       214245 :                         } while (accept (TokenType.COMMA));
     509       214173 :                         if (accept (TokenType.COLON)) {
     510           18 :                                 skip_symbol_name ();
     511              :                         }
     512       214173 :                         expect (TokenType.CLOSE_BRACKET);
     513       214173 :                         accept (TokenType.INTERR);
     514              :                 }
     515     18521100 :                 accept (TokenType.OP_NEG);
     516              :         }
     517              : 
     518     18847102 :         bool is_inner_array_type () {
     519     18847102 :                 var begin = get_location ();
     520              : 
     521     18847102 :                 var result = accept (TokenType.OPEN_PARENS) && accept (TokenType.UNOWNED) && current() != TokenType.CLOSE_PARENS;
     522     18847102 :                 rollback (begin);
     523     18847102 :                 return result;
     524              :         }
     525              : 
     526     19067204 :         DataType parse_type (bool owned_by_default, bool can_weak_ref, bool require_unowned = false) throws ParseError {
     527     19067204 :                 var begin = get_location ();
     528              : 
     529     19067204 :                 bool is_dynamic = accept (TokenType.DYNAMIC);
     530              : 
     531     19067204 :                 bool value_owned = owned_by_default;
     532              : 
     533     19067204 :                 if (require_unowned) {
     534        13952 :                         expect (TokenType.UNOWNED);
     535              :                 } else {
     536     19053252 :                         if (owned_by_default) {
     537     10146140 :                                 if (accept (TokenType.UNOWNED)) {
     538              :                                         value_owned = false;
     539      9293102 :                                 } else if (accept (TokenType.WEAK)) {
     540        59444 :                                         if (!can_weak_ref && !context.deprecated) {
     541            1 :                                                 Report.warning (get_last_src (), "deprecated syntax, use `unowned` modifier");
     542              :                                         }
     543              :                                         value_owned = false;
     544      9233658 :                                 } else if (accept (TokenType.OWNED)) {
     545            1 :                                         Report.warning (get_last_src (), "`owned' is default in this context");
     546              :                                 }
     547              :                         } else {
     548      8907112 :                                 if (accept (TokenType.OWNED)) {
     549              :                                         value_owned = true;
     550              :                                 } else {
     551      8629491 :                                         value_owned = false;
     552      8629491 :                                         if (accept (TokenType.UNOWNED)) {
     553            0 :                                                 Report.warning (get_last_src (), "`unowned' is default in this context");
     554              :                                         }
     555              :                                 }
     556              :                         }
     557              :                 }
     558              : 
     559              :                 DataType type;
     560              : 
     561     19067204 :                 bool inner_type_owned = true;
     562     19067204 :                 if (accept (TokenType.OPEN_PARENS)) {
     563        13952 :                         type = parse_type (false, false, true);
     564        13952 :                         expect (TokenType.CLOSE_PARENS);
     565              : 
     566        13952 :                         inner_type_owned = false;
     567              : 
     568        13952 :                         expect (TokenType.OPEN_BRACKET);
     569        13952 :                         prev ();
     570              :                 } else {
     571     35885173 :                         if (!is_dynamic && value_owned == owned_by_default && accept (TokenType.VOID)) {
     572      2221330 :                                 type = new VoidType (get_src (begin));
     573              :                         } else {
     574     16831922 :                                 var sym = parse_symbol_name ();
     575     16831921 :                                 List<DataType> type_arg_list = parse_type_argument_list (false);
     576              : 
     577     16831921 :                                 type = new UnresolvedType.from_symbol (sym, get_src (begin));
     578     16831921 :                                 if (type_arg_list != null) {
     579      1748043 :                                         foreach (DataType type_arg in type_arg_list) {
     580       600123 :                                                 type.add_type_argument (type_arg);
     581              :                                         }
     582              :                                 }
     583              :                         }
     584              : 
     585     19671748 :                         while (accept (TokenType.STAR)) {
     586       618497 :                                 type = new PointerType (type, get_src (begin));
     587              :                         }
     588              : 
     589     19053251 :                         if (!(type is PointerType)) {
     590     18462205 :                                 type.nullable = accept (TokenType.INTERR);
     591     18462205 :                                 type.source_reference = get_src (begin);
     592              :                         }
     593              :                 }
     594              : 
     595              :                 // array brackets in types are read from right to left,
     596              :                 // this is more logical, especially when nullable arrays
     597              :                 // or pointers are involved
     598     19067203 :                 DataType? array_length_type = null;
     599     19632643 :                 while (accept (TokenType.OPEN_BRACKET)) {
     600              :                         bool invalid_array = false;
     601              :                         int array_rank = 0;
     602      1130937 :                         do {
     603       565497 :                                 array_rank++;
     604              :                                 // required for decision between expression and declaration statement
     605      1126364 :                                 if (current () != TokenType.COMMA && current () != TokenType.CLOSE_BRACKET && current () != TokenType.COLON) {
     606         4609 :                                         parse_expression ();
     607              :                                         // only used for parsing, reject use as real type
     608              :                                         invalid_array = true;
     609              :                                 }
     610       565497 :                         } while (accept (TokenType.COMMA));
     611       565440 :                         if (accept (TokenType.COLON)) {
     612           21 :                                 array_length_type = parse_type (true, false);
     613              :                         }
     614       565440 :                         expect (TokenType.CLOSE_BRACKET);
     615              : 
     616       565440 :                         type.value_owned = inner_type_owned;
     617              : 
     618       565440 :                         var array_type = new ArrayType (type, array_rank, get_src (begin));
     619       565440 :                         array_type.nullable = accept (TokenType.INTERR);
     620       565440 :                         array_type.invalid_syntax = invalid_array;
     621       565440 :                         if (array_length_type != null) {
     622           21 :                                 array_type.length_type = array_length_type.copy ();
     623              :                         }
     624              : 
     625     22539801 :                         type = array_type;
     626              :                 }
     627              : 
     628     19067203 :                 if (accept (TokenType.OP_NEG)) {
     629            0 :                         Report.warning (get_last_src (), "obsolete syntax, types are non-null by default");
     630              :                 }
     631              : 
     632     19067203 :                 if (type is PointerType) {
     633     19067203 :                         value_owned = false;
     634              :                 }
     635              : 
     636     19067203 :                 type.is_dynamic = is_dynamic;
     637     19067203 :                 type.value_owned = value_owned;
     638     19067203 :                 return type;
     639              :         }
     640              : 
     641     10184735 :         DataType? parse_inline_array_type (DataType? type) throws ParseError {
     642     10184735 :                 var begin = get_location ();
     643              : 
     644              :                 // inline-allocated array
     645     10184735 :                 if (type != null && accept (TokenType.OPEN_BRACKET)) {
     646         2450 :                         Expression array_length = null;
     647         2450 :                         DataType? array_length_type = null;
     648              : 
     649         2450 :                         if (current () != TokenType.CLOSE_BRACKET) {
     650         2437 :                                 array_length = parse_expression ();
     651              :                         }
     652         2450 :                         if (accept (TokenType.COLON)) {
     653            4 :                                 array_length_type = parse_type (true, false);
     654              :                         }
     655         2450 :                         expect (TokenType.CLOSE_BRACKET);
     656              : 
     657         2450 :                         var array_type = new ArrayType (type, 1, get_src (begin));
     658         2450 :                         array_type.inline_allocated = true;
     659         2450 :                         if (array_length != null) {
     660         2437 :                                 array_type.fixed_length = true;
     661         2437 :                                 array_type.length = array_length;
     662              :                         }
     663         2450 :                         if (array_length_type != null) {
     664            4 :                                 array_type.length_type = array_length_type;
     665              :                         }
     666         2450 :                         array_type.value_owned = type.value_owned;
     667              : 
     668         2450 :                         return array_type;
     669              :                 }
     670     10182285 :                 return type;
     671              :         }
     672              : 
     673       222097 :         List<Expression> parse_argument_list () throws ParseError {
     674       222097 :                 expect (TokenType.OPEN_PARENS);
     675       222097 :                 var list = new ArrayList<Expression> ();
     676       222097 :                 if (current () != TokenType.CLOSE_PARENS) {
     677       676518 :                         do {
     678       676517 :                                 try {
     679       338259 :                                         list.add (parse_argument ());
     680              :                                 } catch (ParseError e) {
     681            1 :                                         if (current () == TokenType.CLOSE_PARENS) {
     682            1 :                                                 prev ();
     683            1 :                                                 report_parse_error (new ParseError.SYNTAX ("incomplete argument list"));
     684            0 :                                         } else if (context.keep_going) {
     685            0 :                                                 report_parse_error (e);
     686              :                                         } else {
     687            0 :                                                 throw e;
     688              :                                         }
     689              :                                 }
     690       338259 :                         } while (accept (TokenType.COMMA));
     691              :                 }
     692       222097 :                 expect (TokenType.CLOSE_PARENS);
     693              :                 return list;
     694              :         }
     695              : 
     696       341245 :         Expression parse_argument () throws ParseError {
     697       341245 :                 var begin = get_location ();
     698              : 
     699       341245 :                 if (accept (TokenType.REF)) {
     700         3269 :                         var inner = parse_expression ();
     701         3269 :                         return new UnaryExpression (UnaryOperator.REF, inner, get_src (begin));
     702       337976 :                 } else if (accept (TokenType.OUT)) {
     703        17049 :                         var inner = parse_expression ();
     704        17049 :                         return new UnaryExpression (UnaryOperator.OUT, inner, get_src (begin));
     705              :                 } else {
     706       320927 :                         var expr = parse_expression ();
     707       320925 :                         var ma = expr as MemberAccess;
     708       139252 :                         if (ma != null && ma.inner == null && accept (TokenType.COLON)) {
     709              :                                 // named argument
     710           14 :                                 expr = parse_expression ();
     711           14 :                                 return new NamedArgument (ma.member_name, expr, get_src (begin));
     712              :                         } else {
     713       320911 :                                 return expr;
     714              :                         }
     715              :                 }
     716              :         }
     717              : 
     718      2575749 :         Expression parse_primary_expression () throws ParseError {
     719      2575749 :                 var begin = get_location ();
     720              : 
     721              :                 Expression expr;
     722              : 
     723      2575749 :                 switch (current ()) {
     724              :                 case TokenType.TRUE:
     725              :                 case TokenType.FALSE:
     726              :                 case TokenType.INTEGER_LITERAL:
     727              :                 case TokenType.REAL_LITERAL:
     728              :                 case TokenType.CHARACTER_LITERAL:
     729              :                 case TokenType.STRING_LITERAL:
     730              :                 case TokenType.REGEX_LITERAL:
     731              :                 case TokenType.TEMPLATE_STRING_LITERAL:
     732              :                 case TokenType.VERBATIM_STRING_LITERAL:
     733              :                 case TokenType.VERBATIM_TEMPLATE_STRING_LITERAL:
     734              :                 case TokenType.NULL:
     735      1256095 :                         expr = parse_literal ();
     736              :                         break;
     737              :                 case TokenType.OPEN_BRACE:
     738          999 :                         expr = parse_initializer ();
     739              :                         break;
     740              :                 case TokenType.OPEN_BRACKET:
     741            0 :                         expr = parse_simple_name ();
     742              :                         break;
     743              :                 case TokenType.OPEN_PARENS:
     744        88676 :                         expr = parse_tuple ();
     745              :                         break;
     746              :                 case TokenType.OPEN_TEMPLATE:
     747            8 :                         expr = parse_template ();
     748              :                         break;
     749              :                 case TokenType.OPEN_REGEX_LITERAL:
     750           30 :                         expr = parse_regex_literal ();
     751              :                         break;
     752              :                 case TokenType.THIS:
     753       125375 :                         expr = parse_this_access ();
     754              :                         break;
     755              :                 case TokenType.BASE:
     756          211 :                         expr = parse_base_access ();
     757              :                         break;
     758              :                 case TokenType.NEW:
     759        26994 :                         expr = parse_object_or_array_creation_expression ();
     760              :                         break;
     761              :                 case TokenType.YIELD:
     762           58 :                         expr = parse_yield_expression ();
     763              :                         break;
     764              :                 case TokenType.SIZEOF:
     765         6136 :                         expr = parse_sizeof_expression ();
     766              :                         break;
     767              :                 case TokenType.TYPEOF:
     768          150 :                         expr = parse_typeof_expression ();
     769              :                         break;
     770              :                 default:
     771      1071017 :                         expr = parse_simple_name ();
     772              :                         break;
     773              :                 }
     774              : 
     775              :                 // process primary expressions that start with an inner primary expression
     776              :                 bool found = true;
     777      3236754 :                 while (found) {
     778      3230457 :                         switch (current ()) {
     779              :                         case TokenType.INTERR:
     780              :                                 // check for null-safe member or element access
     781         6322 :                                 next ();
     782         6347 :                                 switch (current ()) {
     783              :                                 case TokenType.DOT:
     784           20 :                                         expr = parse_member_access (begin, expr);
     785           20 :                                         break;
     786              :                                 case TokenType.OPEN_BRACKET:
     787            5 :                                         expr = parse_element_access (begin, expr);
     788            5 :                                         break;
     789              :                                 default:
     790         6297 :                                         prev ();
     791         6297 :                                         found = false;
     792         6297 :                                         break;
     793              :                                 }
     794              :                                 break;
     795              :                         case TokenType.DOT:
     796       419092 :                                 expr = parse_member_access (begin, expr);
     797       419092 :                                 break;
     798              :                         case TokenType.OP_PTR:
     799         1538 :                                 expr = parse_pointer_member_access (begin, expr);
     800         1538 :                                 break;
     801              :                         case TokenType.OPEN_PARENS:
     802       202918 :                                 expr = parse_method_call (begin, expr);
     803       202916 :                                 break;
     804              :                         case TokenType.OPEN_BRACKET:
     805        24552 :                                 expr = parse_element_access (begin, expr);
     806        24552 :                                 break;
     807              :                         case TokenType.OP_INC:
     808         4981 :                                 expr = parse_post_increment_expression (begin, expr);
     809         4981 :                                 break;
     810              :                         case TokenType.OP_DEC:
     811         1612 :                                 expr = parse_post_decrement_expression (begin, expr);
     812         1612 :                                 break;
     813              :                         default:
     814              :                                 found = false;
     815              :                                 break;
     816              :                         }
     817              :                 }
     818              : 
     819              :                 return expr;
     820              :         }
     821              : 
     822      1071017 :         Expression parse_simple_name () throws ParseError {
     823      1071017 :                 var begin = get_location ();
     824      1071017 :                 string id = parse_identifier ();
     825      1071011 :                 bool qualified = false;
     826      1071011 :                 if (id == "global" && accept (TokenType.DOUBLE_COLON)) {
     827            1 :                         id = parse_identifier ();
     828            1 :                         qualified = true;
     829              :                 }
     830      1071011 :                 List<DataType> type_arg_list = parse_type_argument_list (true);
     831      1071011 :                 var expr = new MemberAccess (null, id, get_src (begin));
     832      1071011 :                 expr.qualified = qualified;
     833      1071011 :                 if (type_arg_list != null) {
     834         4752 :                         foreach (DataType type_arg in type_arg_list) {
     835         1585 :                                 expr.add_type_argument (type_arg);
     836              :                         }
     837              :                 }
     838      1071011 :                 return expr;
     839              :         }
     840              : 
     841        88676 :         Expression parse_tuple () throws ParseError {
     842        88676 :                 var begin = get_location ();
     843              : 
     844        88676 :                 expect (TokenType.OPEN_PARENS);
     845        88676 :                 var expr_list = new ArrayList<Expression> ();
     846        88676 :                 if (current () != TokenType.CLOSE_PARENS) {
     847       266032 :                         do {
     848        88678 :                                 expr_list.add (parse_expression ());
     849        88678 :                         } while (accept (TokenType.COMMA));
     850              :                 }
     851        88676 :                 expect (TokenType.CLOSE_PARENS);
     852        88676 :                 if (expr_list.size != 1) {
     853            2 :                         var tuple = new Tuple (get_src (begin));
     854           10 :                         foreach (Expression expr in expr_list) {
     855            4 :                                 tuple.add_expression (expr);
     856              :                         }
     857            2 :                         return tuple;
     858              :                 } else {
     859        88674 :                         var expr = expr_list.get (0);
     860        88674 :                         expr.source_reference = get_src (begin);
     861        88674 :                         return expr;
     862              :                 }
     863              :         }
     864              : 
     865            8 :         Expression parse_template () throws ParseError {
     866            8 :                 var begin = get_location ();
     867            8 :                 var template = new Template ();
     868              : 
     869            8 :                 expect (TokenType.OPEN_TEMPLATE);
     870           48 :                 while (current () != TokenType.CLOSE_TEMPLATE) {
     871           20 :                         template.add_expression (parse_expression ());
     872           20 :                         expect (TokenType.COMMA);
     873              :                 }
     874            8 :                 expect (TokenType.CLOSE_TEMPLATE);
     875              : 
     876            8 :                 template.source_reference = get_src (begin);
     877              :                 return template;
     878              :         }
     879              : 
     880           30 :         Expression parse_regex_literal () throws ParseError {
     881           30 :                 expect (TokenType.OPEN_REGEX_LITERAL);
     882              : 
     883           30 :                 var expr = parse_literal ();
     884              : 
     885              :                 return expr;
     886              :         }
     887              : 
     888       419112 :         Expression parse_member_access (SourceLocation begin, Expression inner) throws ParseError {
     889       419112 :                 bool null_safe = previous () == TokenType.INTERR;
     890              : 
     891       419112 :                 expect (TokenType.DOT);
     892       419112 :                 string id = parse_identifier ();
     893       419112 :                 List<DataType> type_arg_list = parse_type_argument_list (true);
     894       419112 :                 var expr = new MemberAccess (inner, id, get_src (begin));
     895       419112 :                 expr.null_safe_access = null_safe;
     896       419112 :                 if (type_arg_list != null) {
     897          108 :                         foreach (DataType type_arg in type_arg_list) {
     898           36 :                                 expr.add_type_argument (type_arg);
     899              :                         }
     900              :                 }
     901       419112 :                 return expr;
     902              :         }
     903              : 
     904         1538 :         Expression parse_pointer_member_access (SourceLocation begin, Expression inner) throws ParseError {
     905         1538 :                 expect (TokenType.OP_PTR);
     906         1538 :                 string id = parse_identifier ();
     907         1538 :                 List<DataType> type_arg_list = parse_type_argument_list (true);
     908         1538 :                 var expr = new MemberAccess.pointer (inner, id, get_src (begin));
     909         1538 :                 if (type_arg_list != null) {
     910            5 :                         foreach (DataType type_arg in type_arg_list) {
     911            2 :                                 expr.add_type_argument (type_arg);
     912              :                         }
     913              :                 }
     914         1538 :                 return expr;
     915              :         }
     916              : 
     917       202918 :         Expression parse_method_call (SourceLocation begin, Expression inner) throws ParseError {
     918       202918 :                 var arg_list = parse_argument_list ();
     919       202918 :                 var src = get_src (begin);
     920              : 
     921       202918 :                 var init_list = parse_object_initializer ();
     922              : 
     923       202916 :                 if (init_list.size > 0 && inner is MemberAccess) {
     924              :                         // struct creation expression
     925           14 :                         unowned MemberAccess member = (MemberAccess) inner;
     926              : 
     927           14 :                         var expr = new ObjectCreationExpression (member, src);
     928           14 :                         expr.struct_creation = true;
     929           14 :                         foreach (Expression arg in arg_list) {
     930            0 :                                 expr.add_argument (arg);
     931              :                         }
     932           46 :                         foreach (MemberInitializer initializer in init_list) {
     933           16 :                                 expr.add_member_initializer (initializer);
     934              :                         }
     935           14 :                         return expr;
     936              :                 } else {
     937       202902 :                         var expr = new MethodCall (inner, src);
     938       801712 :                         foreach (Expression arg in arg_list) {
     939       299405 :                                 expr.add_argument (arg);
     940              :                         }
     941       202902 :                         return expr;
     942              :                 }
     943              :         }
     944              : 
     945        24557 :         Expression parse_element_access (SourceLocation begin, Expression inner) throws ParseError {
     946        24557 :                 Expression? stop = null;
     947              :                 List<Expression> index_list;
     948        24557 :                 bool null_safe = previous () == TokenType.INTERR;
     949              : 
     950        24557 :                 expect (TokenType.OPEN_BRACKET);
     951        24557 :                 if (current () == TokenType.COLON) {
     952              :                         // slice expression
     953            6 :                         index_list = new ArrayList<Expression> ();
     954            6 :                         index_list.add (new IntegerLiteral ("0", get_src (begin)));
     955              :                 } else {
     956        24551 :                         index_list = parse_expression_list ();
     957              :                 }
     958              : 
     959        24557 :                 if (index_list.size == 1 && accept (TokenType.COLON)) {
     960              :                         // slice expression
     961           38 :                         if (current () == TokenType.CLOSE_BRACKET) {
     962            6 :                                 stop = new MemberAccess (inner, "length", get_src (begin));
     963              :                         } else {
     964           32 :                                 stop = parse_expression ();
     965              :                         }
     966              :                 }
     967        24557 :                 expect (TokenType.CLOSE_BRACKET);
     968              : 
     969        24557 :                 if (stop == null) {
     970        24519 :                         var expr = new ElementAccess (inner, get_src (begin));
     971        24519 :                         expr.null_safe_access = null_safe;
     972        73693 :                         foreach (Expression index in index_list) {
     973        24587 :                                 expr.append_index (index);
     974              :                         }
     975        24519 :                         return expr;
     976              :                 } else {
     977           38 :                         var expr = new SliceExpression (inner, index_list[0], stop, get_src (begin));
     978           38 :                         expr.null_safe_access = null_safe;
     979           38 :                         return expr;
     980              :                 }
     981              :         }
     982              : 
     983        24551 :         List<Expression> parse_expression_list () throws ParseError {
     984        24551 :                 var list = new ArrayList<Expression> ();
     985        98340 :                 do {
     986        24619 :                         list.add (parse_expression ());
     987        24619 :                 } while (accept (TokenType.COMMA));
     988              :                 return list;
     989              :         }
     990              : 
     991       125375 :         Expression parse_this_access () throws ParseError {
     992       125375 :                 var begin = get_location ();
     993       125375 :                 expect (TokenType.THIS);
     994       125375 :                 return new MemberAccess (null, "this", get_src (begin));
     995              :         }
     996              : 
     997          211 :         Expression parse_base_access () throws ParseError {
     998          211 :                 var begin = get_location ();
     999          211 :                 expect (TokenType.BASE);
    1000          211 :                 return new BaseAccess (get_src (begin));
    1001              :         }
    1002              : 
    1003         4981 :         Expression parse_post_increment_expression (SourceLocation begin, Expression inner) throws ParseError {
    1004         4981 :                 expect (TokenType.OP_INC);
    1005         4981 :                 return new PostfixExpression (inner, true, get_src (begin));
    1006              :         }
    1007              : 
    1008         1612 :         Expression parse_post_decrement_expression (SourceLocation begin, Expression inner) throws ParseError {
    1009         1612 :                 expect (TokenType.OP_DEC);
    1010         1612 :                 return new PostfixExpression (inner, false, get_src (begin));
    1011              :         }
    1012              : 
    1013        26994 :         Expression parse_object_or_array_creation_expression () throws ParseError {
    1014        26994 :                 var begin = get_location ();
    1015        26994 :                 expect (TokenType.NEW);
    1016              : 
    1017        26994 :                 if (is_inner_array_type ()) {
    1018            2 :                         rollback (begin);
    1019            2 :                         return parse_array_creation_expression ();
    1020              :                 }
    1021              : 
    1022        26992 :                 var member = parse_member_name ();
    1023        26992 :                 if (current () == TokenType.OPEN_PARENS) {
    1024        19179 :                         var expr = parse_object_creation_expression (begin, member);
    1025        19179 :                         return expr;
    1026              :                 } else {
    1027              :                         bool is_pointer_type = false;
    1028         7814 :                         while (accept (TokenType.STAR)) {
    1029              :                                 is_pointer_type = true;
    1030              :                         }
    1031         7813 :                         if (!is_pointer_type) {
    1032         7812 :                                 accept (TokenType.INTERR);
    1033              :                         }
    1034         7813 :                         if (accept (TokenType.OPEN_BRACKET)) {
    1035         7813 :                                 rollback (begin);
    1036         7813 :                                 var expr = parse_array_creation_expression ();
    1037         7811 :                                 return expr;
    1038              :                         } else {
    1039            0 :                                 throw new ParseError.SYNTAX ("expected ( or [");
    1040              :                         }
    1041              :                 }
    1042              :         }
    1043              : 
    1044        19179 :         Expression parse_object_creation_expression (SourceLocation begin, MemberAccess member) throws ParseError {
    1045        19179 :                 var arg_list = parse_argument_list ();
    1046        19179 :                 var src = get_src (begin);
    1047              : 
    1048        19179 :                 var init_list = parse_object_initializer ();
    1049              : 
    1050        19179 :                 var expr = new ObjectCreationExpression (member, src);
    1051        96881 :                 foreach (Expression arg in arg_list) {
    1052        38851 :                         expr.add_argument (arg);
    1053              :                 }
    1054        19259 :                 foreach (MemberInitializer initializer in init_list) {
    1055           40 :                         expr.add_member_initializer (initializer);
    1056              :                 }
    1057        19179 :                 return expr;
    1058              :         }
    1059              : 
    1060         7815 :         Expression parse_array_creation_expression () throws ParseError {
    1061         7815 :                 var begin = get_location ();
    1062         7815 :                 expect (TokenType.NEW);
    1063              : 
    1064         7815 :                 bool inner_array_type = is_inner_array_type ();
    1065         7815 :                 if (inner_array_type) {
    1066            2 :                         expect (TokenType.OPEN_PARENS);
    1067            2 :                         expect (TokenType.UNOWNED);
    1068              :                 }
    1069              : 
    1070         7815 :                 var member = parse_member_name ();
    1071         7815 :                 DataType element_type = new UnresolvedType.from_expression (member);
    1072         7815 :                 bool is_pointer_type = false;
    1073         7816 :                 while (accept (TokenType.STAR)) {
    1074            1 :                         element_type = new PointerType (element_type, get_src (begin));
    1075            1 :                         is_pointer_type = true;
    1076              :                 }
    1077         7815 :                 if (!is_pointer_type) {
    1078         7814 :                         if (accept (TokenType.INTERR)) {
    1079           10 :                                 element_type.nullable = true;
    1080              :                         }
    1081              :                 }
    1082              : 
    1083         7815 :                 if (inner_array_type) {
    1084            2 :                         expect (TokenType.CLOSE_PARENS);
    1085            2 :                         element_type.value_owned = false;
    1086              :                 } else {
    1087         7813 :                         element_type.value_owned = true;
    1088              :                 }
    1089              : 
    1090         7815 :                 expect (TokenType.OPEN_BRACKET);
    1091              : 
    1092              :                 bool size_specified = false;
    1093              :                 List<Expression> size_specifier_list = null;
    1094              :                 bool first = true;
    1095              :                 DataType? array_length_type = null;
    1096        15630 :                 do {
    1097         7816 :                         if (!first) {
    1098              :                                 // array of arrays: new T[][42]
    1099              : 
    1100            1 :                                 if (size_specified) {
    1101            1 :                                         throw new ParseError.SYNTAX ("size of inner arrays must not be specified in array creation expression");
    1102              :                                 }
    1103              : 
    1104            0 :                                 element_type = new ArrayType (element_type, size_specifier_list.size, element_type.source_reference);
    1105            0 :                                 if (array_length_type != null) {
    1106            0 :                                         ((ArrayType) element_type).length_type = array_length_type.copy ();
    1107              :                                 }
    1108              :                         } else {
    1109              :                                 first = false;
    1110              :                         }
    1111              : 
    1112         7815 :                         size_specifier_list = new ArrayList<Expression> ();
    1113        23463 :                         do {
    1114         7824 :                                 Expression size = null;
    1115         7824 :                                 if (current () != TokenType.CLOSE_BRACKET && current () != TokenType.COMMA && current () != TokenType.COLON) {
    1116         7766 :                                         size = parse_expression ();
    1117              :                                         size_specified = true;
    1118              :                                 }
    1119         7824 :                                 size_specifier_list.add (size);
    1120         7824 :                         } while (accept (TokenType.COMMA));
    1121         7815 :                         if (accept (TokenType.COLON)) {
    1122            9 :                                 array_length_type = parse_type (true, false);
    1123              :                         }
    1124         7815 :                         expect (TokenType.CLOSE_BRACKET);
    1125         7815 :                 } while (accept (TokenType.OPEN_BRACKET));
    1126              : 
    1127         7814 :                 var src = get_src (begin);
    1128              : 
    1129         7814 :                 InitializerList initializer = null;
    1130         7814 :                 if (current () == TokenType.OPEN_BRACE) {
    1131           52 :                         initializer = parse_initializer ();
    1132              :                 }
    1133         7814 :                 var expr = new ArrayCreationExpression (element_type, size_specifier_list.size, initializer, src);
    1134         7814 :                 if (array_length_type != null) {
    1135            9 :                         expr.length_type = array_length_type.copy ();
    1136              :                 }
    1137         7814 :                 if (size_specified) {
    1138        23293 :                         foreach (Expression size in size_specifier_list) {
    1139         7765 :                                 expr.append_size (size);
    1140              :                         }
    1141           51 :                 } else if (initializer == null) {
    1142            1 :                         Report.warning (src, "possibly missing array size");
    1143            1 :                         throw new ParseError.SYNTAX ("expected array initializer list");
    1144              :                 }
    1145         7813 :                 return expr;
    1146              :         }
    1147              : 
    1148       222097 :         List<MemberInitializer> parse_object_initializer () throws ParseError {
    1149       222097 :                 var list = new ArrayList<MemberInitializer> ();
    1150       222097 :                 if (accept (TokenType.OPEN_BRACE)) {
    1151           84 :                         while (current () != TokenType.CLOSE_BRACE) {
    1152           58 :                                 list.add (parse_member_initializer ());
    1153              : 
    1154           56 :                                 if (!accept (TokenType.COMMA)) {
    1155           34 :                                         break;
    1156              :                                 }
    1157              :                         }
    1158           38 :                         expect (TokenType.CLOSE_BRACE);
    1159              :                 }
    1160              :                 return list;
    1161              :         }
    1162              : 
    1163          120 :         MemberInitializer parse_member_initializer (bool chained = false) throws ParseError {
    1164          120 :                 var begin = get_location ();
    1165          120 :                 string id = parse_identifier (chained);
    1166          112 :                 expect (TokenType.ASSIGN);
    1167              : 
    1168           62 :                 var inner = get_location ();
    1169              :                 Expression expr;
    1170          118 :                 try {
    1171              :                         // chained member initializer
    1172           62 :                         expr = parse_member_initializer (true);
    1173              :                 } catch {
    1174           56 :                         rollback (inner);
    1175           56 :                         expr = parse_expression ();
    1176              :                 }
    1177           62 :                 return new MemberInitializer (id, expr, get_src (begin));
    1178              :         }
    1179              : 
    1180           58 :         Expression parse_yield_expression () throws ParseError {
    1181           58 :                 expect (TokenType.YIELD);
    1182              : 
    1183           58 :                 var expr = parse_expression ();
    1184              : 
    1185           58 :                 unowned MethodCall? call = expr as MethodCall;
    1186           58 :                 unowned ObjectCreationExpression? object_creation = expr as ObjectCreationExpression;
    1187           58 :                 if (call == null && object_creation == null) {
    1188            1 :                         Report.error (expr.source_reference, "syntax error, expected method call");
    1189            1 :                         expr.error = true;
    1190              :                 }
    1191              : 
    1192           58 :                 if (call != null) {
    1193           48 :                         call.is_yield_expression = true;
    1194           10 :                 } else if (object_creation != null) {
    1195            9 :                         object_creation.is_yield_expression = true;
    1196              :                 }
    1197              : 
    1198              :                 return expr;
    1199              :         }
    1200              : 
    1201         6136 :         Expression parse_sizeof_expression () throws ParseError {
    1202         6136 :                 var begin = get_location ();
    1203         6136 :                 expect (TokenType.SIZEOF);
    1204         6136 :                 expect (TokenType.OPEN_PARENS);
    1205         6136 :                 var type = parse_type (true, false);
    1206         6136 :                 expect (TokenType.CLOSE_PARENS);
    1207              : 
    1208         6136 :                 return new SizeofExpression (type, get_src (begin));
    1209              :         }
    1210              : 
    1211          150 :         Expression parse_typeof_expression () throws ParseError {
    1212          150 :                 var begin = get_location ();
    1213          150 :                 expect (TokenType.TYPEOF);
    1214          150 :                 expect (TokenType.OPEN_PARENS);
    1215          150 :                 var type = parse_type (true, false);
    1216          150 :                 expect (TokenType.CLOSE_PARENS);
    1217              : 
    1218          150 :                 return new TypeofExpression (type, get_src (begin));
    1219              :         }
    1220              : 
    1221      2873015 :         UnaryOperator get_unary_operator (TokenType token_type) {
    1222      2873015 :                 switch (token_type) {
    1223      2873015 :                 case TokenType.PLUS:   return UnaryOperator.PLUS;
    1224        73798 :                 case TokenType.MINUS:  return UnaryOperator.MINUS;
    1225         1212 :                 case TokenType.OP_NEG: return UnaryOperator.LOGICAL_NEGATION;
    1226            2 :                 case TokenType.TILDE:  return UnaryOperator.BITWISE_COMPLEMENT;
    1227           58 :                 case TokenType.OP_INC: return UnaryOperator.INCREMENT;
    1228           17 :                 case TokenType.OP_DEC: return UnaryOperator.DECREMENT;
    1229      2797927 :                 default:               return UnaryOperator.NONE;
    1230              :                 }
    1231              :         }
    1232              : 
    1233      2873015 :         Expression parse_unary_expression () throws ParseError {
    1234      2873015 :                 var begin = get_location ();
    1235      2873015 :                 var operator = get_unary_operator (current ());
    1236      2873015 :                 if (operator != UnaryOperator.NONE) {
    1237        75088 :                         next ();
    1238        75088 :                         var op = parse_unary_expression ();
    1239        75088 :                         unowned IntegerLiteral? lit = op as IntegerLiteral;
    1240        75089 :                         if (lit != null) {
    1241        73767 :                                 if (operator == UnaryOperator.PLUS) {
    1242            1 :                                         return lit;
    1243        73766 :                                 } else if (operator == UnaryOperator.MINUS) {
    1244        73765 :                                         return new IntegerLiteral ("-"+lit.value, get_src (begin));
    1245              :                                 }
    1246              :                         }
    1247         1322 :                         return new UnaryExpression (operator, op, get_src (begin));
    1248              :                 }
    1249      2797927 :                 switch (current ()) {
    1250              :                 case TokenType.OPEN_PARENS:
    1251       294002 :                         next ();
    1252       517492 :                         switch (current ()) {
    1253              :                         case TokenType.UNOWNED:
    1254              :                                 // inner array type
    1255              :                                 break;
    1256              :                         case TokenType.OWNED:
    1257              :                                 // (owned) foo
    1258        15322 :                                 next ();
    1259        15322 :                                 if (accept (TokenType.CLOSE_PARENS)) {
    1260        15322 :                                         var op = parse_unary_expression ();
    1261        15322 :                                         return new ReferenceTransferExpression (op, get_src (begin));
    1262              :                                 }
    1263              :                                 break;
    1264              :                         case TokenType.VOID:
    1265              :                         case TokenType.DYNAMIC:
    1266              :                         case TokenType.OPEN_PARENS:
    1267              :                         case TokenType.IDENTIFIER:
    1268       256228 :                                 if (current () != TokenType.OPEN_PARENS || is_inner_array_type ()) {
    1269       175324 :                                         var type = parse_type (true, false);
    1270       175324 :                                         if (accept (TokenType.CLOSE_PARENS)) {
    1271              :                                                 // check follower to decide whether to create cast expression
    1272       289765 :                                                 switch (current ()) {
    1273              :                                                 case TokenType.OP_NEG:
    1274              :                                                 case TokenType.TILDE:
    1275              :                                                 case TokenType.OPEN_PARENS:
    1276              :                                                 case TokenType.TRUE:
    1277              :                                                 case TokenType.FALSE:
    1278              :                                                 case TokenType.INTEGER_LITERAL:
    1279              :                                                 case TokenType.REAL_LITERAL:
    1280              :                                                 case TokenType.CHARACTER_LITERAL:
    1281              :                                                 case TokenType.STRING_LITERAL:
    1282              :                                                 case TokenType.TEMPLATE_STRING_LITERAL:
    1283              :                                                 case TokenType.VERBATIM_STRING_LITERAL:
    1284              :                                                 case TokenType.VERBATIM_TEMPLATE_STRING_LITERAL:
    1285              :                                                 case TokenType.REGEX_LITERAL:
    1286              :                                                 case TokenType.NULL:
    1287              :                                                 case TokenType.THIS:
    1288              :                                                 case TokenType.BASE:
    1289              :                                                 case TokenType.NEW:
    1290              :                                                 case TokenType.YIELD:
    1291              :                                                 case TokenType.SIZEOF:
    1292              :                                                 case TokenType.TYPEOF:
    1293              :                                                 case TokenType.IDENTIFIER:
    1294              :                                                 case TokenType.PARAMS:
    1295       142578 :                                                         var inner = parse_unary_expression ();
    1296       142578 :                                                         return new CastExpression (inner, type, get_src (begin));
    1297              :                                                 case TokenType.STAR:
    1298            2 :                                                         next ();
    1299            2 :                                                         var op = parse_unary_expression ();
    1300            2 :                                                         var inner = new PointerIndirection (op, get_src (begin));
    1301            2 :                                                         return new CastExpression (inner, type, get_src (begin));
    1302              :                                                 case TokenType.BITWISE_AND:
    1303            6 :                                                         next ();
    1304            6 :                                                         var op = parse_unary_expression ();
    1305            6 :                                                         var inner = new AddressofExpression (op, get_src (begin));
    1306            6 :                                                         return new CastExpression (inner, type, get_src (begin));
    1307              :                                                 default:
    1308              :                                                         break;
    1309              :                                                 }
    1310              :                                         }
    1311              :                                 }
    1312              :                                 break;
    1313              :                         case TokenType.OP_NEG:
    1314        47454 :                                 next ();
    1315        47454 :                                 if (accept (TokenType.CLOSE_PARENS)) {
    1316              :                                         // (!) non-null cast
    1317        47418 :                                         var inner = parse_unary_expression ();
    1318        47418 :                                         return new CastExpression.non_null (inner, get_src (begin));
    1319              :                                 }
    1320              :                                 break;
    1321              :                         default:
    1322              :                                 break;
    1323              :                         }
    1324              :                         // no cast expression
    1325        88676 :                         rollback (begin);
    1326        88676 :                         break;
    1327              :                 case TokenType.STAR:
    1328        13775 :                         next ();
    1329        13775 :                         var op = parse_unary_expression ();
    1330        13775 :                         return new PointerIndirection (op, get_src (begin));
    1331              :                 case TokenType.BITWISE_AND:
    1332         3077 :                         next ();
    1333         3077 :                         var op = parse_unary_expression ();
    1334         3077 :                         return new AddressofExpression (op, get_src (begin));
    1335              :                 default:
    1336              :                         break;
    1337              :                 }
    1338              : 
    1339      2575749 :                 var expr = parse_primary_expression ();
    1340      2873015 :                 return expr;
    1341              :         }
    1342              : 
    1343      7628108 :         BinaryOperator get_binary_operator (TokenType token_type) {
    1344      7628108 :                 switch (token_type) {
    1345      7628108 :                 case TokenType.STAR:    return BinaryOperator.MUL;
    1346           12 :                 case TokenType.DIV:     return BinaryOperator.DIV;
    1347           11 :                 case TokenType.PERCENT: return BinaryOperator.MOD;
    1348       139222 :                 case TokenType.PLUS:    return BinaryOperator.PLUS;
    1349        52376 :                 case TokenType.MINUS:   return BinaryOperator.MINUS;
    1350        55485 :                 case TokenType.OP_LT:   return BinaryOperator.LESS_THAN;
    1351        14425 :                 case TokenType.OP_GT:   return BinaryOperator.GREATER_THAN;
    1352        55365 :                 case TokenType.OP_LE:   return BinaryOperator.LESS_THAN_OR_EQUAL;
    1353        50622 :                 case TokenType.OP_GE:   return BinaryOperator.GREATER_THAN_OR_EQUAL;
    1354       156915 :                 case TokenType.OP_EQ:   return BinaryOperator.EQUALITY;
    1355       199014 :                 case TokenType.OP_NE:   return BinaryOperator.INEQUALITY;
    1356      6903041 :                 default:                return BinaryOperator.NONE;
    1357              :                 }
    1358              :         }
    1359              : 
    1360      2574106 :         Expression parse_multiplicative_expression () throws ParseError {
    1361      2574106 :                 var begin = get_location ();
    1362      2574106 :                 var left = parse_unary_expression ();
    1363              :                 bool found = true;
    1364      2575739 :                 while (found) {
    1365      2575739 :                         var operator = get_binary_operator (current ());
    1366      2575739 :                         switch (operator) {
    1367              :                         case BinaryOperator.MUL:
    1368              :                         case BinaryOperator.DIV:
    1369              :                         case BinaryOperator.MOD:
    1370         1643 :                                 next ();
    1371         1643 :                                 var right = parse_unary_expression ();
    1372         1643 :                                 left = new BinaryExpression (operator, left, right, get_src (begin));
    1373         1643 :                                 break;
    1374              :                         default:
    1375              :                                 found = false;
    1376              :                                 break;
    1377              :                         }
    1378              :                 }
    1379              :                 return left;
    1380              :         }
    1381              : 
    1382      2478307 :         Expression parse_additive_expression () throws ParseError {
    1383      2478307 :                 var begin = get_location ();
    1384      2478307 :                 var left = parse_multiplicative_expression ();
    1385              :                 bool found = true;
    1386      2574096 :                 while (found) {
    1387      2574096 :                         var operator = get_binary_operator (current ());
    1388      2574096 :                         switch (operator) {
    1389              :                         case BinaryOperator.PLUS:
    1390              :                         case BinaryOperator.MINUS:
    1391        95799 :                                 next ();
    1392        95799 :                                 var right = parse_multiplicative_expression ();
    1393        95799 :                                 left = new BinaryExpression (operator, left, right, get_src (begin));
    1394        95799 :                                 break;
    1395              :                         default:
    1396              :                                 found = false;
    1397              :                                 break;
    1398              :                         }
    1399              :                 }
    1400              :                 return left;
    1401              :         }
    1402              : 
    1403      2478283 :         Expression parse_shift_expression () throws ParseError {
    1404      2478283 :                 var begin = get_location ();
    1405      2478283 :                 var left = parse_additive_expression ();
    1406              :                 bool found = true;
    1407      2483104 :                 while (found) {
    1408      2478297 :                         switch (current ()) {
    1409              :                         case TokenType.OP_SHIFT_LEFT:
    1410           22 :                                 next ();
    1411           22 :                                 var right = parse_additive_expression ();
    1412           22 :                                 left = new BinaryExpression (BinaryOperator.SHIFT_LEFT, left, right, get_src (begin));
    1413           22 :                                 break;
    1414              :                         // don't use OP_SHIFT_RIGHT to support >> for nested generics
    1415              :                         case TokenType.OP_GT:
    1416         4809 :                                 char* first_gt_pos = tokens[index].begin.pos;
    1417         4809 :                                 next ();
    1418              :                                 // only accept >> when there is no space between the two > signs
    1419         4811 :                                 if (current () == TokenType.OP_GT && tokens[index].begin.pos == first_gt_pos + 1) {
    1420            2 :                                         next ();
    1421            2 :                                         var right = parse_additive_expression ();
    1422            2 :                                         left = new BinaryExpression (BinaryOperator.SHIFT_RIGHT, left, right, get_src (begin));
    1423              :                                 } else {
    1424         4807 :                                         prev ();
    1425         4807 :                                         found = false;
    1426              :                                 }
    1427         4809 :                                 break;
    1428              :                         default:
    1429              :                                 found = false;
    1430              :                                 break;
    1431              :                         }
    1432              :                 }
    1433              :                 return left;
    1434              :         }
    1435              : 
    1436      2478283 :         Expression parse_type_check_expression () throws ParseError {
    1437      2478283 :                 var begin = get_location ();
    1438      2478283 :                 var left = parse_shift_expression ();
    1439      2479643 :                 if (accept (TokenType.IS)) {
    1440         1370 :                         var type = parse_type (true, false);
    1441         1370 :                         left = new TypeCheck (left, type, get_src (begin));
    1442      2477373 :                 } else if (accept (TokenType.AS)) {
    1443          470 :                         var type = parse_type (true, false);
    1444          470 :                         left = new CastExpression.silent (left, type, get_src (begin));
    1445              :                 }
    1446              :                 return left;
    1447              :         }
    1448              : 
    1449      2301001 :         Expression parse_relational_expression () throws ParseError {
    1450      2301001 :                 var begin = get_location ();
    1451      2301001 :                 var left = parse_type_check_expression ();
    1452              : 
    1453              :                 bool first = true;
    1454              :                 bool found = true;
    1455      4779264 :                 while (found) {
    1456      2478273 :                         var operator = get_binary_operator (current ());
    1457      2478273 :                         switch (operator) {
    1458              :                         case BinaryOperator.LESS_THAN:
    1459              :                         case BinaryOperator.LESS_THAN_OR_EQUAL:
    1460              :                         case BinaryOperator.GREATER_THAN_OR_EQUAL:
    1461              :                         case BinaryOperator.EQUALITY:
    1462              :                         case BinaryOperator.INEQUALITY:
    1463       172477 :                                 next ();
    1464       172477 :                                 var right = parse_type_check_expression ();
    1465       172477 :                                 if (first) {
    1466       169395 :                                         left = new BinaryExpression (operator, left, right, get_src (begin));
    1467              :                                 } else {
    1468         3082 :                                         left = new BinaryExpression.chained (operator, left, right, get_src (begin));
    1469              :                                 }
    1470       172477 :                                 first = false;
    1471       172477 :                                 break;
    1472              :                         case BinaryOperator.GREATER_THAN:
    1473         4807 :                                 next ();
    1474              :                                 // ignore >> and >>= (two tokens due to generics)
    1475         9612 :                                 if (current () != TokenType.OP_GT && current () != TokenType.OP_GE) {
    1476         4805 :                                         var right = parse_type_check_expression ();
    1477         4805 :                                         if (first) {
    1478         4804 :                                                 left = new BinaryExpression (operator, left, right, get_src (begin));
    1479              :                                         } else {
    1480            1 :                                                 left = new BinaryExpression.chained (operator, left, right, get_src (begin));
    1481              :                                         }
    1482         4805 :                                         first = false;
    1483              :                                 } else {
    1484            2 :                                         prev ();
    1485            2 :                                         found = false;
    1486              :                                 }
    1487              :                                 break;
    1488              :                         default:
    1489              :                                 found = false;
    1490              :                                 break;
    1491              :                         }
    1492              :                 }
    1493              :                 return left;
    1494              :         }
    1495              : 
    1496      2300960 :         Expression parse_and_expression () throws ParseError {
    1497      2300960 :                 var begin = get_location ();
    1498      2300960 :                 var left = parse_relational_expression ();
    1499      2300991 :                 while (accept (TokenType.BITWISE_AND)) {
    1500           41 :                         var right = parse_relational_expression ();
    1501           41 :                         left = new BinaryExpression (BinaryOperator.BITWISE_AND, left, right, get_src (begin));
    1502              :                 }
    1503      2300950 :                 return left;
    1504              :         }
    1505              : 
    1506      2300955 :         Expression parse_exclusive_or_expression () throws ParseError {
    1507      2300955 :                 var begin = get_location ();
    1508      2300955 :                 var left = parse_and_expression ();
    1509      2300950 :                 while (accept (TokenType.CARRET)) {
    1510            5 :                         var right = parse_and_expression ();
    1511            5 :                         left = new BinaryExpression (BinaryOperator.BITWISE_XOR, left, right, get_src (begin));
    1512              :                 }
    1513      2300945 :                 return left;
    1514              :         }
    1515              : 
    1516      2300878 :         Expression parse_inclusive_or_expression () throws ParseError {
    1517      2300878 :                 var begin = get_location ();
    1518      2300878 :                 var left = parse_exclusive_or_expression ();
    1519      2300945 :                 while (accept (TokenType.BITWISE_OR)) {
    1520           77 :                         var right = parse_exclusive_or_expression ();
    1521           77 :                         left = new BinaryExpression (BinaryOperator.BITWISE_OR, left, right, get_src (begin));
    1522              :                 }
    1523      2300868 :                 return left;
    1524              :         }
    1525              : 
    1526      2300765 :         Expression parse_in_expression () throws ParseError {
    1527      2300765 :                 var begin = get_location ();
    1528      2300765 :                 var left = parse_inclusive_or_expression ();
    1529      2300868 :                 while (accept (TokenType.IN)) {
    1530          113 :                         var right = parse_inclusive_or_expression ();
    1531          113 :                         left = new BinaryExpression (BinaryOperator.IN, left, right, get_src (begin));
    1532              :                 }
    1533      2300755 :                 return left;
    1534              :         }
    1535              : 
    1536      2270038 :         Expression parse_conditional_and_expression () throws ParseError {
    1537      2270038 :                 var begin = get_location ();
    1538      2270038 :                 var left = parse_in_expression ();
    1539      2300755 :                 while (accept (TokenType.OP_AND)) {
    1540        30727 :                         var right = parse_in_expression ();
    1541        30727 :                         left = new BinaryExpression (BinaryOperator.AND, left, right, get_src (begin));
    1542              :                 }
    1543      2270028 :                 return left;
    1544              :         }
    1545              : 
    1546      2258593 :         Expression parse_conditional_or_expression () throws ParseError {
    1547      2258593 :                 var begin = get_location ();
    1548      2258593 :                 var left = parse_conditional_and_expression ();
    1549      2270028 :                 while (accept (TokenType.OP_OR)) {
    1550        11445 :                         var right = parse_conditional_and_expression ();
    1551        11445 :                         left = new BinaryExpression (BinaryOperator.OR, left, right, get_src (begin));
    1552              :                 }
    1553      2258583 :                 return left;
    1554              :         }
    1555              : 
    1556      2258593 :         Expression parse_coalescing_expression () throws ParseError {
    1557      2258593 :                 var begin = get_location ();
    1558      2258593 :                 var left = parse_conditional_or_expression ();
    1559      2258583 :                 if (accept (TokenType.OP_COALESCING)) {
    1560           62 :                         var right = parse_coalescing_expression ();
    1561           62 :                         return new BinaryExpression (BinaryOperator.COALESCE, left, right, get_src (begin));
    1562              :                 } else {
    1563      2258593 :                         return left;
    1564              :                 }
    1565              :         }
    1566              : 
    1567      2258531 :         Expression parse_conditional_expression () throws ParseError {
    1568      2258531 :                 var begin = get_location ();
    1569      2258531 :                 var condition = parse_coalescing_expression ();
    1570      2258521 :                 if (accept (TokenType.INTERR)) {
    1571         6297 :                         var true_expr = parse_expression ();
    1572         6297 :                         expect (TokenType.COLON);
    1573         6296 :                         var false_expr = parse_expression ();
    1574         6296 :                         return new ConditionalExpression (condition, true_expr, false_expr, get_src (begin));
    1575              :                 } else {
    1576      2258531 :                         return condition;
    1577              :                 }
    1578              :         }
    1579              : 
    1580        12404 :         Parameter parse_lambda_parameter () throws ParseError {
    1581        12404 :                 var begin = get_location ();
    1582        12404 :                 var direction = ParameterDirection.IN;
    1583        12404 :                 if (accept (TokenType.OUT)) {
    1584              :                         direction = ParameterDirection.OUT;
    1585        12401 :                 } else if (accept (TokenType.REF)) {
    1586            3 :                         direction = ParameterDirection.REF;
    1587              :                 }
    1588              : 
    1589        12404 :                 string id = parse_identifier ();
    1590              : 
    1591        12404 :                 var param = new Parameter (id, null, get_src (begin));
    1592        12404 :                 param.direction = direction;
    1593        12404 :                 return param;
    1594              :         }
    1595              : 
    1596         6475 :         Expression parse_lambda_expression () throws ParseError {
    1597         6475 :                 var begin = get_location ();
    1598         6475 :                 List<Parameter> params = new ArrayList<Parameter> ();
    1599         6481 :                 if (accept (TokenType.OPEN_PARENS)) {
    1600         6469 :                         if (current () != TokenType.CLOSE_PARENS) {
    1601        31032 :                                 do {
    1602        12398 :                                         params.add (parse_lambda_parameter ());
    1603        12398 :                                 } while (accept (TokenType.COMMA));
    1604              :                         }
    1605         6469 :                         expect (TokenType.CLOSE_PARENS);
    1606              :                 } else {
    1607            6 :                         params.add (parse_lambda_parameter ());
    1608              :                 }
    1609         6475 :                 expect (TokenType.LAMBDA);
    1610              : 
    1611              :                 LambdaExpression lambda;
    1612        12950 :                 if (current () == TokenType.OPEN_BRACE) {
    1613         4923 :                         var block = parse_block ();
    1614         4923 :                         lambda = new LambdaExpression.with_statement_body (block, get_src (begin));
    1615              :                 } else {
    1616         1552 :                         var expr = parse_expression ();
    1617         1552 :                         lambda = new LambdaExpression (expr, get_src (begin));
    1618              :                 }
    1619        31283 :                 foreach (var param in params) {
    1620        12404 :                         lambda.add_parameter (param);
    1621              :                 }
    1622         6475 :                 return lambda;
    1623              :         }
    1624              : 
    1625      2380849 :         AssignmentOperator get_assignment_operator (TokenType token_type) {
    1626      2380849 :                 switch (token_type) {
    1627              :                 case TokenType.ASSIGN:             return AssignmentOperator.SIMPLE;
    1628              :                 case TokenType.ASSIGN_ADD:         return AssignmentOperator.ADD;
    1629              :                 case TokenType.ASSIGN_SUB:         return AssignmentOperator.SUB;
    1630              :                 case TokenType.ASSIGN_BITWISE_OR:  return AssignmentOperator.BITWISE_OR;
    1631              :                 case TokenType.ASSIGN_BITWISE_AND: return AssignmentOperator.BITWISE_AND;
    1632              :                 case TokenType.ASSIGN_BITWISE_XOR: return AssignmentOperator.BITWISE_XOR;
    1633              :                 case TokenType.ASSIGN_DIV:         return AssignmentOperator.DIV;
    1634              :                 case TokenType.ASSIGN_MUL:         return AssignmentOperator.MUL;
    1635              :                 case TokenType.ASSIGN_PERCENT:     return AssignmentOperator.PERCENT;
    1636              :                 case TokenType.ASSIGN_SHIFT_LEFT:  return AssignmentOperator.SHIFT_LEFT;
    1637              :                 default:                           return AssignmentOperator.NONE;
    1638              :                 }
    1639              :         }
    1640              : 
    1641      2265006 :         Expression parse_expression () throws ParseError {
    1642      2265006 :                 if (is_lambda_expression ()) {
    1643         6475 :                         return parse_lambda_expression ();
    1644              :                 }
    1645              : 
    1646      2258531 :                 var begin = get_location ();
    1647              : 
    1648      2258531 :                 Expression expr = parse_conditional_expression ();
    1649              : 
    1650      2380849 :                 while (true) {
    1651      2380849 :                         var operator = get_assignment_operator (current ());
    1652      2503176 :                         if (operator != AssignmentOperator.NONE) {
    1653       122328 :                                 next ();
    1654       122328 :                                 var rhs = parse_expression ();
    1655       122327 :                                 expr = new Assignment (expr, rhs, operator, get_src (begin));
    1656      2258521 :                         } else if (current () == TokenType.OP_GT) { // >>=
    1657            2 :                                 char* first_gt_pos = tokens[index].begin.pos;
    1658            2 :                                 next ();
    1659              :                                 // only accept >>= when there is no space between the two > signs
    1660            4 :                                 if (current () == TokenType.OP_GE && tokens[index].begin.pos == first_gt_pos + 1) {
    1661            2 :                                         next ();
    1662            2 :                                         var rhs = parse_expression ();
    1663            2 :                                         expr = new Assignment (expr, rhs, AssignmentOperator.SHIFT_RIGHT, get_src (begin));
    1664              :                                 } else {
    1665            0 :                                         prev ();
    1666            0 :                                         break;
    1667              :                                 }
    1668              :                         } else {
    1669              :                                 break;
    1670              :                         }
    1671              :                 }
    1672              : 
    1673              :                 return expr;
    1674              :         }
    1675              : 
    1676       273604 :         Statement? parse_statement (TokenType type) throws ParseError {
    1677       273604 :                 Statement? stmt = null;
    1678       273604 :                 var begin = get_location ();
    1679       273622 :                 try {
    1680       273604 :                         switch (type) {
    1681              :                         case TokenType.IF:
    1682        78219 :                                 stmt = parse_if_statement ();
    1683              :                                 break;
    1684              :                         case TokenType.SWITCH:
    1685          112 :                                 stmt = parse_switch_statement ();
    1686              :                                 break;
    1687              :                         case TokenType.CASE:
    1688              :                         case TokenType.DEFAULT:
    1689            3 :                                 stmt = parse_switch_section_statement ();
    1690              :                                 break;
    1691              :                         case TokenType.WHILE:
    1692         9355 :                                 stmt = parse_while_statement ();
    1693              :                                 break;
    1694              :                         case TokenType.DO:
    1695            8 :                                 stmt = parse_do_statement ();
    1696              :                                 break;
    1697              :                         case TokenType.FOR:
    1698         4765 :                                 stmt = parse_for_statement ();
    1699              :                                 break;
    1700              :                         case TokenType.FOREACH:
    1701          654 :                                 stmt = parse_foreach_statement ();
    1702              :                                 break;
    1703              :                         case TokenType.BREAK:
    1704         5075 :                                 stmt = parse_break_statement ();
    1705              :                                 break;
    1706              :                         case TokenType.CONTINUE:
    1707          115 :                                 stmt = parse_continue_statement ();
    1708              :                                 break;
    1709              :                         case TokenType.RETURN:
    1710       170349 :                                 stmt = parse_return_statement ();
    1711              :                                 break;
    1712              :                         case TokenType.YIELD:
    1713           53 :                                 stmt = parse_yield_statement ();
    1714              :                                 break;
    1715              :                         case TokenType.THROW:
    1716         1595 :                                 stmt = parse_throw_statement ();
    1717              :                                 break;
    1718              :                         case TokenType.TRY:
    1719         3207 :                                 stmt = parse_try_statement ();
    1720              :                                 break;
    1721              :                         case TokenType.LOCK:
    1722           30 :                                 stmt = parse_lock_statement ();
    1723              :                                 break;
    1724              :                         case TokenType.UNLOCK:
    1725            4 :                                 stmt = parse_unlock_statement ();
    1726              :                                 break;
    1727              :                         case TokenType.DELETE:
    1728            7 :                                 stmt = parse_delete_statement ();
    1729              :                                 break;
    1730              :                         case TokenType.WITH:
    1731           53 :                                 stmt = parse_with_statement ();
    1732              :                                 break;
    1733              :                         default:
    1734       273583 :                                 assert_not_reached ();
    1735              :                         }
    1736              :                 } catch (ParseError e) {
    1737           21 :                         var e_begin = get_location ();
    1738           42 :                         string token = ((EnumClass) typeof (TokenType).class_ref ()).get_value (type).value_nick;
    1739           21 :                         rollback (begin);
    1740           21 :                         if (!is_expression ()) {
    1741            1 :                                 rollback (e_begin);
    1742            2 :                                 throw e;
    1743              :                         }
    1744           20 :                         try {
    1745           20 :                                 stmt = parse_expression_statement ();
    1746           18 :                                 Report.warning (get_src (begin), "`%s' is a syntax keyword, replace with `@%s'", token, token);
    1747              :                         } catch (ParseError e2) {
    1748            2 :                                 var e2_begin = get_location ();
    1749            2 :                                 rollback (e_begin);
    1750            2 :                                 next ();
    1751            2 :                                 Report.error (get_src (e_begin), "Possible `%s-statement' syntax error, %s", token, e.message);
    1752            2 :                                 rollback (e2_begin);
    1753            4 :                                 throw e2;
    1754              :                         }
    1755              :                 }
    1756              :                 return stmt;
    1757              :         }
    1758              : 
    1759       291997 :         void parse_statements (Block block) throws ParseError {
    1760       874388 :                 while (current () != TokenType.CLOSE_BRACE
    1761       583325 :                        && current () != TokenType.EOF) {
    1762      1165698 :                         try {
    1763       583316 :                                 Statement stmt = null;
    1764       583316 :                                 bool is_decl = false;
    1765              : 
    1766       583316 :                                 comment = scanner.pop_comment ();
    1767       583316 :                                 switch (current ()) {
    1768              :                                 case TokenType.OPEN_BRACE:
    1769          565 :                                         stmt = parse_block ();
    1770              :                                         break;
    1771              :                                 case TokenType.SEMICOLON:
    1772           11 :                                         stmt = parse_empty_statement ();
    1773              :                                         break;
    1774              :                                 case TokenType.IF:
    1775              :                                 case TokenType.SWITCH:
    1776              :                                 case TokenType.WHILE:
    1777              :                                 case TokenType.DO:
    1778              :                                 case TokenType.FOR:
    1779              :                                 case TokenType.FOREACH:
    1780              :                                 case TokenType.BREAK:
    1781              :                                 case TokenType.CONTINUE:
    1782              :                                 case TokenType.RETURN:
    1783              :                                 case TokenType.YIELD:
    1784              :                                 case TokenType.THROW:
    1785              :                                 case TokenType.TRY:
    1786              :                                 case TokenType.LOCK:
    1787              :                                 case TokenType.UNLOCK:
    1788              :                                 case TokenType.DELETE:
    1789              :                                 case TokenType.WITH:
    1790       270678 :                                         stmt = parse_statement (current ());
    1791              :                                         break;
    1792              :                                 case TokenType.CASE:
    1793              :                                 case TokenType.DEFAULT:
    1794          464 :                                         if (block is SwitchSection) {
    1795              :                                                 // begin a new switch case
    1796              :                                                 return;
    1797              :                                         } else {
    1798            3 :                                                 stmt = parse_statement (current ());
    1799              :                                         }
    1800              :                                         break;
    1801              :                                 case TokenType.VAR:
    1802         8027 :                                         is_decl = true;
    1803         8027 :                                         parse_local_variable_declarations (block);
    1804              :                                         break;
    1805              :                                 case TokenType.CONST:
    1806           24 :                                         is_decl = true;
    1807           24 :                                         parse_local_constant_declarations (block);
    1808              :                                         break;
    1809              :                                 case TokenType.OP_INC:
    1810              :                                 case TokenType.OP_DEC:
    1811              :                                 case TokenType.BASE:
    1812              :                                 case TokenType.THIS:
    1813              :                                 case TokenType.STAR:
    1814              :                                 case TokenType.NEW:
    1815        13043 :                                         stmt = parse_expression_statement ();
    1816              :                                         break;
    1817              :                                 default:
    1818       290504 :                                         bool is_expr = is_expression ();
    1819       290502 :                                         if (is_expr) {
    1820       483685 :                                                 stmt = parse_expression_statement ();
    1821              :                                         } else {
    1822        91114 :                                                 is_decl = true;
    1823        91114 :                                                 bool is_local_func = is_local_function ();
    1824        91114 :                                                 if (is_local_func) {
    1825            6 :                                                         parse_local_function_declaration (block);
    1826              :                                                 } else {
    1827        91108 :                                                         parse_local_variable_declarations (block);
    1828              :                                                 }
    1829              :                                         }
    1830              :                                         break;
    1831              :                                 }
    1832              : 
    1833              :                                 if (!is_decl) {
    1834       483685 :                                         block.add_statement (stmt);
    1835              :                                 }
    1836              :                         } catch (ParseError e) {
    1837            9 :                                 report_parse_error (e);
    1838            9 :                                 if (recover () != RecoveryState.STATEMENT_BEGIN) {
    1839              :                                         // beginning of next declaration or end of file reached
    1840              :                                         // return what we have so far
    1841            3 :                                         break;
    1842              :                                 }
    1843              :                         }
    1844              :                 }
    1845              :         }
    1846              : 
    1847       364228 :         bool is_expression () throws ParseError {
    1848       364228 :                 if (current () == TokenType.OPEN_PARENS) {
    1849         4712 :                         return !is_inner_array_type ();
    1850              :                 }
    1851              : 
    1852       359516 :                 var begin = get_location ();
    1853              : 
    1854              :                 // decide between declaration and expression statement
    1855       359516 :                 try {
    1856       359516 :                         skip_type ();
    1857              :                 } catch (ParseError e) {
    1858            4 :                         var token = previous ();
    1859            4 :                         if (token == TokenType.DOT || token == TokenType.DOUBLE_COLON) {
    1860            0 :                                 rollback (begin);
    1861            0 :                                 return true;
    1862              :                         } else {
    1863            8 :                                 throw e;
    1864              :                         }
    1865              :                 }
    1866       359512 :                 switch (current ()) {
    1867              :                 // invocation expression
    1868              :                 case TokenType.OPEN_PARENS:
    1869              :                 // postfix increment
    1870              :                 case TokenType.OP_INC:
    1871              :                 // postfix decrement
    1872              :                 case TokenType.OP_DEC:
    1873              :                 // assignments
    1874              :                 case TokenType.ASSIGN:
    1875              :                 case TokenType.ASSIGN_ADD:
    1876              :                 case TokenType.ASSIGN_BITWISE_AND:
    1877              :                 case TokenType.ASSIGN_BITWISE_OR:
    1878              :                 case TokenType.ASSIGN_BITWISE_XOR:
    1879              :                 case TokenType.ASSIGN_DIV:
    1880              :                 case TokenType.ASSIGN_MUL:
    1881              :                 case TokenType.ASSIGN_PERCENT:
    1882              :                 case TokenType.ASSIGN_SHIFT_LEFT:
    1883              :                 case TokenType.ASSIGN_SUB:
    1884              :                 case TokenType.OP_GT: // >>=
    1885              :                 // member access
    1886              :                 case TokenType.DOT:
    1887              :                 // pointer member access
    1888              :                 case TokenType.OP_PTR:
    1889              :                 // literal expression
    1890              :                 case TokenType.INTEGER_LITERAL:
    1891              :                 case TokenType.REAL_LITERAL:
    1892       197816 :                         rollback (begin);
    1893       197816 :                         return true;
    1894              :                 default:
    1895       161696 :                         rollback (begin);
    1896       161696 :                         return false;
    1897              :                 }
    1898              :         }
    1899              : 
    1900      2265006 :         bool is_lambda_expression () {
    1901      2265006 :                 var begin = get_location ();
    1902              : 
    1903      2265006 :                 switch (current ()) {
    1904              :                 case TokenType.OUT:
    1905              :                 case TokenType.REF:
    1906            2 :                         next ();
    1907            2 :                         if (accept (TokenType.IDENTIFIER) && accept (TokenType.LAMBDA)) {
    1908            1 :                                 rollback (begin);
    1909            1 :                                 return true;
    1910              :                         }
    1911              :                         break;
    1912              :                 case TokenType.IDENTIFIER:
    1913       773530 :                         next ();
    1914       773530 :                         if (accept (TokenType.LAMBDA)) {
    1915            5 :                                 rollback (begin);
    1916            5 :                                 return true;
    1917              :                         }
    1918              :                         break;
    1919              :                 case TokenType.OPEN_PARENS:
    1920       232437 :                         next ();
    1921       232437 :                         if (current () != TokenType.CLOSE_PARENS) {
    1922       367472 :                                 do {
    1923       238368 :                                         if (current () == TokenType.OUT || current () == TokenType.REF) {
    1924            6 :                                                 next ();
    1925              :                                         }
    1926       238368 :                                         if (!accept (TokenType.IDENTIFIER)) {
    1927       103100 :                                                 rollback (begin);
    1928       103100 :                                                 return false;
    1929              :                                         }
    1930       135268 :                                 } while (accept (TokenType.COMMA));
    1931              :                         }
    1932       129337 :                         if (accept (TokenType.CLOSE_PARENS) && accept (TokenType.LAMBDA)) {
    1933         6469 :                                 rollback (begin);
    1934         6469 :                                 return true;
    1935              :                         }
    1936              :                         break;
    1937              :                 default:
    1938              :                         break;
    1939              :                 }
    1940              : 
    1941      2155431 :                 rollback (begin);
    1942      2155431 :                 return false;
    1943              :         }
    1944              : 
    1945        91114 :         bool is_local_function () {
    1946        91114 :                 var begin = get_location ();
    1947              : 
    1948        91108 :                 try {
    1949        91114 :                         skip_modifier_keyword ();
    1950        91114 :                         skip_type ();
    1951        91114 :                         if (accept (TokenType.IDENTIFIER) && accept (TokenType.OPEN_PARENS)) {
    1952            6 :                                 rollback (begin);
    1953            6 :                                 return true;
    1954              :                         }
    1955              :                 } catch {
    1956              :                 }
    1957              : 
    1958        91108 :                 rollback (begin);
    1959        91108 :                 return false;
    1960              :         }
    1961              : 
    1962       146020 :         Block parse_embedded_statement (string statement_name, bool accept_empty_body = true) throws ParseError {
    1963       146020 :                 if (current () == TokenType.OPEN_BRACE) {
    1964       143064 :                         var block = parse_block ();
    1965              :                         return block;
    1966              :                 }
    1967              : 
    1968         2956 :                 comment = scanner.pop_comment ();
    1969              : 
    1970         2956 :                 var block = new Block (get_src (get_location ()));
    1971              : 
    1972         5908 :                 try {
    1973         2956 :                         var stmt = parse_embedded_statement_without_block (statement_name, accept_empty_body);
    1974         2952 :                         block.add_statement (stmt);
    1975              :                 } catch (ParseError e) {
    1976            4 :                         if (context.keep_going) {
    1977            0 :                                 report_parse_error (e);
    1978              :                         } else {
    1979            8 :                                 throw e;
    1980              :                         }
    1981              :                 }
    1982         2952 :                 block.source_reference.end = get_last_src ().end;
    1983              : 
    1984              :                 return block;
    1985              : 
    1986              :         }
    1987              : 
    1988         2956 :         Statement parse_embedded_statement_without_block (string statement_name, bool accept_empty_body) throws ParseError {
    1989         2956 :                 switch (current ()) {
    1990              :                 case TokenType.SEMICOLON:
    1991            9 :                         if (!accept_empty_body) {
    1992            1 :                                 Report.warning (get_current_src (), "%s-statement without body", statement_name);
    1993              :                         }
    1994            9 :                         return parse_empty_statement ();
    1995              :                 case TokenType.IF:
    1996              :                 case TokenType.SWITCH:
    1997              :                 case TokenType.WHILE:
    1998              :                 case TokenType.DO:
    1999              :                 case TokenType.FOR:
    2000              :                 case TokenType.FOREACH:
    2001              :                 case TokenType.BREAK:
    2002              :                 case TokenType.CONTINUE:
    2003              :                 case TokenType.RETURN:
    2004              :                 case TokenType.YIELD:
    2005              :                 case TokenType.THROW:
    2006              :                 case TokenType.TRY:
    2007              :                 case TokenType.LOCK:
    2008              :                 case TokenType.UNLOCK:
    2009              :                 case TokenType.DELETE:
    2010              :                 case TokenType.WITH:
    2011         2923 :                         return parse_statement (current ());
    2012              :                 case TokenType.VAR:
    2013              :                 case TokenType.CONST:
    2014            1 :                         throw new ParseError.SYNTAX ("embedded statement cannot be declaration ");
    2015              :                 case TokenType.OP_INC:
    2016              :                 case TokenType.OP_DEC:
    2017              :                 case TokenType.BASE:
    2018              :                 case TokenType.THIS:
    2019              :                 case TokenType.OPEN_PARENS:
    2020              :                 case TokenType.STAR:
    2021              :                 case TokenType.NEW:
    2022            0 :                         return parse_expression_statement ();
    2023              :                 default:
    2024           23 :                         if (is_expression ()) {
    2025           20 :                                 return parse_expression_statement ();
    2026              :                         } else {
    2027            1 :                                 throw new ParseError.SYNTAX ("embedded statement cannot be declaration");
    2028              :                         }
    2029              :                 }
    2030              :         }
    2031              : 
    2032       290960 :         Block parse_block () throws ParseError {
    2033       290960 :                 var begin = get_location ();
    2034       290960 :                 expect (TokenType.OPEN_BRACE);
    2035       290959 :                 var block = new Block (get_src (begin));
    2036       290959 :                 parse_statements (block);
    2037       290959 :                 if (!accept (TokenType.CLOSE_BRACE)) {
    2038              :                         // only report error if it's not a secondary error
    2039            6 :                         if (context.report.get_errors () == 0) {
    2040            1 :                                 Report.error (get_current_src (), "expected `}'");
    2041              :                         }
    2042              :                 }
    2043              : 
    2044       290959 :                 block.source_reference.end = get_last_src ().end;
    2045              : 
    2046              :                 return block;
    2047              :         }
    2048              : 
    2049           20 :         Statement parse_empty_statement () throws ParseError {
    2050           20 :                 var begin = get_location ();
    2051           20 :                 expect (TokenType.SEMICOLON);
    2052           20 :                 return new EmptyStatement (get_src (begin));
    2053              :         }
    2054              : 
    2055       201636 :         void parse_local_variable_declarations (Block block) throws ParseError {
    2056       100818 :                 var begin = get_location ();
    2057              :                 DataType variable_type;
    2058       100818 :                 bool is_dynamic = accept (TokenType.DYNAMIC);
    2059       100818 :                 if (accept (TokenType.UNOWNED) && accept (TokenType.VAR)) {
    2060           12 :                         variable_type = new VarType (false);
    2061           12 :                         variable_type.nullable = accept (TokenType.INTERR);
    2062           12 :                         variable_type.is_dynamic = is_dynamic;
    2063              :                 } else {
    2064       100806 :                         rollback (begin);
    2065       100806 :                         is_dynamic = accept (TokenType.DYNAMIC);
    2066       100806 :                         if (accept (TokenType.VAR)) {
    2067         8040 :                                 variable_type = new VarType ();
    2068         8040 :                                 variable_type.nullable = accept (TokenType.INTERR);
    2069         8040 :                                 variable_type.is_dynamic = is_dynamic;
    2070              :                         } else {
    2071        92766 :                                 rollback (begin);
    2072        92766 :                                 variable_type = parse_type (true, true);
    2073              :                         }
    2074              :                 }
    2075       100818 :                 bool is_first = true;
    2076       302521 :                 do {
    2077       100856 :                         if (variable_type is VarType && variable_type.value_owned && accept (TokenType.OPEN_PARENS)) {
    2078              :                                 // tuple
    2079            1 :                                 begin = get_location ();
    2080              : 
    2081            1 :                                 string[] identifiers = {};
    2082            3 :                                 do {
    2083            4 :                                         identifiers += parse_identifier ();
    2084            2 :                                 } while (accept (TokenType.COMMA));
    2085            1 :                                 expect (TokenType.CLOSE_PARENS);
    2086              : 
    2087            1 :                                 expect (TokenType.ASSIGN);
    2088            1 :                                 var tuple = parse_expression ();
    2089            1 :                                 var tuple_local = new LocalVariable (null, CodeNode.get_temp_name (), tuple, get_src (begin));
    2090            1 :                                 block.add_statement (new DeclarationStatement (tuple_local, tuple_local.source_reference));
    2091              : 
    2092            5 :                                 for (int i = 0; i < identifiers.length; i++) {
    2093            2 :                                         var temp_access = new MemberAccess.simple (tuple_local.name, tuple_local.source_reference);
    2094            2 :                                         var ea = new ElementAccess (temp_access, tuple_local.source_reference);
    2095            2 :                                         ea.append_index (new IntegerLiteral (i.to_string ()));
    2096            2 :                                         var local = new LocalVariable (null, identifiers[i], ea, tuple_local.source_reference);
    2097            2 :                                         block.add_statement (new DeclarationStatement (local, local.source_reference));
    2098              :                                 }
    2099              : 
    2100            2 :                                 continue;
    2101              :                         }
    2102              : 
    2103       100855 :                         if (!is_first) {
    2104           38 :                                 begin = get_location ();
    2105              :                         } else {
    2106              :                                 is_first = false;
    2107              :                         }
    2108              : 
    2109       100855 :                         DataType type_copy = null;
    2110       100855 :                         if (variable_type != null) {
    2111       100855 :                                 type_copy = variable_type.copy ();
    2112              :                         }
    2113       100855 :                         var local = parse_local_variable (type_copy);
    2114       100851 :                         block.add_statement (new DeclarationStatement (local, get_src (begin)));
    2115       100852 :                 } while (accept (TokenType.COMMA));
    2116       100814 :                 expect (TokenType.SEMICOLON);
    2117              :         }
    2118              : 
    2119       100870 :         LocalVariable parse_local_variable (DataType? variable_type, bool expect_initializer = false) throws ParseError {
    2120       100870 :                 var begin = get_location ();
    2121       100870 :                 string id = parse_identifier ();
    2122       100868 :                 var type = parse_inline_array_type (variable_type);
    2123       100868 :                 var src = get_src (begin);
    2124              : 
    2125       100868 :                 Expression initializer = null;
    2126       100868 :                 if (accept (TokenType.ASSIGN)) {
    2127        77429 :                         initializer = parse_expression ();
    2128        23439 :                 } else if (expect_initializer) {
    2129            2 :                         report_parse_error (new ParseError.SYNTAX ("expected initializer"));
    2130            2 :                         prev ();
    2131            2 :                         initializer = new InvalidExpression ();
    2132              :                 }
    2133       100866 :                 return new LocalVariable (type, id, initializer, src);
    2134              :         }
    2135              : 
    2136           48 :         void parse_local_constant_declarations (Block block) throws ParseError {
    2137           24 :                 var begin = get_location ();
    2138           24 :                 expect (TokenType.CONST);
    2139           24 :                 var constant_type = parse_type (false, false);
    2140              : 
    2141              :                 // constant arrays don't own their element
    2142           24 :                 unowned ArrayType? array_type = constant_type as ArrayType;
    2143            5 :                 if (array_type != null) {
    2144            5 :                         array_type.element_type.value_owned = false;
    2145              :                 }
    2146              : 
    2147              :                 bool is_first = true;
    2148           48 :                 do {
    2149           24 :                         if (!is_first) {
    2150            0 :                                 begin = get_location ();
    2151              :                         } else {
    2152              :                                 is_first = false;
    2153              :                         }
    2154              : 
    2155           24 :                         DataType type_copy = constant_type.copy ();
    2156           24 :                         var local = parse_local_constant (type_copy);
    2157           24 :                         block.add_statement (new DeclarationStatement (local, get_src (begin)));
    2158           24 :                         block.add_local_constant (local);
    2159           24 :                         local.active = false;
    2160           24 :                 } while (accept (TokenType.COMMA));
    2161           24 :                 expect (TokenType.SEMICOLON);
    2162              :         }
    2163              : 
    2164           24 :         Constant parse_local_constant (DataType constant_type) throws ParseError {
    2165           24 :                 var begin = get_location ();
    2166           24 :                 string id = parse_identifier ();
    2167           24 :                 var type = parse_inline_array_type (constant_type);
    2168           24 :                 var src = get_src (begin);
    2169              : 
    2170           24 :                 expect (TokenType.ASSIGN);
    2171           24 :                 var initializer = parse_expression ();
    2172              : 
    2173           24 :                 if (type.value_owned) {
    2174            1 :                         Report.error (src, "`owned' is not allowed on constants");
    2175              :                 }
    2176              : 
    2177           24 :                 return new Constant (id, type, initializer, src);
    2178              :         }
    2179              : 
    2180           12 :         void parse_local_function_declaration (Block block) throws ParseError {
    2181            6 :                 var begin = get_location ();
    2182            6 :                 var flags = parse_member_declaration_modifiers ("local functions", ModifierFlags.STATIC);
    2183            6 :                 var type = parse_type (true, false);
    2184            6 :                 var sym = parse_symbol_name ();
    2185              : 
    2186            6 :                 expect (TokenType.OPEN_PARENS);
    2187            6 :                 List<Parameter> params = new ArrayList<Parameter> ();
    2188            6 :                 if (current () != TokenType.CLOSE_PARENS) {
    2189           17 :                         do {
    2190            6 :                                 params.add (parse_parameter ());
    2191            6 :                         } while (accept (TokenType.COMMA));
    2192              :                 }
    2193            6 :                 expect (TokenType.CLOSE_PARENS);
    2194              : 
    2195            6 :                 var src = get_src (begin);
    2196              : 
    2197            6 :                 var d = new Delegate ("_LocalFunc%i_".printf (next_local_func_id++), type, src);
    2198            6 :                 d.has_target = !(ModifierFlags.STATIC in flags);
    2199           18 :                 foreach (var param in params) {
    2200            6 :                         d.add_parameter (param);
    2201              :                 }
    2202            6 :                 context.root.add_delegate (d);
    2203              : 
    2204            6 :                 var lambda = new LambdaExpression.with_statement_body (parse_block (), src);
    2205           18 :                 foreach (var p in params) {
    2206            6 :                         var param = new Parameter (p.name, null, p.source_reference);
    2207            6 :                         param.direction = p.direction;
    2208            6 :                         lambda.add_parameter (param);
    2209              :                 }
    2210              : 
    2211            6 :                 if (!context.experimental) {
    2212            6 :                         Report.warning (src, "local functions are experimental");
    2213              :                 }
    2214              : 
    2215            6 :                 var local = new LocalVariable (new DelegateType (d), sym.name, lambda, src);
    2216            6 :                 block.add_statement (new DeclarationStatement (local, src));
    2217              :         }
    2218              : 
    2219       212505 :         Statement parse_expression_statement () throws ParseError {
    2220       212505 :                 var begin = get_location ();
    2221       212505 :                 var expr = parse_statement_expression ();
    2222       212503 :                 var src = get_src (begin);
    2223       212503 :                 expect (TokenType.SEMICOLON);
    2224       212503 :                 return new ExpressionStatement (expr, src);
    2225              :         }
    2226              : 
    2227       220350 :         Expression parse_statement_expression () throws ParseError {
    2228              :                 // invocation expression, assignment,
    2229              :                 // or pre/post increment/decrement expression
    2230       220350 :                 var expr = parse_expression ();
    2231              :                 return expr;
    2232              :         }
    2233              : 
    2234        78219 :         Statement parse_if_statement () throws ParseError {
    2235        78219 :                 var begin = get_location ();
    2236        78219 :                 expect (TokenType.IF);
    2237        78219 :                 expect (TokenType.OPEN_PARENS);
    2238        78218 :                 var condition = parse_expression ();
    2239        78218 :                 expect (TokenType.CLOSE_PARENS);
    2240        78218 :                 var src = get_src (begin);
    2241        78218 :                 var true_stmt = parse_embedded_statement ("if", false);
    2242        78217 :                 Block false_stmt = null;
    2243        78217 :                 if (accept (TokenType.ELSE)) {
    2244        52947 :                         false_stmt = parse_embedded_statement ("else", false);
    2245              :                 }
    2246        78217 :                 return new IfStatement (condition, true_stmt, false_stmt, src);
    2247              :         }
    2248              : 
    2249          112 :         Statement parse_switch_statement () throws ParseError {
    2250          112 :                 var begin = get_location ();
    2251          112 :                 expect (TokenType.SWITCH);
    2252          112 :                 expect (TokenType.OPEN_PARENS);
    2253          111 :                 var condition = parse_expression ();
    2254          111 :                 expect (TokenType.CLOSE_PARENS);
    2255          111 :                 var stmt = new SwitchStatement (condition, get_src (begin));
    2256          111 :                 expect (TokenType.OPEN_BRACE);
    2257         1249 :                 while (current () != TokenType.CLOSE_BRACE) {
    2258          571 :                         stmt.add_section ((SwitchSection) parse_switch_section_statement ());
    2259              :                 }
    2260          109 :                 expect (TokenType.CLOSE_BRACE);
    2261          109 :                 return stmt;
    2262              :         }
    2263              : 
    2264          574 :         Statement parse_switch_section_statement () throws ParseError {
    2265          574 :                 var begin = get_location ();
    2266          574 :                 var section = new SwitchSection (get_src (begin));
    2267         1236 :                 do {
    2268         1253 :                         if (accept (TokenType.CASE)) {
    2269          591 :                                 section.add_label (new SwitchLabel (parse_expression (), get_src (begin)));
    2270          592 :                                 while (current () == TokenType.COMMA) {
    2271            2 :                                         expect (TokenType.COMMA);
    2272            2 :                                         section.add_label (new SwitchLabel (parse_expression (), get_src (begin)));
    2273              :                                 }
    2274          590 :                                 expect (TokenType.COLON);
    2275           74 :                         } else if (accept (TokenType.DEFAULT)) {
    2276           73 :                                 section.add_label (new SwitchLabel.with_default (get_src (begin)));
    2277           73 :                                 expect (TokenType.COLON);
    2278              :                         } else {
    2279            1 :                                 throw new ParseError.SYNTAX ("expected `case' or `default' switch label");
    2280              :                         }
    2281          662 :                 } while (current () == TokenType.CASE || current () == TokenType.DEFAULT);
    2282          572 :                 parse_statements (section);
    2283              :                 return section;
    2284              :         }
    2285              : 
    2286         9355 :         Statement parse_while_statement () throws ParseError {
    2287         9355 :                 var begin = get_location ();
    2288         9355 :                 expect (TokenType.WHILE);
    2289         9355 :                 expect (TokenType.OPEN_PARENS);
    2290         9354 :                 var condition = parse_expression ();
    2291         9354 :                 expect (TokenType.CLOSE_PARENS);
    2292         9354 :                 var body = parse_embedded_statement ("while");
    2293         9354 :                 return new WhileStatement (condition, body, get_src (begin));
    2294              :         }
    2295              : 
    2296            8 :         Statement parse_do_statement () throws ParseError {
    2297            8 :                 var begin = get_location ();
    2298            8 :                 expect (TokenType.DO);
    2299            8 :                 var body = parse_embedded_statement ("do");
    2300            7 :                 expect (TokenType.WHILE);
    2301            7 :                 expect (TokenType.OPEN_PARENS);
    2302            7 :                 var condition = parse_expression ();
    2303            7 :                 expect (TokenType.CLOSE_PARENS);
    2304            7 :                 expect (TokenType.SEMICOLON);
    2305            7 :                 return new DoStatement (condition, body, get_src (begin));
    2306              :         }
    2307              : 
    2308         4765 :         Statement parse_for_statement () throws ParseError {
    2309         4765 :                 var begin = get_location ();
    2310         4765 :                 Block block = null;
    2311         4765 :                 expect (TokenType.FOR);
    2312         4765 :                 expect (TokenType.OPEN_PARENS);
    2313         4764 :                 var initializer_list = new ArrayList<Expression> ();
    2314         4764 :                 if (!accept (TokenType.SEMICOLON)) {
    2315              :                         bool is_expr;
    2316         4761 :                         switch (current ()) {
    2317              :                         case TokenType.VAR:
    2318              :                                 is_expr = false;
    2319              :                                 break;
    2320              :                         case TokenType.OP_INC:
    2321              :                         case TokenType.OP_DEC:
    2322              :                                 is_expr = true;
    2323              :                                 break;
    2324              :                         default:
    2325         4750 :                                 is_expr = is_expression ();
    2326              :                                 break;
    2327              :                         }
    2328              : 
    2329         4750 :                         if (is_expr) {
    2330         9234 :                                 do {
    2331         3078 :                                         initializer_list.add (parse_statement_expression ());
    2332         3078 :                                 } while (accept (TokenType.COMMA));
    2333         3078 :                                 expect (TokenType.SEMICOLON);
    2334              :                         } else {
    2335              :                                 // variable declaration in initializer
    2336         1683 :                                 var decl_begin = get_location ();
    2337         1683 :                                 block = new Block (get_src (decl_begin));
    2338         1683 :                                 parse_local_variable_declarations (block);
    2339         1683 :                                 block.source_reference.end = get_last_src ().end;
    2340              :                         }
    2341              :                 }
    2342         4764 :                 Expression condition = null;
    2343         4764 :                 if (current () != TokenType.SEMICOLON) {
    2344         4763 :                         condition = parse_expression ();
    2345              :                 }
    2346         4764 :                 expect (TokenType.SEMICOLON);
    2347         4764 :                 var iterator_list = new ArrayList<Expression> ();
    2348         4764 :                 if (current () != TokenType.CLOSE_PARENS) {
    2349        14296 :                         do {
    2350         4767 :                                 iterator_list.add (parse_statement_expression ());
    2351         4767 :                         } while (accept (TokenType.COMMA));
    2352              :                 }
    2353         4764 :                 expect (TokenType.CLOSE_PARENS);
    2354         4764 :                 var src = get_src (begin);
    2355         4764 :                 var body = parse_embedded_statement ("for");
    2356         4764 :                 var stmt = new ForStatement (condition, body, src);
    2357        10920 :                 foreach (Expression init in initializer_list) {
    2358         3078 :                         stmt.add_initializer (init);
    2359              :                 }
    2360        14298 :                 foreach (Expression iter in iterator_list) {
    2361         4767 :                         stmt.add_iterator (iter);
    2362              :                 }
    2363         4764 :                 if (block != null) {
    2364         1683 :                         block.add_statement (stmt);
    2365         1683 :                         return block;
    2366              :                 } else {
    2367         3081 :                         return stmt;
    2368              :                 }
    2369              :         }
    2370              : 
    2371          654 :         Statement parse_foreach_statement () throws ParseError {
    2372          654 :                 var begin = get_location ();
    2373          654 :                 expect (TokenType.FOREACH);
    2374          654 :                 expect (TokenType.OPEN_PARENS);
    2375          653 :                 var var_or_type = get_location ();
    2376              :                 DataType type;
    2377          653 :                 bool is_dynamic = accept (TokenType.DYNAMIC);
    2378          653 :                 if (accept (TokenType.UNOWNED) && accept (TokenType.VAR)) {
    2379            5 :                         type = new VarType (false);
    2380            5 :                         type.nullable = accept (TokenType.INTERR);
    2381            5 :                         type.is_dynamic = is_dynamic;
    2382              :                 } else {
    2383          648 :                         rollback (var_or_type);
    2384          648 :                         is_dynamic = accept (TokenType.DYNAMIC);
    2385         1144 :                         if (accept (TokenType.VAR)) {
    2386          151 :                                 type = new VarType ();
    2387          151 :                                 type.nullable = accept (TokenType.INTERR);
    2388          151 :                                 type.is_dynamic = is_dynamic;
    2389              :                         } else {
    2390          497 :                                 rollback (var_or_type);
    2391          498 :                                 type = parse_type (true, true);
    2392          497 :                                 if (accept (TokenType.IN)) {
    2393            1 :                                         Report.error (type.source_reference, "syntax error, expected `unowned var', `var' or type");
    2394            1 :                                         throw new ParseError.SYNTAX ("expected `unowned var', `var' or type");
    2395              :                                 }
    2396              :                         }
    2397              :                 }
    2398          652 :                 string id = parse_identifier ();
    2399          652 :                 expect (TokenType.IN);
    2400          652 :                 var collection = parse_expression ();
    2401          652 :                 expect (TokenType.CLOSE_PARENS);
    2402          652 :                 var src = get_src (begin);
    2403          652 :                 var body = parse_embedded_statement ("foreach");
    2404          652 :                 return new ForeachStatement (type, id, collection, body, src);
    2405              :         }
    2406              : 
    2407         5075 :         Statement parse_break_statement () throws ParseError {
    2408         5075 :                 var begin = get_location ();
    2409         5075 :                 expect (TokenType.BREAK);
    2410         5075 :                 var src = get_src (begin);
    2411         5075 :                 expect (TokenType.SEMICOLON);
    2412         5075 :                 return new BreakStatement (src);
    2413              :         }
    2414              : 
    2415          115 :         Statement parse_continue_statement () throws ParseError {
    2416          115 :                 var begin = get_location ();
    2417          115 :                 expect (TokenType.CONTINUE);
    2418          115 :                 var src = get_src (begin);
    2419          115 :                 expect (TokenType.SEMICOLON);
    2420          115 :                 return new ContinueStatement (src);
    2421              :         }
    2422              : 
    2423       170349 :         Statement parse_return_statement () throws ParseError {
    2424       170349 :                 var begin = get_location ();
    2425       170349 :                 expect (TokenType.RETURN);
    2426       170349 :                 Expression expr = null;
    2427       170349 :                 if (current () != TokenType.SEMICOLON) {
    2428       170032 :                         expr = parse_expression ();
    2429              :                 }
    2430       170348 :                 var src = get_src (begin);
    2431       170348 :                 expect (TokenType.SEMICOLON);
    2432       170348 :                 return new ReturnStatement (expr, src);
    2433              :         }
    2434              : 
    2435           53 :         Statement parse_yield_statement () throws ParseError {
    2436           53 :                 var begin = get_location ();
    2437           53 :                 expect (TokenType.YIELD);
    2438           53 :                 var token = current ();
    2439           53 :                 if (token != TokenType.SEMICOLON) {
    2440              :                         // yield expression
    2441           35 :                         prev ();
    2442           35 :                         if (token == TokenType.RETURN) {
    2443            1 :                                 throw new ParseError.SYNTAX ("expected `return yield'");
    2444              :                         }
    2445           34 :                         return parse_expression_statement ();
    2446              :                 }
    2447           18 :                 var src = get_src (begin);
    2448           18 :                 expect (TokenType.SEMICOLON);
    2449           18 :                 return new YieldStatement (src);
    2450              :         }
    2451              : 
    2452         1595 :         Statement parse_throw_statement () throws ParseError {
    2453         1595 :                 var begin = get_location ();
    2454         1595 :                 expect (TokenType.THROW);
    2455         1595 :                 var expr = parse_expression ();
    2456         1594 :                 var src = get_src (begin);
    2457         1594 :                 expect (TokenType.SEMICOLON);
    2458         1594 :                 return new ThrowStatement (expr, src);
    2459              :         }
    2460              : 
    2461         3207 :         Statement parse_try_statement () throws ParseError {
    2462         3207 :                 var begin = get_location ();
    2463         3207 :                 expect (TokenType.TRY);
    2464         3207 :                 var try_block = parse_block ();
    2465         3206 :                 Block finally_clause = null;
    2466         3206 :                 var catch_clauses = new ArrayList<CatchClause> ();
    2467         3206 :                 if (current () == TokenType.CATCH) {
    2468         3190 :                         parse_catch_clauses (catch_clauses);
    2469         3190 :                         if (current () == TokenType.FINALLY) {
    2470            4 :                                 finally_clause = parse_finally_clause ();
    2471              :                         }
    2472           16 :                 } else if (current () == TokenType.FINALLY) {
    2473           14 :                         finally_clause = parse_finally_clause ();
    2474              :                 } else {
    2475            2 :                         report_parse_error (new ParseError.SYNTAX ("expected `catch' or `finally'"));
    2476              :                 }
    2477         3206 :                 var stmt = new TryStatement (try_block, finally_clause, get_src (begin));
    2478         9608 :                 foreach (CatchClause clause in catch_clauses) {
    2479         3201 :                         stmt.add_catch_clause (clause);
    2480              :                 }
    2481         3206 :                 return stmt;
    2482              :         }
    2483              : 
    2484         3190 :         void parse_catch_clauses (List<CatchClause> catch_clauses) throws ParseError {
    2485         6391 :                 while (current () == TokenType.CATCH) {
    2486         3201 :                         var begin = get_location ();
    2487         3201 :                         expect (TokenType.CATCH);
    2488         3201 :                         DataType type = null;
    2489         3201 :                         string id = null;
    2490         3201 :                         if (accept (TokenType.OPEN_PARENS)) {
    2491         3150 :                                 type = parse_type (true, true);
    2492         3150 :                                 id = parse_identifier ();
    2493         3150 :                                 expect (TokenType.CLOSE_PARENS);
    2494              :                         }
    2495         3201 :                         var src = get_src (begin);
    2496         3201 :                         var block = parse_block ();
    2497         3201 :                         catch_clauses.add (new CatchClause (type, id, block, src));
    2498              :                 }
    2499              :         }
    2500              : 
    2501           18 :         Block parse_finally_clause () throws ParseError {
    2502           18 :                 expect (TokenType.FINALLY);
    2503           18 :                 var block = parse_block ();
    2504              :                 return block;
    2505              :         }
    2506              : 
    2507           30 :         Statement parse_lock_statement () throws ParseError {
    2508           30 :                 var begin = get_location ();
    2509           30 :                 expect (TokenType.LOCK);
    2510           30 :                 expect (TokenType.OPEN_PARENS);
    2511           29 :                 var expr = parse_expression ();
    2512           29 :                 expect (TokenType.CLOSE_PARENS);
    2513           29 :                 var src = get_src (begin);
    2514           29 :                 Block? stmt = null;
    2515           29 :                 if (current () != TokenType.SEMICOLON) {
    2516           26 :                         stmt = parse_embedded_statement ("lock", false);
    2517              :                 }
    2518           29 :                 return new LockStatement (expr, stmt, src);
    2519              :         }
    2520              : 
    2521            4 :         Statement parse_unlock_statement () throws ParseError {
    2522            4 :                 var begin = get_location ();
    2523            4 :                 expect (TokenType.UNLOCK);
    2524            4 :                 expect (TokenType.OPEN_PARENS);
    2525            3 :                 var expr = parse_expression ();
    2526            3 :                 expect (TokenType.CLOSE_PARENS);
    2527            3 :                 var src = get_src (begin);
    2528            3 :                 expect (TokenType.SEMICOLON);
    2529            3 :                 return new UnlockStatement (expr, src);
    2530              :         }
    2531              : 
    2532            7 :         Statement parse_delete_statement () throws ParseError {
    2533            7 :                 var begin = get_location ();
    2534            7 :                 expect (TokenType.DELETE);
    2535            7 :                 var expr = parse_expression ();
    2536            6 :                 var src = get_src (begin);
    2537            6 :                 expect (TokenType.SEMICOLON);
    2538            6 :                 return new DeleteStatement (expr, src);
    2539              :         }
    2540              : 
    2541           53 :         Statement? parse_with_statement () throws ParseError {
    2542           53 :                 var begin = get_location ();
    2543           53 :                 expect (TokenType.WITH);
    2544           53 :                 expect (TokenType.OPEN_PARENS);
    2545           52 :                 var expr_or_decl = get_location ();
    2546              : 
    2547           52 :                 LocalVariable? local = null;
    2548              : 
    2549              :                 // Try "with (expr)"
    2550              :                 Expression expr;
    2551           52 :                 try {
    2552           52 :                         expr = parse_expression ();
    2553              :                 } catch {
    2554            2 :                         expr = null;
    2555              :                 }
    2556           67 :                 if (expr == null || !accept (TokenType.CLOSE_PARENS)) {
    2557              :                         // Try "with (var identifier = expr)"
    2558           16 :                         rollback (expr_or_decl);
    2559              :                         DataType variable_type;
    2560           16 :                         bool is_dynamic = accept (TokenType.DYNAMIC);
    2561           16 :                         if (accept (TokenType.UNOWNED) && accept (TokenType.VAR)) {
    2562            4 :                                 variable_type = new VarType (false);
    2563            4 :                                 variable_type.nullable = accept (TokenType.INTERR);
    2564            4 :                                 variable_type.is_dynamic = is_dynamic;
    2565              :                         } else {
    2566           12 :                                 rollback (expr_or_decl);
    2567           12 :                                 is_dynamic = accept (TokenType.DYNAMIC);
    2568           12 :                                 if (accept (TokenType.VAR)) {
    2569            7 :                                         variable_type = new VarType ();
    2570            7 :                                         variable_type.nullable = accept (TokenType.INTERR);
    2571            7 :                                         variable_type.is_dynamic = is_dynamic;
    2572              :                                 } else {
    2573           12 :                                         variable_type = parse_type (true, true);
    2574              :                                 }
    2575              :                         }
    2576           15 :                         local = parse_local_variable (variable_type, true);
    2577           30 :                         expr = local.initializer;
    2578           15 :                         expect (TokenType.CLOSE_PARENS);
    2579              :                 }
    2580              : 
    2581           51 :                 var src = get_src (begin);
    2582           51 :                 if (!context.experimental) {
    2583           51 :                         Report.warning (src, "`with' statements are experimental");
    2584              :                 }
    2585           51 :                 var body = parse_embedded_statement ("with", false);
    2586           49 :                 return new WithStatement (local, expr, body, src);
    2587              :         }
    2588              : 
    2589      9677377 :         string parse_attribute_value () throws ParseError {
    2590      9677377 :                 switch (current ()) {
    2591              :                 case TokenType.NULL:
    2592              :                 case TokenType.TRUE:
    2593              :                 case TokenType.FALSE:
    2594              :                 case TokenType.INTEGER_LITERAL:
    2595              :                 case TokenType.REAL_LITERAL:
    2596              :                 case TokenType.STRING_LITERAL:
    2597      9611158 :                         next ();
    2598      9611158 :                         return get_last_string ();
    2599              :                 case TokenType.MINUS:
    2600        66218 :                         next ();
    2601        66218 :                         switch (current ()) {
    2602              :                         case TokenType.INTEGER_LITERAL:
    2603              :                         case TokenType.REAL_LITERAL:
    2604        66217 :                                 next ();
    2605        66217 :                                 return "-" + get_last_string ();
    2606              :                         default:
    2607            1 :                                 throw new ParseError.SYNTAX ("expected number");
    2608              :                         }
    2609              :                 default:
    2610            1 :                         throw new ParseError.SYNTAX ("expected literal");
    2611              :                 }
    2612              :         }
    2613              : 
    2614     21340969 :         List<Attribute>? parse_attributes () throws ParseError {
    2615     21340969 :                 if (current () != TokenType.OPEN_BRACKET) {
    2616              :                         return null;
    2617              :                 }
    2618      5785280 :                 var attrs = new ArrayList<Attribute> ();
    2619     13144312 :                 while (accept (TokenType.OPEN_BRACKET)) {
    2620     14725824 :                         do {
    2621      7366792 :                                 var begin = get_location ();
    2622      7366794 :                                 string id = parse_identifier ();
    2623      7366792 :                                 var attr = new Attribute (id, get_src (begin));
    2624      7366792 :                                 if (accept (TokenType.OPEN_PARENS)) {
    2625      6639449 :                                         if (current () != TokenType.CLOSE_PARENS) {
    2626     16264822 :                                                 do {
    2627      9677377 :                                                         id = parse_identifier ();
    2628      9677377 :                                                         expect (TokenType.ASSIGN);
    2629      9677377 :                                                         attr.add_argument (id, parse_attribute_value ());
    2630      9677375 :                                                 } while (accept (TokenType.COMMA));
    2631              :                                         }
    2632      6639447 :                                         expect (TokenType.CLOSE_PARENS);
    2633              :                                 }
    2634      7366790 :                                 attrs.add (attr);
    2635      7366790 :                         } while (accept (TokenType.COMMA));
    2636      7359032 :                         expect (TokenType.CLOSE_BRACKET);
    2637              :                 }
    2638              :                 return attrs;
    2639              :         }
    2640              : 
    2641     20974358 :         void set_attributes (CodeNode node, List<Attribute>? attributes) {
    2642     20974358 :                 if (attributes != null) {
    2643     20483246 :                         foreach (Attribute attr in (List<Attribute>) attributes) {
    2644      7354399 :                                 if (node.has_attribute (attr.name)) {
    2645            1 :                                         Report.error (attr.source_reference, "duplicate attribute `%s'", attr.name);
    2646              :                                 }
    2647     14708798 :                                 node.attributes.append (attr);
    2648              :                         }
    2649              :                 }
    2650              :         }
    2651              : 
    2652           10 :         void parse_main_block (Symbol parent) throws ParseError {
    2653            5 :                 var begin = get_location ();
    2654              : 
    2655            5 :                 var method = new Method.main_block (new SourceReference (scanner.source_file, begin, begin));
    2656            5 :                 method.access = SymbolAccessibility.PUBLIC;
    2657            5 :                 method.binding = MemberBinding.STATIC;
    2658            5 :                 method.body = new Block (get_src (begin));
    2659            5 :                 parse_statements (method.body);
    2660            5 :                 if (current () != TokenType.EOF) {
    2661            0 :                         Report.error (get_current_src (), "expected end of file");
    2662              :                 }
    2663              : 
    2664            5 :                 method.body.source_reference.end = get_current_src ().end;
    2665              : 
    2666            5 :                 if (!context.experimental) {
    2667            5 :                         Report.warning (method.source_reference, "main blocks are experimental");
    2668              :                 }
    2669              : 
    2670            5 :                 parent.add_method (method);
    2671              :         }
    2672              : 
    2673      9661495 :         void parse_declaration (Symbol parent, bool root = false) throws ParseError {
    2674      9661495 :                 comment = scanner.pop_comment ();
    2675      9661495 :                 var attrs = parse_attributes ();
    2676              : 
    2677      9661493 :                 var begin = get_location ();
    2678              : 
    2679      9661493 :                 TokenType last_keyword = current ();
    2680              : 
    2681     23513253 :                 while (is_declaration_keyword (current ())) {
    2682     13851760 :                         last_keyword = current ();
    2683     13851760 :                         next ();
    2684              :                 }
    2685              : 
    2686      9661493 :                 switch (current ()) {
    2687              :                 case TokenType.CONSTRUCT:
    2688           40 :                         if (context.profile == Profile.GOBJECT) {
    2689           40 :                                 rollback (begin);
    2690           40 :                                 if (!(parent is TypeSymbol)) {
    2691            0 :                                         throw new ParseError.SYNTAX ("unexpected `construct' declaration");
    2692              :                                 }
    2693           40 :                                 parse_constructor_declaration (parent, attrs);
    2694           40 :                                 return;
    2695              :                         }
    2696              :                         break;
    2697              :                 case TokenType.TILDE:
    2698           25 :                         rollback (begin);
    2699           25 :                         if (!(parent is TypeSymbol)) {
    2700            0 :                                 throw new ParseError.SYNTAX ("unexpected `destructor' declaration");
    2701              :                         }
    2702           25 :                         parse_destructor_declaration (parent, attrs);
    2703           25 :                         return;
    2704              :                 case TokenType.OPEN_BRACE:
    2705              :                 case TokenType.SEMICOLON:
    2706              :                 case TokenType.IF:
    2707              :                 case TokenType.SWITCH:
    2708              :                 case TokenType.WHILE:
    2709              :                 case TokenType.DO:
    2710              :                 case TokenType.FOR:
    2711              :                 case TokenType.FOREACH:
    2712              :                 case TokenType.BREAK:
    2713              :                 case TokenType.CONTINUE:
    2714              :                 case TokenType.RETURN:
    2715              :                 case TokenType.YIELD:
    2716              :                 case TokenType.THROW:
    2717              :                 case TokenType.TRY:
    2718              :                 case TokenType.LOCK:
    2719              :                 case TokenType.UNLOCK:
    2720              :                 case TokenType.DELETE:
    2721              :                 case TokenType.VAR:
    2722              :                 case TokenType.OP_INC:
    2723              :                 case TokenType.OP_DEC:
    2724              :                 case TokenType.BASE:
    2725              :                 case TokenType.THIS:
    2726              :                 case TokenType.STAR:
    2727              :                 case TokenType.NEW:
    2728              :                         // statement
    2729            4 :                         if (attrs != null) {
    2730              :                                 // no attributes allowed before statements
    2731            0 :                                 throw new ParseError.SYNTAX ("expected statement");
    2732              :                         }
    2733            4 :                         if (!root) {
    2734            1 :                                 throw new ParseError.SYNTAX ("statements outside blocks allowed only in root namespace");
    2735              :                         }
    2736            3 :                         rollback (begin);
    2737            3 :                         parse_main_block (parent);
    2738              :                         return;
    2739              :                 default:
    2740      9661424 :                         if (root) {
    2741        68930 :                                 bool is_expr = is_expression ();
    2742        68930 :                                 if (is_expr) {
    2743            2 :                                         rollback (begin);
    2744            2 :                                         parse_main_block (parent);
    2745            2 :                                         return;
    2746              :                                 }
    2747              :                         }
    2748              : 
    2749      9661422 :                         skip_type ();
    2750     11111511 :                         switch (current ()) {
    2751              :                         case TokenType.OPEN_BRACE:
    2752              :                         case TokenType.SEMICOLON:
    2753              :                         case TokenType.COLON:
    2754       885029 :                                 rollback (begin);
    2755       885029 :                                 switch (last_keyword) {
    2756              :                                 case TokenType.CLASS:
    2757      1257181 :                                         parse_class_declaration (parent, attrs);
    2758       373719 :                                         return;
    2759              :                                 case TokenType.ENUM:
    2760       209059 :                                         parse_enum_declaration (parent, attrs);
    2761       209059 :                                         return;
    2762              :                                 case TokenType.ERRORDOMAIN:
    2763        30819 :                                         parse_errordomain_declaration (parent, attrs);
    2764        30819 :                                         return;
    2765              :                                 case TokenType.INTERFACE:
    2766        58551 :                                         parse_interface_declaration (parent, attrs);
    2767        58551 :                                         return;
    2768              :                                 case TokenType.NAMESPACE:
    2769        68086 :                                         parse_namespace_declaration (parent, attrs);
    2770        68086 :                                         return;
    2771              :                                 case TokenType.STRUCT:
    2772       143227 :                                         parse_struct_declaration (parent, attrs);
    2773       143227 :                                         return;
    2774              :                                 default:
    2775         1567 :                                         break;
    2776              :                                 }
    2777         1567 :                                 break;
    2778              :                         case TokenType.OPEN_PARENS:
    2779       565060 :                                 rollback (begin);
    2780       565060 :                                 if (!(parent is TypeSymbol)) {
    2781            1 :                                         throw new ParseError.SYNTAX ("unexpected `constructor' declaration");
    2782              :                                 }
    2783       565059 :                                 parse_creation_method_declaration (parent, attrs);
    2784       565058 :                                 return;
    2785              :                         default:
    2786      8211333 :                                 skip_type (); // might contain type parameter list
    2787     15946047 :                                 switch (current ()) {
    2788              :                                 case TokenType.OPEN_PARENS:
    2789      6299316 :                                         rollback (begin);
    2790      6299316 :                                         switch (last_keyword) {
    2791              :                                         case TokenType.DELEGATE:
    2792       190806 :                                                 parse_delegate_declaration (parent, attrs);
    2793       190806 :                                                 return;
    2794              :                                         case TokenType.SIGNAL:
    2795       136235 :                                                 if (!(parent is ObjectTypeSymbol)) {
    2796            0 :                                                         throw new ParseError.SYNTAX ("unexpected `signal' declaration");
    2797              :                                                 }
    2798       136235 :                                                 parse_signal_declaration (parent, attrs);
    2799       136235 :                                                 return;
    2800              :                                         default:
    2801      5972275 :                                                 parse_method_declaration (parent, attrs);
    2802      5972263 :                                                 return;
    2803              :                                         }
    2804              :                                 case TokenType.ASSIGN:
    2805              :                                 case TokenType.COMMA:
    2806              :                                 case TokenType.SEMICOLON:
    2807      1225769 :                                         rollback (begin);
    2808      1225769 :                                         switch (last_keyword) {
    2809              :                                         case TokenType.CONST:
    2810       648536 :                                                 parse_constant_declaration (parent, attrs);
    2811       648536 :                                                 return;
    2812              :                                         default:
    2813       577233 :                                                 parse_field_declaration (parent, attrs);
    2814       577233 :                                                 return;
    2815              :                                         }
    2816              :                                 case TokenType.OPEN_BRACE:
    2817              :                                 case TokenType.THROWS:
    2818       447938 :                                         rollback (begin);
    2819       447938 :                                         if (!(parent is TypeSymbol)) {
    2820            0 :                                                 throw new ParseError.SYNTAX ("unexpected `property' declaration");
    2821              :                                         }
    2822       447938 :                                         parse_property_declaration (parent, attrs);
    2823       447930 :                                         return;
    2824              :                                 default:
    2825              :                                         break;
    2826              :                                 }
    2827              :                                 break;
    2828              :                         }
    2829              :                         break;
    2830              :                 }
    2831              : 
    2832         1568 :                 rollback (begin);
    2833              : 
    2834         1568 :                 throw new ParseError.SYNTAX ("expected declaration");
    2835              :         }
    2836              : 
    2837       650223 :         void parse_declarations (Symbol parent, bool root = false) throws ParseError {
    2838       650197 :                 if (!root) {
    2839       575506 :                         expect (TokenType.OPEN_BRACE);
    2840              :                 }
    2841     10006170 :                 while (current () != TokenType.CLOSE_BRACE && current () != TokenType.EOF) {
    2842      9355973 :                         try {
    2843      9355999 :                                 parse_declaration (parent, (parent == context.root));
    2844              :                         } catch (ParseError e) {
    2845           27 :                                 report_parse_error (e);
    2846              :                                 int r;
    2847           29 :                                 do {
    2848           28 :                                         r = recover ();
    2849           28 :                                         if (r == RecoveryState.STATEMENT_BEGIN) {
    2850            1 :                                                 next ();
    2851              :                                         } else {
    2852              :                                                 break;
    2853              :                                         }
    2854              :                                 } while (true);
    2855           27 :                                 if (r == RecoveryState.EOF) {
    2856           26 :                                         return;
    2857              :                                 }
    2858              :                         }
    2859              :                 }
    2860       650171 :                 if (!root) {
    2861       575487 :                         if (!accept (TokenType.CLOSE_BRACE)) {
    2862              :                                 // only report error if it's not a secondary error
    2863            0 :                                 if (context.report.get_errors () == 0) {
    2864            0 :                                         Report.error (get_current_src (), "expected `}'");
    2865              :                                 }
    2866              :                         }
    2867              :                 }
    2868              :         }
    2869              : 
    2870              :         enum RecoveryState {
    2871              :                 EOF,
    2872              :                 DECLARATION_BEGIN,
    2873              :                 STATEMENT_BEGIN
    2874              :         }
    2875              : 
    2876           37 :         RecoveryState recover () {
    2877          335 :                 while (current () != TokenType.EOF) {
    2878          306 :                         switch (current ()) {
    2879              :                         case TokenType.ABSTRACT:
    2880              :                         case TokenType.CLASS:
    2881              :                         case TokenType.CONST:
    2882              :                         case TokenType.CONSTRUCT:
    2883              :                         case TokenType.DELEGATE:
    2884              :                         case TokenType.ENUM:
    2885              :                         case TokenType.ERRORDOMAIN:
    2886              :                         case TokenType.EXTERN:
    2887              :                         case TokenType.INLINE:
    2888              :                         case TokenType.INTERFACE:
    2889              :                         case TokenType.INTERNAL:
    2890              :                         case TokenType.NAMESPACE:
    2891              :                         case TokenType.NEW:
    2892              :                         case TokenType.OVERRIDE:
    2893              :                         case TokenType.PARTIAL:
    2894              :                         case TokenType.PRIVATE:
    2895              :                         case TokenType.PROTECTED:
    2896              :                         case TokenType.PUBLIC:
    2897              :                         case TokenType.SEALED:
    2898              :                         case TokenType.SIGNAL:
    2899              :                         case TokenType.STATIC:
    2900              :                         case TokenType.STRUCT:
    2901              :                         case TokenType.VIRTUAL:
    2902              :                         case TokenType.VOLATILE:
    2903              :                                 return RecoveryState.DECLARATION_BEGIN;
    2904              :                         case TokenType.BREAK:
    2905              :                         case TokenType.CONTINUE:
    2906              :                         case TokenType.DELETE:
    2907              :                         case TokenType.DO:
    2908              :                         case TokenType.FOR:
    2909              :                         case TokenType.FOREACH:
    2910              :                         case TokenType.IF:
    2911              :                         case TokenType.LOCK:
    2912              :                         case TokenType.RETURN:
    2913              :                         case TokenType.SWITCH:
    2914              :                         case TokenType.THROW:
    2915              :                         case TokenType.TRY:
    2916              :                         case TokenType.UNLOCK:
    2917              :                         case TokenType.VAR:
    2918              :                         case TokenType.WHILE:
    2919              :                         case TokenType.WITH:
    2920              :                         case TokenType.YIELD:
    2921              :                                 return RecoveryState.STATEMENT_BEGIN;
    2922              :                         default:
    2923          298 :                                 next ();
    2924          298 :                                 break;
    2925              :                         }
    2926              :                 }
    2927              :                 return RecoveryState.EOF;
    2928              :         }
    2929              : 
    2930       136172 :         void parse_namespace_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
    2931        68086 :                 var begin = get_location ();
    2932        68086 :                 expect (TokenType.NAMESPACE);
    2933        68086 :                 var sym = parse_symbol_name ();
    2934        68086 :                 var ns = new Namespace (sym.name, get_src (begin));
    2935        68086 :                 if (comment != null) {
    2936         1529 :                         ns.add_comment (comment);
    2937         1529 :                         comment = null;
    2938              :                 }
    2939              : 
    2940        68086 :                 set_attributes (ns, attrs);
    2941              : 
    2942        68086 :                 expect (TokenType.OPEN_BRACE);
    2943              : 
    2944      6696033 :                 var old_using_directives = scanner.source_file.current_using_directives;
    2945        68086 :                 parse_using_directives (ns);
    2946              : 
    2947        68086 :                 parse_declarations (ns, true);
    2948              : 
    2949        68086 :                 scanner.source_file.current_using_directives = old_using_directives;
    2950              : 
    2951        68086 :                 if (!accept (TokenType.CLOSE_BRACE)) {
    2952              :                         // only report error if it's not a secondary error
    2953            3 :                         if (context.report.get_errors () == 0) {
    2954            1 :                                 Report.error (get_current_src (), "expected `}'");
    2955              :                         }
    2956              :                 }
    2957              : 
    2958        68086 :                 Symbol result = ns;
    2959       204278 :                 while (sym != null) {
    2960        68106 :                         sym = sym.inner;
    2961              : 
    2962        68096 :                         Symbol next = (sym != null ? new Namespace (sym.name, ns.source_reference) : parent);
    2963        68096 :                         next.add_namespace ((Namespace) result);
    2964       136192 :                         result = next;
    2965              :                 }
    2966              :         }
    2967              : 
    2968        74691 :         void parse_using_directives (Namespace ns) throws ParseError {
    2969        74890 :                 while (accept (TokenType.USING)) {
    2970          398 :                         do {
    2971          199 :                                 var begin = get_location ();
    2972          199 :                                 var sym = parse_symbol_name ();
    2973          199 :                                 var ns_ref = new UsingDirective (sym, get_src (begin));
    2974          199 :                                 scanner.source_file.add_using_directive (ns_ref);
    2975          199 :                                 ns.add_using_directive (ns_ref);
    2976          199 :                         } while (accept (TokenType.COMMA));
    2977          199 :                         expect (TokenType.SEMICOLON);
    2978              :                 }
    2979              :         }
    2980              : 
    2981       747464 :         void parse_class_declaration (Symbol parent, List<Attribute>? attrs, bool partial_reparse = false) throws ParseError {
    2982       373732 :                 var begin = get_location ();
    2983       373732 :                 var access = parse_access_modifier ();
    2984       373732 :                 var flags = parse_type_declaration_modifiers ("classes", ModifierFlags.ABSTRACT | ModifierFlags.EXTERN | ModifierFlags.PARTIAL | ModifierFlags.SEALED);
    2985       373732 :                 expect (TokenType.CLASS);
    2986       373731 :                 var sym = parse_symbol_name ();
    2987       373731 :                 var type_param_list = parse_type_parameter_list ();
    2988       373731 :                 var base_types = new ArrayList<DataType> ();
    2989       373731 :                 if (accept (TokenType.COLON)) {
    2990       905447 :                         do {
    2991       337964 :                                 base_types.add (parse_type (true, false));
    2992       337964 :                         } while (accept (TokenType.COMMA));
    2993              :                 }
    2994              : 
    2995       373731 :                 var cl = new Class (sym.name, get_src (begin), comment);
    2996       373731 :                 cl.access = access;
    2997       373731 :                 if (ModifierFlags.ABSTRACT in flags) {
    2998        32599 :                         cl.is_abstract = true;
    2999              :                 }
    3000       373731 :                 if (ModifierFlags.SEALED in flags) {
    3001        50621 :                         cl.is_sealed = true;
    3002              :                 }
    3003       373731 :                 if (ModifierFlags.PARTIAL in flags) {
    3004           24 :                         if (!context.experimental) {
    3005           24 :                                 Report.warning (cl.source_reference, "`partial' classes are experimental");
    3006              :                         }
    3007           24 :                         cl.is_partial = true;
    3008              :                 }
    3009       373731 :                 if (ModifierFlags.EXTERN in flags) {
    3010            0 :                         cl.is_extern = true;
    3011              :                 }
    3012              : 
    3013       373731 :                 Class? old_cl = null;
    3014       373743 :                 if (partial_reparse) {
    3015           12 :                         var names = new ArrayList<string> ();
    3016           14 :                         while (sym.inner != null) {
    3017            4 :                                 sym = sym.inner;
    3018            2 :                                 names.insert (0, sym.name);
    3019              :                         }
    3020           12 :                         Symbol p = parent;
    3021           16 :                         while (p != null && p != context.root) {
    3022            4 :                                 names.insert (0, p.name);
    3023            7 :                                 p = p.parent_symbol;
    3024              :                         }
    3025           24 :                         p = context.root;
    3026           18 :                         foreach (var name in names) {
    3027            6 :                                 p = p.scope.lookup (name);
    3028            6 :                                 if (p == null) {
    3029            0 :                                         break;
    3030              :                                 }
    3031              :                         }
    3032           12 :                         if (p != null) {
    3033           12 :                                 old_cl = p.scope.lookup (cl.name) as Class;
    3034              :                                 parent = p;
    3035              :                         }
    3036              :                 }
    3037       373731 :                 if (old_cl != null && old_cl.is_partial) {
    3038            6 :                         if (cl.is_partial != old_cl.is_partial) {
    3039            0 :                                 Report.error (cl.source_reference, "conflicting partial and not partial declarations of `%s'", cl.name);
    3040            0 :                                 cl.error = true;
    3041              :                         }
    3042            6 :                         if (cl.access != old_cl.access) {
    3043            3 :                                 Report.error (cl.source_reference, "partial declarations of `%s' have conflicting accessiblity modifiers", cl.name);
    3044            3 :                                 cl.error = true;
    3045              :                         }
    3046            6 :                         if (cl.is_abstract != old_cl.is_abstract) {
    3047            1 :                                 Report.error (cl.source_reference, "partial declarations of `%s' have conflicting abstract modifiers", cl.name);
    3048            1 :                                 cl.error = true;
    3049              :                         }
    3050            6 :                         if (cl.is_sealed != old_cl.is_sealed) {
    3051            1 :                                 Report.error (cl.source_reference, "partial declarations of `%s' have conflicting sealed modifiers", cl.name);
    3052            1 :                                 cl.error = true;
    3053              :                         }
    3054            6 :                         if (cl.error) {
    3055            3 :                                 Report.notice (old_cl.source_reference, "previous declaration of `%s' was here", old_cl.name);
    3056            3 :                                 return;
    3057              :                         }
    3058              : 
    3059            3 :                         cl = old_cl;
    3060              :                 }
    3061              : 
    3062       373728 :                 set_attributes (cl, attrs);
    3063       429362 :                 foreach (TypeParameter type_param in type_param_list) {
    3064        27817 :                         cl.add_type_parameter (type_param);
    3065              :                 }
    3066      1049656 :                 foreach (DataType base_type in base_types) {
    3067       337964 :                         cl.add_base_type (base_type);
    3068              :                 }
    3069              : 
    3070       373728 :                 parse_declarations (cl);
    3071              : 
    3072       373728 :                 if (old_cl != null && old_cl.is_partial) {
    3073            3 :                         return;
    3074              :                 }
    3075              : 
    3076              :                 // ensure there is always a default construction method
    3077       374597 :                 if (scanner.source_file.file_type == SourceFileType.SOURCE
    3078         1188 :                     && cl.default_construction_method == null) {
    3079          872 :                         var m = new CreationMethod (cl.name, null, cl.source_reference);
    3080          872 :                         m.access = (cl.is_abstract ? SymbolAccessibility.PROTECTED : SymbolAccessibility.PUBLIC);
    3081          872 :                         m.body = new Block (cl.source_reference);
    3082          872 :                         cl.add_method (m);
    3083              :                 }
    3084              : 
    3085       373725 :                 if (partial_reparse) {
    3086            6 :                         parent.add_class (cl);
    3087            6 :                         return;
    3088              :                 }
    3089              : 
    3090       373719 :                 Symbol result = cl;
    3091      1121875 :                 while (sym != null) {
    3092       374437 :                         sym = sym.inner;
    3093              : 
    3094       374078 :                         Symbol next = (sym != null ? new Namespace (sym.name, cl.source_reference) : parent);
    3095       374078 :                         if (result is Namespace) {
    3096          359 :                                 next.add_namespace ((Namespace) result);
    3097       373731 :                         } else if (!partial_reparse && cl.is_partial) {
    3098           12 :                                 PartialInfo info = { parent, begin, attrs };
    3099           24 :                                 partials += info;
    3100       373707 :                         } else if (!cl.is_partial) {
    3101       373707 :                                 next.add_class ((Class) result);
    3102              :                         }
    3103       748156 :                         result = next;
    3104              :                 }
    3105              :         }
    3106              : 
    3107      1297072 :         void parse_constant_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
    3108       648536 :                 var begin = get_location ();
    3109       648536 :                 var access = parse_access_modifier ();
    3110       648536 :                 var flags = parse_member_declaration_modifiers ("constants", ModifierFlags.EXTERN | ModifierFlags.NEW);
    3111       648536 :                 expect (TokenType.CONST);
    3112       648536 :                 var type = parse_type (false, false);
    3113       648536 :                 string id = parse_identifier ();
    3114              : 
    3115       648536 :                 type = parse_inline_array_type (type);
    3116       648536 :                 var src = get_src (begin);
    3117              : 
    3118              :                 // constant arrays don't own their element
    3119       648536 :                 unowned ArrayType? array_type = type as ArrayType;
    3120           31 :                 if (array_type != null) {
    3121           31 :                         array_type.element_type.value_owned = false;
    3122              :                 }
    3123              : 
    3124       648536 :                 Expression? initializer = null;
    3125       648536 :                 if (accept (TokenType.ASSIGN)) {
    3126          165 :                         initializer = parse_expression ();
    3127              :                 }
    3128       648536 :                 expect (TokenType.SEMICOLON);
    3129              : 
    3130       648536 :                 var c = new Constant (id, type, initializer, src, comment);
    3131       648536 :                 c.access = access;
    3132       648536 :                 if (ModifierFlags.EXTERN in flags) {
    3133            2 :                         c.is_extern = true;
    3134              :                 }
    3135       648536 :                 if (ModifierFlags.NEW in flags) {
    3136            0 :                         c.hides = true;
    3137              :                 }
    3138       648536 :                 set_attributes (c, attrs);
    3139              : 
    3140       648536 :                 if (type.value_owned) {
    3141            1 :                         Report.error (c.source_reference, "`owned' is not allowed on constants");
    3142              :                 }
    3143              : 
    3144       648536 :                 parent.add_constant (c);
    3145              :         }
    3146              : 
    3147      1154466 :         void parse_field_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
    3148       577233 :                 var begin = get_location ();
    3149       831025 :                 var access = parse_access_modifier ((parent is Struct) ? SymbolAccessibility.PUBLIC : SymbolAccessibility.PRIVATE);
    3150       577233 :                 var flags = parse_member_declaration_modifiers ("fields", ModifierFlags.CLASS | ModifierFlags.EXTERN | ModifierFlags.NEW | ModifierFlags.STATIC );
    3151       577233 :                 var type = parse_type (true, true);
    3152      1154470 :                 do {
    3153       577237 :                         string id = parse_identifier ();
    3154       577237 :                         var ftype = parse_inline_array_type (type.copy ());
    3155              : 
    3156       577237 :                         var f = new Field (id, ftype, null, get_src (begin), comment);
    3157       577237 :                         f.access = access;
    3158              : 
    3159       577237 :                         set_attributes (f, attrs);
    3160       577237 :                         if (ModifierFlags.STATIC in flags && ModifierFlags.CLASS in flags) {
    3161            1 :                                 Report.error (f.source_reference, "only one of `static' or `class' may be specified");
    3162       577236 :                         } else if (ModifierFlags.STATIC in flags) {
    3163        84869 :                                 f.binding = MemberBinding.STATIC;
    3164       492367 :                         } else if (ModifierFlags.CLASS in flags) {
    3165           26 :                                 f.binding = MemberBinding.CLASS;
    3166       492341 :                         } else if (parent is Namespace) {
    3167              :                                 // default to static member binding in namespace
    3168         3370 :                                 f.binding = MemberBinding.STATIC;
    3169              :                         }
    3170              : 
    3171       577237 :                         if (!parent.external_package && parent is Struct
    3172          261 :                                 && f.access != SymbolAccessibility.PUBLIC && f.binding == MemberBinding.INSTANCE) {
    3173            2 :                                 Report.warning (f.source_reference, "accessibility of struct fields can only be `public`");
    3174              :                         }
    3175              : 
    3176       577237 :                         if (ModifierFlags.EXTERN in flags) {
    3177            3 :                                 f.is_extern = true;
    3178              :                         }
    3179       577237 :                         if (ModifierFlags.NEW in flags) {
    3180            0 :                                 f.hides = true;
    3181              :                         }
    3182       577601 :                         if (accept (TokenType.ASSIGN)) {
    3183          364 :                                 f.initializer = parse_expression ();
    3184              :                         }
    3185              : 
    3186       577237 :                         parent.add_field (f);
    3187       577237 :                 } while (accept (TokenType.COMMA));
    3188       577233 :                 expect (TokenType.SEMICOLON);
    3189              :         }
    3190              : 
    3191         1051 :         InitializerList parse_initializer () throws ParseError {
    3192         1051 :                 var begin = get_location ();
    3193         1051 :                 expect (TokenType.OPEN_BRACE);
    3194         1051 :                 var initializer = new InitializerList (get_src (begin));
    3195         3036 :                 while (current () != TokenType.CLOSE_BRACE) {
    3196         5971 :                         try {
    3197         2986 :                                 initializer.append (parse_argument ());
    3198              :                         } catch (ParseError e) {
    3199            1 :                                 if (current () == TokenType.CLOSE_BRACE) {
    3200            1 :                                         prev ();
    3201            1 :                                         report_parse_error (new ParseError.SYNTAX ("incomplete initializer"));
    3202            0 :                                 } else if (context.keep_going) {
    3203            0 :                                         report_parse_error (e);
    3204              :                                 } else {
    3205            0 :                                         throw e;
    3206              :                                 }
    3207              :                         }
    3208              : 
    3209         2986 :                         if (!accept (TokenType.COMMA)) {
    3210              :                                 break;
    3211              :                         }
    3212              :                 }
    3213         1051 :                 expect (TokenType.CLOSE_BRACE);
    3214         1051 :                 initializer.source_reference = get_src (begin);
    3215              :                 return initializer;
    3216              :         }
    3217              : 
    3218     11944550 :         void parse_method_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
    3219      5972275 :                 var begin = get_location ();
    3220      5972275 :                 var access = parse_access_modifier ();
    3221      5972275 :                 var flags = parse_member_declaration_modifiers ("methods", ModifierFlags.ABSTRACT | ModifierFlags.ASYNC | ModifierFlags.CLASS | ModifierFlags.EXTERN | ModifierFlags.NEW | ModifierFlags.INLINE | ModifierFlags.OVERRIDE | ModifierFlags.STATIC | ModifierFlags.VIRTUAL);
    3222      5972275 :                 var type = parse_type (true, false);
    3223      5972275 :                 var sym = parse_symbol_name ();
    3224      5972275 :                 var type_param_list = parse_type_parameter_list ();
    3225      5972275 :                 var method = new Method (sym.name, type, get_src (begin), comment);
    3226      5972275 :                 if (sym.inner != null) {
    3227           12 :                         method.base_interface_type = new UnresolvedType.from_symbol (sym.inner, sym.inner.source_reference);
    3228              :                 }
    3229      5972275 :                 method.access = access;
    3230      5972275 :                 set_attributes (method, attrs);
    3231      6070729 :                 foreach (TypeParameter type_param in type_param_list) {
    3232        49227 :                         method.add_type_parameter (type_param);
    3233              :                 }
    3234      5972275 :                 if (ModifierFlags.STATIC in flags && ModifierFlags.CLASS in flags) {
    3235            1 :                         Report.error (method.source_reference, "only one of `static' or `class' may be specified");
    3236      5972274 :                 } else if (ModifierFlags.STATIC in flags) {
    3237      1485489 :                         method.binding = MemberBinding.STATIC;
    3238      4486785 :                 } else if (ModifierFlags.CLASS in flags) {
    3239          441 :                         method.binding = MemberBinding.CLASS;
    3240      4486344 :                 } else if (parent is Namespace) {
    3241              :                         // default to static member binding in namespace
    3242        70292 :                         method.binding = MemberBinding.STATIC;
    3243              :                 }
    3244      5972275 :                 if (ModifierFlags.ASYNC in flags) {
    3245       205252 :                         method.coroutine = true;
    3246              :                 }
    3247      5972275 :                 if (ModifierFlags.NEW in flags) {
    3248            8 :                         method.hides = true;
    3249              :                 }
    3250              : 
    3251      5972275 :                 if (method.binding == MemberBinding.INSTANCE) {
    3252      4416053 :                         if (ModifierFlags.ABSTRACT in flags) {
    3253       324518 :                                 method.is_abstract = true;
    3254              :                         }
    3255      4416053 :                         if (ModifierFlags.VIRTUAL in flags) {
    3256       306047 :                                 method.is_virtual = true;
    3257              :                         }
    3258      4416053 :                         if (ModifierFlags.OVERRIDE in flags) {
    3259        13294 :                                 method.overrides = true;
    3260              :                         }
    3261      4416053 :                         if ((method.is_abstract && method.is_virtual)
    3262      4416051 :                             || (method.is_abstract && method.overrides)
    3263      4416049 :                             || (method.is_virtual && method.overrides)) {
    3264            4 :                                 throw new ParseError.SYNTAX ("only one of `abstract', `virtual', or `override' may be specified");
    3265              :                         }
    3266              :                 } else {
    3267      1556222 :                         if (ModifierFlags.ABSTRACT in flags
    3268      1556220 :                             || ModifierFlags.VIRTUAL in flags
    3269      1556217 :                             || ModifierFlags.OVERRIDE in flags) {
    3270            8 :                                 throw new ParseError.SYNTAX ("the modifiers `abstract', `virtual', and `override' are not valid for %s methods", (ModifierFlags.CLASS in flags) ? "class" : "static");
    3271              :                         }
    3272              :                 }
    3273              : 
    3274      5972263 :                 if (ModifierFlags.INLINE in flags) {
    3275         3290 :                         method.is_inline = true;
    3276              :                 }
    3277      5972263 :                 if (ModifierFlags.EXTERN in flags) {
    3278           28 :                         method.is_extern = true;
    3279              :                 }
    3280      5972263 :                 expect (TokenType.OPEN_PARENS);
    3281      5972263 :                 if (current () != TokenType.CLOSE_PARENS) {
    3282     18800289 :                         do {
    3283      7431069 :                                 var param = parse_parameter ();
    3284      7431069 :                                 method.add_parameter (param);
    3285      7431069 :                         } while (accept (TokenType.COMMA));
    3286              :                 }
    3287      5972263 :                 expect (TokenType.CLOSE_PARENS);
    3288      5972263 :                 if (accept (TokenType.THROWS)) {
    3289      2492492 :                         do {
    3290       838969 :                                 method.add_error_type (parse_type (true, false));
    3291       838969 :                         } while (accept (TokenType.COMMA));
    3292              :                 }
    3293      5972287 :                 while (accept (TokenType.REQUIRES)) {
    3294           12 :                         expect (TokenType.OPEN_PARENS);
    3295           12 :                         method.add_precondition (parse_expression ());
    3296           12 :                         expect (TokenType.CLOSE_PARENS);
    3297              :                 }
    3298      5972305 :                 while (accept (TokenType.ENSURES)) {
    3299           21 :                         expect (TokenType.OPEN_PARENS);
    3300           21 :                         method.add_postcondition (parse_expression ());
    3301           21 :                         expect (TokenType.CLOSE_PARENS);
    3302              :                 }
    3303      6099906 :                 if (!accept (TokenType.SEMICOLON)) {
    3304       127643 :                         method.body = parse_block ();
    3305       127643 :                         method.external = false;
    3306              :                 }
    3307              : 
    3308      5972263 :                 parent.add_method (method);
    3309              :         }
    3310              : 
    3311       895876 :         void parse_property_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
    3312       447938 :                 var begin = get_location ();
    3313       447938 :                 var access = parse_access_modifier ();
    3314       447938 :                 var flags = parse_member_declaration_modifiers ("properties", ModifierFlags.ABSTRACT | ModifierFlags.CLASS | ModifierFlags.EXTERN | ModifierFlags.NEW | ModifierFlags.OVERRIDE | ModifierFlags.STATIC | ModifierFlags.VIRTUAL);
    3315       447938 :                 var type = parse_type (true, true);
    3316       447938 :                 string id = parse_identifier ();
    3317       447938 :                 var prop = new Property (id, type, null, null, get_src (begin), comment);
    3318       447938 :                 prop.access = access;
    3319       447938 :                 set_attributes (prop, attrs);
    3320       447938 :                 if (ModifierFlags.STATIC in flags && ModifierFlags.CLASS in flags) {
    3321            1 :                         Report.error (prop.source_reference, "only one of `static' or `class' may be specified");
    3322       447937 :                 } else if (ModifierFlags.STATIC in flags) {
    3323            9 :                         prop.binding = MemberBinding.STATIC;
    3324       447928 :                 } else if (ModifierFlags.CLASS in flags) {
    3325            0 :                         prop.binding = MemberBinding.CLASS;
    3326              :                 }
    3327       447938 :                 if (ModifierFlags.ABSTRACT in flags) {
    3328        51454 :                         prop.is_abstract = true;
    3329              :                 }
    3330       447938 :                 if (ModifierFlags.VIRTUAL in flags) {
    3331           80 :                         prop.is_virtual = true;
    3332              :                 }
    3333       447938 :                 if (ModifierFlags.OVERRIDE in flags) {
    3334          223 :                         prop.overrides = true;
    3335              :                 }
    3336       447938 :                 if (ModifierFlags.NEW in flags) {
    3337            1 :                         prop.hides = true;
    3338              :                 }
    3339       447938 :                 if (ModifierFlags.EXTERN in flags) {
    3340            0 :                         prop.is_extern = true;
    3341              :                 }
    3342       447938 :                 if ((prop.is_abstract && prop.is_virtual)
    3343       447936 :                         || (prop.is_abstract && prop.overrides)
    3344       447935 :                         || (prop.is_virtual && prop.overrides)) {
    3345            4 :                         throw new ParseError.SYNTAX ("only one of `abstract', `virtual', or `override' may be specified");
    3346              :                 }
    3347              : 
    3348       447934 :                 if (accept (TokenType.THROWS)) {
    3349            2 :                         do {
    3350            1 :                                 parse_type (true, false);
    3351            1 :                         } while (accept (TokenType.COMMA));
    3352            1 :                         Report.error (prop.source_reference, "properties throwing errors are not supported yet");
    3353              :                 }
    3354       447934 :                 expect (TokenType.OPEN_BRACE);
    3355      1202029 :                 while (current () != TokenType.CLOSE_BRACE) {
    3356      1508194 :                         if (accept (TokenType.DEFAULT)) {
    3357           41 :                                 if (prop.initializer != null) {
    3358            1 :                                         throw new ParseError.SYNTAX ("property default value already defined");
    3359              :                                 }
    3360           40 :                                 expect (TokenType.ASSIGN);
    3361           40 :                                 prop.initializer = parse_expression ();
    3362           40 :                                 expect (TokenType.SEMICOLON);
    3363              :                         } else {
    3364       754058 :                                 comment = scanner.pop_comment ();
    3365              : 
    3366       754058 :                                 var accessor_begin = get_location ();
    3367       754061 :                                 var accessor_attrs = parse_attributes ();
    3368       754058 :                                 var accessor_access = parse_access_modifier (SymbolAccessibility.PUBLIC);
    3369              : 
    3370       754058 :                                 var value_type = type.copy ();
    3371       754058 :                                 if (accept (TokenType.OWNED)) {
    3372        91647 :                                         value_type.value_owned = true;
    3373              :                                 } else {
    3374       662411 :                                         value_type.value_owned = false;
    3375       662411 :                                         if (accept (TokenType.UNOWNED)) {
    3376            0 :                                                 Report.warning (get_last_src (), "property getters are `unowned' by default");
    3377              :                                         }
    3378              :                                 }
    3379              : 
    3380      1508113 :                                 if (accept (TokenType.GET)) {
    3381       420099 :                                         if (prop.get_accessor != null) {
    3382            1 :                                                 throw new ParseError.SYNTAX ("property get accessor already defined");
    3383              :                                         }
    3384              : 
    3385       420098 :                                         Block block = null;
    3386       420098 :                                         if (!accept (TokenType.SEMICOLON)) {
    3387         6291 :                                                 block = parse_block ();
    3388         6291 :                                                 prop.external = false;
    3389              :                                         }
    3390       420098 :                                         prop.get_accessor = new PropertyAccessor (true, false, false, value_type, block, get_src (accessor_begin), comment);
    3391       420098 :                                         set_attributes (prop.get_accessor, accessor_attrs);
    3392       420098 :                                         prop.get_accessor.access = accessor_access;
    3393              :                                 } else {
    3394              :                                         bool writable, _construct;
    3395       333959 :                                         if (accept (TokenType.SET)) {
    3396       159078 :                                                 writable = true;
    3397       159078 :                                                 _construct = (context.profile == Profile.GOBJECT) && accept (TokenType.CONSTRUCT);
    3398       174881 :                                         } else if (context.profile == Profile.GOBJECT && accept (TokenType.CONSTRUCT)) {
    3399       174880 :                                                 _construct = true;
    3400       174880 :                                                 writable = accept (TokenType.SET);
    3401              :                                         } else {
    3402            2 :                                                 throw new ParseError.SYNTAX ("expected get, set, or construct");
    3403              :                                         }
    3404       333958 :                                         if (prop.set_accessor != null) {
    3405            1 :                                                 throw new ParseError.SYNTAX ("property set accessor already defined");
    3406              :                                         }
    3407       333957 :                                         Block block = null;
    3408       333957 :                                         if (!accept (TokenType.SEMICOLON)) {
    3409           38 :                                                 block = parse_block ();
    3410           38 :                                                 prop.external = false;
    3411              :                                         }
    3412       333957 :                                         prop.set_accessor = new PropertyAccessor (false, writable, _construct, value_type, block, get_src (accessor_begin), comment);
    3413       333957 :                                         set_attributes (prop.set_accessor, accessor_attrs);
    3414       333957 :                                         prop.set_accessor.access = accessor_access;
    3415              :                                 }
    3416              :                         }
    3417              :                 }
    3418       447930 :                 expect (TokenType.CLOSE_BRACE);
    3419              : 
    3420       447930 :                 parent.add_property (prop);
    3421              :         }
    3422              : 
    3423       272470 :         void parse_signal_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
    3424       136235 :                 var begin = get_location ();
    3425       136235 :                 var access = parse_access_modifier ();
    3426       136235 :                 var flags = parse_member_declaration_modifiers ("signals", ModifierFlags.NEW | ModifierFlags.VIRTUAL);
    3427       136235 :                 expect (TokenType.SIGNAL);
    3428       136235 :                 var type = parse_type (true, false);
    3429       136235 :                 string id = parse_identifier ();
    3430       136235 :                 var sig = new Signal (id, type, get_src (begin), comment);
    3431       136235 :                 sig.access = access;
    3432       136235 :                 set_attributes (sig, attrs);
    3433       136235 :                 if (ModifierFlags.VIRTUAL in flags) {
    3434       118252 :                         sig.is_virtual = true;
    3435              :                 }
    3436       136235 :                 if (ModifierFlags.NEW in flags) {
    3437            1 :                         sig.hides = true;
    3438              :                 }
    3439       136235 :                 expect (TokenType.OPEN_PARENS);
    3440       136235 :                 if (current () != TokenType.CLOSE_PARENS) {
    3441       439586 :                         do {
    3442       168626 :                                 var param = parse_parameter ();
    3443       168626 :                                 sig.add_parameter (param);
    3444       168626 :                         } while (accept (TokenType.COMMA));
    3445              :                 }
    3446       136235 :                 expect (TokenType.CLOSE_PARENS);
    3447       136249 :                 if (!accept (TokenType.SEMICOLON)) {
    3448           14 :                         sig.body = parse_block ();
    3449              :                 }
    3450              : 
    3451       136235 :                 parent.add_signal (sig);
    3452              :         }
    3453              : 
    3454           80 :         void parse_constructor_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
    3455           40 :                 var begin = get_location ();
    3456           40 :                 var flags = parse_member_declaration_modifiers ("constructors", ModifierFlags.CLASS | ModifierFlags.STATIC);
    3457           40 :                 expect (TokenType.CONSTRUCT);
    3458           40 :                 var c = new Constructor (get_src (begin));
    3459           40 :                 if (ModifierFlags.STATIC in flags && ModifierFlags.CLASS in flags) {
    3460            1 :                         Report.error (c.source_reference, "only one of `static' or `class' may be specified");
    3461           39 :                 } else if (ModifierFlags.STATIC in flags) {
    3462            8 :                         c.binding = MemberBinding.STATIC;
    3463           31 :                 } else if (ModifierFlags.CLASS in flags) {
    3464            9 :                         c.binding = MemberBinding.CLASS;
    3465              :                 }
    3466           40 :                 c.body = parse_block ();
    3467              : 
    3468           40 :                 parent.add_constructor (c);
    3469              :         }
    3470              : 
    3471           50 :         void parse_destructor_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
    3472           25 :                 var begin = get_location ();
    3473           25 :                 var flags = parse_member_declaration_modifiers ("destructors", ModifierFlags.CLASS | ModifierFlags.STATIC);
    3474           25 :                 expect (TokenType.TILDE);
    3475           25 :                 string identifier = parse_identifier ();
    3476           25 :                 expect (TokenType.OPEN_PARENS);
    3477           25 :                 expect (TokenType.CLOSE_PARENS);
    3478           25 :                 var d = new Destructor (get_src (begin));
    3479           25 :                 if (identifier != parent.name) {
    3480            1 :                         Report.error (d.source_reference, "destructor and parent symbol name do not match");
    3481              :                 }
    3482           25 :                 if (ModifierFlags.STATIC in flags && ModifierFlags.CLASS in flags) {
    3483            1 :                         Report.error (d.source_reference, "only one of `static' or `class' may be specified");
    3484           24 :                 } else if (ModifierFlags.STATIC in flags) {
    3485            3 :                         d.binding = MemberBinding.STATIC;
    3486           21 :                 } else if (ModifierFlags.CLASS in flags) {
    3487            5 :                         d.binding = MemberBinding.CLASS;
    3488              :                 }
    3489           25 :                 d.body = parse_block ();
    3490              : 
    3491           25 :                 parent.add_destructor (d);
    3492              :         }
    3493              : 
    3494       286454 :         void parse_struct_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
    3495       143227 :                 var begin = get_location ();
    3496       143227 :                 var access = parse_access_modifier ();
    3497       143227 :                 var flags = parse_type_declaration_modifiers ("structs", ModifierFlags.EXTERN);
    3498       143227 :                 expect (TokenType.STRUCT);
    3499       143227 :                 var sym = parse_symbol_name ();
    3500       143227 :                 var type_param_list = parse_type_parameter_list ();
    3501       143227 :                 DataType base_type = null;
    3502       143227 :                 if (accept (TokenType.COLON)) {
    3503        11256 :                         base_type = parse_type (true, false);
    3504              :                 }
    3505       143227 :                 var st = new Struct (sym.name, get_src (begin), comment);
    3506       143227 :                 st.access = access;
    3507       143227 :                 if (ModifierFlags.EXTERN in flags) {
    3508            0 :                         st.is_extern = true;
    3509              :                 }
    3510       143227 :                 set_attributes (st, attrs);
    3511       161583 :                 foreach (TypeParameter type_param in type_param_list) {
    3512         9178 :                         st.add_type_parameter (type_param);
    3513              :                 }
    3514       143227 :                 if (base_type != null) {
    3515        11256 :                         st.base_type = base_type;
    3516              :                 }
    3517              : 
    3518       143227 :                 parse_declarations (st);
    3519              : 
    3520       143227 :                 Symbol result = st;
    3521       429683 :                 while (sym != null) {
    3522       143229 :                         sym = sym.inner;
    3523              : 
    3524       143228 :                         Symbol next = (sym != null ? new Namespace (sym.name, st.source_reference) : parent);
    3525       143228 :                         if (result is Namespace) {
    3526            1 :                                 next.add_namespace ((Namespace) result);
    3527              :                         } else {
    3528       143227 :                                 next.add_struct ((Struct) result);
    3529              :                         }
    3530       286456 :                         result = next;
    3531              :                 }
    3532              :         }
    3533              : 
    3534       117102 :         void parse_interface_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
    3535        58551 :                 var begin = get_location ();
    3536        58551 :                 var access = parse_access_modifier ();
    3537        58551 :                 var flags = parse_type_declaration_modifiers ("interfaces", ModifierFlags.EXTERN);
    3538        58551 :                 expect (TokenType.INTERFACE);
    3539        58551 :                 var sym = parse_symbol_name ();
    3540        58551 :                 var type_param_list = parse_type_parameter_list ();
    3541        58551 :                 var base_types = new ArrayList<DataType> ();
    3542        58551 :                 if (accept (TokenType.COLON)) {
    3543       204097 :                         do {
    3544        73568 :                                 var type = parse_type (true, false);
    3545        73568 :                                 base_types.add (type);
    3546        73568 :                         } while (accept (TokenType.COMMA));
    3547              :                 }
    3548        58551 :                 var iface = new Interface (sym.name, get_src (begin), comment);
    3549        58551 :                 iface.access = access;
    3550        58551 :                 if (ModifierFlags.EXTERN in flags) {
    3551            0 :                         iface.is_extern = true;
    3552              :                 }
    3553        58551 :                 set_attributes (iface, attrs);
    3554        58575 :                 foreach (TypeParameter type_param in type_param_list) {
    3555           12 :                         iface.add_type_parameter (type_param);
    3556              :                 }
    3557       205687 :                 foreach (DataType base_type in base_types) {
    3558        73568 :                         iface.add_prerequisite (base_type);
    3559              :                 }
    3560              : 
    3561        58551 :                 parse_declarations (iface);
    3562              : 
    3563        58551 :                 Symbol result = iface;
    3564       175697 :                 while (sym != null) {
    3565        58595 :                         sym = sym.inner;
    3566              : 
    3567        58573 :                         Symbol next = (sym != null ? new Namespace (sym.name, iface.source_reference) : parent);
    3568        58573 :                         if (result is Namespace) {
    3569           22 :                                 next.add_namespace ((Namespace) result);
    3570              :                         } else {
    3571        58551 :                                 next.add_interface ((Interface) result);
    3572              :                         }
    3573       117146 :                         result = next;
    3574              :                 }
    3575              :         }
    3576              : 
    3577       418118 :         void parse_enum_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
    3578       209059 :                 var begin = get_location ();
    3579       209059 :                 var access = parse_access_modifier ();
    3580       209059 :                 var flags = parse_type_declaration_modifiers ("enums", ModifierFlags.EXTERN);
    3581       209059 :                 expect (TokenType.ENUM);
    3582       209059 :                 var sym = parse_symbol_name ();
    3583       209059 :                 var en = new Enum (sym.name, get_src (begin), comment);
    3584       209059 :                 en.access = access;
    3585       209059 :                 if (ModifierFlags.EXTERN in flags) {
    3586            0 :                         en.is_extern = true;
    3587              :                 }
    3588       209059 :                 set_attributes (en, attrs);
    3589              : 
    3590       209059 :                 expect (TokenType.OPEN_BRACE);
    3591       209059 :                 var inner_begin = get_location ();
    3592       418117 :                 try {
    3593              :                         // enum methods
    3594       209059 :                         while (current () != TokenType.CLOSE_BRACE) {
    3595       209058 :                                 parse_declaration (en);
    3596              :                         }
    3597              :                 } catch (ParseError e) {
    3598       209058 :                         rollback (inner_begin);
    3599              :                 }
    3600      1704241 :                 do {
    3601      1498361 :                         if (current () == TokenType.CLOSE_BRACE) {
    3602              :                                 break;
    3603              :                         }
    3604      1495182 :                         var value_attrs = parse_attributes ();
    3605      1495182 :                         var value_begin = get_location ();
    3606      1495182 :                         string id = parse_identifier ();
    3607      1495182 :                         if (comment == null) {
    3608      1495150 :                                 comment = scanner.pop_comment ();
    3609              :                         }
    3610              : 
    3611      1495182 :                         Expression value = null;
    3612      1495182 :                         if (accept (TokenType.ASSIGN)) {
    3613           60 :                                 value = parse_expression ();
    3614              :                         }
    3615              : 
    3616      1495182 :                         var ev = new EnumValue (id, value, get_src (value_begin), comment);
    3617      1495182 :                         ev.access = SymbolAccessibility.PUBLIC;
    3618      1495182 :                         set_attributes (ev, value_attrs);
    3619      1495182 :                         en.add_value (ev);
    3620      1495182 :                         comment = null;
    3621      1495182 :                 } while (accept (TokenType.COMMA));
    3622       209059 :                 if (accept (TokenType.SEMICOLON)) {
    3623              :                         // enum methods
    3624        20723 :                         while (current () != TokenType.CLOSE_BRACE) {
    3625        12339 :                                 parse_declaration (en);
    3626              :                         }
    3627              :                 }
    3628       209059 :                 expect (TokenType.CLOSE_BRACE);
    3629              : 
    3630       209059 :                 Symbol result = en;
    3631       627215 :                 while (sym != null) {
    3632       209097 :                         sym = sym.inner;
    3633              : 
    3634       209078 :                         Symbol next = (sym != null ? new Namespace (sym.name, en.source_reference) : parent);
    3635       209078 :                         if (result is Namespace) {
    3636           19 :                                 next.add_namespace ((Namespace) result);
    3637              :                         } else {
    3638       209059 :                                 next.add_enum ((Enum) result);
    3639              :                         }
    3640       418156 :                         result = next;
    3641              :                 }
    3642              :         }
    3643              : 
    3644        61638 :         void parse_errordomain_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
    3645        30819 :                 var begin = get_location ();
    3646        30819 :                 var access = parse_access_modifier ();
    3647        30819 :                 var flags = parse_type_declaration_modifiers ("errordomains", ModifierFlags.EXTERN);
    3648        30819 :                 expect (TokenType.ERRORDOMAIN);
    3649        30819 :                 var sym = parse_symbol_name ();
    3650        30819 :                 var ed = new ErrorDomain (sym.name, get_src (begin), comment);
    3651        30819 :                 ed.access = access;
    3652        30819 :                 if (ModifierFlags.EXTERN in flags) {
    3653            0 :                         ed.is_extern = true;
    3654              :                 }
    3655        30819 :                 set_attributes (ed, attrs);
    3656              : 
    3657        30819 :                 expect (TokenType.OPEN_BRACE);
    3658        30819 :                 var inner_begin = get_location ();
    3659        61637 :                 try {
    3660              :                         // errordomain methods
    3661        30819 :                         while (current () != TokenType.CLOSE_BRACE) {
    3662        30818 :                                 parse_declaration (ed);
    3663              :                         }
    3664              :                 } catch (ParseError e) {
    3665        30818 :                         rollback (inner_begin);
    3666              :                 }
    3667       476315 :                 do {
    3668       445498 :                         if (current () == TokenType.CLOSE_BRACE) {
    3669              :                                 break;
    3670              :                         }
    3671       445496 :                         var code_attrs = parse_attributes ();
    3672       445496 :                         var code_begin = get_location ();
    3673       445496 :                         string id = parse_identifier ();
    3674       445496 :                         if (comment == null) {
    3675       445496 :                                 comment = scanner.pop_comment ();
    3676              :                         }
    3677              : 
    3678       445496 :                         var ec = new ErrorCode (id, get_src (code_begin), comment);
    3679       445496 :                         ec.access = SymbolAccessibility.PUBLIC;
    3680       445496 :                         set_attributes (ec, code_attrs);
    3681       445500 :                         if (accept (TokenType.ASSIGN)) {
    3682            4 :                                 ec.value = parse_expression ();
    3683              :                         }
    3684       445496 :                         ed.add_code (ec);
    3685       445496 :                         comment = null;
    3686       445496 :                 } while (accept (TokenType.COMMA));
    3687        30819 :                 if (accept (TokenType.SEMICOLON)) {
    3688              :                         // errordomain methods
    3689        83978 :                         while (current () != TokenType.CLOSE_BRACE) {
    3690        53281 :                                 parse_declaration (ed);
    3691              :                         }
    3692              :                 }
    3693        30819 :                 expect (TokenType.CLOSE_BRACE);
    3694              : 
    3695        30819 :                 Symbol result = ed;
    3696        92463 :                 while (sym != null) {
    3697        30825 :                         sym = sym.inner;
    3698              : 
    3699        30822 :                         Symbol next = (sym != null ? new Namespace (sym.name, ed.source_reference) : parent);
    3700        30822 :                         if (result is Namespace) {
    3701            3 :                                 next.add_namespace ((Namespace) result);
    3702              :                         } else {
    3703        30819 :                                 next.add_error_domain ((ErrorDomain) result);
    3704              :                         }
    3705        61644 :                         result = next;
    3706              :                 }
    3707              :         }
    3708              : 
    3709     10107528 :         SymbolAccessibility parse_access_modifier (SymbolAccessibility default_access = SymbolAccessibility.PRIVATE) {
    3710     10107528 :                 switch (current ()) {
    3711              :                 case TokenType.PRIVATE:
    3712        13657 :                         next ();
    3713        13657 :                         return SymbolAccessibility.PRIVATE;
    3714              :                 case TokenType.PROTECTED:
    3715        71532 :                         next ();
    3716        71532 :                         return SymbolAccessibility.PROTECTED;
    3717              :                 case TokenType.INTERNAL:
    3718          115 :                         next ();
    3719          115 :                         return SymbolAccessibility.INTERNAL;
    3720              :                 case TokenType.PUBLIC:
    3721      9223570 :                         next ();
    3722      9223570 :                         return SymbolAccessibility.PUBLIC;
    3723              :                 default:
    3724     10107528 :                         return default_access;
    3725              :                 }
    3726              :         }
    3727              : 
    3728       815388 :         ModifierFlags parse_type_declaration_modifiers (string symbol_type, ModifierFlags supported) {
    3729              :                 ModifierFlags flags = 0;
    3730       898632 :                 while (true) {
    3731       898632 :                         var begin = get_location ();
    3732       898632 :                         switch (current ()) {
    3733              :                         case TokenType.ABSTRACT:
    3734        32599 :                                 next ();
    3735        32599 :                                 flags |= ModifierFlags.ABSTRACT;
    3736        32599 :                                 break;
    3737              :                         case TokenType.EXTERN:
    3738            0 :                                 next ();
    3739            0 :                                 flags |= ModifierFlags.EXTERN;
    3740            0 :                                 break;
    3741              :                         case TokenType.PARTIAL:
    3742           24 :                                 next ();
    3743           24 :                                 flags |= ModifierFlags.PARTIAL;
    3744           24 :                                 break;
    3745              :                         case TokenType.SEALED:
    3746        50621 :                                 next ();
    3747        50621 :                                 flags |= ModifierFlags.SEALED;
    3748        50621 :                                 break;
    3749              :                         default:
    3750       815388 :                                 return flags;
    3751              :                         }
    3752        83244 :                         if (supported > 0) {
    3753        83244 :                                 ModifierFlags unsupported = (flags | supported) ^ supported;
    3754        83244 :                                 if (unsupported > 0) {
    3755            0 :                                         Report.error (get_src (begin), "`%s' modifier not applicable on %s", unsupported.to_string (), symbol_type);
    3756              :                                 }
    3757              :                         }
    3758              :                 }
    3759              :         }
    3760              : 
    3761      8538153 :         ModifierFlags parse_member_declaration_modifiers (string symbol_type, ModifierFlags supported) {
    3762              :                 ModifierFlags flags = 0;
    3763     11140643 :                 while (true) {
    3764     11140643 :                         var begin = get_location ();
    3765     11140643 :                         switch (current ()) {
    3766              :                         case TokenType.ABSTRACT:
    3767       375976 :                                 next ();
    3768       375976 :                                 flags |= ModifierFlags.ABSTRACT;
    3769       375976 :                                 break;
    3770              :                         case TokenType.ASYNC:
    3771       214393 :                                 next ();
    3772       214393 :                                 flags |= ModifierFlags.ASYNC;
    3773       214393 :                                 break;
    3774              :                         case TokenType.CLASS:
    3775          487 :                                 next ();
    3776          487 :                                 flags |= ModifierFlags.CLASS;
    3777          487 :                                 break;
    3778              :                         case TokenType.EXTERN:
    3779           34 :                                 next ();
    3780           34 :                                 flags |= ModifierFlags.EXTERN;
    3781           34 :                                 break;
    3782              :                         case TokenType.INLINE:
    3783         3290 :                                 next ();
    3784         3290 :                                 flags |= ModifierFlags.INLINE;
    3785         3290 :                                 break;
    3786              :                         case TokenType.NEW:
    3787           14 :                                 next ();
    3788           14 :                                 flags |= ModifierFlags.NEW;
    3789           14 :                                 break;
    3790              :                         case TokenType.OVERRIDE:
    3791        13522 :                                 next ();
    3792        13522 :                                 flags |= ModifierFlags.OVERRIDE;
    3793        13522 :                                 break;
    3794              :                         case TokenType.SEALED:
    3795            0 :                                 next ();
    3796            0 :                                 flags |= ModifierFlags.SEALED;
    3797            0 :                                 break;
    3798              :                         case TokenType.STATIC:
    3799      1570390 :                                 next ();
    3800      1570390 :                                 flags |= ModifierFlags.STATIC;
    3801      1570390 :                                 break;
    3802              :                         case TokenType.VIRTUAL:
    3803       424384 :                                 next ();
    3804       424384 :                                 flags |= ModifierFlags.VIRTUAL;
    3805       424384 :                                 break;
    3806              :                         default:
    3807      8538153 :                                 return flags;
    3808              :                         }
    3809      2602490 :                         if (supported > 0) {
    3810      2602490 :                                 ModifierFlags unsupported = (flags | supported) ^ supported;
    3811      2602490 :                                 if (unsupported > 0) {
    3812           13 :                                         Report.error (get_src (begin), "`%s' modifier not applicable on %s", unsupported.to_string (), symbol_type);
    3813              :                                 }
    3814              :                         }
    3815              :                 }
    3816              :         }
    3817              : 
    3818      8984738 :         Parameter parse_parameter () throws ParseError {
    3819      8984738 :                 var attrs = parse_attributes ();
    3820      8984738 :                 var begin = get_location ();
    3821      8984738 :                 if (accept (TokenType.ELLIPSIS)) {
    3822              :                         // varargs
    3823       126668 :                         return new Parameter.with_ellipsis (get_src (begin));
    3824              :                 }
    3825      8858070 :                 bool params_array = accept (TokenType.PARAMS);
    3826      8858070 :                 var direction = ParameterDirection.IN;
    3827      8858070 :                 if (accept (TokenType.OUT)) {
    3828              :                         direction = ParameterDirection.OUT;
    3829      8345669 :                 } else if (accept (TokenType.REF)) {
    3830              :                         direction = ParameterDirection.REF;
    3831              :                 }
    3832              : 
    3833              :                 DataType type;
    3834      8258552 :                 if (direction == ParameterDirection.IN) {
    3835              :                         // in parameters are unowned by default
    3836      8258552 :                         type = parse_type (false, false);
    3837       599518 :                 } else if (direction == ParameterDirection.REF) {
    3838              :                         // ref parameters own the value by default
    3839        87117 :                         type = parse_type (true, true);
    3840              :                 } else {
    3841              :                         // out parameters own the value by default
    3842       512401 :                         type = parse_type (true, false);
    3843              :                 }
    3844      8858070 :                 string id = parse_identifier ();
    3845              : 
    3846      8858070 :                 type = parse_inline_array_type (type);
    3847              : 
    3848      8858070 :                 var param = new Parameter (id, type, get_src (begin));
    3849      8858070 :                 set_attributes (param, attrs);
    3850      8858070 :                 param.direction = direction;
    3851      8858070 :                 param.params_array = params_array;
    3852      9949164 :                 if (accept (TokenType.ASSIGN)) {
    3853      1091094 :                         param.initializer = parse_expression ();
    3854              :                 }
    3855      8858070 :                 return param;
    3856              :         }
    3857              : 
    3858      1130118 :         void parse_creation_method_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
    3859       565059 :                 var begin = get_location ();
    3860       565059 :                 var access = parse_access_modifier ();
    3861       565059 :                 var flags = parse_member_declaration_modifiers ("creation methods", ModifierFlags.ASYNC | ModifierFlags.EXTERN);
    3862       565059 :                 var sym = parse_symbol_name ();
    3863       565059 :                 if (ModifierFlags.NEW in flags) {
    3864            1 :                         throw new ParseError.SYNTAX ("`new' modifier not allowed on creation method");
    3865              :                 }
    3866              :                 CreationMethod method;
    3867       565058 :                 if (sym.inner == null) {
    3868       341279 :                         method = new CreationMethod (sym.name, null, get_src (begin), comment);
    3869              :                 } else {
    3870       223779 :                         method = new CreationMethod (sym.inner.name, sym.name, get_src (begin), comment);
    3871              :                 }
    3872       565058 :                 if (ModifierFlags.EXTERN in flags) {
    3873            1 :                         method.is_extern = true;
    3874              :                 }
    3875       565058 :                 if (ModifierFlags.ABSTRACT in flags
    3876       565057 :                     || ModifierFlags.VIRTUAL in flags
    3877       565056 :                     || ModifierFlags.OVERRIDE in flags) {
    3878            3 :                         Report.error (method.source_reference, "abstract, virtual, and override modifiers are not applicable to creation methods");
    3879              :                 }
    3880       565058 :                 if (ModifierFlags.ASYNC in flags) {
    3881         9140 :                         method.coroutine = true;
    3882              :                 }
    3883       565058 :                 expect (TokenType.OPEN_PARENS);
    3884       565058 :                 if (current () != TokenType.CLOSE_PARENS) {
    3885      2381404 :                         do {
    3886       979674 :                                 var param = parse_parameter ();
    3887       979674 :                                 method.add_parameter (param);
    3888       979674 :                         } while (accept (TokenType.COMMA));
    3889              :                 }
    3890       565058 :                 expect (TokenType.CLOSE_PARENS);
    3891       565058 :                 if (accept (TokenType.THROWS)) {
    3892       183366 :                         do {
    3893        61122 :                                 method.add_error_type (parse_type (true, false));
    3894        61122 :                         } while (accept (TokenType.COMMA));
    3895              :                 }
    3896       565062 :                 while (accept (TokenType.REQUIRES)) {
    3897            2 :                         expect (TokenType.OPEN_PARENS);
    3898            2 :                         method.add_precondition (parse_expression ());
    3899            2 :                         expect (TokenType.CLOSE_PARENS);
    3900              :                 }
    3901       565062 :                 while (accept (TokenType.ENSURES)) {
    3902            2 :                         expect (TokenType.OPEN_PARENS);
    3903            2 :                         method.add_postcondition (parse_expression ());
    3904            2 :                         expect (TokenType.CLOSE_PARENS);
    3905              :                 }
    3906       565058 :                 method.access = access;
    3907       565058 :                 set_attributes (method, attrs);
    3908       566983 :                 if (!accept (TokenType.SEMICOLON)) {
    3909         1925 :                         method.body = parse_block ();
    3910         1925 :                         method.external = false;
    3911              :                 }
    3912              : 
    3913       565058 :                 parent.add_method (method);
    3914              :         }
    3915              : 
    3916       381612 :         void parse_delegate_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
    3917       190806 :                 var begin = get_location ();
    3918       190806 :                 var access = parse_access_modifier ();
    3919       190806 :                 var flags = parse_member_declaration_modifiers ("delegates", ModifierFlags.EXTERN | ModifierFlags.STATIC);
    3920       190806 :                 expect (TokenType.DELEGATE);
    3921       190806 :                 var type = parse_type (true, false);
    3922       190806 :                 var sym = parse_symbol_name ();
    3923       190806 :                 var type_param_list = parse_type_parameter_list ();
    3924       190806 :                 var d = new Delegate (sym.name, type, get_src (begin), comment);
    3925       190806 :                 d.access = access;
    3926       190806 :                 set_attributes (d, attrs);
    3927       190806 :                 if (ModifierFlags.STATIC in flags) {
    3928            5 :                         if (!context.deprecated) {
    3929              :                                 // TODO enable warning in future releases
    3930            5 :                                 Report.warning (get_last_src (), "deprecated syntax, use [CCode (has_target = false)]");
    3931              :                         }
    3932            5 :                         d.has_target = false;
    3933              :                 }
    3934       190806 :                 if (ModifierFlags.EXTERN in flags) {
    3935            0 :                         d.is_extern = true;
    3936              :                 }
    3937       190806 :                 if (!d.get_attribute_bool ("CCode", "has_typedef", true)) {
    3938        17088 :                         if (!d.external) {
    3939            1 :                                 Report.error (get_last_src (), "Delegates without definition must be external");
    3940              :                         }
    3941        17088 :                         d.anonymous = true;
    3942              :                 }
    3943       276518 :                 foreach (TypeParameter type_param in type_param_list) {
    3944        42856 :                         d.add_type_parameter (type_param);
    3945              :                 }
    3946       190806 :                 expect (TokenType.OPEN_PARENS);
    3947       190806 :                 if (current () != TokenType.CLOSE_PARENS) {
    3948       986012 :                         do {
    3949       405363 :                                 var param = parse_parameter ();
    3950       405363 :                                 d.add_parameter (param);
    3951       405363 :                         } while (accept (TokenType.COMMA));
    3952              :                 }
    3953       190806 :                 expect (TokenType.CLOSE_PARENS);
    3954       190806 :                 if (accept (TokenType.THROWS)) {
    3955        37464 :                         do {
    3956        12488 :                                 d.add_error_type (parse_type (true, false));
    3957        12488 :                         } while (accept (TokenType.COMMA));
    3958              :                 }
    3959       190806 :                 expect (TokenType.SEMICOLON);
    3960              : 
    3961       190806 :                 Symbol result = d;
    3962       572438 :                 while (sym != null) {
    3963       190826 :                         sym = sym.inner;
    3964              : 
    3965       190816 :                         Symbol next = (sym != null ? new Namespace (sym.name, d.source_reference) : parent);
    3966       190816 :                         if (result is Namespace) {
    3967           10 :                                 next.add_namespace ((Namespace) result);
    3968              :                         } else {
    3969       190806 :                                 next.add_delegate ((Delegate) result);
    3970              :                         }
    3971       381632 :                         result = next;
    3972              :                 }
    3973              :         }
    3974              : 
    3975      6738590 :         List<TypeParameter> parse_type_parameter_list () throws ParseError {
    3976      6738590 :                 if (accept (TokenType.OP_LT)) {
    3977       110679 :                         var list = new ArrayList<TypeParameter> ();
    3978       239769 :                         do {
    3979       129090 :                                 var begin = get_location ();
    3980       129090 :                                 string id = parse_identifier ();
    3981       129090 :                                 list.add (new TypeParameter (id, get_src (begin)));
    3982       129090 :                         } while (accept (TokenType.COMMA));
    3983       110679 :                         expect (TokenType.OP_GT);
    3984      6738590 :                         return list;
    3985              :                 } else {
    3986      6627911 :                         if (_empty_type_parameter_list == null) {
    3987         1538 :                                 _empty_type_parameter_list = new ArrayList<TypeParameter> ();
    3988              :                         }
    3989     13255822 :                         return _empty_type_parameter_list;
    3990              :                 }
    3991              :         }
    3992              : 
    3993     16576598 :         void skip_type_argument_list () throws ParseError {
    3994     16576598 :                 if (accept (TokenType.OP_LT)) {
    3995       808669 :                         do {
    3996       425183 :                                 skip_type ();
    3997       425183 :                         } while (accept (TokenType.COMMA));
    3998       383486 :                         expect (TokenType.OP_GT);
    3999              :                 }
    4000              :         }
    4001              : 
    4002              :         // try to parse type argument list
    4003     18374228 :         List<DataType>? parse_type_argument_list (bool maybe_expression) throws ParseError {
    4004     18374228 :                 var begin = get_location ();
    4005     18374228 :                 if (accept (TokenType.OP_LT)) {
    4006       566730 :                         var list = new ArrayList<DataType> ();
    4007      1740319 :                         do {
    4008       619164 :                                 switch (current ()) {
    4009              :                                 case TokenType.VOID:
    4010              :                                 case TokenType.DYNAMIC:
    4011              :                                 case TokenType.UNOWNED:
    4012              :                                 case TokenType.WEAK:
    4013              :                                 case TokenType.IDENTIFIER:
    4014       606859 :                                         var type = parse_type (true, true);
    4015       606859 :                                         list.add (type);
    4016       606859 :                                         break;
    4017              :                                 default:
    4018        12305 :                                         rollback (begin);
    4019        12305 :                                         return null;
    4020              :                                 }
    4021       606859 :                         } while (accept (TokenType.COMMA));
    4022       554425 :                         if (!accept (TokenType.OP_GT)) {
    4023         4654 :                                 rollback (begin);
    4024         4654 :                                 return null;
    4025              :                         }
    4026       549771 :                         if (maybe_expression) {
    4027              :                                 // check follower to decide whether to keep type argument list
    4028         1619 :                                 switch (current ()) {
    4029              :                                 case TokenType.OPEN_PARENS:
    4030              :                                 case TokenType.CLOSE_PARENS:
    4031              :                                 case TokenType.CLOSE_BRACKET:
    4032              :                                 case TokenType.OPEN_BRACE:
    4033              :                                 case TokenType.COLON:
    4034              :                                 case TokenType.SEMICOLON:
    4035              :                                 case TokenType.COMMA:
    4036              :                                 case TokenType.DOT:
    4037              :                                 case TokenType.INTERR:
    4038              :                                 case TokenType.OP_EQ:
    4039              :                                 case TokenType.OP_NE:
    4040              :                                         // keep type argument list
    4041              :                                         break;
    4042              :                                 default:
    4043              :                                         // interpret tokens as expression
    4044            0 :                                         rollback (begin);
    4045            0 :                                         return null;
    4046              :                                 }
    4047              :                         }
    4048       549771 :                         return list;
    4049              :                 }
    4050     18374228 :                 return null;
    4051              :         }
    4052              : 
    4053        34807 :         MemberAccess parse_member_name (Expression? base_expr = null) throws ParseError {
    4054        34807 :                 var begin = get_location ();
    4055        34807 :                 MemberAccess expr = null;
    4056        34807 :                 bool first = true;
    4057        85453 :                 do {
    4058        50646 :                         string id = parse_identifier ();
    4059              : 
    4060              :                         // The first member access can be global:: qualified
    4061        50646 :                         bool qualified = false;
    4062        50646 :                         if (first && id == "global" && accept (TokenType.DOUBLE_COLON)) {
    4063            1 :                                 id = parse_identifier ();
    4064            1 :                                 qualified = true;
    4065              :                         }
    4066              : 
    4067        50646 :                         List<DataType> type_arg_list = parse_type_argument_list (false);
    4068        50646 :                         expr = new MemberAccess (expr != null ? expr : base_expr, id, get_src (begin));
    4069        50646 :                         expr.qualified = qualified;
    4070        50646 :                         if (type_arg_list != null) {
    4071         1273 :                                 foreach (DataType type_arg in type_arg_list) {
    4072          459 :                                         expr.add_type_argument (type_arg);
    4073              :                                 }
    4074              :                         }
    4075              : 
    4076        50646 :                         first = false;
    4077        50646 :                 } while (accept (TokenType.DOT));
    4078        34807 :                 return expr;
    4079              :         }
    4080              : 
    4081     23513253 :         bool is_declaration_keyword (TokenType type) {
    4082     23513253 :                 switch (type) {
    4083              :                 case TokenType.ABSTRACT:
    4084              :                 case TokenType.ASYNC:
    4085              :                 case TokenType.CLASS:
    4086              :                 case TokenType.CONST:
    4087              :                 case TokenType.DELEGATE:
    4088              :                 case TokenType.ENUM:
    4089              :                 case TokenType.ERRORDOMAIN:
    4090              :                 case TokenType.EXTERN:
    4091              :                 case TokenType.INLINE:
    4092              :                 case TokenType.INTERFACE:
    4093              :                 case TokenType.INTERNAL:
    4094              :                 case TokenType.NAMESPACE:
    4095              :                 case TokenType.NEW:
    4096              :                 case TokenType.OVERRIDE:
    4097              :                 case TokenType.PARTIAL:
    4098              :                 case TokenType.PRIVATE:
    4099              :                 case TokenType.PROTECTED:
    4100              :                 case TokenType.PUBLIC:
    4101              :                 case TokenType.SEALED:
    4102              :                 case TokenType.SIGNAL:
    4103              :                 case TokenType.STATIC:
    4104              :                 case TokenType.STRUCT:
    4105              :                 case TokenType.VIRTUAL:
    4106              :                 case TokenType.VOLATILE:
    4107              :                         return true;
    4108              :                 default:
    4109              :                         return false;
    4110              :                 }
    4111              :         }
    4112              : 
    4113        91114 :         void skip_modifier_keyword () {
    4114        91116 :                 while (true) {
    4115        91115 :                         switch (current ()) {
    4116              :                         case TokenType.ABSTRACT:
    4117              :                         case TokenType.ASYNC:
    4118              :                         case TokenType.CLASS:
    4119              :                         case TokenType.EXTERN:
    4120              :                         case TokenType.INLINE:
    4121              :                         case TokenType.NEW:
    4122              :                         case TokenType.OVERRIDE:
    4123              :                         case TokenType.STATIC:
    4124              :                         case TokenType.VIRTUAL:
    4125            1 :                                 next ();
    4126            1 :                                 break;
    4127              :                         default:
    4128              :                                 return;
    4129              :                         }
    4130              :                 }
    4131              :         }
    4132              : }
    4133              : 
    4134              : public errordomain Vala.ParseError {
    4135              :         FAILED,
    4136              :         SYNTAX
    4137              : }
    4138              : 
        

Generated by: LCOV version 2.0-1