Skip to content
This repository was archived by the owner on Oct 9, 2021. It is now read-only.

Commit 2e636d3

Browse files
committed
Detect GAS *.s files as Assembly language
1 parent e6ece40 commit 2e636d3

5 files changed

Lines changed: 76 additions & 66 deletions

File tree

tests/samples/codefiles/gas.s

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.global _start
2+
3+
.text
4+
_start:
5+
movl $4, %eax
6+
movl $1, %ebx
7+
movl $msg, %ecx
8+
movl $len, %edx
9+
int $0x80
10+
11+
movl $1, %eax
12+
movl $0, %ebx
13+
int $0x80
14+
.data
15+
msg:
16+
.ascii "Hello, world!\n"
17+
len = . - msg

tests/test_dependencies.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ def test_classnotfound_error_suppressed_when_parsing_dependencies(self):
193193
)
194194

195195
def test_dependencies_still_detected_when_alternate_language_used(self):
196-
with mock.patch('wakatime.stats.smart_guess_lexer') as mock_guess_lexer:
196+
with mock.patch('wakatime.stats.guess_lexer') as mock_guess_lexer:
197197
mock_guess_lexer.return_value = None
198198

199199
self.shared(

tests/test_languages.py

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import time
99
from wakatime.compat import u
1010
from wakatime.constants import SUCCESS
11-
from wakatime.stats import guess_language
11+
from wakatime.stats import guess_lexer
1212
from . import utils
1313
from .utils import ANY, CustomResponse
1414

@@ -105,27 +105,26 @@ def test_objectivecpp_language_detected_when_m_files_in_folder(self):
105105
entity='c_and_cpp/objective-cpp.h',
106106
)
107107

108-
def test_guess_language(self):
109-
with utils.mock.patch('wakatime.stats.smart_guess_lexer') as mock_guess_lexer:
110-
mock_guess_lexer.return_value = None
111-
source_file = 'tests/samples/codefiles/python.py'
112-
local_file = None
113-
result = guess_language(source_file, local_file)
114-
mock_guess_lexer.assert_called_once_with(source_file, local_file)
115-
self.assertEquals(result, (None, None))
108+
def test_guess_lexer(self):
109+
source_file = 'tests/samples/codefiles/python.py'
110+
local_file = None
111+
lexer = guess_lexer(source_file, local_file)
112+
language = u(lexer.name) if lexer else None
113+
self.assertEquals(language, 'Python')
116114

117-
def test_guess_language_from_vim_modeline(self):
115+
def test_guess_lexer_from_vim_modeline(self):
118116
self.shared(
119117
expected_language='Python',
120118
entity='python_without_extension',
121119
)
122120

123-
def test_guess_language_when_entity_not_exist_but_local_file_exists(self):
121+
def test_guess_lexer_when_entity_not_exist_but_local_file_exists(self):
124122
source_file = 'tests/samples/codefiles/does_not_exist.py'
125123
local_file = 'tests/samples/codefiles/python.py'
126124
self.assertFalse(os.path.exists(source_file))
127-
result = guess_language(source_file, local_file)
128-
self.assertEquals(result[0], 'Python')
125+
lexer = guess_lexer(source_file, local_file)
126+
language = u(lexer.name) if lexer else None
127+
self.assertEquals(language, 'Python')
129128

130129
def test_language_arg_takes_priority_over_detected_language(self):
131130
self.shared(
@@ -135,7 +134,7 @@ def test_language_arg_takes_priority_over_detected_language(self):
135134
)
136135

137136
def test_language_arg_is_used_when_not_guessed(self):
138-
with utils.mock.patch('wakatime.stats.smart_guess_lexer') as mock_guess_lexer:
137+
with utils.mock.patch('wakatime.stats.guess_lexer') as mock_guess_lexer:
139138
mock_guess_lexer.return_value = None
140139

141140
self.shared(
@@ -169,7 +168,7 @@ def test_language_arg_used_for_entity_type_domain(self):
169168
)
170169

171170
def test_vim_language_arg_is_used_when_not_guessed(self):
172-
with utils.mock.patch('wakatime.stats.smart_guess_lexer') as mock_guess_lexer:
171+
with utils.mock.patch('wakatime.stats.guess_lexer') as mock_guess_lexer:
173172
mock_guess_lexer.return_value = None
174173

175174
self.shared(
@@ -179,7 +178,7 @@ def test_vim_language_arg_is_used_when_not_guessed(self):
179178
)
180179

181180
def test_alternate_language_not_used_when_invalid(self):
182-
with utils.mock.patch('wakatime.stats.smart_guess_lexer') as mock_guess_lexer:
181+
with utils.mock.patch('wakatime.stats.guess_lexer') as mock_guess_lexer:
183182
mock_guess_lexer.return_value = None
184183

185184
self.shared(
@@ -189,7 +188,7 @@ def test_alternate_language_not_used_when_invalid(self):
189188
)
190189

191190
def test_error_reading_alternate_language_json_map_file(self):
192-
with utils.mock.patch('wakatime.stats.smart_guess_lexer') as mock_guess_lexer:
191+
with utils.mock.patch('wakatime.stats.guess_lexer') as mock_guess_lexer:
193192
mock_guess_lexer.return_value = None
194193

195194
with utils.mock.patch('wakatime.stats.open') as mock_open:
@@ -286,3 +285,9 @@ def test_coldfusion_detected(self):
286285
expected_language='ColdFusion',
287286
entity='coldfusion.cfm',
288287
)
288+
289+
def test_gas_detected_as_assembly(self):
290+
self.shared(
291+
expected_language='Assembly',
292+
entity='gas.s',
293+
)

wakatime/languages/default.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"cocoa": "Cocoa",
1616
"coffeescript": "CoffeeScript",
1717
"coldfusion": "ColdFusion",
18+
"coldfusion html": "ColdFusion",
1819
"common lisp": "Common Lisp",
1920
"cshtml": "CSHTML",
2021
"css": "CSS",
@@ -26,6 +27,7 @@
2627
"erlang": "Erlang",
2728
"f#": "F#",
2829
"fortran": "Fortran",
30+
"gas": "Assembly",
2931
"go": "Go",
3032
"gosu": "Gosu",
3133
"groovy": "Groovy",

wakatime/stats.py

Lines changed: 34 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -68,56 +68,42 @@ def get_file_stats(file_name, entity_type='file', lineno=None, cursorpos=None,
6868

6969
if entity_type == 'file':
7070
lexer = get_lexer(language)
71-
if not language:
72-
language, lexer = guess_language(file_name, local_file)
71+
if not lexer:
72+
lexer = guess_lexer(file_name, local_file)
73+
language = root_language(lexer)
7374
parser = DependencyParser(local_file or file_name, lexer)
7475
stats.update({
75-
'language': use_root_language(language, lexer),
76+
'language': standardize_language(language),
7677
'dependencies': parser.parse(),
7778
'lines': number_lines_in_file(local_file or file_name),
7879
})
7980

8081
return stats
8182

8283

83-
def guess_language(file_name, local_file):
84-
"""Guess lexer and language for a file.
85-
86-
Returns a tuple of (language_str, lexer_obj).
87-
"""
88-
89-
lexer = None
90-
91-
language = get_language_from_extension(file_name)
92-
if language:
93-
lexer = get_lexer(language)
94-
else:
95-
lexer = smart_guess_lexer(file_name, local_file)
96-
if lexer:
97-
language = u(lexer.name)
98-
99-
return language, lexer
100-
101-
102-
def smart_guess_lexer(file_name, local_file):
84+
def guess_lexer(file_name, local_file):
10385
"""Guess Pygments lexer for a file.
10486
10587
Looks for a vim modeline in file contents, then compares the accuracy
10688
of that lexer with a second guess. The second guess looks up all lexers
10789
matching the file name, then runs a text analysis for the best choice.
10890
"""
109-
lexer = None
11091

111-
text = get_file_head(file_name)
92+
lexer = None
11293

113-
lexer1, accuracy1 = guess_lexer_using_filename(local_file or file_name, text)
114-
lexer2, accuracy2 = guess_lexer_using_modeline(text)
94+
language = get_language_from_extension(file_name)
95+
if language:
96+
lexer = get_lexer(language)
11597

116-
if lexer1:
117-
lexer = lexer1
118-
if (lexer2 and accuracy2 is not None and
119-
(accuracy1 is None or accuracy2 > accuracy1)):
120-
lexer = lexer2
98+
if not lexer:
99+
text = get_file_head(file_name)
100+
lexer1, accuracy1 = guess_lexer_using_filename(local_file or file_name, text)
101+
lexer2, accuracy2 = guess_lexer_using_modeline(text)
102+
if lexer1:
103+
lexer = lexer1
104+
if (lexer2 and accuracy2 is not None and
105+
(accuracy1 is None or accuracy2 > accuracy1)):
106+
lexer = lexer2
121107

122108
return lexer
123109

@@ -238,7 +224,7 @@ def number_lines_in_file(file_name):
238224
return lines
239225

240226

241-
def standardize_language(language, plugin):
227+
def standardize_language(language, plugin=None):
242228
"""Maps a string to the equivalent Pygments language.
243229
244230
Returns the standardized language string.
@@ -247,15 +233,17 @@ def standardize_language(language, plugin):
247233
if not language:
248234
return None
249235

250-
# standardize language for this plugin
251236
if plugin:
252237
plugin = plugin.split(' ')[-1].split('/')[0].split('-')[0]
253238
standardized = get_language_from_json(language, plugin)
254239
if standardized is not None:
255-
return standardized
240+
language = standardized
241+
242+
standardized = get_language_from_json(language, 'default')
243+
if standardized is not None:
244+
language = standardized
256245

257-
# standardize language against default languages
258-
return get_language_from_json(language, 'default')
246+
return language
259247

260248

261249
def get_lexer(language):
@@ -271,17 +259,15 @@ def get_lexer(language):
271259
return None
272260

273261

274-
def use_root_language(language, lexer):
275-
override = {
276-
'Coldfusion HTML': 'ColdFusion',
277-
}
278-
if language in override:
279-
return override[language]
280-
281-
if lexer and hasattr(lexer, 'root_lexer'):
282-
return u(lexer.root_lexer.name)
283-
284-
return language
262+
def root_language(lexer):
263+
if lexer:
264+
prevent_using_root = set([
265+
'coldfusion html',
266+
])
267+
if hasattr(lexer, 'root_lexer') and u(lexer.name).lower() not in prevent_using_root:
268+
lexer = lexer.root_lexer
269+
return u(lexer.name)
270+
return None
285271

286272

287273
def get_language_from_json(language, key):

0 commit comments

Comments
 (0)