]> gitweb.factorcode.org Git - factor.git/commitdiff
v0.3 rename / rebrand pedantic lint to help coverage; rewrite again
authorCat Stevens <catb0t@protonmail.ch>
Sat, 3 Feb 2018 18:16:53 +0000 (13:16 -0500)
committerJohn Benediktsson <mrjbq7@gmail.com>
Sat, 3 Feb 2018 22:58:32 +0000 (14:58 -0800)
extra/help/lint/coverage/authors.txt [new file with mode: 0644]
extra/help/lint/coverage/coverage-docs.factor [new file with mode: 0644]
extra/help/lint/coverage/coverage-tests.factor [new file with mode: 0644]
extra/help/lint/coverage/coverage.factor [new file with mode: 0644]
extra/help/lint/coverage/summary.txt [new file with mode: 0644]
extra/help/lint/coverage/tags.txt [new file with mode: 0644]
extra/help/lint/pedantic/authors.txt [deleted file]
extra/help/lint/pedantic/pedantic-docs.factor [deleted file]
extra/help/lint/pedantic/pedantic.factor [deleted file]
extra/help/lint/pedantic/summary.txt [deleted file]
extra/help/lint/pedantic/tags.txt [deleted file]

diff --git a/extra/help/lint/coverage/authors.txt b/extra/help/lint/coverage/authors.txt
new file mode 100644 (file)
index 0000000..9d4a8e1
--- /dev/null
@@ -0,0 +1 @@
+Cat Stevens
diff --git a/extra/help/lint/coverage/coverage-docs.factor b/extra/help/lint/coverage/coverage-docs.factor
new file mode 100644 (file)
index 0000000..1191b1f
--- /dev/null
@@ -0,0 +1,137 @@
+USING: help help.lint.coverage help.lint.coverage.private help.markup help.syntax kernel
+sequences strings vocabs words ;
+IN: help.lint.coverage
+
+<PRIVATE
+: $related-subsections ( element -- )
+    [ related-words ] [ $subsections ] bi ;
+PRIVATE>
+
+ABOUT: "help.lint.coverage"
+
+ARTICLE: "help.lint.coverage" "Help coverage linting"
+"The " { $vocab-link "help.lint.coverage" } " vocabulary implements a very picky documentation completeness checker."
+$nl
+"The documentation coverage linter requires most words to have " { $link POSTPONE: HELP: } " declarations defining some of the "
+{ $links $values $description $error-description $class-description $examples } " sections (see " { $links "element-types" } ")."
+$nl
+"This vocabulary is intended to be used alongside and after " { $vocab-link "help.lint" } ", not as a replacement for it."
+$nl
+"These words are provided to aid in writing more complete documentation:"
+{ $related-subsections
+    <word-help-coverage>
+    <vocab-help-coverage>
+    <prefix-help-coverage>
+}
+
+"Coverage reports:"
+{ $related-subsections
+    word-help-coverage
+    print-coverage
+} ;
+
+{ <word-help-coverage> <vocab-help-coverage> <prefix-help-coverage> word-help-coverage }
+related-words
+
+HELP: word-help-coverage
+{ $class-description "A documentation coverage report for a single word." } ;
+
+HELP: print-coverage
+{ $values { "coverage" word-help-coverage } }
+{ $contract "Displays a coverage object." }
+{ $examples
+    { $example
+        "USING: help.lint.coverage io ;"
+        "\\ <word-help-coverage> <word-help-coverage> print-coverage"
+        "Word '<word-help-coverage>' has 100% help coverage"
+    }
+} ;
+
+HELP: <prefix-help-coverage>
+{ $values { "prefix" string } { "private?" boolean } { "coverage" sequence } }
+{ $description "Runs the help coverage checker on every child vocabulary of the given " { $snippet "prefix" } ", including the base vocabulary. If " { $snippet "private?" } " is " { $snippet "f" } ", the prefix's child " { $snippet ".private" } " vocabularies are not checked. If " { $snippet "private?" } " is " { $snippet "t" } ", " { $emphasis "all" } " child vocabularies are checked." }
+{ $examples
+    { $example
+        "USING: help.lint.coverage prettyprint ;"
+        "\"help.lint.coverage\" f <prefix-help-coverage> ."
+"{
+    {
+        T{ word-help-coverage
+            { word-name <prefix-help-coverage> }
+            { 100%-coverage? t }
+        }
+        T{ word-help-coverage
+            { word-name <vocab-help-coverage> }
+            { 100%-coverage? t }
+        }
+        T{ word-help-coverage
+            { word-name <word-help-coverage> }
+            { 100%-coverage? t }
+        }
+        T{ word-help-coverage
+            { word-name print-coverage }
+            { 100%-coverage? t }
+        }
+        T{ word-help-coverage
+            { word-name word-help-coverage }
+            { 100%-coverage? t }
+        }
+        T{ word-help-coverage
+            { word-name word-help-coverage? }
+            { 100%-coverage? t }
+        }
+    }
+    { }
+}"
+    }
+} ;
+
+HELP: <word-help-coverage>
+{ $values { "word" { $or string word } } { "coverage" word-help-coverage } }
+{ $contract "Looks up a word in the current scope and generates a documentation coverage report for it."}
+{ $examples
+    { $example
+        "USING: help.lint.coverage prettyprint ;"
+        "\\ <word-help-coverage> <word-help-coverage> ."
+"T{ word-help-coverage
+    { word-name <word-help-coverage> }
+    { 100%-coverage? t }
+}"
+    }
+} ;
+
+HELP: <vocab-help-coverage>
+{ $values { "vocab-spec" { $or vocab string } } { "coverage" sequence } }
+{ $description "Runs the help coverage checker on the vocabulary in the given " { $snippet "vocab-spec" } "." }
+{ $examples
+    { $example
+        "USING: help.lint.coverage prettyprint ;"
+        "\"help.lint.coverage\" <vocab-help-coverage> ."
+"{
+    T{ word-help-coverage
+        { word-name <prefix-help-coverage> }
+        { 100%-coverage? t }
+    }
+    T{ word-help-coverage
+        { word-name <vocab-help-coverage> }
+        { 100%-coverage? t }
+    }
+    T{ word-help-coverage
+        { word-name <word-help-coverage> }
+        { 100%-coverage? t }
+    }
+    T{ word-help-coverage
+        { word-name print-coverage }
+        { 100%-coverage? t }
+    }
+    T{ word-help-coverage
+        { word-name word-help-coverage }
+        { 100%-coverage? t }
+    }
+    T{ word-help-coverage
+        { word-name word-help-coverage? }
+        { 100%-coverage? t }
+    }
+}"
+    }
+} ;
diff --git a/extra/help/lint/coverage/coverage-tests.factor b/extra/help/lint/coverage/coverage-tests.factor
new file mode 100644 (file)
index 0000000..b0faa88
--- /dev/null
@@ -0,0 +1,36 @@
+USING: help.lint.coverage help.lint.coverage.private help.markup
+help.syntax kernel math.matrices sorting tools.test vocabs ;
+IN: help.lint.coverage.tests
+
+<PRIVATE
+: empty ( a v -- x y ) ;
+: nonexistent ( a v -- x y ) ;
+: defined ( x -- x ) ;
+
+HELP: empty { $examples } ;
+HELP: nonexistent ;
+HELP: defined { $examples { $example "USING: x ;" "blah" "hahaha" } } ;
+PRIVATE>
+
+{ t } [ \ empty empty-examples? ] unit-test
+{ f } [ \ nonexistent empty-examples? ] unit-test
+{ f } [ \ defined empty-examples? ] unit-test
+{ f } [ \ keep empty-examples? ] unit-test
+
+{ { $description $values } } [ \ empty missing-sections natural-sort ] unit-test
+{ { $description $values } } [ \ defined missing-sections natural-sort ] unit-test
+{ { } } [ \ keep missing-sections ] unit-test
+
+{ { "a.b" "a.b.c" } } [ { "a.b" "a.b.private" "a.b.c.private" "a.b.c" } filter-private ] unit-test
+
+{ "sections" } [ 0 "section" ?pluralize ] unit-test
+{ "section" } [ 1 "section" ?pluralize ] unit-test
+{ "sections" } [ 10 "section" ?pluralize ] unit-test
+
+{ { $examples } } [ \ empty word-defines-sections ] unit-test
+{ { $examples } } [ \ defined word-defines-sections ] unit-test
+{ { } } [ \ nonexistent word-defines-sections ] unit-test
+{ { $values $description $examples } } [ \ keep word-defines-sections ] unit-test
+{ { $values $contract $examples } } [ \ <word-help-coverage> word-defines-sections ] unit-test
+
+{ eye } [ "eye" loaded-vocab-names resolve-name-in ] unit-test
diff --git a/extra/help/lint/coverage/coverage.factor b/extra/help/lint/coverage/coverage.factor
new file mode 100644 (file)
index 0000000..25a6383
--- /dev/null
@@ -0,0 +1,115 @@
+USING: accessors arrays classes classes.error combinators
+combinators.short-circuit continuations english eval formatting
+fry generic help help.lint help.lint.checks help.markup io
+kernel math namespaces parser prettyprint sequences sets sorting
+splitting strings summary vocabs words ;
+FROM: namespaces => set ;
+IN: help.lint.coverage
+
+TUPLE: word-help-coverage
+    { word-name word initial: POSTPONE: f }
+    { omitted-sections sequence initial: { } }
+    { empty-examples? boolean initial: f }
+    { 100%-coverage? boolean initial: f } ;
+
+<PRIVATE
+! <<
+CONSTANT: ignored-words {
+    $low-level-note
+    $prettyprinting-note
+    $values-x/y
+    $parsing-note
+    $io-error
+    $shuffle
+    $complex-shuffle
+    $nl
+}
+! >>
+
+DEFER: ?pluralize
+
+M: word-help-coverage summary
+    [ word-name>> [ vocabulary>> ] [ name>> ] bi "[%s] %s: " sprintf ] keep
+    dup 100%-coverage?>>
+    [ drop "full help coverage" append ]
+    [
+        [ empty-examples?>> "defined empty { $examples }, " "" ? ]
+        [ omitted-sections>> dup [
+                length "section" ?pluralize
+            ] dip
+            [ name>> ] map ", " join
+        ] bi
+        "%sshould define help %s %s" sprintf append
+    ] if ; inline
+
+: sorted-loaded-child-vocabs ( prefix -- assoc )
+    loaded-child-vocab-names natural-sort ; inline
+
+: resolve-name-in ( name namespaces -- word )
+    "syntax" swap remove " " join
+    "USING: " " ; \\ " surround
+    prepend eval( -- word ) ;
+
+: filter-private ( seq -- no-private )
+    [ ".private" ?tail nip not ] filter ; inline
+
+: ?pluralize ( n singular -- singular/plural )
+    count-of-things " " split1 nip ;
+
+: should-define ( word -- spec )
+    {
+        { [ dup predicate? ]    [ drop { } ] } ! predicate?s have generated docs
+        { [ dup error-class? ]  [ drop { $values $description $error-description } ] }
+        { [ dup class? ]        [ drop { $class-description } ] }
+        { [ dup generic? ]      [ drop { $values $contract $examples } ] }
+        { [ dup word? ]         [ drop { $values $description $examples } ] }
+        [ drop no-cond ]
+    } cond ;
+
+: word-defines-sections ( word -- seq )
+    word-help [ ignored-words member? not ] filter [ ?first ] map ;
+
+! only words that need examples, need to have them nonempty
+! not defining examples is not the same as an empty { $examples }
+: empty-examples? ( word -- ? )
+    word-help \ $examples swap elements [ f ] [ first rest empty? ] if-empty ;
+
+: missing-sections ( word -- missing )
+    [ should-define ] [ word-defines-sections ] bi diff ;
+PRIVATE>
+
+GENERIC: print-coverage ( coverage-seq -- )
+M: sequence print-coverage
+    [
+        [ print-coverage ] each
+    ] [
+        [ [ 100%-coverage?>> ] count ] [ length ] bi /f
+        100 *
+        "\n%3.1f%% of words have complete documentation\n"
+        printf
+    ] bi ;
+
+M: word-help-coverage print-coverage
+    summary print ;
+
+GENERIC: <word-help-coverage> ( word -- coverage )
+M: word <word-help-coverage>
+    dup
+    [ missing-sections ]
+    [ empty-examples? ] bi
+    2dup 2array { { } f } =
+    word-help-coverage boa ; inline
+
+M: string <word-help-coverage>
+    loaded-vocab-names resolve-name-in <word-help-coverage> ; inline
+
+: <vocab-help-coverage> ( vocab-spec -- coverage )
+    [ auto-use? off vocab-words natural-sort [ <word-help-coverage> ] map ] with-scope ;
+
+: <prefix-help-coverage> ( prefix private? -- coverage )
+    [
+        auto-use? off group-articles vocab-articles set
+        [ sorted-loaded-child-vocabs ] dip not
+        [ filter-private ] when
+        [ <vocab-help-coverage> ] map
+    ] with-scope ;
diff --git a/extra/help/lint/coverage/summary.txt b/extra/help/lint/coverage/summary.txt
new file mode 100644 (file)
index 0000000..7b8e1cf
--- /dev/null
@@ -0,0 +1 @@
+Documentation coverage linter
diff --git a/extra/help/lint/coverage/tags.txt b/extra/help/lint/coverage/tags.txt
new file mode 100644 (file)
index 0000000..ef1aab0
--- /dev/null
@@ -0,0 +1 @@
+tools
diff --git a/extra/help/lint/pedantic/authors.txt b/extra/help/lint/pedantic/authors.txt
deleted file mode 100644 (file)
index 9d4a8e1..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Cat Stevens
diff --git a/extra/help/lint/pedantic/pedantic-docs.factor b/extra/help/lint/pedantic/pedantic-docs.factor
deleted file mode 100644 (file)
index 5db2597..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-USING: help help.lint.pedantic help.lint.pedantic.private help.markup help.syntax kernel
-sequences strings vocabs words ;
-IN: help.lint.pedantic
-
-ABOUT: "help.lint.pedantic"
-
-ARTICLE: "help.lint.pedantic" "Pedantic help coverage"
-"pedant, " { $emphasis "n." } " one who pays more attention to formal rules and book learning than they merit."
-$nl
-"The " { $vocab-link "help.lint.pedantic" } " vocabulary implements a very picky documentation completeness checker -- your very own documentation pedant."
-$nl
-"The pedantic linter requires most words to have documentation defining the "
-{ $links $values $description $error-description $class-description $examples } " sections (see " { $links "element-types" } ")."
-$nl
-"This vocabulary is intended to be used alongside and after " { $vocab-link "help.lint" } ", not as a replacement for it."
-$nl
-"These words are provided to aid in writing more complete documentation:"
-{ $subsections
-    word-pedant
-    vocab-pedant
-    prefix-pedant
-} ;
-
-{ word-pedant vocab-pedant prefix-pedant } related-words
-{ missing-sections empty-examples } related-words
-
-HELP: missing-sections
-{ $values { "missing-sections" sequence } { "word-name" word } }
-{ $description "Throws an " { $link missing-sections } " error." }
-{ $error-description "Thrown when a word's documentation is missing one or more sections required for it by " { $link should-define } "." } ;
-
-HELP: empty-examples
-{ $values { "word-name" word } }
-{ $description "Throws an " { $link empty-examples } " error." }
-{ $error-description "Thrown when a word's " { $link $examples } " section is missing or empty." } ;
-
-HELP: prefix-pedant
-{ $values { "prefix" string } { "private?" boolean } }
-{ $description "Runs the help coverage checker on every child vocabulary of the given " { $snippet "prefix" } ", including the base vocabulary. If " { $snippet "private?" } " is " { $snippet "f" } ", the prefix's child " { $snippet ".private" } " vocabularies are not checked. If " { $snippet "private?" } " is " { $snippet "t" } ", " { $emphasis "all" } " child vocabularies are checked." }
-{ $errors
-    { $link empty-examples } " if a word has an empty " { $snippet "$examples" } " section
-"
-    { $link missing-sections } " if a word is missing a section entirely"
-}
-{ $examples
-  { $example
-      "USING: help.lint.pedantic ;"
-      "\"help.lint.pedantic\" f prefix-pedant"
-      ""
-  }
-} ;
-
-HELP: word-pedant
-{ $values { "word" { $or string word } } }
-{ $description "Runs the help coverage checker on the word described by " { $snippet "word-desc" } "." }
-{ $errors
-    { $link empty-examples } " if a word has an empty " { $snippet "$examples" } " section
-"
-    { $link missing-sections } " if a word is missing a section entirely"
-}
-{ $examples
-    { $example
-        "USING: help.lint.pedantic ;"
-        "\\ word-pedant word-pedant"
-        ""
-    }
-} ;
-
-HELP: vocab-pedant
-{ $values { "vocab-spec" { $or vocab string } } }
-{ $description "Runs the help coverage checker on the vocabulary in the given " { $snippet "vocab-spec" } "." }
-{ $errors
-    { $link empty-examples } " if a word has an empty " { $snippet "$examples" } " section
-"
-    { $link missing-sections } " if a word is missing a section entirely"
-}
-{ $examples
-    { $example
-      "USING: help.lint.pedantic ;"
-      "\"help.lint.pedantic\" vocab-pedant"
-      ""
-    }
-} ;
diff --git a/extra/help/lint/pedantic/pedantic.factor b/extra/help/lint/pedantic/pedantic.factor
deleted file mode 100644 (file)
index 14056e5..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-USING: accessors arrays classes combinators
-combinators.short-circuit continuations english eval formatting
-fry help help.lint help.lint.checks help.markup kernel
-namespaces parser prettyprint sequences sets sorting splitting
-strings summary vocabs words ;
-FROM: namespaces => set ;
-IN: help.lint.pedantic
-
-ERROR: missing-sections
-    { word-name word initial: POSTPONE: f }
-    { missing-sections sequence initial: { } } ;
-ERROR: empty-examples { word-name initial: POSTPONE: f } ;
-
-<PRIVATE
-DEFER: ?pluralize
-
-M: empty-examples summary
-    word-name>> "Word '%s' has defined empty $examples section" sprintf ;
-
-M: missing-sections summary
-    [ word-name>> ] [
-        missing-sections>> dup [
-            length "section" ?pluralize
-        ] dip
-        [ name>> ] map ", " join
-    ] bi
-    "Word '%s' should define help %s: %s" sprintf ;
-
-: sorted-loaded-child-vocabs ( prefix -- assoc )
-    loaded-child-vocab-names natural-sort ; inline
-
-: filter-private ( seq -- no-private )
-    [ ".private" ?tail nip not ] filter ; inline
-
-: ?pluralize ( n singular -- singular/plural )
-    count-of-things " " split1 nip ;
-
-: should-define ( word -- spec )
-    {
-        { [ dup predicate? ] [ drop { } ] } ! predicate?s have generated docs
-        { [ dup error? ] [ drop { $values $description $error-description } ] }
-        { [ dup class? ] [ drop { $class-description } ] }
-        { [ dup word? ]  [ drop { $values $description $examples } ] }
-        [ drop no-cond ]
-    } cond ;
-
-: word-defines-sections ( word -- seq )
-    word-help [ first ] map ;
-
-: missing-examples? ( word -- ? )
-    word-help \ $examples swap elements empty? ;
-
-: check-examples ( word -- )
-    [ missing-examples? ] keep '[ _ empty-examples ] when ;
-
-: check-sections ( word -- )
-    [ ] [ should-define ] [ word-defines-sections ] tri
-    diff [ drop ] [ missing-sections ] if-empty ;
-PRIVATE>
-
-GENERIC: word-pedant ( word -- )
-M: word word-pedant
-    {
-        { [ dup predicate? ] [ drop ] }
-        { [ dup error? ] [ check-sections ] }
-        { [ dup word? ] [ [ check-sections ] [ check-examples ] bi ] }
-        [ drop no-cond ]
-    } cond ; inline
-
-M: string word-pedant
-    "\\ " prepend eval( -- word ) word-pedant ; inline
-
-: vocab-pedant ( vocab-spec -- )
-    [ auto-use? off vocab-words natural-sort [ word-pedant ] each ] with-scope ;
-
-: prefix-pedant ( prefix private? -- )
-    [
-        auto-use? off group-articles vocab-articles set
-        [ sorted-loaded-child-vocabs ] dip not
-        [ filter-private ] when
-        [ vocab-pedant ] each
-    ] with-scope ;
diff --git a/extra/help/lint/pedantic/summary.txt b/extra/help/lint/pedantic/summary.txt
deleted file mode 100644 (file)
index c42033c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Pedantic help coverage checker
diff --git a/extra/help/lint/pedantic/tags.txt b/extra/help/lint/pedantic/tags.txt
deleted file mode 100644 (file)
index ef1aab0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-tools