Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: third_party/closure_linter/closure_linter/aliaspass.py

Issue 2328693002: Updated linter with upstream release (2.3.19) (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
11 # distributed under the License is distributed on an "AS-IS" BASIS, 11 # distributed under the License is distributed on an "AS-IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and 13 # See the License for the specific language governing permissions and
14 # limitations under the License. 14 # limitations under the License.
15 15
16 """Pass that scans for goog.scope aliases and lint/usage errors.""" 16 """Pass that scans for goog.scope aliases and lint/usage errors."""
17 17
18 # Allow non-Google copyright 18 # Allow non-Google copyright
19 # pylint: disable=g-bad-file-header 19 # pylint: disable=g-bad-file-header
20 20
21 __author__ = ('nnaze@google.com (Nathan Naze)') 21 __author__ = ('nnaze@google.com (Nathan Naze)')
22 22
23 import itertools
24
25 from closure_linter import ecmametadatapass 23 from closure_linter import ecmametadatapass
26 from closure_linter import errors 24 from closure_linter import errors
27 from closure_linter import javascripttokens 25 from closure_linter import javascripttokens
28 from closure_linter import scopeutil 26 from closure_linter import scopeutil
29 from closure_linter import tokenutil 27 from closure_linter import tokenutil
30 from closure_linter.common import error 28 from closure_linter.common import error
31 29
32 30
33 # TODO(nnaze): Create a Pass interface and move this class, EcmaMetaDataPass, 31 # TODO(nnaze): Create a Pass interface and move this class, EcmaMetaDataPass,
34 # and related classes onto it. 32 # and related classes onto it.
(...skipping 16 matching lines...) Expand all
51 49
52 Returns: 50 Returns:
53 The aliased symbol name or None if not found. 51 The aliased symbol name or None if not found.
54 """ 52 """
55 ns = identifier.split('.', 1)[0] 53 ns = identifier.split('.', 1)[0]
56 aliased_symbol = alias_map.get(ns) 54 aliased_symbol = alias_map.get(ns)
57 if aliased_symbol: 55 if aliased_symbol:
58 return aliased_symbol + identifier[len(ns):] 56 return aliased_symbol + identifier[len(ns):]
59 57
60 58
59 def _SetTypeAlias(js_type, alias_map):
60 """Updates the alias for identifiers in a type.
61
62 Args:
63 js_type: A typeannotation.TypeAnnotation instance.
64 alias_map: A dictionary mapping a symbol to an alias.
65 """
66 aliased_symbol = _GetAliasForIdentifier(js_type.identifier, alias_map)
67 if aliased_symbol:
68 js_type.alias = aliased_symbol
69 for sub_type in js_type.IterTypes():
70 _SetTypeAlias(sub_type, alias_map)
71
72
61 class AliasPass(object): 73 class AliasPass(object):
62 """Pass to identify goog.scope() usages. 74 """Pass to identify goog.scope() usages.
63 75
64 Identifies goog.scope() usages and finds lint/usage errors. Notes any 76 Identifies goog.scope() usages and finds lint/usage errors. Notes any
65 aliases of symbols in Closurized namespaces (that is, reassignments 77 aliases of symbols in Closurized namespaces (that is, reassignments
66 such as "var MyClass = goog.foo.MyClass;") and annotates identifiers 78 such as "var MyClass = goog.foo.MyClass;") and annotates identifiers
67 when they're using an alias (so they may be expanded to the full symbol 79 when they're using an alias (so they may be expanded to the full symbol
68 later -- that "MyClass.prototype.action" refers to 80 later -- that "MyClass.prototype.action" refers to
69 "goog.foo.MyClass.prototype.action" when expanded.). 81 "goog.foo.MyClass.prototype.action" when expanded.).
70 """ 82 """
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 return True 174 return True
163 context = context.parent 175 context = context.parent
164 176
165 return False 177 return False
166 178
167 def _ProcessRootContext(self, root_context): 179 def _ProcessRootContext(self, root_context):
168 """Processes all goog.scope blocks under the root context.""" 180 """Processes all goog.scope blocks under the root context."""
169 181
170 assert root_context.type is ecmametadatapass.EcmaContext.ROOT 182 assert root_context.type is ecmametadatapass.EcmaContext.ROOT
171 183
172 # Identify all goog.scope blocks. 184 # Process aliases in statements in the root scope for goog.module-style
173 goog_scope_blocks = itertools.ifilter( 185 # aliases.
174 scopeutil.IsGoogScopeBlock, 186 global_alias_map = {}
175 self._YieldAllContexts(root_context)) 187 for context in root_context.children:
188 if context.type == ecmametadatapass.EcmaContext.STATEMENT:
189 for statement_child in context.children:
190 if statement_child.type == ecmametadatapass.EcmaContext.VAR:
191 match = scopeutil.MatchModuleAlias(statement_child)
192 if match:
193 # goog.require aliases cannot use further aliases, the symbol is
194 # the second part of match, directly.
195 symbol = match[1]
196 if scopeutil.IsInClosurizedNamespace(symbol,
197 self._closurized_namespaces):
198 global_alias_map[match[0]] = symbol
176 199
177 # Process each block to find aliases. 200 # Process each block to find aliases.
178 for scope_block in goog_scope_blocks: 201 for context in root_context.children:
179 self._ProcessGoogScopeBlock(scope_block) 202 self._ProcessBlock(context, global_alias_map)
180 203
181 def _ProcessGoogScopeBlock(self, scope_block): 204 def _ProcessBlock(self, context, global_alias_map):
182 """Scans a goog.scope block to find aliases and mark alias tokens.""" 205 """Scans a goog.scope block to find aliases and mark alias tokens."""
206 alias_map = global_alias_map.copy()
183 207
184 alias_map = dict() 208 # Iterate over every token in the context. Each token points to one
185
186 # Iterate over every token in the scope_block. Each token points to one
187 # context, but multiple tokens may point to the same context. We only want 209 # context, but multiple tokens may point to the same context. We only want
188 # to check each context once, so keep track of those we've seen. 210 # to check each context once, so keep track of those we've seen.
189 seen_contexts = set() 211 seen_contexts = set()
190 token = scope_block.start_token 212 token = context.start_token
191 while token and self._IsTokenInParentBlock(token, scope_block): 213 while token and self._IsTokenInParentBlock(token, context):
192 214 token_context = token.metadata.context if token.metadata else None
193 token_context = token.metadata.context
194 215
195 # Check to see if this token is an alias. 216 # Check to see if this token is an alias.
196 if token_context not in seen_contexts: 217 if token_context and token_context not in seen_contexts:
197 seen_contexts.add(token_context) 218 seen_contexts.add(token_context)
198 219
199 # If this is a alias statement in the goog.scope block. 220 # If this is a alias statement in the goog.scope block.
200 if (token_context.type == ecmametadatapass.EcmaContext.VAR and 221 if (token_context.type == ecmametadatapass.EcmaContext.VAR and
201 token_context.parent.parent is scope_block): 222 scopeutil.IsGoogScopeBlock(token_context.parent.parent)):
202 match = scopeutil.MatchAlias(token_context) 223 match = scopeutil.MatchAlias(token_context)
203 224
204 # If this is an alias, remember it in the map. 225 # If this is an alias, remember it in the map.
205 if match: 226 if match:
206 alias, symbol = match 227 alias, symbol = match
207 symbol = _GetAliasForIdentifier(symbol, alias_map) or symbol 228 symbol = _GetAliasForIdentifier(symbol, alias_map) or symbol
208 if scopeutil.IsInClosurizedNamespace(symbol, 229 if scopeutil.IsInClosurizedNamespace(symbol,
209 self._closurized_namespaces): 230 self._closurized_namespaces):
210 alias_map[alias] = symbol 231 alias_map[alias] = symbol
211 232
212 # If this token is an identifier that matches an alias, 233 # If this token is an identifier that matches an alias,
213 # mark the token as an alias to the original symbol. 234 # mark the token as an alias to the original symbol.
214 if (token.type is javascripttokens.JavaScriptTokenType.SIMPLE_LVALUE or 235 if (token.type is javascripttokens.JavaScriptTokenType.SIMPLE_LVALUE or
215 token.type is javascripttokens.JavaScriptTokenType.IDENTIFIER): 236 token.type is javascripttokens.JavaScriptTokenType.IDENTIFIER):
216 identifier = tokenutil.GetIdentifierForToken(token) 237 identifier = tokenutil.GetIdentifierForToken(token)
217 if identifier: 238 if identifier:
218 aliased_symbol = _GetAliasForIdentifier(identifier, alias_map) 239 aliased_symbol = _GetAliasForIdentifier(identifier, alias_map)
219 if aliased_symbol: 240 if aliased_symbol:
220 token.metadata.aliased_symbol = aliased_symbol 241 token.metadata.aliased_symbol = aliased_symbol
221 242
243 elif token.type == javascripttokens.JavaScriptTokenType.DOC_FLAG:
244 flag = token.attached_object
245 if flag and flag.HasType() and flag.jstype:
246 _SetTypeAlias(flag.jstype, alias_map)
247
222 token = token.next # Get next token 248 token = token.next # Get next token
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698