15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#!/usr/bin/env python
25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Copyright 2012 The Closure Linter Authors. All Rights Reserved.
45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Licensed under the Apache License, Version 2.0 (the "License");
65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# you may not use this file except in compliance with the License.
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# You may obtain a copy of the License at
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#      http://www.apache.org/licenses/LICENSE-2.0
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Unless required by applicable law or agreed to in writing, software
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# distributed under the License is distributed on an "AS-IS" BASIS,
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# See the License for the specific language governing permissions and
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# limitations under the License.
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)"""Utility functions for testing gjslint components."""
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Allow non-Google copyright
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# pylint: disable=g-bad-file-header
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)__author__ = ('nnaze@google.com (Nathan Naze)')
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import StringIO
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from closure_linter import ecmametadatapass
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from closure_linter import javascriptstatetracker
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from closure_linter import javascripttokenizer
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def TokenizeSource(source):
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  """Convert a source into a string of tokens.
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Args:
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    source: A source file as a string or file-like object (iterates lines).
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Returns:
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    The first token of the resulting token stream.
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  """
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if isinstance(source, basestring):
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    source = StringIO.StringIO(source)
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  tokenizer = javascripttokenizer.JavaScriptTokenizer()
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return tokenizer.TokenizeFile(source)
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def TokenizeSourceAndRunEcmaPass(source):
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  """Tokenize a source and run the EcmaMetaDataPass on it.
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Args:
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    source: A source file as a string or file-like object (iterates lines).
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Returns:
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    The first token of the resulting token stream.
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  """
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  start_token = TokenizeSource(source)
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ecma_pass = ecmametadatapass.EcmaMetaDataPass()
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ecma_pass.Process(start_token)
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return start_token
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def ParseFunctionsAndComments(source):
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  """Run the tokenizer and tracker and return comments and functions found.
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Args:
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    source: A source file as a string or file-like object (iterates lines).
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Returns:
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    The functions and comments as a tuple.
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  """
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  start_token = TokenizeSourceAndRunEcmaPass(source)
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  tracker = javascriptstatetracker.JavaScriptStateTracker()
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  functions = []
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  comments = []
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for token in start_token:
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    tracker.HandleToken(token, tracker.GetLastNonSpaceToken())
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    function = tracker.GetFunction()
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if function and function not in functions:
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      functions.append(function)
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    comment = tracker.GetDocComment()
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if comment and comment not in comments:
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      comments.append(comment)
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    tracker.HandleAfterToken(token)
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return functions, comments
92