#!/usr/bin/env python
#
# Copyright 2008 The Closure Linter Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS-IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Core methods for checking EcmaScript files for common style guide violations.
"""

__author__ = ('robbyw@google.com (Robert Walker)',
              'ajp@google.com (Andy Perelson)',
              'jacobr@google.com (Jacob Richman)')

import re

import gflags as flags

from closure_linter import checkerbase
from closure_linter import ecmametadatapass
from closure_linter import error_check
from closure_linter import errorrules
from closure_linter import errors
from closure_linter import indentation
from closure_linter import javascripttokenizer
from closure_linter import javascripttokens
from closure_linter import statetracker
from closure_linter import tokenutil
from closure_linter.common import error
from closure_linter.common import position


FLAGS = flags.FLAGS
flags.DEFINE_list('custom_jsdoc_tags', '', 'Extra jsdoc tags to allow')
# TODO(user): When flipping this to True, remove logic from unit tests
# that overrides this flag.
flags.DEFINE_boolean('dot_on_next_line', False, 'Require dots to be'
                     'placed on the next line for wrapped expressions')

# TODO(robbyw): Check for extra parens on return statements
# TODO(robbyw): Check for 0px in strings
# TODO(robbyw): Ensure inline jsDoc is in {}
# TODO(robbyw): Check for valid JS types in parameter docs

# Shorthand
Context = ecmametadatapass.EcmaContext
Error = error.Error
Modes = javascripttokenizer.JavaScriptModes
Position = position.Position
Rule = error_check.Rule
Type = javascripttokens.JavaScriptTokenType


class EcmaScriptLintRules(checkerbase.LintRulesBase):
  """EmcaScript lint style checking rules.

  Can be used to find common style errors in JavaScript, ActionScript and other
  Ecma like scripting languages.  Style checkers for Ecma scripting languages
  should inherit from this style checker.
  Please do not add any state to EcmaScriptLintRules or to any subclasses.

  All state should be added to the StateTracker subclass used for a particular
  language.
  """

  # It will be initialized in constructor so the flags are initialized.
  max_line_length = -1

  # Static constants.
  MISSING_PARAMETER_SPACE = re.compile(r',\S')

  EXTRA_SPACE = re.compile(r'(\(\s|\s\))')

  ENDS_WITH_SPACE = re.compile(r'\s$')

  ILLEGAL_TAB = re.compile(r'\t')

  # Regex used to split up complex types to check for invalid use of ? and |.
  TYPE_SPLIT = re.compile(r'[,<>()]')

  # Regex for form of author lines after the @author tag.
  AUTHOR_SPEC = re.compile(r'(\s*)[^\s]+@[^(\s]+(\s*)\(.+\)')

  # Acceptable tokens to remove for line too long testing.
  LONG_LINE_IGNORE = frozenset(
      ['*', '//', '@see'] +
      ['@%s' % tag for tag in statetracker.DocFlag.HAS_TYPE])

  JSDOC_FLAGS_DESCRIPTION_NOT_REQUIRED = frozenset([
      '@fileoverview', '@param', '@return', '@returns'])

  def __init__(self):
    """Initialize this lint rule object."""
    checkerbase.LintRulesBase.__init__(self)
    if EcmaScriptLintRules.max_line_length == -1:
      EcmaScriptLintRules.max_line_length = errorrules.GetMaxLineLength()

  def Initialize(self, checker, limited_doc_checks, is_html):
    """Initialize this lint rule object before parsing a new file."""
    checkerbase.LintRulesBase.Initialize(self, checker, limited_doc_checks,
                                         is_html)
    self._indentation = indentation.IndentationRules()

  def HandleMissingParameterDoc(self, token, param_name):
    """Handle errors associated with a parameter missing a @param tag."""
    raise TypeError('Abstract method HandleMissingParameterDoc not implemented')

  def _CheckLineLength(self, last_token, state):
    """Checks whether the line is too long.

    Args:
      last_token: The last token in the line.
      state: parser_state object that indicates the current state in the page
    """
    # Start from the last token so that we have the flag object attached to
    # and DOC_FLAG tokens.
    line_number = last_token.line_number
    token = last_token

    # Build a representation of the string where spaces indicate potential
    # line-break locations.
    line = []
    while token and token.line_number == line_number:
      if state.IsTypeToken(token):
        line.insert(0, 'x' * len(token.string))
      elif token.type in (Type.IDENTIFIER, Type.OPERATOR):
        # Dots are acceptable places to wrap (may be tokenized as identifiers).
        line.insert(0, token.string.replace('.', ' '))
      else:
        line.insert(0, token.string)
      token = token.previous

    line = ''.join(line)
    line = line.rstrip('\n\r\f')
    try:
      length = len(unicode(line, 'utf-8'))
    except (LookupError, UnicodeDecodeError):
      # Unknown encoding. The line length may be wrong, as was originally the
      # case for utf-8 (see bug 1735846). For now just accept the default
      # length, but as we find problems we can either add test for other
      # possible encodings or return without an error to protect against
      # false positives at the cost of more false negatives.
      length = len(line)

    if length > EcmaScriptLintRules.max_line_length:

      # If the line matches one of the exceptions, then it's ok.
      for long_line_regexp in self.GetLongLineExceptions():
        if long_line_regexp.match(last_token.line):
          return

      # If the line consists of only one "word", or multiple words but all
      # except one are ignoreable, then it's ok.
      parts = set(line.split())

      # We allow two "words" (type and name) when the line contains @param
      max_parts = 1
      if '@param' in parts:
        max_parts = 2

      # Custom tags like @requires may have url like descriptions, so ignore
      # the tag, similar to how we handle @see.
      custom_tags = set(['@%s' % f for f in FLAGS.custom_jsdoc_tags])
      if (len(parts.difference(self.LONG_LINE_IGNORE | custom_tags))
          > max_parts):
        self._HandleError(
            errors.LINE_TOO_LONG,
            'Line too long (%d characters).' % len(line), last_token)

  def _CheckJsDocType(self, token, js_type):
    """Checks the given type for style errors.

    Args:
      token: The DOC_FLAG token for the flag whose type to check.
      js_type: The flag's typeannotation.TypeAnnotation instance.
    """
    if not js_type: return

    if js_type.type_group and len(js_type.sub_types) == 2:
      identifiers = [t.identifier for t in js_type.sub_types]
      if 'null' in identifiers:
        # Don't warn if the identifier is a template type (e.g. {TYPE|null}.
        if not identifiers[0].isupper() and not identifiers[1].isupper():
          self._HandleError(
              errors.JSDOC_PREFER_QUESTION_TO_PIPE_NULL,
              'Prefer "?Type" to "Type|null": "%s"' % js_type, token)

    # TODO(user): We should report an error for wrong usage of '?' and '|'
    # e.g. {?number|string|null} etc.

    for sub_type in js_type.IterTypes():
      self._CheckJsDocType(token, sub_type)

  def _CheckForMissingSpaceBeforeToken(self, token):
    """Checks for a missing space at the beginning of a token.

    Reports a MISSING_SPACE error if the token does not begin with a space or
    the previous token doesn't end with a space and the previous token is on the
    same line as the token.

    Args:
      token: The token being checked
    """
    # TODO(user): Check if too many spaces?
    if (len(token.string) == len(token.string.lstrip()) and
        token.previous and token.line_number == token.previous.line_number and
        len(token.previous.string) - len(token.previous.string.rstrip()) == 0):
      self._HandleError(
          errors.MISSING_SPACE,
          'Missing space before "%s"' % token.string,
          token,
          position=Position.AtBeginning())

  def _CheckOperator(self, token):
    """Checks an operator for spacing and line style.

    Args:
      token: The operator token.
    """
    last_code = token.metadata.last_code

    if not self._ExpectSpaceBeforeOperator(token):
      if (token.previous and token.previous.type == Type.WHITESPACE and
          last_code and last_code.type in (Type.NORMAL, Type.IDENTIFIER) and
          last_code.line_number == token.line_number):
        self._HandleError(
            errors.EXTRA_SPACE, 'Extra space before "%s"' % token.string,
            token.previous, position=Position.All(token.previous.string))

    elif (token.previous and
          not token.previous.IsComment() and
          not tokenutil.IsDot(token) and
          token.previous.type in Type.EXPRESSION_ENDER_TYPES):
      self._HandleError(errors.MISSING_SPACE,
                        'Missing space before "%s"' % token.string, token,
                        position=Position.AtBeginning())

    # Check wrapping of operators.
    next_code = tokenutil.GetNextCodeToken(token)

    is_dot = tokenutil.IsDot(token)
    wrapped_before = last_code and last_code.line_number != token.line_number
    wrapped_after = next_code and next_code.line_number != token.line_number

    if FLAGS.dot_on_next_line and is_dot and wrapped_after:
      self._HandleError(
          errors.LINE_ENDS_WITH_DOT,
          '"." must go on the following line',
          token)
    if (not is_dot and wrapped_before and
        not token.metadata.IsUnaryOperator()):
      self._HandleError(
          errors.LINE_STARTS_WITH_OPERATOR,
          'Binary operator must go on previous line "%s"' % token.string,
          token)

  def _IsLabel(self, token):
    # A ':' token is considered part of a label if it occurs in a case
    # statement, a plain label, or an object literal, i.e. is not part of a
    # ternary.

    return (token.string == ':' and
            token.metadata.context.type in (Context.LITERAL_ELEMENT,
                                            Context.CASE_BLOCK,
                                            Context.STATEMENT))

  def _ExpectSpaceBeforeOperator(self, token):
    """Returns whether a space should appear before the given operator token.

    Args:
      token: The operator token.

    Returns:
      Whether there should be a space before the token.
    """
    if token.string == ',' or token.metadata.IsUnaryPostOperator():
      return False

    if tokenutil.IsDot(token):
      return False

    # Colons should appear in labels, object literals, the case of a switch
    # statement, and ternary operator. Only want a space in the case of the
    # ternary operator.
    if self._IsLabel(token):
      return False

    if token.metadata.IsUnaryOperator() and token.IsFirstInLine():
      return False

    return True

  def CheckToken(self, token, state):
    """Checks a token, given the current parser_state, for warnings and errors.

    Args:
      token: The current token under consideration
      state: parser_state object that indicates the current state in the page
    """
    # Store some convenience variables
    first_in_line = token.IsFirstInLine()
    last_in_line = token.IsLastInLine()
    last_non_space_token = state.GetLastNonSpaceToken()

    token_type = token.type

    # Process the line change.
    if not self._is_html and error_check.ShouldCheck(Rule.INDENTATION):
      # TODO(robbyw): Support checking indentation in HTML files.
      indentation_errors = self._indentation.CheckToken(token, state)
      for indentation_error in indentation_errors:
        self._HandleError(*indentation_error)

    if last_in_line:
      self._CheckLineLength(token, state)

    if token_type == Type.PARAMETERS:
      # Find missing spaces in parameter lists.
      if self.MISSING_PARAMETER_SPACE.search(token.string):
        fix_data = ', '.join([s.strip() for s in token.string.split(',')])
        self._HandleError(errors.MISSING_SPACE, 'Missing space after ","',
                          token, position=None, fix_data=fix_data.strip())

      # Find extra spaces at the beginning of parameter lists.  Make sure
      # we aren't at the beginning of a continuing multi-line list.
      if not first_in_line:
        space_count = len(token.string) - len(token.string.lstrip())
        if space_count:
          self._HandleError(errors.EXTRA_SPACE, 'Extra space after "("',
                            token, position=Position(0, space_count))

    elif (token_type == Type.START_BLOCK and
          token.metadata.context.type == Context.BLOCK):
      self._CheckForMissingSpaceBeforeToken(token)

    elif token_type == Type.END_BLOCK:
      last_code = token.metadata.last_code
      if state.InFunction() and state.IsFunctionClose():
        if state.InTopLevelFunction():
          # A semicolons should not be included at the end of a function
          # declaration.
          if not state.InAssignedFunction():
            if not last_in_line and token.next.type == Type.SEMICOLON:
              self._HandleError(
                  errors.ILLEGAL_SEMICOLON_AFTER_FUNCTION,
                  'Illegal semicolon after function declaration',
                  token.next, position=Position.All(token.next.string))

        # A semicolon should be included at the end of a function expression
        # that is not immediately called or used by a dot operator.
        if (state.InAssignedFunction() and token.next
            and token.next.type != Type.SEMICOLON):
          next_token = tokenutil.GetNextCodeToken(token)
          is_immediately_used = next_token and (
              next_token.type == Type.START_PAREN or
              tokenutil.IsDot(next_token))
          if not is_immediately_used:
            self._HandleError(
                errors.MISSING_SEMICOLON_AFTER_FUNCTION,
                'Missing semicolon after function assigned to a variable',
                token, position=Position.AtEnd(token.string))

        if state.InInterfaceMethod() and last_code.type != Type.START_BLOCK:
          self._HandleError(errors.INTERFACE_METHOD_CANNOT_HAVE_CODE,
                            'Interface methods cannot contain code', last_code)

      elif (state.IsBlockClose() and
            token.next and token.next.type == Type.SEMICOLON):
        if (last_code.metadata.context.parent.type != Context.OBJECT_LITERAL
            and last_code.metadata.context.type != Context.OBJECT_LITERAL):
          self._HandleError(
              errors.REDUNDANT_SEMICOLON,
              'No semicolon is required to end a code block',
              token.next, position=Position.All(token.next.string))

    elif token_type == Type.SEMICOLON:
      if token.previous and token.previous.type == Type.WHITESPACE:
        self._HandleError(
            errors.EXTRA_SPACE, 'Extra space before ";"',
            token.previous, position=Position.All(token.previous.string))

      if token.next and token.next.line_number == token.line_number:
        if token.metadata.context.type != Context.FOR_GROUP_BLOCK:
          # TODO(robbyw): Error about no multi-statement lines.
          pass

        elif token.next.type not in (
            Type.WHITESPACE, Type.SEMICOLON, Type.END_PAREN):
          self._HandleError(
              errors.MISSING_SPACE,
              'Missing space after ";" in for statement',
              token.next,
              position=Position.AtBeginning())

      last_code = token.metadata.last_code
      if last_code and last_code.type == Type.SEMICOLON:
        # Allow a single double semi colon in for loops for cases like:
        # for (;;) { }.
        # NOTE(user): This is not a perfect check, and will not throw an error
        # for cases like: for (var i = 0;; i < n; i++) {}, but then your code
        # probably won't work either.
        for_token = tokenutil.CustomSearch(
            last_code,
            lambda token: token.type == Type.KEYWORD and token.string == 'for',
            end_func=lambda token: token.type == Type.SEMICOLON,
            distance=None,
            reverse=True)

        if not for_token:
          self._HandleError(errors.REDUNDANT_SEMICOLON, 'Redundant semicolon',
                            token, position=Position.All(token.string))

    elif token_type == Type.START_PAREN:
      # Ensure that opening parentheses have a space before any keyword
      # that is not being invoked like a member function.
      if (token.previous and token.previous.type == Type.KEYWORD and
          (not token.previous.metadata or
           not token.previous.metadata.last_code or
           not token.previous.metadata.last_code.string or
           token.previous.metadata.last_code.string[-1:] != '.')):
        self._HandleError(errors.MISSING_SPACE, 'Missing space before "("',
                          token, position=Position.AtBeginning())
      elif token.previous and token.previous.type == Type.WHITESPACE:
        before_space = token.previous.previous
        # Ensure that there is no extra space before a function invocation,
        # even if the function being invoked happens to be a keyword.
        if (before_space and before_space.line_number == token.line_number and
            before_space.type == Type.IDENTIFIER or
            (before_space.type == Type.KEYWORD and before_space.metadata and
             before_space.metadata.last_code and
             before_space.metadata.last_code.string and
             before_space.metadata.last_code.string[-1:] == '.')):
          self._HandleError(
              errors.EXTRA_SPACE, 'Extra space before "("',
              token.previous, position=Position.All(token.previous.string))

    elif token_type == Type.START_BRACKET:
      self._HandleStartBracket(token, last_non_space_token)
    elif token_type in (Type.END_PAREN, Type.END_BRACKET):
      # Ensure there is no space before closing parentheses, except when
      # it's in a for statement with an omitted section, or when it's at the
      # beginning of a line.
      if (token.previous and token.previous.type == Type.WHITESPACE and
          not token.previous.IsFirstInLine() and
          not (last_non_space_token and last_non_space_token.line_number ==
               token.line_number and
               last_non_space_token.type == Type.SEMICOLON)):
        self._HandleError(
            errors.EXTRA_SPACE, 'Extra space before "%s"' %
            token.string, token.previous,
            position=Position.All(token.previous.string))

    elif token_type == Type.WHITESPACE:
      if self.ILLEGAL_TAB.search(token.string):
        if token.IsFirstInLine():
          if token.next:
            self._HandleError(
                errors.ILLEGAL_TAB,
                'Illegal tab in whitespace before "%s"' % token.next.string,
                token, position=Position.All(token.string))
          else:
            self._HandleError(
                errors.ILLEGAL_TAB,
                'Illegal tab in whitespace',
                token, position=Position.All(token.string))
        else:
          self._HandleError(
              errors.ILLEGAL_TAB,
              'Illegal tab in whitespace after "%s"' % token.previous.string,
              token, position=Position.All(token.string))

      # Check whitespace length if it's not the first token of the line and
      # if it's not immediately before a comment.
      if last_in_line:
        # Check for extra whitespace at the end of a line.
        self._HandleError(errors.EXTRA_SPACE, 'Extra space at end of line',
                          token, position=Position.All(token.string))
      elif not first_in_line and not token.next.IsComment():
        if token.length > 1:
          self._HandleError(
              errors.EXTRA_SPACE, 'Extra space after "%s"' %
              token.previous.string, token,
              position=Position(1, len(token.string) - 1))

    elif token_type == Type.OPERATOR:
      self._CheckOperator(token)
    elif token_type == Type.DOC_FLAG:
      flag = token.attached_object

      if flag.flag_type == 'bug':
        # TODO(robbyw): Check for exactly 1 space on the left.
        string = token.next.string.lstrip()
        string = string.split(' ', 1)[0]

        if not string.isdigit():
          self._HandleError(errors.NO_BUG_NUMBER_AFTER_BUG_TAG,
                            '@bug should be followed by a bug number', token)

      elif flag.flag_type == 'suppress':
        if flag.type is None:
          # A syntactically invalid suppress tag will get tokenized as a normal
          # flag, indicating an error.
          self._HandleError(
              errors.INCORRECT_SUPPRESS_SYNTAX,
              'Invalid suppress syntax: should be @suppress {errortype}. '
              'Spaces matter.', token)
        else:
          for suppress_type in flag.jstype.IterIdentifiers():
            if suppress_type not in state.GetDocFlag().SUPPRESS_TYPES:
              self._HandleError(
                  errors.INVALID_SUPPRESS_TYPE,
                  'Invalid suppression type: %s' % suppress_type, token)

      elif (error_check.ShouldCheck(Rule.WELL_FORMED_AUTHOR) and
            flag.flag_type == 'author'):
        # TODO(user): In non strict mode check the author tag for as much as
        # it exists, though the full form checked below isn't required.
        string = token.next.string
        result = self.AUTHOR_SPEC.match(string)
        if not result:
          self._HandleError(errors.INVALID_AUTHOR_TAG_DESCRIPTION,
                            'Author tag line should be of the form: '
                            '@author foo@somewhere.com (Your Name)',
                            token.next)
        else:
          # Check spacing between email address and name. Do this before
          # checking earlier spacing so positions are easier to calculate for
          # autofixing.
          num_spaces = len(result.group(2))
          if num_spaces < 1:
            self._HandleError(errors.MISSING_SPACE,
                              'Missing space after email address',
                              token.next, position=Position(result.start(2), 0))
          elif num_spaces > 1:
            self._HandleError(
                errors.EXTRA_SPACE, 'Extra space after email address',
                token.next,
                position=Position(result.start(2) + 1, num_spaces - 1))

          # Check for extra spaces before email address. Can't be too few, if
          # not at least one we wouldn't match @author tag.
          num_spaces = len(result.group(1))
          if num_spaces > 1:
            self._HandleError(errors.EXTRA_SPACE,
                              'Extra space before email address',
                              token.next, position=Position(1, num_spaces - 1))

      elif (flag.flag_type in state.GetDocFlag().HAS_DESCRIPTION and
            not self._limited_doc_checks):
        if flag.flag_type == 'param':
          if flag.name is None:
            self._HandleError(errors.MISSING_JSDOC_PARAM_NAME,
                              'Missing name in @param tag', token)

        if not flag.description or flag.description is None:
          flag_name = token.type
          if 'name' in token.values:
            flag_name = '@' + token.values['name']

          if flag_name not in self.JSDOC_FLAGS_DESCRIPTION_NOT_REQUIRED:
            self._HandleError(
                errors.MISSING_JSDOC_TAG_DESCRIPTION,
                'Missing description in %s tag' % flag_name, token)
        else:
          self._CheckForMissingSpaceBeforeToken(flag.description_start_token)

      if flag.HasType():
        if flag.type_start_token is not None:
          self._CheckForMissingSpaceBeforeToken(
              token.attached_object.type_start_token)

        if flag.jstype and not flag.jstype.IsEmpty():
          self._CheckJsDocType(token, flag.jstype)

          if error_check.ShouldCheck(Rule.BRACES_AROUND_TYPE) and (
              flag.type_start_token.type != Type.DOC_START_BRACE or
              flag.type_end_token.type != Type.DOC_END_BRACE):
            self._HandleError(
                errors.MISSING_BRACES_AROUND_TYPE,
                'Type must always be surrounded by curly braces.', token)

    if token_type in (Type.DOC_FLAG, Type.DOC_INLINE_FLAG):
      if (token.values['name'] not in state.GetDocFlag().LEGAL_DOC and
          token.values['name'] not in FLAGS.custom_jsdoc_tags):
        self._HandleError(
            errors.INVALID_JSDOC_TAG,
            'Invalid JsDoc tag: %s' % token.values['name'], token)

      if (error_check.ShouldCheck(Rule.NO_BRACES_AROUND_INHERIT_DOC) and
          token.values['name'] == 'inheritDoc' and
          token_type == Type.DOC_INLINE_FLAG):
        self._HandleError(errors.UNNECESSARY_BRACES_AROUND_INHERIT_DOC,
                          'Unnecessary braces around @inheritDoc',
                          token)

    elif token_type == Type.SIMPLE_LVALUE:
      identifier = token.values['identifier']

      if ((not state.InFunction() or state.InConstructor()) and
          state.InTopLevel() and not state.InObjectLiteralDescendant()):
        jsdoc = state.GetDocComment()
        if not state.HasDocComment(identifier):
          # Only test for documentation on identifiers with .s in them to
          # avoid checking things like simple variables. We don't require
          # documenting assignments to .prototype itself (bug 1880803).
          if (not state.InConstructor() and
              identifier.find('.') != -1 and not
              identifier.endswith('.prototype') and not
              self._limited_doc_checks):
            comment = state.GetLastComment()
            if not (comment and comment.lower().count('jsdoc inherited')):
              self._HandleError(
                  errors.MISSING_MEMBER_DOCUMENTATION,
                  "No docs found for member '%s'" % identifier,
                  token)
        elif jsdoc and (not state.InConstructor() or
                        identifier.startswith('this.')):
          # We are at the top level and the function/member is documented.
          if identifier.endswith('_') and not identifier.endswith('__'):
            # Can have a private class which inherits documentation from a
            # public superclass.
            #
            # @inheritDoc is deprecated in favor of using @override, and they
            if (jsdoc.HasFlag('override') and not jsdoc.HasFlag('constructor')
                and ('accessControls' not in jsdoc.suppressions)):
              self._HandleError(
                  errors.INVALID_OVERRIDE_PRIVATE,
                  '%s should not override a private member.' % identifier,
                  jsdoc.GetFlag('override').flag_token)
            if (jsdoc.HasFlag('inheritDoc') and not jsdoc.HasFlag('constructor')
                and ('accessControls' not in jsdoc.suppressions)):
              self._HandleError(
                  errors.INVALID_INHERIT_DOC_PRIVATE,
                  '%s should not inherit from a private member.' % identifier,
                  jsdoc.GetFlag('inheritDoc').flag_token)
            if (not jsdoc.HasFlag('private') and
                ('underscore' not in jsdoc.suppressions) and not
                ((jsdoc.HasFlag('inheritDoc') or jsdoc.HasFlag('override')) and
                 ('accessControls' in jsdoc.suppressions))):
              self._HandleError(
                  errors.MISSING_PRIVATE,
                  'Member "%s" must have @private JsDoc.' %
                  identifier, token)
            if jsdoc.HasFlag('private') and 'underscore' in jsdoc.suppressions:
              self._HandleError(
                  errors.UNNECESSARY_SUPPRESS,
                  '@suppress {underscore} is not necessary with @private',
                  jsdoc.suppressions['underscore'])
          elif (jsdoc.HasFlag('private') and
                not self.InExplicitlyTypedLanguage()):
            # It is convention to hide public fields in some ECMA
            # implementations from documentation using the @private tag.
            self._HandleError(
                errors.EXTRA_PRIVATE,
                'Member "%s" must not have @private JsDoc' %
                identifier, token)

          # These flags are only legal on localizable message definitions;
          # such variables always begin with the prefix MSG_.
          if not identifier.startswith('MSG_') and '.MSG_' not in identifier:
            for f in ('desc', 'hidden', 'meaning'):
              if jsdoc.HasFlag(f):
                self._HandleError(
                    errors.INVALID_USE_OF_DESC_TAG,
                    'Member "%s" does not start with MSG_ and thus '
                    'should not have @%s JsDoc' % (identifier, f),
                    token)

      # Check for illegaly assigning live objects as prototype property values.
      index = identifier.find('.prototype.')
      # Ignore anything with additional .s after the prototype.
      if index != -1 and identifier.find('.', index + 11) == -1:
        equal_operator = tokenutil.SearchExcept(token, Type.NON_CODE_TYPES)
        next_code = tokenutil.SearchExcept(equal_operator, Type.NON_CODE_TYPES)
        if next_code and (
            next_code.type in (Type.START_BRACKET, Type.START_BLOCK) or
            next_code.IsOperator('new')):
          self._HandleError(
              errors.ILLEGAL_PROTOTYPE_MEMBER_VALUE,
              'Member %s cannot have a non-primitive value' % identifier,
              token)

    elif token_type == Type.END_PARAMETERS:
      # Find extra space at the end of parameter lists.  We check the token
      # prior to the current one when it is a closing paren.
      if (token.previous and token.previous.type == Type.PARAMETERS
          and self.ENDS_WITH_SPACE.search(token.previous.string)):
        self._HandleError(errors.EXTRA_SPACE, 'Extra space before ")"',
                          token.previous)

      jsdoc = state.GetDocComment()
      if state.GetFunction().is_interface:
        if token.previous and token.previous.type == Type.PARAMETERS:
          self._HandleError(
              errors.INTERFACE_CONSTRUCTOR_CANNOT_HAVE_PARAMS,
              'Interface constructor cannot have parameters',
              token.previous)
      elif (state.InTopLevel() and jsdoc and not jsdoc.HasFlag('see')
            and not jsdoc.InheritsDocumentation()
            and not state.InObjectLiteralDescendant() and not
            jsdoc.IsInvalidated()):
        distance, edit = jsdoc.CompareParameters(state.GetParams())
        if distance:
          params_iter = iter(state.GetParams())
          docs_iter = iter(jsdoc.ordered_params)

          for op in edit:
            if op == 'I':
              # Insertion.
              # Parsing doc comments is the same for all languages
              # but some languages care about parameters that don't have
              # doc comments and some languages don't care.
              # Languages that don't allow variables to by typed such as
              # JavaScript care but languages such as ActionScript or Java
              # that allow variables to be typed don't care.
              if not self._limited_doc_checks:
                self.HandleMissingParameterDoc(token, params_iter.next())

            elif op == 'D':
              # Deletion
              self._HandleError(errors.EXTRA_PARAMETER_DOCUMENTATION,
                                'Found docs for non-existing parameter: "%s"' %
                                docs_iter.next(), token)
            elif op == 'S':
              # Substitution
              if not self._limited_doc_checks:
                self._HandleError(
                    errors.WRONG_PARAMETER_DOCUMENTATION,
                    'Parameter mismatch: got "%s", expected "%s"' %
                    (params_iter.next(), docs_iter.next()), token)

            else:
              # Equality - just advance the iterators
              params_iter.next()
              docs_iter.next()

    elif token_type == Type.STRING_TEXT:
      # If this is the first token after the start of the string, but it's at
      # the end of a line, we know we have a multi-line string.
      if token.previous.type in (
          Type.SINGLE_QUOTE_STRING_START,
          Type.DOUBLE_QUOTE_STRING_START) and last_in_line:
        self._HandleError(errors.MULTI_LINE_STRING,
                          'Multi-line strings are not allowed', token)

    # This check is orthogonal to the ones above, and repeats some types, so
    # it is a plain if and not an elif.
    if token.type in Type.COMMENT_TYPES:
      if self.ILLEGAL_TAB.search(token.string):
        self._HandleError(errors.ILLEGAL_TAB,
                          'Illegal tab in comment "%s"' % token.string, token)

      trimmed = token.string.rstrip()
      if last_in_line and token.string != trimmed:
        # Check for extra whitespace at the end of a line.
        self._HandleError(
            errors.EXTRA_SPACE, 'Extra space at end of line', token,
            position=Position(len(trimmed), len(token.string) - len(trimmed)))

    # This check is also orthogonal since it is based on metadata.
    if token.metadata.is_implied_semicolon:
      self._HandleError(errors.MISSING_SEMICOLON,
                        'Missing semicolon at end of line', token)

  def _HandleStartBracket(self, token, last_non_space_token):
    """Handles a token that is an open bracket.

    Args:
      token: The token to handle.
      last_non_space_token: The last token that was not a space.
    """
    if (not token.IsFirstInLine() and token.previous.type == Type.WHITESPACE and
        last_non_space_token and
        last_non_space_token.type in Type.EXPRESSION_ENDER_TYPES):
      self._HandleError(
          errors.EXTRA_SPACE, 'Extra space before "["',
          token.previous, position=Position.All(token.previous.string))
    # If the [ token is the first token in a line we shouldn't complain
    # about a missing space before [.  This is because some Ecma script
    # languages allow syntax like:
    # [Annotation]
    # class MyClass {...}
    # So we don't want to blindly warn about missing spaces before [.
    # In the the future, when rules for computing exactly how many spaces
    # lines should be indented are added, then we can return errors for
    # [ tokens that are improperly indented.
    # For example:
    # var someVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongVariableName =
    # [a,b,c];
    # should trigger a proper indentation warning message as [ is not indented
    # by four spaces.
    elif (not token.IsFirstInLine() and token.previous and
          token.previous.type not in (
              [Type.WHITESPACE, Type.START_PAREN, Type.START_BRACKET] +
              Type.EXPRESSION_ENDER_TYPES)):
      self._HandleError(errors.MISSING_SPACE, 'Missing space before "["',
                        token, position=Position.AtBeginning())

  def Finalize(self, state):
    """Perform all checks that need to occur after all lines are processed.

    Args:
      state: State of the parser after parsing all tokens

    Raises:
      TypeError: If not overridden.
    """
    last_non_space_token = state.GetLastNonSpaceToken()
    # Check last line for ending with newline.
    if state.GetLastLine() and not (
        state.GetLastLine().isspace() or
        state.GetLastLine().rstrip('\n\r\f') != state.GetLastLine()):
      self._HandleError(
          errors.FILE_MISSING_NEWLINE,
          'File does not end with new line.  (%s)' % state.GetLastLine(),
          last_non_space_token)

    try:
      self._indentation.Finalize()
    except Exception, e:
      self._HandleError(
          errors.FILE_DOES_NOT_PARSE,
          str(e),
          last_non_space_token)

  def GetLongLineExceptions(self):
    """Gets a list of regexps for lines which can be longer than the limit.

    Returns:
      A list of regexps, used as matches (rather than searches).
    """
    return []

  def InExplicitlyTypedLanguage(self):
    """Returns whether this ecma implementation is explicitly typed."""
    return False
