// 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 RUNTIME_VM_PARSER_H_
#define RUNTIME_VM_PARSER_H_

#include "include/dart_api.h"

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

namespace dart {

// Forward declarations.

namespace kernel {

class ScopeBuildingResult;

}  // namespace kernel

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;
class RecursionChecker;

// We cache compile time constants during compilation.  This allows us
// to look them up when the same code gets compiled again.  During
// background compilation, we are not able to evaluate the constants
// so this cache is necessary to support background compilation.
//
// We cache the constants with the script itself. This is helpful during isolate
// reloading, as it allows us to reference the compile time constants associated
// with a particular version of a script. The map key is simply the
// TokenPosition where the constant is defined.
class ConstMapKeyEqualsTraits {
 public:
  static const char* Name() { return "ConstMapKeyEqualsTraits"; }
  static bool ReportStats() { return false; }

  static bool IsMatch(const Object& a, const Object& b) {
    const Smi& key1 = Smi::Cast(a);
    const Smi& key2 = Smi::Cast(b);
    return (key1.Value() == key2.Value());
  }
  static bool IsMatch(const TokenPosition& key1, const Object& b) {
    const Smi& key2 = Smi::Cast(b);
    return (key1.value() == key2.Value());
  }
  static uword Hash(const Object& obj) {
    const Smi& key = Smi::Cast(obj);
    return HashValue(key.Value());
  }
  static uword Hash(const TokenPosition& key) { return HashValue(key.value()); }
  // Used by CacheConstantValue if a new constant is added to the map.
  static RawObject* NewKey(const TokenPosition& key) {
    return Smi::New(key.value());
  }

 private:
  static uword HashValue(intptr_t pos) { return pos % (Smi::kMaxValue - 13); }
};
typedef UnorderedHashMap<ConstMapKeyEqualsTraits> ConstantsMap;

// The class ParsedFunction holds the result of parsing a function.
class ParsedFunction : public ZoneAllocated {
 public:
  ParsedFunction(Thread* thread, const Function& function);

  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) {
    ASSERT(instantiator != NULL);
    instantiator_ = instantiator;
  }

  LocalVariable* function_type_arguments() const {
    return function_type_arguments_;
  }
  void set_function_type_arguments(LocalVariable* function_type_arguments) {
    ASSERT(function_type_arguments != NULL);
    function_type_arguments_ = function_type_arguments;
  }
  LocalVariable* parent_type_arguments() const {
    return parent_type_arguments_;
  }
  void set_parent_type_arguments(LocalVariable* parent_type_arguments) {
    ASSERT(parent_type_arguments != NULL);
    parent_type_arguments_ = parent_type_arguments;
  }

  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_; }

  bool has_arg_desc_var() const { return arg_desc_var_ != NULL; }
  LocalVariable* arg_desc_var() const { return arg_desc_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_;
  }

  VariableIndex first_parameter_index() const { return first_parameter_index_; }
  int num_stack_locals() const { return num_stack_locals_; }

  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_; }
  bool is_forwarding_stub() const {
    return forwarding_stub_super_target_ != -1;
  }
  kernel::NameIndex forwarding_stub_super_target() const {
    return forwarding_stub_super_target_;
  }
  void MarkForwardingStub(kernel::NameIndex target) {
    forwarding_stub_super_target_ = target;
  }

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

  // Adds only relevant fields: field must be unique and its guarded_cid()
  // relevant.
  void AddToGuardedFields(const Field* field) const;

  void Bailout(const char* origin, const char* reason) const;

  kernel::ScopeBuildingResult* EnsureKernelScopes();

  LocalVariable* RawTypeArgumentsVariable() const {
    return raw_type_arguments_var_;
  }

  LocalVariable* RawParameterVariable(intptr_t i) const {
    return raw_parameters_[i];
  }

 private:
  Thread* thread_;
  const Function& function_;
  Code& code_;
  SequenceNode* node_sequence_;
  RegExpCompileData* regexp_compile_data_;
  LocalVariable* instantiator_;
  LocalVariable* function_type_arguments_;
  LocalVariable* parent_type_arguments_;
  LocalVariable* current_context_var_;
  LocalVariable* arg_desc_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_;

  LocalVariable* raw_type_arguments_var_;
  ZoneGrowableArray<LocalVariable*> raw_parameters_;

  VariableIndex first_parameter_index_;
  int num_stack_locals_;
  bool have_seen_await_expr_;

  kernel::NameIndex forwarding_stub_super_target_;
  kernel::ScopeBuildingResult* kernel_scopes_;

  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);

  // Return true if |field| has a function literal initializer.
  // When true is returned, |start| and |end| will hold the token
  // range of the function literal.
  static bool FieldHasFunctionLiteralInitializer(const Field& field,
                                                 TokenPosition* start,
                                                 TokenPosition* end);

  // 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 Field& meta_data);

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

  static void InsertCachedConstantValue(const Script& script,
                                        TokenPosition token_pos,
                                        const Instance& value);

  // Parse a function to retrieve parameter information that is not retained in
  // the 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;
  class TokenPosScope;

  Parser(const Script& script, const Library& library, TokenPosition token_pos);
  Parser(const Script& script,
         ParsedFunction* function,
         TokenPosition 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().

  // FunctionLevel is 0 when parsing code of current_function(), and denotes
  // the relative nesting level when parsing a nested function.
  int FunctionLevel() const;

  // 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, TokenPosition 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;
  }

  TokenPosition TokenPos() const { return tokens_iterator_.CurrentPosition(); }
  TokenPosition PrevTokenPos() const { return prev_token_pos_; }

  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(TokenPosition position);

  void ConsumeToken() {
    // Reset cache and advance the token.
    prev_token_pos_ = tokens_iterator_.CurrentPosition();
    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();
  void SkipOneMetadata();
  TokenPosition SkipMetadata();
  bool IsPatchAnnotation(TokenPosition pos);
  bool IsPragmaAnnotation(TokenPosition pos);
  void SkipTypeArguments();
  void SkipTypeParameters();
  void SkipType(bool allow_void);
  void SkipTypeOrFunctionType(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(TokenPosition 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,
                           TokenPosition 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);

  void ReportErrorBefore(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);

  // Report error message at given location in current script.
  void ReportError(TokenPosition 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(TokenPosition token_pos, const char* msg, ...) const
      PRINTF_ATTRIBUTE(3, 4);

  void CheckRecursiveInvocation();

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

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

  RawFunction::AsyncModifier ParseFunctionModifier();

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

  void ResolveSignatureTypeParameters(const Function& signature);
  void ResolveTypeParameters(AbstractType* type);
  RawAbstractType* CanonicalizeType(const 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);
  RawType* ParseFunctionType(const AbstractType& result_type,
                             ClassFinalizer::FinalizationKind finalization);
  RawAbstractType* ParseTypeOrFunctionType(
      bool allow_void,
      ClassFinalizer::FinalizationKind finalization);
  void ParseTypeParameters(bool parameterizing_class);
  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,
                                  TokenPosition metadata_pos);
  void CheckFinalInitializationConflicts(const ClassDesc* class_desc,
                                         const MemberDesc* member);
  void ParseParameterType(ParamList* params);
  void ParseFormalParameter(bool allow_explicit_default_value,
                            bool evaluate_metadata,
                            ParamList* params);
  void ParseFormalParameters(bool use_function_type_syntax,
                             bool allow_explicit_default_values,
                             bool evaluate_metadata,
                             ParamList* params);
  void ParseFormalParameterList(bool use_function_type_syntax,
                                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(TokenPosition init_pos,
                                   GrowableArray<Field*>* initialized_fields,
                                   AstNode* instance,
                                   Field* field,
                                   AstNode* init_value);
  StaticCallNode* GenerateSuperConstructorCall(
      const Class& cls,
      TokenPosition supercall_pos,
      LocalVariable* receiver,
      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(
      TokenPosition 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(
      TokenPosition call_pos,
      const String& function_name,
      const ArgumentListNode& function_args,
      const LocalVariable* temp,
      bool is_super_invocation);
  RawFunction* GetSuperFunction(TokenPosition token_pos,
                                const String& name,
                                ArgumentListNode* arguments,
                                bool resolve_getter,
                                bool* is_no_such_method);
  AstNode* ParseSuperCall(const String& function_name,
                          const TypeArguments& func_type_args);
  AstNode* ParseSuperFieldAccess(const String& field_name,
                                 TokenPosition 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,
                                         TokenPosition token_pos,
                                         AstNode* receiver);
  void FinalizeFormalParameterTypes(const ParamList* params);
  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, bool check_semicolon);

  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);

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

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

  // Support for async* functions.
  RawFunction* OpenAsyncGeneratorFunction(TokenPosition 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,
                                  TokenPosition func_end_pos);
  SequenceNode* CloseAsyncTryBlock(SequenceNode* try_block,
                                   TokenPosition func_end_pos);
  SequenceNode* CloseAsyncGeneratorTryBlock(SequenceNode* body);

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

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

  AstNode* ParseAssertStatement(bool is_const = false);
  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(TokenPosition 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(TokenPosition 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);
  void RemoveNodesForFinallyInlining(SourceLabel* label);
  // 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 IsFunctionTypeSymbol();
  bool IsFunctionTypeAliasName(bool* use_function_type_syntax);
  bool TryParseQualIdent();
  bool TryParseTypeParameters();
  bool TryParseTypeArguments();
  bool IsTypeParameters();
  bool IsArgumentPart();
  bool IsParameterPart();
  bool TryParseType(bool allow_void);
  bool IsVariableDeclaration();
  bool IsFunctionReturnType();
  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* ParseCascades(AstNode* expr);
  AstNode* ParsePrimary();
  AstNode* ParseStringLiteral(bool allow_interpolation);
  String* ParseImportStringLiteral();
  AstNode* ParseCompoundLiteral();
  AstNode* ParseSymbolLiteral();
  AstNode* ParseListLiteral(TokenPosition type_pos,
                            bool is_const,
                            const TypeArguments& type_arguments);
  AstNode* ParseMapLiteral(TokenPosition type_pos,
                           bool is_const,
                           const TypeArguments& type_arguments);

  AstNode* ParseNewOperator(Token::Kind op_kind);

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

  LocalVariable* LookupLocalScope(const String& ident);
  void CheckInstanceFieldAccess(TokenPosition field_pos,
                                const String& field_name);
  bool ParsingStaticMember() const;
  bool GetFunctionLiteralInitializerRange(const Field& field,
                                          TokenPosition* start,
                                          TokenPosition* end);
  const AbstractType* ReceiverType(const Class& cls);
  bool IsInstantiatorRequired() const;
  bool InGenericFunctionScope() const;
  bool ResolveIdentInLocalScope(TokenPosition ident_pos,
                                const String& ident,
                                AstNode** node,
                                intptr_t* function_level);
  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(TokenPosition ident_pos,
                                             const String& ident);
  AstNode* ResolveIdentInPrefixScope(TokenPosition ident_pos,
                                     const LibraryPrefix& prefix,
                                     const String& ident);

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

  static SequenceNode* NodeAsSequenceNode(TokenPosition 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* ThrowTypeError(TokenPosition type_pos,
                          const AbstractType& type,
                          LibraryPrefix* prefix = NULL);
  AstNode* ThrowNoSuchMethodError(TokenPosition call_pos,
                                  const Class& cls,
                                  const String& function_name,
                                  ArgumentListNode* function_arguments,
                                  InvocationMirror::Level level,
                                  InvocationMirror::Kind kind,
                                  const Function* func,
                                  const LibraryPrefix* prefix = NULL);

  void SetupSavedTryContext(LocalVariable* saved_try_context);

  void CheckOperatorArity(const MemberDesc& member);

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

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

  void AddEqualityNullCheck();

  AstNode* AddAsyncResultTypeCheck(TokenPosition expr_pos, AstNode* expr);

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

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

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

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

  // It is Heap::kNew for mutator thread and Heap::kOld for other threads (e.g.
  // background compiler).
  Heap::Space allocation_space_;

  Script& script_;
  TokenStream::Iterator tokens_iterator_;
  Token::Kind token_kind_;  // Cached token kind for current token.
  TokenPosition prev_token_pos_;
  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_;

  intptr_t recursion_counter_;
  friend class RecursionChecker;

  DISALLOW_COPY_AND_ASSIGN(Parser);
};

}  // namespace dart

#endif  // RUNTIME_VM_PARSER_H_
