Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions plugins/axiomcode/skills/axiomcode/scripts/ax_fresh.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,17 @@
'python': ('pyproject.toml', 'setup.cfg', 'setup.py'),
'csharp': ('global.json', 'Directory.Build.props'),
}
# EXTENSION CASE (#1771). The JavaScript parser matches an extension whatever its case (jsExtensionOf lower-cases the
# name, so Main.JS and Up.VUE are read) and the C# parser reads *.CS (discoverCsFiles); the others match it exactly.
# Matched exactly here, such a file was parsed but left out of the table: an edit to it was invisible and `index` said
# "graph up to date". These are the extensions each parser folds; every other one stays case-sensitive, as its parser is.
FOLD = {'javascript': frozenset(EXT['javascript']), 'csharp': frozenset({'.cs'})}

def has_ext(lang, name, exts):
"""True when the parser of `lang` takes file `name` as ending in one of `exts`"""
if name.endswith(exts): return True
fold = FOLD.get(lang)
return bool(fold) and name.lower().endswith(tuple(e for e in exts if e in fold))
# TOOL OUTPUT NOBODY PARSES: what the non-source scan of `impact` (axiomcode-impact) leaves out. NOT what the file table
# prunes: that is SKIP below, per language.
PRUNE_ALL = {'.git', '.hg', '.svn', '.axiomcode', 'node_modules', 'bower_components', 'dist', 'build', 'out',
Expand Down Expand Up @@ -194,7 +205,7 @@ def watched(root, lang):
for f in files:
for l, exts, names in spec:
if l in off: continue
if f.endswith(exts) or f in names or (l == 'java' and os.path.basename(d) == 'services' and 'META-INF' in d) \
if has_ext(l, f, exts) or f in names or (l == 'java' and os.path.basename(d) == 'services' and 'META-INF' in d) \
or (l == 'python' and python_script(os.path.join(d, f), f)):
yield os.path.join(d, f); break

Expand Down Expand Up @@ -1118,7 +1129,7 @@ def main(argv):
n = {l: 0 for l in SOURCE}
for l in SOURCE:
for p in watched(repo, l):
if p.endswith(SOURCE[l]) or (l == 'python' and python_script(p)): n[l] += 1
if has_ext(l, os.path.basename(p), SOURCE[l]) or (l == 'python' and python_script(p)): n[l] += 1
print(n['java'], n['typescript'], n['python'], n['javascript'], n['csharp']); return 0
if cmd == 'pyscripts':
# how many extensionless python scripts are under repo: added to the build's .py count when it picks a language
Expand Down
21 changes: 21 additions & 0 deletions tests/freshness.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,27 @@ def prune_checks():
write(only, 'src/App.vue', '<script>export default {}</script>\n')
n = {l: sum(1 for p in ax_fresh.watched(only, l) if p.endswith(ax_fresh.SOURCE[l])) for l in ('javascript', 'typescript')}
check("prune: a repository of .vue files alone counts no JavaScript or TypeScript source", n == {'javascript': 0, 'typescript': 0}, n)
# EXTENSION CASE (#1771): the JavaScript parser reads Main.JS and Up.VUE and the C# parser reads Calc.CS, so an edit
# to one makes the graph stale and they count as source. The control: the TypeScript, Python and Java parsers match
# an extension exactly, so Main.TS, calc.PY and Calc.JAVA stay unwatched and uncounted
upper = os.path.join(work, 'upper')
for f in ('src/lib.js', 'src/Main.JS', 'src/views/Up.VUE', 'src/Old.Mjs', 'src/Main.TS', 'src/calc.PY',
'src/Calc.JAVA', 'src/Calc.CS'):
write(upper, f, 'x\n')
want = {'javascript': {'src/lib.js', 'src/Main.JS', 'src/views/Up.VUE', 'src/Old.Mjs'}, 'typescript': {'src/lib.js'},
'python': set(), 'java': set(), 'csharp': {'src/Calc.CS'}}
for lang, files in want.items():
got = {os.path.relpath(p, upper) for p in ax_fresh.watched(upper, lang)}
check(f"prune: {lang} watches an upper-case extension exactly when its parser reads one", got == files, sorted(got))
table = dict(lang='javascript', lang_auto=True, src='', files=ax_fresh.snapshot(upper, 'javascript', upper))
write(upper, 'src/Main.JS', 'third();\n'); write(upper, 'src/views/Up.VUE', 'third();\n'); write(upper, 'src/Main.TS', 'y\n')
c = ax_fresh.changes(upper, table)
check("prune: javascript: an edit to Main.JS or Up.VUE makes the graph stale; one to Main.TS does not",
c == (['src/Main.JS', 'src/views/Up.VUE'], [], []), c)
n = {l: sum(1 for p in ax_fresh.watched(upper, l) if ax_fresh.has_ext(l, os.path.basename(p), ax_fresh.SOURCE[l]))
for l in ax_fresh.SOURCE}
check("prune: Main.JS and Calc.CS count as source; Main.TS, calc.PY, Calc.JAVA and Up.VUE do not",
n == {'java': 0, 'typescript': 0, 'python': 0, 'javascript': 3, 'csharp': 1}, n)
finally:
shutil.rmtree(work, ignore_errors=True)

Expand Down
Loading