support for JavaScript imports

This commit is contained in:
Alan Hamlett 2018-03-11 13:29:30 -07:00
parent bc1d847e39
commit a212d48c57
17 changed files with 176 additions and 109 deletions

View file

View file

@ -0,0 +1,37 @@
import Alpha from './bravo';
import { charlie, delta } from '../../echo/foxtrot';
import golf from './hotel/india.js';
import juliett from 'kilo';
import {
lima,
mike,
} from './november';
import * from '/modules/oscar';
import * as papa from 'quebec';
import {romeo as sierra} from from 'tango.jsx';
import 'uniform.js';
import victorDefault, * as victorModule from '/modules/victor.js';
import whiskeyDefault, {whiskeyOne, whiskeyTwo} from 'whiskey';
const propTypes = {};
const defaultProps = {};
class Link extends Alpha.Component {
static method() {
return true;
}
render() {
return (
<a href={this.props.url} data-id={this.props.id}>
{this.props.text}
</a>
);
}
}
Link.propTypes = propTypes;
Link.defaultProps = defaultProps;
export default Link;

View file

@ -1,3 +0,0 @@
/**
* A Comment
*/

View file

@ -188,6 +188,28 @@ class DependenciesTestCase(TestCase):
entity='python.py',
)
def test_dependencies_still_detected_when_alternate_language_used(self):
with mock.patch('wakatime.stats.smart_guess_lexer') as mock_guess_lexer:
mock_guess_lexer.return_value = None
self.shared(
expected_dependencies=[
'app',
'django',
'flask',
'jinja',
'mock',
'pygments',
'simplejson',
'sqlalchemy',
'unittest',
],
expected_language='Python',
expected_lines=37,
entity='python.py',
extra_args=['--alternate-language', 'PYTHON'],
)
def test_python_dependencies_detected(self):
self.shared(
expected_dependencies=[
@ -302,7 +324,7 @@ class DependenciesTestCase(TestCase):
expected_dependencies=[
'"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"',
],
expected_language='HTML+PHP',
expected_language='HTML',
expected_lines=22,
entity='html-with-php.html',
)
@ -312,7 +334,7 @@ class DependenciesTestCase(TestCase):
expected_dependencies=[
'"libs/json2.js"',
],
expected_language='HTML+Django/Jinja',
expected_language='HTML',
expected_lines=40,
entity='html-django.html',
)
@ -336,24 +358,22 @@ class DependenciesTestCase(TestCase):
entity='go.go',
)
def test_dependencies_still_detected_when_alternate_language_used(self):
with mock.patch('wakatime.stats.smart_guess_lexer') as mock_guess_lexer:
mock_guess_lexer.return_value = None
self.shared(
expected_dependencies=[
'app',
'django',
'flask',
'jinja',
'mock',
'pygments',
'simplejson',
'sqlalchemy',
'unittest',
],
expected_language='Python',
expected_lines=37,
entity='python.py',
extra_args=['--alternate-language', 'PYTHON'],
)
def test_es6_dependencies_detected(self):
self.shared(
expected_dependencies=[
'bravo',
'foxtrot',
'india',
'kilo',
'november',
'oscar',
'quebec',
'tango',
'uniform',
'victor',
'whiskey',
],
expected_language='JavaScript',
expected_lines=37,
entity='es6.js',
)

View file

@ -141,7 +141,7 @@ class LanguagesTestCase(utils.TestCase):
def test_typescript_detected_over_typoscript(self):
self.shared(
expected_language='TypeScript',
entity='typescript.ts',
entity='empty.ts',
extra_args=['--language', 'foo', '--plugin', 'NeoVim/703 vim-wakatime/4.0.9']
)

View file

@ -106,8 +106,8 @@ class DependencyParser(object):
self.lexer = lexer
if self.lexer:
module_name = self.lexer.__module__.rsplit('.', 1)[-1]
class_name = self.lexer.__class__.__name__.replace('Lexer', 'Parser', 1)
module_name = self.root_lexer.__module__.rsplit('.', 1)[-1]
class_name = self.root_lexer.__class__.__name__.replace('Lexer', 'Parser', 1)
else:
module_name = 'unknown'
class_name = 'UnknownParser'
@ -121,6 +121,14 @@ class DependencyParser(object):
except ImportError:
log.debug('Parsing dependencies not supported for {0}.{1}'.format(module_name, class_name))
@property
def root_lexer(self):
if not self.lexer:
return None
if hasattr(self.lexer, 'root_lexer'):
return self.lexer.root_lexer
return self.lexer
def parse(self):
if self.parser:
plugin = self.parser(self.source_file, lexer=self.lexer)

View file

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""
wakatime.languages.c_cpp
~~~~~~~~~~~~~~~~~~~~~~~~
wakatime.dependencies.c_cpp
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Parse dependencies from C++ code.

View file

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""
wakatime.languages.data
~~~~~~~~~~~~~~~~~~~~~~~
wakatime.dependencies.data
~~~~~~~~~~~~~~~~~~~~~~~~~~
Parse dependencies from data files.

View file

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""
wakatime.languages.dotnet
~~~~~~~~~~~~~~~~~~~~~~~~~
wakatime.dependencies.dotnet
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Parse dependencies from .NET code.

View file

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""
wakatime.languages.go
~~~~~~~~~~~~~~~~~~~~~
wakatime.dependencies.go
~~~~~~~~~~~~~~~~~~~~~~~~
Parse dependencies from Go code.

View file

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
"""
wakatime.languages.templates
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
wakatime.dependencies.html
~~~~~~~~~~~~~~~~~~~~~~~~~~
Parse dependencies from Templates.
Parse dependencies from HTML.
:copyright: (c) 2014 Alan Hamlett.
:license: BSD, see LICENSE for more details.
@ -69,7 +69,7 @@ KEYWORDS = [
]
class HtmlDjangoParser(TokenParser):
class HtmlParser(TokenParser):
tags = []
opening_tag = False
getting_attrs = False
@ -141,63 +141,3 @@ class HtmlDjangoParser(TokenParser):
elif content.startswith('"') or content.startswith("'"):
if self.current_attr_value is None:
self.current_attr_value = content
class VelocityHtmlParser(HtmlDjangoParser):
pass
class MyghtyHtmlParser(HtmlDjangoParser):
pass
class MasonParser(HtmlDjangoParser):
pass
class MakoHtmlParser(HtmlDjangoParser):
pass
class CheetahHtmlParser(HtmlDjangoParser):
pass
class HtmlGenshiParser(HtmlDjangoParser):
pass
class RhtmlParser(HtmlDjangoParser):
pass
class HtmlPhpParser(HtmlDjangoParser):
pass
class HtmlSmartyParser(HtmlDjangoParser):
pass
class EvoqueHtmlParser(HtmlDjangoParser):
pass
class ColdfusionHtmlParser(HtmlDjangoParser):
pass
class LassoHtmlParser(HtmlDjangoParser):
pass
class HandlebarsHtmlParser(HtmlDjangoParser):
pass
class YamlJinjaParser(HtmlDjangoParser):
pass
class TwigHtmlParser(HtmlDjangoParser):
pass

View file

@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
"""
wakatime.dependencies.javascript
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Parse dependencies from JavaScript code.
:copyright: (c) 2018 Alan Hamlett.
:license: BSD, see LICENSE for more details.
"""
import re
from . import TokenParser
class JavascriptParser(TokenParser):
state = None
extension = re.compile(r'\.\w{1,4}$')
def parse(self):
for index, token, content in self.tokens:
self._process_token(token, content)
return self.dependencies
def _process_token(self, token, content):
if self.partial(token) == 'Reserved':
self._process_reserved(token, content)
elif self.partial(token) == 'Single':
self._process_string(token, content)
elif self.partial(token) == 'Punctuation':
self._process_punctuation(token, content)
else:
self._process_other(token, content)
def _process_reserved(self, token, content):
if self.state is None:
self.state = content
def _process_string(self, token, content):
if self.state == 'import':
self.append(self._format_module(content))
self.state = None
def _process_punctuation(self, token, content):
if content == ';':
self.state = None
def _process_other(self, token, content):
pass
def _format_module(self, content):
content = content.strip().strip('"').strip("'").strip()
content = content.split('/')[-1].split('\\')[-1]
content = self.extension.sub('', content, count=1)
return content

View file

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""
wakatime.languages.java
~~~~~~~~~~~~~~~~~~~~~~~
wakatime.dependencies.java
~~~~~~~~~~~~~~~~~~~~~~~~~~
Parse dependencies from Java code.

View file

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""
wakatime.languages.php
~~~~~~~~~~~~~~~~~~~~~~
wakatime.dependencies.php
~~~~~~~~~~~~~~~~~~~~~~~~~
Parse dependencies from PHP code.

View file

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""
wakatime.languages.python
~~~~~~~~~~~~~~~~~~~~~~~~~
wakatime.dependencies.python
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Parse dependencies from Python code.

View file

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""
wakatime.languages.unknown
~~~~~~~~~~~~~~~~~~~~~~~~~~
wakatime.dependencies.unknown
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Parse dependencies from files of unknown language.

View file

@ -53,6 +53,8 @@ def get_file_stats(file_name, entity_type='file', lineno=None, cursorpos=None,
if not language:
language, lexer = guess_language(file_name)
language = use_root_language(language, lexer)
parser = DependencyParser(file_name, lexer)
dependencies = parser.parse()
@ -236,6 +238,13 @@ def get_lexer(language):
return None
def use_root_language(language, lexer):
if lexer and hasattr(lexer, 'root_lexer'):
return u(lexer.root_lexer.name)
return language
def get_language_from_json(language, key):
"""Finds the given language in a json file."""