| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright 2012 The Closure Linter Authors. All Rights Reserved. | 3 # Copyright 2012 The Closure Linter Authors. All Rights Reserved. |
| 4 # Licensed under the Apache License, Version 2.0 (the "License"); | 4 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 # you may not use this file except in compliance with the License. | 5 # you may not use this file except in compliance with the License. |
| 6 # You may obtain a copy of the License at | 6 # You may obtain a copy of the License at |
| 7 # | 7 # |
| 8 # http://www.apache.org/licenses/LICENSE-2.0 | 8 # http://www.apache.org/licenses/LICENSE-2.0 |
| 9 # | 9 # |
| 10 # Unless required by applicable law or agreed to in writing, software | 10 # Unless required by applicable law or agreed to in writing, software |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 Returns: | 113 Returns: |
| 114 True if symbol is an identifier in a Closurized namespace, otherwise False. | 114 True if symbol is an identifier in a Closurized namespace, otherwise False. |
| 115 """ | 115 """ |
| 116 for ns in closurized_namespaces: | 116 for ns in closurized_namespaces: |
| 117 if symbol.startswith(ns + '.'): | 117 if symbol.startswith(ns + '.'): |
| 118 return True | 118 return True |
| 119 | 119 |
| 120 return False | 120 return False |
| 121 | 121 |
| 122 | 122 |
| 123 def MatchAlias(context): | 123 def _GetVarAssignmentTokens(context): |
| 124 """Match an alias statement (some identifier assigned to a variable). | 124 """Returns the tokens from context if it is a var assignment. |
| 125 | |
| 126 Example alias: var MyClass = proj.longNamespace.MyClass. | |
| 127 | 125 |
| 128 Args: | 126 Args: |
| 129 context: An EcmaContext of type EcmaContext.VAR. | 127 context: An EcmaContext. |
| 130 | 128 |
| 131 Returns: | 129 Returns: |
| 132 If a valid alias, returns a tuple of alias and symbol, otherwise None. | 130 If a var assignment, the tokens contained within it w/o the trailing |
| 131 semicolon. |
| 133 """ | 132 """ |
| 134 if context.type != ecmametadatapass.EcmaContext.VAR: | 133 if context.type != ecmametadatapass.EcmaContext.VAR: |
| 135 return | 134 return |
| 136 | 135 |
| 137 # The var's parent is a STATEMENT, which should be directly below goog.scope. | |
| 138 if not IsGoogScopeBlock(context.parent.parent): | |
| 139 return | |
| 140 | |
| 141 # Get the tokens in this statement. | 136 # Get the tokens in this statement. |
| 142 if context.start_token and context.end_token: | 137 if context.start_token and context.end_token: |
| 143 statement_tokens = tokenutil.GetTokenRange(context.start_token, | 138 statement_tokens = tokenutil.GetTokenRange(context.start_token, |
| 144 context.end_token) | 139 context.end_token) |
| 145 else: | 140 else: |
| 146 return | 141 return |
| 147 | 142 |
| 148 # And now just those tokens that are actually code. | 143 # And now just those tokens that are actually code. |
| 149 is_non_code_type = lambda t: t.type not in JavaScriptTokenType.NON_CODE_TYPES | 144 is_non_code_type = lambda t: t.type not in JavaScriptTokenType.NON_CODE_TYPES |
| 150 code_tokens = filter(is_non_code_type, statement_tokens) | 145 code_tokens = filter(is_non_code_type, statement_tokens) |
| 151 | 146 |
| 152 # This section identifies statements of the alias form "var alias = symbol". | |
| 153 | |
| 154 # Pop off the semicolon if present. | 147 # Pop off the semicolon if present. |
| 155 if code_tokens and code_tokens[-1].IsType(JavaScriptTokenType.SEMICOLON): | 148 if code_tokens and code_tokens[-1].IsType(JavaScriptTokenType.SEMICOLON): |
| 156 code_tokens.pop() | 149 code_tokens.pop() |
| 157 | 150 |
| 158 if len(code_tokens) < 4: | 151 if len(code_tokens) < 4: |
| 159 return | 152 return |
| 160 | 153 |
| 161 # Verify that this is of the form "var lvalue = identifier;". | |
| 162 # The identifier may span multiple lines and could be multiple tokens. | |
| 163 if (code_tokens[0].IsKeyword('var') and | 154 if (code_tokens[0].IsKeyword('var') and |
| 164 code_tokens[1].IsType(JavaScriptTokenType.SIMPLE_LVALUE) and | 155 code_tokens[1].IsType(JavaScriptTokenType.SIMPLE_LVALUE) and |
| 165 code_tokens[2].IsOperator('=') and | 156 code_tokens[2].IsOperator('=')): |
| 166 all(t.IsType(JavaScriptTokenType.IDENTIFIER) for t in code_tokens[3:])): | 157 return code_tokens |
| 158 |
| 159 |
| 160 def MatchAlias(context): |
| 161 """Match an alias statement (some identifier assigned to a variable). |
| 162 |
| 163 Example alias: var MyClass = proj.longNamespace.MyClass. |
| 164 |
| 165 Args: |
| 166 context: An EcmaContext of type EcmaContext.VAR. |
| 167 |
| 168 Returns: |
| 169 If a valid alias, returns a tuple of alias and symbol, otherwise None. |
| 170 """ |
| 171 code_tokens = _GetVarAssignmentTokens(context) |
| 172 if code_tokens is None: |
| 173 return |
| 174 |
| 175 if all(tokenutil.IsIdentifierOrDot(t) for t in code_tokens[3:]): |
| 176 # var Foo = bar.Foo; |
| 167 alias, symbol = code_tokens[1], code_tokens[3] | 177 alias, symbol = code_tokens[1], code_tokens[3] |
| 168 # Mark both tokens as an alias definition to avoid counting them as usages. | 178 # Mark both tokens as an alias definition to not count them as usages. |
| 169 alias.metadata.is_alias_definition = True | 179 alias.metadata.is_alias_definition = True |
| 170 symbol.metadata.is_alias_definition = True | 180 symbol.metadata.is_alias_definition = True |
| 181 return alias.string, tokenutil.GetIdentifierForToken(symbol) |
| 171 | 182 |
| 172 return alias.string, tokenutil.GetIdentifierForToken(symbol) | 183 |
| 184 def MatchModuleAlias(context): |
| 185 """Match an alias statement in a goog.module style import. |
| 186 |
| 187 Example alias: var MyClass = goog.require('proj.longNamespace.MyClass'). |
| 188 |
| 189 Args: |
| 190 context: An EcmaContext. |
| 191 |
| 192 Returns: |
| 193 If a valid alias, returns a tuple of alias and symbol, otherwise None. |
| 194 """ |
| 195 code_tokens = _GetVarAssignmentTokens(context) |
| 196 if code_tokens is None: |
| 197 return |
| 198 |
| 199 if(code_tokens[3].IsType(JavaScriptTokenType.IDENTIFIER) and |
| 200 code_tokens[3].string == 'goog.require'): |
| 201 # var Foo = goog.require('bar.Foo'); |
| 202 alias = code_tokens[1] |
| 203 symbol = tokenutil.GetStringAfterToken(code_tokens[3]) |
| 204 if symbol: |
| 205 alias.metadata.is_alias_definition = True |
| 206 return alias.string, symbol |
| OLD | NEW |