// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef VM_PARSER_H_
#define VM_PARSER_H_

#include "include/dart_api.h"

#include "platform/assert.h"
#include "platform/globals.h"
#include "lib/invocation_mirror.h"
#include "vm/allocation.h"
#include "vm/ast.h"
#include "vm/class_finalizer.h"
#include "vm/compiler_stats.h"
#include "vm/object.h"
#include "vm/raw_object.h"
#include "vm/token.h"

namespace dart {

// Forward declarations.
class ArgumentsDescriptor;
class Isolate;
class LocalScope;
class LocalVariable;
struct RegExpCompileData;
class SourceLabel;
template <typename T> class GrowableArray;
class Parser;

struct CatchParamDesc;
class ClassDesc;
struct MemberDesc;
struct ParamList;
struct QualIdent;
class TopLevel;

// The class ParsedFunction holds the result of parsing a function.
class ParsedFunction : public ZoneAllocated {
 public:
  ParsedFunction(Thread* thread, const Function& function)
      : thread_(thread),
        function_(function),
        code_(Code::Handle(zone(), function.unoptimized_code())),
        node_sequence_(NULL),
        regexp_compile_data_(NULL),
        instantiator_(NULL),
        current_context_var_(NULL),
        expression_temp_var_(NULL),
        finally_return_temp_var_(NULL),
        deferred_prefixes_(new ZoneGrowableArray<const LibraryPrefix*>()),
        guarded_fields_(new ZoneGrowableArray<const Field*>()),
        default_parameter_values_(NULL),
        first_parameter_index_(0),
        first_stack_local_index_(0),
        num_copied_params_(0),
        num_stack_locals_(0),
        have_seen_await_expr_(false) {
    ASSERT(function.IsZoneHandle());
    // Every function has a local variable for the current context.
    LocalVariable* temp = new(zone()) LocalVariable(
        function.token_pos(),
        Symbols::CurrentContextVar(),
        Type::ZoneHandle(zone(), Type::DynamicType()));
    ASSERT(temp != NULL);
    current_context_var_ = temp;
  }

  const Function& function() const { return function_; }
  const Code& code() const { return code_; }

  SequenceNode* node_sequence() const { return node_sequence_; }
  void SetNodeSequence(SequenceNode* node_sequence);

  RegExpCompileData* regexp_compile_data() const {
    return regexp_compile_data_;
  }
  void SetRegExpCompileData(RegExpCompileData* regexp_compile_data);

  LocalVariable* instantiator() const { return instantiator_; }
  void set_instantiator(LocalVariable* instantiator) {
    // May be NULL.
    instantiator_ = instantiator;
  }

  void set_default_parameter_values(ZoneGrowableArray<const Instance*>* list) {
    default_parameter_values_ = list;
#if defined(DEBUG)
    if (list == NULL) return;
    for (intptr_t i = 0; i < list->length(); i++) {
      ASSERT(list->At(i)->IsZoneHandle() || list->At(i)->InVMHeap());
    }
#endif
  }


  const Instance& DefaultParameterValueAt(intptr_t i) const {
    ASSERT(default_parameter_values_ != NULL);
    return *default_parameter_values_->At(i);
  }

  ZoneGrowableArray<const Instance*>* default_parameter_values() const {
    return default_parameter_values_;
  }

  LocalVariable* current_context_var() const {
    return current_context_var_;
  }

  LocalVariable* expression_temp_var() const {
    ASSERT(has_expression_temp_var());
    return expression_temp_var_;
  }
  void set_expression_temp_var(LocalVariable* value) {
    ASSERT(!has_expression_temp_var());
    expression_temp_var_ = value;
  }
  bool has_expression_temp_var() const {
    return expression_temp_var_ != NULL;
  }

  LocalVariable* finally_return_temp_var() const {
    ASSERT(has_finally_return_temp_var());
    return finally_return_temp_var_;
  }
  void set_finally_return_temp_var(LocalVariable* value) {
    ASSERT(!has_finally_return_temp_var());
    finally_return_temp_var_ = value;
  }
  bool has_finally_return_temp_var() const {
    return finally_return_temp_var_ != NULL;
  }
  void EnsureFinallyReturnTemp(bool is_async);

  LocalVariable* EnsureExpressionTemp();

  bool HasDeferredPrefixes() const { return deferred_prefixes_->length() != 0; }
  ZoneGrowableArray<const LibraryPrefix*>* deferred_prefixes() const {
    return deferred_prefixes_;
  }
  void AddDeferredPrefix(const LibraryPrefix& prefix);

  ZoneGrowableArray<const Field*>* guarded_fields() const {
    return guarded_fields_;
  }

  int first_parameter_index() const { return first_parameter_index_; }
  int first_stack_local_index() const { return first_stack_local_index_; }
  int num_copied_params() const { return num_copied_params_; }
  int num_stack_locals() const { return num_stack_locals_; }
  int num_non_copied_params() const {
    return (num_copied_params_ == 0)
        ? function().num_fixed_parameters() : 0;
  }

  void AllocateVariables();
  void AllocateIrregexpVariables(intptr_t num_stack_locals);

  void record_await() { have_seen_await_expr_ = true; }
  bool have_seen_await() const { return have_seen_await_expr_; }

  Thread* thread() const { return thread_; }
  Isolate* isolate() const { return thread_->isolate(); }
  Zone* zone() const { return thread_->zone(); }

 private:
  Thread* thread_;
  const Function& function_;
  Code& code_;
  SequenceNode* node_sequence_;
  RegExpCompileData* regexp_compile_data_;
  LocalVariable* instantiator_;
  LocalVariable* current_context_var_;
  LocalVariable* expression_temp_var_;
  LocalVariable* finally_return_temp_var_;
  ZoneGrowableArray<const LibraryPrefix*>* deferred_prefixes_;
  ZoneGrowableArray<const Field*>* guarded_fields_;
  ZoneGrowableArray<const Instance*>* default_parameter_values_;

  int first_parameter_index_;
  int first_stack_local_index_;
  int num_copied_params_;
  int num_stack_locals_;
  bool have_seen_await_expr_;

  friend class Parser;
  DISALLOW_COPY_AND_ASSIGN(ParsedFunction);
};


class Parser : public ValueObject {
 public:
  // Parse the top level of a whole script file and register declared classes
  // in the given library.
  static void ParseCompilationUnit(const Library& library,
                                   const Script& script);

  // Parse top level of a class and register all functions/fields.
  static void ParseClass(const Class& cls);

  static void ParseFunction(ParsedFunction* parsed_function);

  // Parse and evaluate the metadata expressions at token_pos in the
  // class namespace of class cls (which can be the implicit toplevel
  // class if the metadata is at the top-level).
  static RawObject* ParseMetadata(const Class& cls, intptr_t token_pos);

  // Build a function containing the initializer expression of the
  // given static field.
  static ParsedFunction* ParseStaticFieldInitializer(const Field& field);

  // Parse a function to retrieve parameter information that is not retained in
  // the dart::Function object. Returns either an error if the parse fails
  // (which could be the case for local functions), or a flat array of entries
  // for each parameter. Each parameter entry contains:
  // * a Dart bool indicating whether the parameter was declared final
  // * its default value (or null if none was declared)
  // * an array of metadata (or null if no metadata was declared).
  enum {
    kParameterIsFinalOffset,
    kParameterDefaultValueOffset,
    kParameterMetadataOffset,
    kParameterEntrySize,
  };
  static RawObject* ParseFunctionParameters(const Function& func);

 private:
  friend class EffectGraphVisitor;  // For BuildNoSuchMethodArguments.

  struct Block;
  class TryStack;

  Parser(const Script& script, const Library& library, intptr_t token_pos);
  Parser(const Script& script, ParsedFunction* function, intptr_t token_pos);
  ~Parser();

  // The function for which we will generate code.
  const Function& current_function() const;

  // The innermost function being parsed.
  const Function& innermost_function() const;

  // Note that a local function may be parsed multiple times. It is first parsed
  // when its outermost enclosing function is being parsed. It is then parsed
  // again when an enclosing function calls this local function or calls
  // another local function enclosing it. Code for the local function will only
  // be generated the last time the local function is parsed, i.e. when it is
  // invoked. For example, a local function nested in another local function,
  // itself nested in a static function, is parsed 3 times (unless it does not
  // end up being invoked).
  // Now, current_function() always points to the outermost function being
  // compiled (i.e. the function that is being invoked), and is not updated
  // while parsing a nested function of that outermost function.
  // Therefore, the statements being parsed may or may not belong to the body
  // of the current_function(); they may belong to nested functions.
  // innermost_function() is the function that is currently being parsed.
  // It is either the same as current_function(), or a lexically nested
  // function.
  // The function level of the current parsing scope reflects the function
  // nesting. The function level is zero while parsing the body of the
  // current_function(), but is greater than zero while parsing the body of
  // local functions nested in current_function().

  // The class being parsed.
  const Class& current_class() const;
  void set_current_class(const Class& value);

  // ParsedFunction accessor.
  ParsedFunction* parsed_function() const {
    return parsed_function_;
  }

  const Script& script() const { return script_; }
  void SetScript(const Script& script, intptr_t token_pos);

  const Library& library() const { return library_; }
  void set_library(const Library& value) const { library_ = value.raw(); }

  // Parsing a library or a regular source script.
  bool is_library_source() const {
    return (script_.kind() == RawScript::kScriptTag) ||
        (script_.kind() == RawScript::kLibraryTag);
  }

  bool is_part_source() const {
    return script_.kind() == RawScript::kSourceTag;
  }

  // Parsing library patch script.
  bool is_patch_source() const {
    return script_.kind() == RawScript::kPatchTag;
  }

  intptr_t TokenPos() const { return tokens_iterator_.CurrentPosition(); }

  Token::Kind CurrentToken() {
    if (token_kind_ == Token::kILLEGAL) {
      ComputeCurrentToken();
    }
    return token_kind_;
  }

  void ComputeCurrentToken();

  RawLibraryPrefix* ParsePrefix();

  Token::Kind LookaheadToken(int num_tokens);
  String* CurrentLiteral() const;
  RawDouble* CurrentDoubleLiteral() const;
  RawInteger* CurrentIntegerLiteral() const;

  // Sets parser to given token position in the stream.
  void SetPosition(intptr_t position);

  void ConsumeToken() {
    // Reset cache and advance the token.
    token_kind_ = Token::kILLEGAL;
    tokens_iterator_.Advance();
    INC_STAT(thread(), num_tokens_consumed, 1);
  }
  void ConsumeRightAngleBracket();
  void CheckToken(Token::Kind token_expected, const char* msg = NULL);
  void ExpectToken(Token::Kind token_expected);
  void ExpectSemicolon();
  void UnexpectedToken();
  String* ExpectUserDefinedTypeIdentifier(const char* msg);
  String* ExpectIdentifier(const char* msg);
  bool IsAwaitKeyword();
  bool IsYieldKeyword();

  void SkipIf(Token::Kind);
  void SkipToMatching();
  void SkipToMatchingParenthesis();
  void SkipBlock();
  intptr_t SkipMetadata();
  void SkipTypeArguments();
  void SkipType(bool allow_void);
  void SkipInitializers();
  void SkipExpr();
  void SkipNestedExpr();
  void SkipConditionalExpr();
  void SkipBinaryExpr();
  void SkipUnaryExpr();
  void SkipPostfixExpr();
  void SkipSelectors();
  void SkipPrimary();
  void SkipCompoundLiteral();
  void SkipSymbolLiteral();
  void SkipNewOperator();
  void SkipActualParameters();
  void SkipMapLiteral();
  void SkipListLiteral();
  void SkipFunctionLiteral();
  void SkipStringLiteral();
  void SkipQualIdent();
  void SkipFunctionPreamble();

  AstNode* DartPrint(const char* str);

  void CheckConstructorCallTypeArguments(intptr_t pos,
                                         const Function& constructor,
                                         const TypeArguments& type_arguments);

  // Report already formatted error.
  static void ReportError(const Error& error);

  // Concatenate and report an already formatted error and a new error message.
  static void ReportErrors(const Error& prev_error,
                           const Script& script, intptr_t token_pos,
                           const char* format, ...) PRINTF_ATTRIBUTE(4, 5);

  // Report error message at location of current token in current script.
  void ReportError(const char* msg, ...) const PRINTF_ATTRIBUTE(2, 3);

  // Report error message at given location in current script.
  void ReportError(intptr_t token_pos,
                   const char* msg, ...) const PRINTF_ATTRIBUTE(3, 4);

  // Report warning message at location of current token in current script.
  void ReportWarning(const char* msg, ...) const PRINTF_ATTRIBUTE(2, 3);

  // Report warning message at given location in current script.
  void ReportWarning(intptr_t token_pos,
                     const char* msg, ...) const PRINTF_ATTRIBUTE(3, 4);

  void CheckRecursiveInvocation();

  const Instance& EvaluateConstExpr(intptr_t expr_pos, AstNode* expr);
  StaticGetterNode* RunStaticFieldInitializer(const Field& field,
                                              intptr_t field_ref_pos);
  RawObject* EvaluateConstConstructorCall(const Class& type_class,
                                          const TypeArguments& type_arguments,
                                          const Function& constructor,
                                          ArgumentListNode* arguments);
  LiteralNode* FoldConstExpr(intptr_t expr_pos, AstNode* expr);

  // Support for parsing of scripts.
  void ParseTopLevel();
  void ParseEnumDeclaration(const GrowableObjectArray& pending_classes,
                            const Class& toplevel_class,
                            intptr_t metadata_pos);
  void ParseEnumDefinition(const Class& cls);
  void ParseClassDeclaration(const GrowableObjectArray& pending_classes,
                             const Class& toplevel_class,
                             intptr_t metadata_pos);
  void ParseClassDefinition(const Class& cls);
  void ParseMixinAppAlias(const GrowableObjectArray& pending_classes,
                          const Class& toplevel_class,
                          intptr_t metadata_pos);
  void ParseTypedef(const GrowableObjectArray& pending_classes,
                    const Class& toplevel_class,
                    intptr_t metadata_pos);
  void ParseTopLevelVariable(TopLevel* top_level, intptr_t metadata_pos);
  void ParseTopLevelFunction(TopLevel* top_level, intptr_t metadata_pos);
  void ParseTopLevelAccessor(TopLevel* top_level, intptr_t metadata_pos);
  RawArray* EvaluateMetadata();

  RawFunction::AsyncModifier ParseFunctionModifier();

  // Support for parsing libraries.
  RawObject* CallLibraryTagHandler(Dart_LibraryTag tag,
                                   intptr_t token_pos,
                                   const String& url);
  void ParseIdentList(GrowableObjectArray* names);
  void ParseLibraryDefinition();
  void ParseLibraryName();
  void ParseLibraryImportExport(intptr_t metadata_pos);
  void ParseLibraryPart();
  void ParsePartHeader();
  void ParseLibraryNameObsoleteSyntax();
  void ParseLibraryImportObsoleteSyntax();
  void ParseLibraryIncludeObsoleteSyntax();

  void ResolveTypeFromClass(const Class& cls,
                            ClassFinalizer::FinalizationKind finalization,
                            AbstractType* type);
  RawAbstractType* ParseType(ClassFinalizer::FinalizationKind finalization,
                             bool allow_deferred_type = false,
                             bool consume_unresolved_prefix = true);
  RawAbstractType* ParseType(
      ClassFinalizer::FinalizationKind finalization,
      bool allow_deferred_type,
      bool consume_unresolved_prefix,
      LibraryPrefix* prefix);

  void ParseTypeParameters(const Class& cls);
  RawTypeArguments* ParseTypeArguments(
      ClassFinalizer::FinalizationKind finalization);
  void ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method);
  void ParseFieldDefinition(ClassDesc* members, MemberDesc* field);
  void CheckMemberNameConflict(ClassDesc* members, MemberDesc* member);
  void ParseClassMemberDefinition(ClassDesc* members,
                                  intptr_t metadata_pos);
  void ParseFormalParameter(bool allow_explicit_default_value,
                            bool evaluate_metadata,
                            ParamList* params);
  void ParseFormalParameters(bool allow_explicit_default_values,
                             bool evaluate_metadata,
                             ParamList* params);
  void ParseFormalParameterList(bool allow_explicit_default_values,
                                bool evaluate_metadata,
                                ParamList* params);
  void CheckFieldsInitialized(const Class& cls);
  void AddImplicitConstructor(const Class& cls);
  void CheckConstructors(ClassDesc* members);
  AstNode* ParseExternalInitializedField(const Field& field);
  void ParseInitializedInstanceFields(
      const Class& cls,
      LocalVariable* receiver,
      GrowableArray<Field*>* initialized_fields);
  AstNode* CheckDuplicateFieldInit(
      intptr_t init_pos,
      GrowableArray<Field*>* initialized_fields,
      AstNode* instance,
      Field* field,
      AstNode* init_value);
  StaticCallNode* GenerateSuperConstructorCall(
      const Class& cls,
      intptr_t supercall_pos,
      LocalVariable* receiver,
      AstNode* phase_parameter,
      ArgumentListNode* forwarding_args);
  StaticCallNode* ParseSuperInitializer(
      const Class& cls,
      LocalVariable* receiver);
  AstNode* ParseInitializer(const Class& cls,
                            LocalVariable* receiver,
                            GrowableArray<Field*>* initialized_fields);
  void ParseConstructorRedirection(const Class& cls, LocalVariable* receiver);
  void ParseInitializers(const Class& cls,
                         LocalVariable* receiver,
                         GrowableArray<Field*>* initialized_fields);
  String& ParseNativeDeclaration();
  void ParseInterfaceList(const Class& cls);
  RawAbstractType* ParseMixins(const AbstractType& super_type);
  static StaticCallNode* BuildInvocationMirrorAllocation(
      intptr_t call_pos,
      const String& function_name,
      const ArgumentListNode& function_args,
      const LocalVariable* temp,
      bool is_super_invocation);
  // Build arguments for a NoSuchMethodCall. If LocalVariable temp is not NULL,
  // the last argument is stored in temp.
  static ArgumentListNode* BuildNoSuchMethodArguments(
      intptr_t call_pos,
      const String& function_name,
      const ArgumentListNode& function_args,
      const LocalVariable* temp,
      bool is_super_invocation);
  RawFunction* GetSuperFunction(intptr_t token_pos,
                                const String& name,
                                ArgumentListNode* arguments,
                                bool resolve_getter,
                                bool* is_no_such_method);
  AstNode* ParseSuperCall(const String& function_name);
  AstNode* ParseSuperFieldAccess(const String& field_name, intptr_t field_pos);
  AstNode* ParseSuperOperator();
  AstNode* BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super);

  static bool ParseFormalParameters(const Function& func, ParamList* params);

  void SetupDefaultsForOptionalParams(const ParamList& params);
  ClosureNode* CreateImplicitClosureNode(const Function& func,
                                         intptr_t token_pos,
                                         AstNode* receiver);
  static void AddFormalParamsToFunction(const ParamList* params,
                                        const Function& func);
  void AddFormalParamsToScope(const ParamList* params, LocalScope* scope);

  SequenceNode* ParseConstructor(const Function& func);
  SequenceNode* ParseFunc(const Function& func);

  void ParseNativeFunctionBlock(const ParamList* params, const Function& func);

  SequenceNode* ParseInstanceGetter(const Function& func);
  SequenceNode* ParseInstanceSetter(const Function& func);
  SequenceNode* ParseStaticFinalGetter(const Function& func);
  SequenceNode* ParseStaticInitializer();
  SequenceNode* ParseMethodExtractor(const Function& func);
  SequenceNode* ParseNoSuchMethodDispatcher(const Function& func);
  SequenceNode* ParseInvokeFieldDispatcher(const Function& func);
  SequenceNode* ParseImplicitClosure(const Function& func);
  SequenceNode* ParseConstructorClosure(const Function& func);

  void BuildDispatcherScope(const Function& func,
                            const ArgumentsDescriptor& desc);

  void EnsureHasReturnStatement(SequenceNode* seq, intptr_t return_pos);
  void ChainNewBlock(LocalScope* outer_scope);
  void OpenBlock();
  void OpenLoopBlock();
  void OpenFunctionBlock(const Function& func);
  void OpenAsyncClosure();
  RawFunction* OpenAsyncFunction(intptr_t formal_param_pos);
  RawFunction* OpenSyncGeneratorFunction(intptr_t func_pos);
  SequenceNode* CloseSyncGenFunction(const Function& closure,
                                     SequenceNode* closure_node);
  void AddSyncGenClosureParameters(ParamList* params);
  void AddAsyncGenClosureParameters(ParamList* params);

  // Support for async* functions.
  RawFunction* OpenAsyncGeneratorFunction(intptr_t func_pos);
  SequenceNode* CloseAsyncGeneratorFunction(const Function& closure,
                                            SequenceNode* closure_node);
  void OpenAsyncGeneratorClosure();
  SequenceNode* CloseAsyncGeneratorClosure(SequenceNode* body);

  void OpenAsyncTryBlock();
  SequenceNode* CloseBlock();
  SequenceNode* CloseAsyncFunction(const Function& closure,
                                   SequenceNode* closure_node);

  SequenceNode* CloseAsyncClosure(SequenceNode* body);
  SequenceNode* CloseAsyncTryBlock(SequenceNode* try_block);
  SequenceNode* CloseAsyncGeneratorTryBlock(SequenceNode *body);

  void AddAsyncClosureParameters(ParamList* params);
  void AddContinuationVariables();
  void AddAsyncClosureVariables();
  void AddAsyncGeneratorVariables();

  LocalVariable* LookupPhaseParameter();
  LocalVariable* LookupReceiver(LocalScope* from_scope, bool test_only);
  LocalVariable* LookupTypeArgumentsParameter(LocalScope* from_scope,
                                              bool test_only);
  void CaptureInstantiator();
  AstNode* LoadReceiver(intptr_t token_pos);
  AstNode* LoadFieldIfUnresolved(AstNode* node);
  AstNode* LoadClosure(PrimaryNode* primary);
  InstanceGetterNode* CallGetter(intptr_t token_pos,
                                 AstNode* object,
                                 const String& name);

  AstNode* ParseAssertStatement();
  AstNode* ParseJump(String* label_name);
  AstNode* ParseIfStatement(String* label_name);
  AstNode* ParseWhileStatement(String* label_name);
  AstNode* ParseDoWhileStatement(String* label_name);
  AstNode* ParseForStatement(String* label_name);
  AstNode* ParseAwaitForStatement(String* label_name);
  AstNode* ParseForInStatement(intptr_t forin_pos, SourceLabel* label);
  RawClass* CheckCaseExpressions(const GrowableArray<LiteralNode*>& values);
  CaseNode* ParseCaseClause(LocalVariable* switch_expr_value,
                            GrowableArray<LiteralNode*>* case_expr_values,
                            SourceLabel* case_label);
  AstNode* ParseSwitchStatement(String* label_name);

  // try/catch/finally parsing.
  void AddCatchParamsToScope(CatchParamDesc* exception_param,
                             CatchParamDesc* stack_trace_param,
                             LocalScope* scope);
  void SetupExceptionVariables(LocalScope* try_scope,
                               bool is_async,
                               LocalVariable** context_var,
                               LocalVariable** exception_var,
                               LocalVariable** stack_trace_var,
                               LocalVariable** saved_exception_var,
                               LocalVariable** saved_stack_trace_var);
  void SaveExceptionAndStacktrace(SequenceNode* statements,
                                  LocalVariable* exception_var,
                                  LocalVariable* stack_trace_var,
                                  LocalVariable* saved_exception_var,
                                  LocalVariable* saved_stack_trace_var);
  // Parse all the catch clause of a try.
  SequenceNode* ParseCatchClauses(intptr_t handler_pos,
                                  bool is_async,
                                  LocalVariable* exception_var,
                                  LocalVariable* stack_trace_var,
                                  LocalVariable* rethrow_exception_var,
                                  LocalVariable* rethrow_stack_trace_var,
                                  const GrowableObjectArray& handler_types,
                                  bool* needs_stack_trace);
  // Parse or generate a finally clause.
  SequenceNode* EnsureFinallyClause(bool parse,
                                    bool is_async,
                                    LocalVariable* exception_var,
                                    LocalVariable* stack_trace_var,
                                    LocalVariable* rethrow_exception_var,
                                    LocalVariable* rethrow_stack_trace_var);
  // Push try block onto the stack of try blocks in scope.
  void PushTry(Block* try_block);
  // Pop the inner most try block from the stack.
  TryStack* PopTry();
  // Collect saved try context variables if await or yield is in try block.
  void CheckAsyncOpInTryBlock(
      LocalVariable** saved_try_ctx,
      LocalVariable** async_saved_try_ctx,
      LocalVariable** outer_saved_try_ctx,
      LocalVariable** outer_async_saved_try_ctx) const;
  // Add specified node to try block list so that it can be patched with
  // inlined finally code if needed.
  void AddNodeForFinallyInlining(AstNode* node);
  // Add the inlined finally clause to the specified node.
  void AddFinallyClauseToNode(bool is_async,
                              AstNode* node,
                              InlinedFinallyNode* finally_clause);
  AstNode* ParseTryStatement(String* label_name);
  RawAbstractType* ParseConstFinalVarOrType(
      ClassFinalizer::FinalizationKind finalization);
  AstNode* ParseVariableDeclaration(const AbstractType& type,
                                    bool is_final,
                                    bool is_const,
                                    SequenceNode** await_preamble);
  AstNode* ParseVariableDeclarationList();
  AstNode* ParseFunctionStatement(bool is_literal);
  AstNode* ParseYieldStatement();
  AstNode* ParseStatement();
  SequenceNode* ParseNestedStatement(bool parsing_loop_body,
                                     SourceLabel* label);
  void ParseStatementSequence();
  bool IsIdentifier();
  bool IsSymbol(const String& symbol);
  bool IsSimpleLiteral(const AbstractType& type, Instance* value);
  bool IsFunctionTypeAliasName();
  bool IsMixinAppAlias();
  bool TryParseQualIdent();
  bool TryParseTypeParameters();
  bool TryParseOptionalType();
  bool TryParseReturnType();
  bool IsVariableDeclaration();
  bool IsFunctionDeclaration();
  bool IsFunctionLiteral();
  bool IsForInStatement();
  bool IsTopLevelAccessor();

  AstNode* ParseBinaryExpr(int min_preced);
  LiteralNode* ParseConstExpr();
  static const bool kRequireConst = true;
  static const bool kAllowConst = false;
  static const bool kConsumeCascades = true;
  static const bool kNoCascades = false;
  AstNode* ParseAwaitableExpr(bool require_compiletime_const,
                              bool consume_cascades,
                              SequenceNode** await_preamble);
  AstNode* ParseExpr(bool require_compiletime_const, bool consume_cascades);
  AstNode* ParseAwaitableExprList();
  AstNode* ParseConditionalExpr();
  AstNode* ParseUnaryExpr();
  AstNode* ParsePostfixExpr();
  AstNode* ParseSelectors(AstNode* primary, bool is_cascade);
  AstNode* ParseClosurization(AstNode* primary);
  AstNode* ParseCascades(AstNode* expr);
  AstNode* ParsePrimary();
  AstNode* ParseStringLiteral(bool allow_interpolation);
  String* ParseImportStringLiteral();
  AstNode* ParseCompoundLiteral();
  AstNode* ParseSymbolLiteral();
  AstNode* ParseListLiteral(intptr_t type_pos,
                            bool is_const,
                            const TypeArguments& type_arguments);
  AstNode* ParseMapLiteral(intptr_t type_pos,
                           bool is_const,
                           const TypeArguments& type_arguments);

  RawFunction* BuildConstructorClosureFunction(const Function& ctr,
                                               intptr_t token_pos);
  AstNode* ParseNewOperator(Token::Kind op_kind);
  void ParseConstructorClosurization(Function* constructor,
                                     TypeArguments* type_arguments);

  // An implicit argument, if non-null, is prepended to the returned list.
  ArgumentListNode* ParseActualParameters(ArgumentListNode* implicit_arguments,
                                          bool require_const);
  AstNode* ParseStaticCall(const Class& cls,
                           const String& method_name,
                           intptr_t ident_pos);
  AstNode* ParseInstanceCall(AstNode* receiver,
                             const String& method_name,
                             intptr_t ident_pos,
                             bool is_conditional);
  AstNode* ParseClosureCall(AstNode* closure);
  AstNode* GenerateStaticFieldLookup(const Field& field,
                                     intptr_t ident_pos);
  AstNode* GenerateStaticFieldAccess(const Class& cls,
                                     const String& field_name,
                                     intptr_t ident_pos);

  LocalVariable* LookupLocalScope(const String& ident);
  void CheckInstanceFieldAccess(intptr_t field_pos, const String& field_name);
  bool ParsingStaticMember() const;
  const AbstractType* ReceiverType(const Class& cls);
  bool IsInstantiatorRequired() const;
  bool ResolveIdentInLocalScope(intptr_t ident_pos,
                                const String &ident,
                                AstNode** node);
  static const bool kResolveLocally = true;
  static const bool kResolveIncludingImports = false;

  // Resolve a primary identifier in the library or prefix scope and
  // generate the corresponding AstNode.
  AstNode* ResolveIdentInCurrentLibraryScope(intptr_t ident_pos,
                                             const String& ident);
  AstNode* ResolveIdentInPrefixScope(intptr_t ident_pos,
                                     const LibraryPrefix& prefix,
                                     const String& ident);

  AstNode* ResolveIdent(intptr_t ident_pos,
                        const String& ident,
                        bool allow_closure_names);
  RawString* ResolveImportVar(intptr_t ident_pos, const String& ident);
  AstNode* OptimizeBinaryOpNode(intptr_t op_pos,
                                Token::Kind binary_op,
                                AstNode* lhs,
                                AstNode* rhs);
  AstNode* ExpandAssignableOp(intptr_t op_pos,
                              Token::Kind assignment_op,
                              AstNode* lhs,
                              AstNode* rhs);
  LetNode* PrepareCompoundAssignmentNodes(AstNode** expr);
  LocalVariable* CreateTempConstVariable(intptr_t token_pos, const char* s);

  static SequenceNode* NodeAsSequenceNode(intptr_t sequence_pos,
                                          AstNode* node,
                                          LocalScope* scope);

  SequenceNode* MakeImplicitConstructor(const Function& func);
  AstNode* MakeStaticCall(const String& cls_name,
                          const String& func_name,
                          ArgumentListNode* arguments);
  String& Interpolate(const GrowableArray<AstNode*>& values);
  AstNode* MakeAssertCall(intptr_t begin, intptr_t end);
  AstNode* ThrowTypeError(intptr_t type_pos, const AbstractType& type,
                           LibraryPrefix* prefix = NULL);
  AstNode* ThrowNoSuchMethodError(intptr_t call_pos,
                                  const Class& cls,
                                  const String& function_name,
                                  ArgumentListNode* function_arguments,
                                  InvocationMirror::Call call,
                                  InvocationMirror::Type type,
                                  const Function* func,
                                  const LibraryPrefix* prefix = NULL);

  void SetupSavedTryContext(LocalVariable* saved_try_context);

  void CheckOperatorArity(const MemberDesc& member);

  void EnsureExpressionTemp();
  bool IsLegalAssignableSyntax(AstNode* expr, intptr_t end_pos);
  AstNode* CreateAssignmentNode(AstNode* original,
                                AstNode* rhs,
                                const String* left_ident,
                                intptr_t left_pos,
                                bool is_compound = false);
  AstNode* InsertClosureCallNodes(AstNode* condition);

  ConstructorCallNode* CreateConstructorCallNode(
      intptr_t token_pos,
      const TypeArguments& type_arguments,
      const Function& constructor,
      ArgumentListNode* arguments);

  void AddEqualityNullCheck();

  AstNode* BuildClosureCall(intptr_t token_pos,
                            AstNode* closure,
                            ArgumentListNode* arguments);

  RawInstance* TryCanonicalize(const Instance& instance, intptr_t token_pos);
  void CacheConstantValue(intptr_t token_pos, const Instance& value);
  bool GetCachedConstant(intptr_t token_pos, Instance* value);

  Thread* thread() const { return thread_; }
  Isolate* isolate() const { return isolate_; }
  Zone* zone() const { return thread_->zone(); }

  Isolate* isolate_;  // Cached current isolate.
  Thread* thread_;

  Script& script_;
  TokenStream::Iterator tokens_iterator_;
  Token::Kind token_kind_;  // Cached token kind for current token.
  Block* current_block_;

  // is_top_level_ is true if parsing the "top level" of a compilation unit,
  // that is class definitions, function type aliases, global functions,
  // global variables.
  bool is_top_level_;

  // await_is_keyword_ is true if we are parsing an async or generator
  // function. In this context the identifiers await, async and yield
  // are treated as keywords.
  bool await_is_keyword_;

  // The member currently being parsed during "top level" parsing.
  MemberDesc* current_member_;

  // Parser mode to allow/disallow function literals. This is used in
  // constructor initializer expressions to handle ambiguous grammar.
  bool SetAllowFunctionLiterals(bool value);
  bool allow_function_literals_;

  // The function currently being compiled.
  ParsedFunction* parsed_function_;

  // The function currently being parsed.
  Function& innermost_function_;

  // Current literal token.
  LiteralToken& literal_token_;

  // The class currently being parsed, or the owner class of the
  // function currently being parsed. It is used for primary identifier lookups.
  Class& current_class_;

  // The current library (and thus class dictionary) used to resolve names.
  // When parsing a function, this is the library in which the function
  // is defined. This can be the library in which the current_class_ is
  // defined, or the library of a mixin class where the function originates.
  Library& library_;

  // Stack of try blocks in scope, this is used to generate inlined finally
  // code at all points in the try block where an exit from the block is
  // done using 'return', 'break' or 'continue' statements.
  TryStack* try_stack_;

  // Each try in this function gets its own try index.
  int16_t AllocateTryIndex();

  int16_t last_used_try_index_;

  bool unregister_pending_function_;

  LocalScope* async_temp_scope_;

  // Indentation of parser trace.
  intptr_t trace_indent_;

  DISALLOW_COPY_AND_ASSIGN(Parser);
};

}  // namespace dart

#endif  // VM_PARSER_H_
