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 io.streams.string io.styles kernel math namespaces parser prettyprint sequences sequences.deep sets sorting splitting strings summary vocabs vocabs.parser words words.alias ; 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 } ; > dup lookup-vocab 2array "] " 3array over push-all ] [ [ name>> ] keep 2array ": " 2array over push-all ] bi ; inline : (assemble-empty-examples) ( vec coverage -- vec ) empty-examples?>> [ "empty " \ $examples [ name>> ] keep 2array "; " 3array over push-all ] when ; : (assemble-omitted-sections) ( vec coverage -- vec ) omitted-sections>> [ length "section" ?pluralize ": " append ] [ [ [ name>> ] keep 2array ] map "and" comma-list ] bi [ "needs help " ] 2dip 3array over push-all ; : (assemble-full-coverage) ( vec coverage -- vec ) drop "full help coverage" over push ; : (present-coverage) ( coverage-report -- ) [ V{ } clone ] dip [ word-name>> (assemble-word-metadata) ] keep dup 100%-coverage?>> [ (assemble-full-coverage) ] [ [ (assemble-empty-examples) ] [ (assemble-omitted-sections) ] bi ] if "\n" over push write-object-seq ; M: word-help-coverage summary [ (present-coverage) ] with-string-writer ; inline : find-word ( name -- word/f ) dup words-named dup length { { 0 [ 2drop f ] } { 1 [ first nip ] } [ drop throw-restarts ] } case ; : sorted-loaded-child-vocabs ( prefix -- assoc ) loaded-child-vocab-names natural-sort ; inline : filter-private ( seq -- no-private ) [ ".private" ?tail nip ] reject ; inline : ?remove-$values ( word spec -- spec ) \ $values over member? [ swap "declared-effect" word-prop [ [ in>> ] [ out>> ] bi append [ \ $values swap remove ] [ drop ] if-empty ] when* ] [ nip ] if ; : should-define ( word -- spec ) dup { ! predicates have generated docs { [ dup predicate? ] [ drop { } ] } { [ dup primitive? ] [ drop { $description } ] } ! aliases should describe why they exist but ideally $values should be ! automatically inherited from the aliased word's docs { [ dup alias? ] [ drop { $values $description } ] } { [ 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 } ] } } cond ?remove-$values ; : 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 ; GENERIC: loaded-vocab? ( vocab-spec -- ? ) M: string loaded-vocab? lookup-vocab >boolean ; M: vocab loaded-vocab? source-loaded?>> +done+ = ; PRIVATE> GENERIC: ( word -- coverage ) M: word dup [ missing-sections ] [ empty-examples? ] bi 2dup 2array { { } f } = word-help-coverage boa ; inline M: string find-word ; inline : ( vocab-spec -- coverage ) dup loaded-vocab? [ [ auto-use? off vocab-words natural-sort [ ] map ] with-scope ] [ unloaded-vocab ] if ; : ( prefix private? -- coverage ) over loaded-vocab? [ [ auto-use? off group-articles vocab-articles set [ sorted-loaded-child-vocabs ] dip not [ filter-private ] when [ ] map flatten ] with-scope ] [ drop unloaded-vocab ] if ; GENERIC: help-coverage. ( coverage -- ) M: sequence help-coverage. [ [ help-coverage. ] each ] [ [ [ 100%-coverage?>> ] count ] [ length ] bi /f 100 * "\n%3.1f%% of words have complete documentation\n" printf ] bi ; recursive M: word-help-coverage help-coverage. (present-coverage) ; : word-help-coverage. ( word-spec -- ) help-coverage. ; : vocab-help-coverage. ( vocab-spec -- ) help-coverage. ; : prefix-help-coverage. ( prefix-spec private? -- ) help-coverage. ;