blob: 2ce5c02c6c4af432b049adf0faaf46893c33e80e [file] [log] [blame]
#!/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.
"""Parser for JavaScript files."""
from closure_linter import javascripttokens
from closure_linter import statetracker
from closure_linter import tokenutil
# Shorthand
Type = javascripttokens.JavaScriptTokenType
class JsDocFlag(statetracker.DocFlag):
"""Javascript doc flag object.
Attribute:
flag_type: param, return, define, type, etc.
flag_token: The flag token.
type_start_token: The first token specifying the flag JS type,
including braces.
type_end_token: The last token specifying the flag JS type,
including braces.
type: The JavaScript type spec.
name_token: The token specifying the flag name.
name: The flag name
description_start_token: The first token in the description.
description_end_token: The end token in the description.
description: The description.
"""
# Please keep these lists alphabetized.
# Some projects use the following extensions to JsDoc.
# TODO(robbyw): determine which of these, if any, should be illegal.
EXTENDED_DOC = frozenset([
'class', 'code', 'desc', 'final', 'hidden', 'inheritDoc', 'link',
'meaning', 'protected', 'notypecheck', 'throws'])
LEGAL_DOC = EXTENDED_DOC | statetracker.DocFlag.LEGAL_DOC
def __init__(self, flag_token):
"""Creates the JsDocFlag object and attaches it to the given start token.
Args:
flag_token: The starting token of the flag.
"""
statetracker.DocFlag.__init__(self, flag_token)
class JavaScriptStateTracker(statetracker.StateTracker):
"""JavaScript state tracker.
Inherits from the core EcmaScript StateTracker adding extra state tracking
functionality needed for JavaScript.
"""
def __init__(self):
"""Initializes a JavaScript token stream state tracker."""
statetracker.StateTracker.__init__(self, JsDocFlag)
def InTopLevel(self):
"""Compute whether we are at the top level in the class.
This function call is language specific. In some languages like
JavaScript, a function is top level if it is not inside any parenthesis.
In languages such as ActionScript, a function is top level if it is directly
within a class.
Returns:
Whether we are at the top level in the class.
"""
return not self.InParentheses()
def GetBlockType(self, token):
"""Determine the block type given a START_BLOCK token.
Code blocks come after parameters, keywords like else, and closing parens.
Args:
token: The current token. Can be assumed to be type START_BLOCK
Returns:
Code block type for current token.
"""
last_code = tokenutil.SearchExcept(token, Type.NON_CODE_TYPES, None,
True)
if last_code.type in (Type.END_PARAMETERS, Type.END_PAREN,
Type.KEYWORD) and not last_code.IsKeyword('return'):
return self.CODE
else:
return self.OBJECT_LITERAL
def HandleToken(self, token, last_non_space_token):
"""Handles the given token and updates state.
Args:
token: The token to handle.
last_non_space_token:
"""
super(JavaScriptStateTracker, self).HandleToken(token,
last_non_space_token)