diff options
Diffstat (limited to 'tools/closure_linter/build/lib/closure_linter/requireprovidesorter.py')
-rw-r--r-- | tools/closure_linter/build/lib/closure_linter/requireprovidesorter.py | 329 |
1 files changed, 0 insertions, 329 deletions
diff --git a/tools/closure_linter/build/lib/closure_linter/requireprovidesorter.py b/tools/closure_linter/build/lib/closure_linter/requireprovidesorter.py deleted file mode 100644 index e7e08a13c2..0000000000 --- a/tools/closure_linter/build/lib/closure_linter/requireprovidesorter.py +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2011 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. - -"""Contains logic for sorting goog.provide and goog.require statements. - -Closurized JavaScript files use goog.provide and goog.require statements at the -top of the file to manage dependencies. These statements should be sorted -alphabetically, however, it is common for them to be accompanied by inline -comments or suppression annotations. In order to sort these statements without -disrupting their comments and annotations, the association between statements -and comments/annotations must be maintained while sorting. - - RequireProvideSorter: Handles checking/fixing of provide/require statements. -""" - - - -from closure_linter import javascripttokens -from closure_linter import tokenutil - -# Shorthand -Type = javascripttokens.JavaScriptTokenType - - -class RequireProvideSorter(object): - """Checks for and fixes alphabetization of provide and require statements. - - When alphabetizing, comments on the same line or comments directly above a - goog.provide or goog.require statement are associated with that statement and - stay with the statement as it gets sorted. - """ - - def CheckProvides(self, token): - """Checks alphabetization of goog.provide statements. - - Iterates over tokens in given token stream, identifies goog.provide tokens, - and checks that they occur in alphabetical order by the object being - provided. - - Args: - token: A token in the token stream before any goog.provide tokens. - - Returns: - The first provide token in the token stream. - - None is returned if all goog.provide statements are already sorted. - """ - provide_tokens = self._GetRequireOrProvideTokens(token, 'goog.provide') - provide_strings = self._GetRequireOrProvideTokenStrings(provide_tokens) - sorted_provide_strings = sorted(provide_strings) - if provide_strings != sorted_provide_strings: - return provide_tokens[0] - return None - - def CheckRequires(self, token): - """Checks alphabetization of goog.require statements. - - Iterates over tokens in given token stream, identifies goog.require tokens, - and checks that they occur in alphabetical order by the dependency being - required. - - Args: - token: A token in the token stream before any goog.require tokens. - - Returns: - The first require token in the token stream. - - None is returned if all goog.require statements are already sorted. - """ - require_tokens = self._GetRequireOrProvideTokens(token, 'goog.require') - require_strings = self._GetRequireOrProvideTokenStrings(require_tokens) - sorted_require_strings = sorted(require_strings) - if require_strings != sorted_require_strings: - return require_tokens[0] - return None - - def FixProvides(self, token): - """Sorts goog.provide statements in the given token stream alphabetically. - - Args: - token: The first token in the token stream. - """ - self._FixProvidesOrRequires( - self._GetRequireOrProvideTokens(token, 'goog.provide')) - - def FixRequires(self, token): - """Sorts goog.require statements in the given token stream alphabetically. - - Args: - token: The first token in the token stream. - """ - self._FixProvidesOrRequires( - self._GetRequireOrProvideTokens(token, 'goog.require')) - - def _FixProvidesOrRequires(self, tokens): - """Sorts goog.provide or goog.require statements. - - Args: - tokens: A list of goog.provide or goog.require tokens in the order they - appear in the token stream. i.e. the first token in this list must - be the first goog.provide or goog.require token. - """ - strings = self._GetRequireOrProvideTokenStrings(tokens) - sorted_strings = sorted(strings) - - # Make a separate pass to remove any blank lines between goog.require/ - # goog.provide tokens. - first_token = tokens[0] - last_token = tokens[-1] - i = last_token - while i != first_token and i is not None: - if i.type is Type.BLANK_LINE: - tokenutil.DeleteToken(i) - i = i.previous - - # A map from required/provided object name to tokens that make up the line - # it was on, including any comments immediately before it or after it on the - # same line. - tokens_map = self._GetTokensMap(tokens) - - # Iterate over the map removing all tokens. - for name in tokens_map: - tokens_to_delete = tokens_map[name] - for i in tokens_to_delete: - tokenutil.DeleteToken(i) - - # Save token to rest of file. Sorted token will be inserted before this. - rest_of_file = tokens_map[strings[-1]][-1].next - - # Re-add all tokens in the map in alphabetical order. - insert_after = tokens[0].previous - for string in sorted_strings: - for i in tokens_map[string]: - if rest_of_file: - tokenutil.InsertTokenBefore(i, rest_of_file) - else: - tokenutil.InsertTokenAfter(i, insert_after) - insert_after = i - - def _GetRequireOrProvideTokens(self, token, token_string): - """Gets all goog.provide or goog.require tokens in the given token stream. - - Args: - token: The first token in the token stream. - token_string: One of 'goog.provide' or 'goog.require' to indicate which - tokens to find. - - Returns: - A list of goog.provide or goog.require tokens in the order they appear in - the token stream. - """ - tokens = [] - while token: - if token.type == Type.IDENTIFIER: - if token.string == token_string: - tokens.append(token) - elif token.string not in [ - 'goog.provide', 'goog.require', 'goog.setTestOnly']: - # These 3 identifiers are at the top of the file. So if any other - # identifier is encountered, return. - # TODO(user): Once it's decided what ordering goog.require - # should use, add 'goog.module' to the list above and implement the - # decision. - break - token = token.next - - return tokens - - def _GetRequireOrProvideTokenStrings(self, tokens): - """Gets a list of strings corresponding to the given list of tokens. - - The string will be the next string in the token stream after each token in - tokens. This is used to find the object being provided/required by a given - goog.provide or goog.require token. - - Args: - tokens: A list of goog.provide or goog.require tokens. - - Returns: - A list of object names that are being provided or required by the given - list of tokens. For example: - - ['object.a', 'object.c', 'object.b'] - """ - token_strings = [] - for token in tokens: - if not token.is_deleted: - name = tokenutil.GetStringAfterToken(token) - token_strings.append(name) - return token_strings - - def _GetTokensMap(self, tokens): - """Gets a map from object name to tokens associated with that object. - - Starting from the goog.provide/goog.require token, searches backwards in the - token stream for any lines that start with a comment. These lines are - associated with the goog.provide/goog.require token. Also associates any - tokens on the same line as the goog.provide/goog.require token with that - token. - - Args: - tokens: A list of goog.provide or goog.require tokens. - - Returns: - A dictionary that maps object names to the tokens associated with the - goog.provide or goog.require of that object name. For example: - - { - 'object.a': [JavaScriptToken, JavaScriptToken, ...], - 'object.b': [...] - } - - The list of tokens includes any comment lines above the goog.provide or - goog.require statement and everything after the statement on the same - line. For example, all of the following would be associated with - 'object.a': - - /** @suppress {extraRequire} */ - goog.require('object.a'); // Some comment. - """ - tokens_map = {} - for token in tokens: - object_name = tokenutil.GetStringAfterToken(token) - # If the previous line starts with a comment, presume that the comment - # relates to the goog.require or goog.provide and keep them together when - # sorting. - first_token = token - previous_first_token = tokenutil.GetFirstTokenInPreviousLine(first_token) - while (previous_first_token and - previous_first_token.IsAnyType(Type.COMMENT_TYPES)): - first_token = previous_first_token - previous_first_token = tokenutil.GetFirstTokenInPreviousLine( - first_token) - - # Find the last token on the line. - last_token = tokenutil.GetLastTokenInSameLine(token) - - all_tokens = self._GetTokenList(first_token, last_token) - tokens_map[object_name] = all_tokens - return tokens_map - - def _GetTokenList(self, first_token, last_token): - """Gets a list of all tokens from first_token to last_token, inclusive. - - Args: - first_token: The first token to get. - last_token: The last token to get. - - Returns: - A list of all tokens between first_token and last_token, including both - first_token and last_token. - - Raises: - Exception: If the token stream ends before last_token is reached. - """ - token_list = [] - token = first_token - while token != last_token: - if not token: - raise Exception('ran out of tokens') - token_list.append(token) - token = token.next - token_list.append(last_token) - - return token_list - - def GetFixedRequireString(self, token): - """Get fixed/sorted order of goog.require statements. - - Args: - token: The first token in the token stream. - - Returns: - A string for correct sorted order of goog.require. - """ - return self._GetFixedRequireOrProvideString( - self._GetRequireOrProvideTokens(token, 'goog.require')) - - def GetFixedProvideString(self, token): - """Get fixed/sorted order of goog.provide statements. - - Args: - token: The first token in the token stream. - - Returns: - A string for correct sorted order of goog.provide. - """ - return self._GetFixedRequireOrProvideString( - self._GetRequireOrProvideTokens(token, 'goog.provide')) - - def _GetFixedRequireOrProvideString(self, tokens): - """Sorts goog.provide or goog.require statements. - - Args: - tokens: A list of goog.provide or goog.require tokens in the order they - appear in the token stream. i.e. the first token in this list must - be the first goog.provide or goog.require token. - - Returns: - A string for sorted goog.require or goog.provide statements - """ - - # A map from required/provided object name to tokens that make up the line - # it was on, including any comments immediately before it or after it on the - # same line. - tokens_map = self._GetTokensMap(tokens) - sorted_strings = sorted(tokens_map.keys()) - - new_order = '' - for string in sorted_strings: - for i in tokens_map[string]: - new_order += i.string - if i.IsLastInLine(): - new_order += '\n' - - return new_order |