Last active
February 9, 2018 02:23
-
-
Save cwalston/f6da9cca0105f5d67483935380001d84 to your computer and use it in GitHub Desktop.
Linter for Factor USING: ... ; forms
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
! Copyright (C) Charles Alston | |
! See http://factorcode.org/license.txt for BSD license | |
USING: accessors arrays fry io io.backend io.directories.search | |
io.encodings.utf8 io.files io.pathnames kernel parser regexp | |
sequences tools.crossref vocabs vocabs.refresh wrap.strings ; | |
IN: lint-using | |
! gist title: Linter for Factor USING: ... ; forms | |
! gist URL: | |
! https://gist.github.com/cwalston/f6da9cca0105f5d67483935380001d84 | |
! Remove superfluous vocabs declared in USING: ... ; forms. | |
! Test by adding & saving unnecessary vocab declarations to a working | |
! vocab USING: ... ; form & calling `lint-using` on the vocab. | |
! (As usual, place in an eponymously named folder in your work directory, | |
! & back up your stuff, to test) | |
! matches a well-formed sub-sequence of "USING: ... ;" in a source file. | |
CONSTANT: USING-list-regexp R/ USING:(\s+[^;]+)+\s+;/ ! Thanks, John | |
: first-using-list ( string -- slice ) | |
USING-list-regexp first-match ; | |
: write-USING ( vocab-name -- string ) | |
vocab-uses ! ( -- seq ) | |
"USING:" prefix ";" suffix " " join | |
64 wrap-string ; ! ( -- string ) | |
: work-vocabs>source-path ( vocab-name -- abspath ) | |
[ "resource:work" normalize-path 1array ] dip ! ( -- dir-path name ) | |
file-name ".factor" append | |
'[ file-name _ = ] | |
find-file-in-directories ; | |
: replace-USING ( string vocab-name -- string' ) | |
work-vocabs>source-path utf8 file-contents | |
first-using-list ! ( -- string slice ) | |
[ from>> ] [ to>> ] [ seq>> ] tri replace-slice ; | |
! turn on auto-use to fill in minimal list | |
: reload-linted ( string vocab-name -- ) | |
work-vocabs>source-path utf8 set-file-contents ! ( -- ) | |
auto-use refresh-all ; | |
! vocab-name can be a plain vocab name, e.g., "3way-search", | |
! a filename w/ extension, e.g., "3way-search.factor", | |
! a nested form, e.g., "resource:work/search-herbal/3way-search/3way-search.factor", | |
! or a fully qualified work directory path. | |
! Searches only source files in "resource:work" directory. | |
! - Listener lint utility for USING: ... ; forms, in loaded vocabs. | |
! - Press F2 after executing `lint-using` to display | |
! linted USING: ... ; form for copy/paste/save to target source file. | |
! example tests on my system: | |
! execute `<vocab-name> lint-using` in Listener, e.g., | |
! "herbal-article-element" lint-using ! Press F2 after this, | |
! "3way-search" lint-using ! to invoke refresh/restarts | |
! "open-query-browser" lint-using | |
: lint-using ( vocab-name -- ) | |
[ write-USING ] ! ( -- string ) | |
[ replace-USING ] ! ( -- string' ) | |
[ reload-linted ] tri ; ! ( -- ) | |
! convenience word & alias to distinguish loaded/not-loaded vocabs | |
: lint-if-loaded ( vocab-name -- ) | |
dup lookup-vocab ! ( -- vocab-name T{ vocab }/f ) | |
[ lint-using ] | |
[ "``" "'' " surround "is not loaded." append print ] if ; | |
ALIAS: lil lint-if-loaded | |
! Lint workflow looks like this (tl;dr): | |
! (1) open <vocab-name> in your editor, | |
! (2) copy <vocab-name> at the IN: line (or wherever convenient, per your editor), | |
! (3) in Listener, enter: "<vocab-name>" lint-if-loaded (double-quoted) | |
! (easier, enter "<vocab-name>" lil); press <ret>, | |
! (4) you'll see either the msg: ``<vocab-name>'' is not loaded. (so skip this vocab), | |
! or auto-use is on; if on, | |
! (5) press F2 for restart/refresh, & copy the presented USING: ... ; form (now linted), | |
! paste over the form in your editor & save the file (close it if you want). | |
! (Note: when you switch back to your editor, the USING form there will shrink, | |
! typically; just paste the newly copied linted form over what is there, & save. | |
! - If no restarts are triggered & no USING revisions appear, | |
! return to editor & save vocab with USING form as is or has changed.) | |
! (6) in Listener, press F2 to reload the saved vocab file; turn off auto-use. | |
! Done; the vocab is saved & reloaded, with its USING: ... ; form linted. | |
! Rinse & repeat to lint USING: ... ; forms in other vocabs. | |
! ----------------------------------------------------------------------------------- | |
! to do: work out routines for these other syntax words -- | |
! USE: vocab | |
! UNUSE: vocab | |
! FROM: vocab => words ... ; | |
! EXCLUDE: vocab => word ... ; | |
! QUALIFIED: vocab | |
! QUALIFIED-WITH: vocab name |
Alternatively, we could preserve the manifest
somewhere that was created as part of parsing the vocabulary and then you'd have the exact one the vocabulary was parsed with.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This would be a lot easier with the refactoring abilities of the new parser we'd like to get finished for 0.99, but... if you want to use the
see
machinery, another way is to assemble a manifest for all the vocab words then write it out as a single using list:You can see it works more or less (missing
fry
since that turns into a bunch of curry instructions) and gets locals wrong (includinglocals.backend
instead oflocals
for a similar reason tofry
).For example on vocabs like
calendars.holiday
.vs.
Probably could fix that bug and then it would be pretty good, except for any top-level code that might have
USE:
declarations that aren't used by any word definitions, and it wouldn't get theFROM:
forms correct for writing back, but the new parser fixes all that.Maybe if you just built a
help.lint.using
warning system and then the user could manually confirm/fix, that would be a good first step?