#!/usr/bin/python
# Copyright (c) 2011, 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.

import os
import sys

import idl_definitions
from idl_types import IdlType, IdlUnionType, IdlArrayOrSequenceType

from compute_interfaces_info_overall import interfaces_info


new_asts = {}


_operation_suffix_map = {
  '__getter__': "Getter",
  '__setter__': "Setter",
  '__delete__': "Deleter",
}

class IDLNode(object):
  """Base class for all IDL elements.
  IDLNode may contain various child nodes, and have properties. Examples
  of IDLNode are interfaces, interface members, function arguments,
  etc.
  """

  def __init__(self, ast):
    """Initializes an IDLNode from a PegParser AST output."""
    self.id = self._find_first(ast, 'Id') if ast is not None else None


  def __repr__(self):
    """Generates string of the form <class id extra extra ... 0x12345678>."""
    extras = self._extra_repr()
    if isinstance(extras, list):
      extras = ' '.join([str(e) for e in extras])
    try:
      if self.id:
        return '<%s %s 0x%x>' % (
            type(self).__name__,
            ('%s %s' % (self.id, extras)).strip(),
            hash(self))
      return '<%s %s 0x%x>' % (
          type(self).__name__,
          extras,
          hash(self))
    except Exception, e:
      return "can't convert to string: %s" % e

  def _extra_repr(self):
    """Returns string of extra info for __repr__()."""
    return ''

  def __cmp__(self, other):
    """Override default compare operation.
    IDLNodes are equal if all their properties are equal."""
    if other is None or not isinstance(other, IDLNode):
      return 1
    return self.__dict__.__cmp__(other.__dict__)

  def reset_id(self, newId):
    """Reset the id of the Node.  This is typically done during a normalization
    phase (e.g., "DOMWindow" -> "Window")."""
    self.id = newId

  def all(self, type_filter=None):
    """Returns a list containing this node and all it child nodes
    (recursive).

    Args:
      type_filter -- can be used to limit the results to a specific
        node type (e.g. IDLOperation).
    """
    res = []
    if type_filter is None or isinstance(self, type_filter):
      res.append(self)
    for v in self._all_subnodes():
      if isinstance(v, IDLNode):
        res.extend(v.all(type_filter))
      elif isinstance(v, list):
        for item in v:
          if isinstance(item, IDLNode):
            res.extend(item.all(type_filter))
    return res

  def _all_subnodes(self):
    """Accessor used by all() to find subnodes."""
    return self.__dict__.values()

  def to_dict(self):
    """Converts the IDLNode and its children into a dictionary.
    This method is useful mostly for debugging and pretty printing.
    """
    res = {}
    for (k, v) in self.__dict__.items():
      if v == None or v == False or v == [] or v == {}:
        # Skip empty/false members.
        continue
      elif isinstance(v, IDLDictNode) and not len(v):
        # Skip empty dict sub-nodes.
        continue
      elif isinstance(v, list):
        # Convert lists:
        new_v = []
        for sub_node in v:
          if isinstance(sub_node, IDLNode):
            # Convert sub-node:
            new_v.append(sub_node.to_dict())
          else:
            new_v.append(sub_node)
        v = new_v
      elif isinstance(v, IDLNode):
        # Convert sub-node:
        v = v.to_dict()
      res[k] = v
    return res

  def _find_all(self, ast, label, max_results=sys.maxint):
    """Searches the AST for tuples with a given label. The PegParser
    output is composed of lists and tuples, where the tuple 1st argument
    is a label. If ast root is a list, will search recursively inside each
    member in the list.

    Args:
      ast -- the AST to search.
      label -- the label to look for.
      res -- results are put into this list.
      max_results -- maximum number of results.
    """
    res = []
    if max_results <= 0:
      return res

    if isinstance(ast, list):
      for childAst in ast:
        if childAst and \
           not(isinstance(childAst, dict)) and \
           not(isinstance(childAst, str)) and \
           not(isinstance(childAst, tuple)) and \
           childAst.__module__ == "idl_definitions":
          field_name = self._convert_label_to_field(label)
          if hasattr(childAst, field_name):
            field_value = getattr(childAst, field_name)
            # It's an IdlType we need the string name of the type.
            if field_name == 'idl_type':
              field_value =  getattr(field_value, 'base_type')
            res.append(field_value)
        else:
          sub_res = self._find_all(childAst, label,
                       max_results - len(res))
          res.extend(sub_res)
    elif isinstance(ast, tuple):
      (nodeLabel, value) = ast
      if nodeLabel == label:
        res.append(value)
    # TODO(terry): Seems bogus to check for so many things probably better to just
    #              pass in blink_compile and drive it off from that...
    elif (ast and not(isinstance(ast, dict)) and
          not(isinstance(ast, str)) and
          (ast.__module__ == "idl_definitions" or ast.__module__ == "idl_types")):
      field_name = self._convert_label_to_field(label)
      if hasattr(ast, field_name):
        field_value = getattr(ast, field_name)
        if field_value:
          if label == 'Interface' or label == 'Enum':
            for key in field_value:
              value = field_value[key]
              res.append(value)
          elif isinstance(field_value, list):
            for item in field_value:
              res.append(item)
          elif label == 'ParentInterface' or label == 'InterfaceType':
            # Fetch the AST for the parent interface.
            parent_idlnode = new_asts[field_value]
            res.append(parent_idlnode.interfaces[field_value])
          else:
            res.append(field_value)

    return res

  def _find_first(self, ast, label):
    """Convenience method for _find_all(..., max_results=1).
    Returns a single element instead of a list, or None if nothing
    is found."""
    res = self._find_all(ast, label, max_results=1)
    if len(res):
      return res[0]
    return None

  def _has(self, ast, label):
    """Returns true if an element with the given label is
    in the AST by searching for it."""
    return len(self._find_all(ast, label, max_results=1)) == 1

  # Mapping from original AST tuple names to new AST field names idl_definitions.Idl*.
  def _convert_label_to_field(self, label):
    label_field = {
      # Keys old AST names, Values Blink IdlInterface names.
      'ParentInterface': 'parent',
      'Id': 'name',
      'Interface': 'interfaces',
      'Callback': 'is_callback',
      'Partial': 'is_partial',
      'Operation': 'operations',
      'Attribute': 'attributes',
      'Const': 'constants',
      'Type': 'idl_type',
      'ExtAttrs':  'extended_attributes',
      'Special': 'specials',
      'ReturnType': 'idl_type',
      'Argument': 'arguments',
      'InterfaceType': 'name',
      'ConstExpr': 'value',
      'Static': 'is_static',
      'ReadOnly': 'is_read_only',
      'Optional': 'is_optional',
      'Nullable': 'is_nullable',
      'Enum': 'enumerations',
      'Annotation': '',         # TODO(terry): Ignore annotation used for database cache.
      'TypeDef': '',            # typedef in an IDL are already resolved.
    }
    result = label_field.get(label)
    if result != '' and not(result):
      print 'FATAL ERROR: AST mapping name not found %s.' % label
    return result if result else ''

  def _convert_all(self, ast, label, idlnode_ctor):
    """Converts AST elements into IDLNode elements.
    Uses _find_all to find elements with a given label and converts
    them into IDLNodes with a given constructor.
    Returns:
      A list of the converted nodes.
    Args:
      ast -- the ast element to start a search at.
      label -- the element label to look for.
      idlnode_ctor -- a constructor function of one of the IDLNode
        sub-classes.
    """
    res = []
    found = self._find_all(ast, label)
    if not found:
      return res
    if not isinstance(found, list):
      raise RuntimeError("Expected list but %s found" % type(found))
    for childAst in found:
      converted = idlnode_ctor(childAst)
      res.append(converted)
    return res

  def _convert_first(self, ast, label, idlnode_ctor):
    """Like _convert_all, but only converts the first found results."""
    childAst = self._find_first(ast, label)
    if not childAst:
      return None
    return idlnode_ctor(childAst)

  def _convert_ext_attrs(self, ast):
    """Helper method for uniform conversion of extended attributes."""
    self.ext_attrs = IDLExtAttrs(ast)

  def _convert_annotations(self, ast):
    """Helper method for uniform conversion of annotations."""
    self.annotations = IDLAnnotations(ast)


class IDLDictNode(IDLNode):
  """Base class for dictionary-like IDL nodes such as extended attributes
  and annotations. The base class implements various dict interfaces."""

  def __init__(self, ast):
    IDLNode.__init__(self, None)
    if ast is not None and isinstance(ast, dict):
      self.__map = ast
    else:
      self.__map = {}

  def __len__(self):
    return len(self.__map)

  def __getitem__(self, key):
    return self.__map[key]

  def __setitem__(self, key, value):
    self.__map[key] = value

  def __delitem__(self, key):
    del self.__map[key]

  def __contains__(self, key):
    return key in self.__map

  def __iter__(self):
    return self.__map.__iter__()

  def get(self, key, default=None):
    return self.__map.get(key, default)

  def setdefault(self, key, value=None):
    return self.__map.setdefault(key, value)

  def items(self):
    return self.__map.items()

  def keys(self):
    return self.__map.keys()

  def values(self):
    return self.__map.values()

  def clear(self):
    self.__map = {}

  def to_dict(self):
    """Overrides the default IDLNode.to_dict behavior.
    The IDLDictNode members are copied into a new dictionary, and
    IDLNode members are recursively converted into dicts as well.
    """
    res = {}
    for (k, v) in self.__map.items():
      if isinstance(v, IDLNode):
        v = v.to_dict()
      res[k] = v
    return res

  def _all_subnodes(self):
    # Usually an IDLDictNode does not contain further IDLNodes.
    return []


class IDLFile(IDLNode):
  """IDLFile is the top-level node in each IDL file. It may contain interfaces."""

  DART_IDL = 'dart.idl'

  def __init__(self, ast, filename=None):
    IDLNode.__init__(self, ast)
    self.filename = filename

    filename_basename = os.path.basename(filename)

    self.interfaces = self._convert_all(ast, 'Interface', IDLInterface)

    is_blink = not(isinstance(ast, list)) and ast.__module__ == 'idl_definitions'

    if is_blink:
      # implements is handled by the interface merging step (see the function
      # merge_interface_dependencies).
      for interface in self.interfaces:
        blink_interface = ast.interfaces.get(interface.id)
        if filename_basename == self.DART_IDL:
          # Special handling for dart.idl we need to remember the interface,
          # since we could have many (not one interface / file). Then build up
          # the IDLImplementsStatement for any implements in dart.idl.
          interface_info = interfaces_info['__dart_idl___'];

          self.implementsStatements = []

          implement_pairs = interface_info['implement_pairs']
          for implement_pair in implement_pairs:
            interface_name = implement_pair[0]
            implemented_name = implement_pair[1]

            implementor = new_asts[interface_name].interfaces.get(interface_name)
            implement_statement = self._createImplementsStatement(implementor,
                                                                  implemented_name)

            self.implementsStatements.append(implement_statement)
        else:
          interface_info = interfaces_info[interface.id]

          implements = interface_info['implements_interfaces']
          if not(blink_interface.is_partial) and len(implements) > 0:
            implementor = new_asts[interface.id].interfaces.get(interface.id)

            self.implementsStatements = []

            # TODO(terry): Need to handle more than one implements.
            for implemented_name in implements:
              implement_statement = self._createImplementsStatement(implementor,
                                                                    implemented_name)
              self.implementsStatements.append(implement_statement)
          else:
            self.implementsStatements = []
    else:
      self.implementsStatements = self._convert_all(ast, 'ImplStmt',
        IDLImplementsStatement)

    # No reason to handle typedef they're already aliased in Blink's AST.
    self.typeDefs = [] if is_blink else self._convert_all(ast, 'TypeDef', IDLTypeDef)

    self.enums = self._convert_all(ast, 'Enum', IDLEnum)

  def _createImplementsStatement(self, implementor, implemented_name):
    implemented = new_asts[implemented_name].interfaces.get(implemented_name)

    implement_statement = IDLImplementsStatement(implemented)

    implement_statement.implementor = IDLType(implementor)
    implement_statement.implemented = IDLType(implemented)

    return implement_statement


class IDLModule(IDLNode):
  """IDLModule has an id, and may contain interfaces, type defs and
  implements statements."""
  def __init__(self, ast):
    IDLNode.__init__(self, ast)
    self._convert_ext_attrs(ast)
    self._convert_annotations(ast)
    self.interfaces = self._convert_all(ast, 'Interface', IDLInterface)

    is_blink = ast.__module__ == 'idl_definitions'

    # No reason to handle typedef they're already aliased in Blink's AST.
    self.typeDefs = [] if is_blink else self._convert_all(ast, 'TypeDef', IDLTypeDef)

    self.enums = self._convert_all(ast, 'Enum', IDLNode)

    if is_blink:
      # implements is handled by the interface merging step (see the function
      # merge_interface_dependencies).
      for interface in self.interfaces:
        interface_info = interfaces_info[interface.id]
        # TODO(terry): Same handling for implementsStatements as in IDLFile?
        self.implementsStatements = interface_info['implements_interfaces']
    else:
      self.implementsStatements = self._convert_all(ast, 'ImplStmt',
        IDLImplementsStatement)


class IDLExtAttrs(IDLDictNode):
  """IDLExtAttrs is an IDLDictNode that stores IDL Extended Attributes.
  Modules, interfaces, members and arguments can all own IDLExtAttrs."""
  def __init__(self, ast=None):
    IDLDictNode.__init__(self, None)
    if not ast:
      return
    if not(isinstance(ast, list)) and ast.__module__ == "idl_definitions":
      # Pull out extended attributes from Blink AST.
      for name, value in ast.extended_attributes.items():
        # TODO(terry): Handle constructors...
        if name == 'NamedConstructor' or name == 'Constructor':
          for constructor in ast.constructors:
            if constructor.name == 'NamedConstructor':
              constructor_name = ast.extended_attributes['NamedConstructor']
            else:
              constructor_name = None
            func_value = IDLExtAttrFunctionValue(constructor_name, constructor.arguments, True)
            if name == 'Constructor':
              self.setdefault('Constructor', []).append(func_value)
            else:
              self[name] = func_value
        else:
          self[name] = value
    else:
      ext_attrs_ast = self._find_first(ast, 'ExtAttrs')
      if not ext_attrs_ast:
        return
      for ext_attr in self._find_all(ext_attrs_ast, 'ExtAttr'):
        name = self._find_first(ext_attr, 'Id')
        value = self._find_first(ext_attr, 'ExtAttrValue')

        if name == 'Constructor':
          # There might be multiple constructor attributes, collect them
          # as a list.  Represent plain Constructor attribute
          # (without any signature) as None.
          assert value is None
          func_value = None
          ctor_args = self._find_first(ext_attr, 'ExtAttrArgList')
          if ctor_args:
            func_value = IDLExtAttrFunctionValue(None, ctor_args)
          self.setdefault('Constructor', []).append(func_value)
          continue
  
        func_value = self._find_first(value, 'ExtAttrFunctionValue')
        if func_value:
          # E.g. NamedConstructor=Audio(optional DOMString src)
          self[name] = IDLExtAttrFunctionValue(
              func_value,
              self._find_first(func_value, 'ExtAttrArgList'))
          continue

        self[name] = value

  def _all_subnodes(self):
    # Extended attributes may contain IDLNodes, e.g. IDLExtAttrFunctionValue
    return self.values()


class IDLExtAttrFunctionValue(IDLNode):
  """IDLExtAttrFunctionValue."""
  def __init__(self, func_value_ast, arg_list_ast, is_blink=False):
    IDLNode.__init__(self, func_value_ast)
    if is_blink:
      # Blink path
      self.id = func_value_ast   # func_value_ast is the function name for Blink.
      self.arguments = []
      for argument in arg_list_ast:
        self.arguments.append(IDLArgument(argument))
    else:
      self.arguments = self._convert_all(arg_list_ast, 'Argument', IDLArgument)


class IDLType(IDLNode):
  """IDLType is used to describe constants, attributes and operations'
  return and input types. IDLType matches AST labels such as ScopedName,
  StringType, VoidType, IntegerType, etc."""

  def __init__(self, ast):
    IDLNode.__init__(self, ast)

    self.nullable = self._has(ast, 'Nullable')
    # Search for a 'ScopedName' or any label ending with 'Type'.
    if isinstance(ast, list):
      self.id = self._find_first(ast, 'ScopedName')
      if not self.id:
        # FIXME: use regexp search instead
        def findType(ast):
          for label, childAst in ast:
            if label.endswith('Type'):
              type = self._label_to_type(label, ast)
              if type != 'sequence':
                return type
              type_ast = self._find_first(childAst, 'Type')
              if not type_ast:
                return type
              return 'sequence<%s>' % findType(type_ast)
          raise Exception('No type declaration found in %s' % ast)
        self.id = findType(ast)
      # TODO(terry): Remove array_modifiers id has [] appended, keep for old
      #              parsing.
      array_modifiers = self._find_first(ast, 'ArrayModifiers')
      if array_modifiers:
        self.id += array_modifiers
    elif isinstance(ast, tuple):
      (label, value) = ast
      if label == 'ScopedName':
        self.id = value
      else:
        self.id = self._label_to_type(label, ast)
    elif isinstance(ast, str):
      self.id = ast
    # New blink handling.
    elif ast.__module__ == "idl_types":
      if isinstance(ast, IdlType) or isinstance(ast, IdlArrayOrSequenceType):
        type_name = str(ast)

        # TODO(terry): For now don't handle unrestricted types see
        #              https://code.google.com/p/chromium/issues/detail?id=354298
        type_name = type_name.replace('unrestricted ', '', 1);

        # TODO(terry): Handled ScalarValueString as a DOMString.
        type_name = type_name.replace('ScalarValueString', 'DOMString', 1)

        self.id = type_name
      else:
        # IdlUnionType
        if ast.is_union_type:
          print 'WARNING type %s is union mapped to \'any\'' % self.id
        # TODO(terry): For union types use any otherwise type is unionType is
        #              not found and is removed during merging.
        self.id = 'any'
        # TODO(terry): Any union type e.g. 'type1 or type2 or type2',
        #                            'typedef (Type1 or Type2) UnionType'
        # Is a problem we need to extend IDLType and IDLTypeDef to handle more
        # than one type.
        #
        # Also for typedef's e.g.,
        #                 typedef (Type1 or Type2) UnionType
        # should consider synthesizing a new interface (e.g., UnionType) that's
        # both Type1 and Type2.
    if not self.id:
      print '>>>> __module__ %s' % ast.__module__
      raise SyntaxError('Could not parse type %s' % (ast))

  def _label_to_type(self, label, ast):
    if label == 'LongLongType':
      label = 'long long'
    elif label.endswith('Type'):
      # Omit 'Type' suffix and lowercase the rest.
      label = '%s%s' % (label[0].lower(), label[1:-4])

    # Add unsigned qualifier.
    if self._has(ast, 'Unsigned'):
      label = 'unsigned %s' % label
    return label


class IDLEnum(IDLNode):
  """IDLNode for 'enum [id] { [string]+ }'"""
  def __init__(self, ast):
    IDLNode.__init__(self, ast)
    self._convert_annotations(ast)
    if not(isinstance(ast, list)) and ast.__module__ == "idl_definitions":
      # Blink AST
      self.values = ast.values
    else:
      self.values = self._find_all(ast, 'StringLiteral')

    # TODO(terry): Need to handle emitting of enums for dart:html


class IDLTypeDef(IDLNode):
  """IDLNode for 'typedef [type] [id]' declarations."""
  def __init__(self, ast):
    IDLNode.__init__(self, ast)
    self._convert_annotations(ast)
    self.type = self._convert_first(ast, 'Type', IDLType)


class IDLInterface(IDLNode):
  """IDLInterface node contains operations, attributes, constants,
  as well as parent references."""

  def __init__(self, ast):
    IDLNode.__init__(self, ast)
    self._convert_ext_attrs(ast)
    self._convert_annotations(ast)

    self.parents = self._convert_all(ast, 'ParentInterface',
      IDLParentInterface)

    javascript_interface_name = self.ext_attrs.get('InterfaceName', self.id)
    self.javascript_binding_name = javascript_interface_name
    self.doc_js_name = javascript_interface_name

    if not (self._find_first(ast, 'Callback') is None):
      self.ext_attrs['Callback'] = None
    if not (self._find_first(ast, 'Partial') is None):
      self.is_supplemental = True
      self.ext_attrs['DartSupplemental'] = None

    self.operations = self._convert_all(ast, 'Operation',
      lambda ast: IDLOperation(ast, self.doc_js_name))
    self.attributes = self._convert_all(ast, 'Attribute',
      lambda ast: IDLAttribute(ast, self.doc_js_name))
    self.constants = self._convert_all(ast, 'Const',
      lambda ast: IDLConstant(ast, self.doc_js_name))
    self.is_supplemental = 'DartSupplemental' in self.ext_attrs
    self.is_no_interface_object = 'NoInterfaceObject' in self.ext_attrs
    # TODO(terry): Can eliminate Suppressed when we're only using blink parser.
    self.is_fc_suppressed = 'Suppressed' in self.ext_attrs or \
                            'DartSuppress' in self.ext_attrs


  def reset_id(self, new_id):
    """Reset the id of the Interface and corresponding the JS names."""
    if self.id != new_id:
      self.id = new_id
      self.doc_js_name = new_id
      self.javascript_binding_name = new_id
      for member in self.operations:
        member.doc_js_interface_name = new_id
      for member in self.attributes:
        member.doc_js_interface_name = new_id
      for member in self.constants:
        member.doc_js_interface_name = new_id

  def has_attribute(self, candidate):
    for attribute in self.attributes:
      if (attribute.id == candidate.id and
          attribute.is_read_only == candidate.is_read_only):
        return True
    return False


class IDLParentInterface(IDLNode):
  """This IDLNode specialization is for 'Interface Child : Parent {}'
  declarations."""
  def __init__(self, ast):
    IDLNode.__init__(self, ast)
    self._convert_annotations(ast)
    self.type = self._convert_first(ast, 'InterfaceType', IDLType)


class IDLMember(IDLNode):
  """A base class for constants, attributes and operations."""

  def __init__(self, ast, doc_js_interface_name):
    IDLNode.__init__(self, ast)

    self.type = self._convert_first(ast, 'Type', IDLType)
    self._convert_ext_attrs(ast)
    self._convert_annotations(ast)
    self.doc_js_interface_name = doc_js_interface_name
    # TODO(terry): Can eliminate Suppressed when we're only using blink parser.
    self.is_fc_suppressed = 'Suppressed' in self.ext_attrs or \
                            'DartSuppress' in self.ext_attrs
    self.is_static = self._has(ast, 'Static')


class IDLOperation(IDLMember):
  """IDLNode specialization for 'type name(args)' declarations."""
  def __init__(self, ast, doc_js_interface_name):
    IDLMember.__init__(self, ast, doc_js_interface_name)

    self.type = self._convert_first(ast, 'ReturnType', IDLType)
    self.arguments = self._convert_all(ast, 'Argument', IDLArgument)
    self.specials = self._find_all(ast, 'Special')
    # Special case: there are getters of the form
    # getter <ReturnType>(args).  For now force the name to be __getter__,
    # but it should be operator[] later.
    if self.id is None:
      if self.specials == ['getter']:
        if self.ext_attrs.get('Custom') == 'PropertyQuery':
          # Handling __propertyQuery__ the extended attribute is:
          # [Custom=PropertyQuery] getter boolean (DOMString name);
          self.id = '__propertyQuery__'
        else:
          self.id = '__getter__'
      elif self.specials == ['setter']:
        self.id = '__setter__'
        # Special case: if it's a setter, ignore 'declared' return type
        self.type = IDLType([('VoidType', None)])
      elif self.specials == ['deleter']:
        self.id = '__delete__'
      else:
        raise Exception('Cannot handle %s: operation has no id' % ast)

      if len(self.arguments) >= 1 and (self.id in _operation_suffix_map) and not self.ext_attrs.get('ImplementedAs'):
        arg = self.arguments[0]
        operation_category = 'Named' if arg.type.id == 'DOMString' else 'Indexed'
        self.ext_attrs.setdefault('ImplementedAs', 'anonymous%s%s' % (operation_category, _operation_suffix_map[self.id]))

  def _extra_repr(self):
    return [self.arguments]

  def SameSignatureAs(self, operation):
    if self.type != operation.type:
      return False
    return [a.type for a in self.arguments] == [a.type for a in operation.arguments]

class IDLAttribute(IDLMember):
  """IDLNode specialization for 'attribute type name' declarations."""
  def __init__(self, ast, doc_js_interface_name):
    IDLMember.__init__(self, ast, doc_js_interface_name)
    self.is_read_only = self._has(ast, 'ReadOnly')
    # There are various ways to define exceptions for attributes:

  def _extra_repr(self):
    extra = []
    if self.is_read_only: extra.append('readonly')
    return extra


class IDLConstant(IDLMember):
  """IDLNode specialization for 'const type name = value' declarations."""
  def __init__(self, ast, doc_js_interface_name):
    IDLMember.__init__(self, ast, doc_js_interface_name)
    self.value = self._find_first(ast, 'ConstExpr')


class IDLArgument(IDLNode):
  """IDLNode specialization for operation arguments."""
  def __init__(self, ast):
    IDLNode.__init__(self, ast)

    self.default_value = None
    self.default_value_is_null = False
    # Handle the 'argType arg = default'. IDL syntax changed from
    # [default=NullString].
    if not isinstance(ast, list):
      if isinstance(ast.default_value, idl_definitions.IdlLiteral) and ast.default_value:
        self.default_value = ast.default_value.value
        self.default_value_is_null = ast.default_value.is_null
      elif 'Default' in ast.extended_attributes:
        # Work around [Default=Undefined] for arguments - only look in the model's
        # default_value
        self.default_value = ast.extended_attributes.get('Default')
        self.default_value_is_null = False

    self.type = self._convert_first(ast, 'Type', IDLType)
    self.optional = self._has(ast, 'Optional')
    self._convert_ext_attrs(ast)
    # TODO(vsm): Recover this from the type instead.
    if 'Callback' in self.type.id:
      self.ext_attrs['Callback'] = None

  def __repr__(self):
    return '<IDLArgument(type = %s, id = %s)>' % (self.type, self.id)


class IDLImplementsStatement(IDLNode):
  """IDLNode specialization for 'IMPLEMENTOR implements IMPLEMENTED' declarations."""
  def __init__(self, ast):
    IDLNode.__init__(self, ast)
    if isinstance(ast, list) or ast.__module__ != 'idl_definitions':
      self.implementor = self._convert_first(ast, 'ImplStmtImplementor', IDLType)
      self.implemented = self._convert_first(ast, 'ImplStmtImplemented', IDLType)


class IDLAnnotations(IDLDictNode):
  """IDLDictNode specialization for a list of FremontCut annotations."""
  def __init__(self, ast=None):
    IDLDictNode.__init__(self, ast)
    self.id = None
    if not ast:
      return
    for annotation in self._find_all(ast, 'Annotation'):
      name = self._find_first(annotation, 'Id')
      value = IDLAnnotation(annotation)
      self[name] = value


class IDLAnnotation(IDLDictNode):
  """IDLDictNode specialization for one annotation."""
  def __init__(self, ast=None):
    IDLDictNode.__init__(self, ast)
    self.id = None
    if not ast:
      return
    for arg in self._find_all(ast, 'AnnotationArg'):
      name = self._find_first(arg, 'Id')
      value = self._find_first(arg, 'AnnotationArgValue')
      self[name] = value
