-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
303 additions
and
135 deletions.
There are no files selected for viewing
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
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#lang racket/base | ||
|
||
(provide document-syntax-parameter | ||
kind-tech | ||
kind-tech-definition | ||
phase-order-tech | ||
phase-order-tech-definition | ||
source-code-link | ||
warn-examples | ||
warn-tech | ||
warn-tech-definition) | ||
|
||
(require scribble/base | ||
scribble/example | ||
scribble/manual | ||
scribble/text | ||
syntax/parse/define) | ||
|
||
|
||
(define-simple-macro | ||
(define-techs [key:str use-id:id def-id:id] ...) | ||
(begin | ||
(begin | ||
(define (def-id . pre-flow) | ||
(apply deftech #:key key pre-flow)) | ||
(define (use-id . pre-flow) | ||
(apply tech #:key key #:doc warn-doc pre-flow))) | ||
...)) | ||
|
||
(define warn-doc | ||
'(lib "syntax/warn/main.scrbl")) | ||
|
||
(define-techs | ||
["syntax warning" warn-tech warn-tech-definition] | ||
["warning kind" kind-tech kind-tech-definition] | ||
["phase order" phase-order-tech phase-order-tech-definition]) | ||
|
||
(define (source-code-link url-str) | ||
(begin/text "Source code for this library is avaible at " | ||
(url url-str))) | ||
|
||
(define warn-requires | ||
'(syntax/warn)) | ||
|
||
(define (make-warn-eval) | ||
(make-base-eval #:lang 'racket/base | ||
(cons 'require warn-requires))) | ||
|
||
(define (make-warn-lang-eval) | ||
(make-base-eval #:lang 'racket/base/warn)) | ||
|
||
(define-syntax-rule (warn-examples example ...) | ||
(examples #:eval (make-warn-eval) example ...)) | ||
|
||
(define-syntax-rule (document-syntax-parameter id pre-flow ...) | ||
(defform #:kind "syntax parameter" #:id id id pre-flow ...)) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
#lang scribble/manual | ||
|
||
@(require "base.rkt") | ||
|
||
@title[#:tag "syntax-warn-cli"]{The Syntax Warning Command Line Interface} | ||
|
||
This document describes the @exec{raco warn} and @exec{raco fix} | ||
commands. This commands allow a programmer to check for | ||
@warn-tech{syntax warnings} and, where possible, automatically fix | ||
them. The two commands are designed to work together - when | ||
@exec{raco warn} outputs no warnings, @exec{raco fix} makes no | ||
changes to any modules. Additionally, both commands accept the same | ||
flags for specifying which modules to check. | ||
|
||
@section{@exec{raco warn}: Checking Syntax Warnings} | ||
|
||
The @exec{raco warn} command searches for @warn-tech{syntax warnings} | ||
in a specified set of modules. Any found warnings are displayed with | ||
a message, the offending source code, and a suggested fix (if present). | ||
If any warnings are found the command exits as a failure, making it | ||
suitable for use in continuous integration systems. | ||
|
||
The @exec{raco warn} command accepts any number of arguments along with | ||
the following flags: | ||
|
||
@itemize[ | ||
@item{@DFlag{arg-kind} --- Sets how to interpret the given arguments. | ||
Defaults to "file". Valid interpretation modes are: | ||
@itemize[@item{file: Each argument is interpreted as a relative | ||
or absolute file path to a module.} | ||
@item{directory: Each argument is interpreted as a | ||
relative or absolute directory path, which is | ||
recursively scanned for modules. All files in | ||
the given directories are assumed to be modules.} | ||
@item{collection: Each argument is interpreted as a | ||
collection, whose modules are checked recursively.} | ||
@item{package: Each argument is interpreted as a | ||
package, whose modules are checked recursively.}]} | ||
@item{@Flag{f} or @DFlag{file} --- Shorthand for @exec{--arg-kind file}.} | ||
@item{@Flag{d} or @DFlag{directory} --- Shorthand for @exec{--arg-kind | ||
directory}.} | ||
@item{@Flag{c} or @DFlag{collection} --- Shorthand for @exec{--arg-kind | ||
collection}.} | ||
@item{@Flag{p} or @DFlag{package} --- Shorthand for @exec{--arg-kind | ||
package}.}] | ||
|
||
@section{@exec{raco fix}: Fixing Syntax Warnings} | ||
|
||
The @exec{raco fix} command searches for @warn-tech{syntax warnings} | ||
in a specified set of modules and fixes them, if possible. For each | ||
module checked, the set of warnings is filtered to only warnings with | ||
suggested fixes that won't interfere with each other. For instance, if | ||
two warnings suggest changing the same piece of code, @exec{raco fix} | ||
will either fix one of the warnings if its affected source code fully | ||
encompasses the other warning's source code, or fix neither warning if | ||
they only partially overlap. The @exec{raco fix} command also accepts | ||
a @italic{run mode} argument that can configure how @exec{raco fix} | ||
applies changes, if at all. | ||
|
||
The @exec{raco fix} command accepts any number of arguments along with | ||
the following flags: | ||
|
||
@itemize[ | ||
@item{@DFlag{arg-kind} --- Sets how to interpret the given arguments. | ||
This flag accepts the same values and has the same default as it does | ||
for @exec{raco warn}. Additionally, the same shorthand flags for the | ||
various values are accepted.} | ||
@item{@Flag{D} or @DFlag{dry-run} --- Sets the run mode to @italic{ | ||
dry run}. In a dry run, @exec{raco fix} performs no file writes and | ||
merely outputs what it would fix in which modules.}] |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#lang scribble/manual | ||
|
||
@(require "base.rkt") | ||
|
||
@title[#:tag "syntax-warn-lang"]{The Syntax Warnings Language} | ||
@defmodule[racket/base/warn #:packages ("syntax-warn" "syntax-warn-lang")] | ||
|
||
This library provides a variant of the @racketmodname[racket/base] | ||
language that adds @warn-tech{syntax warning} wrappers around various | ||
forms. For example, the @racket[require] binding introduced by this | ||
language enforces a few "good style" practices around require clauses. | ||
|
||
@section{Warnings as a @hash-lang[]} | ||
|
||
When @racketmodname[racket/base/warn] is used as a @hash-lang[] language, | ||
everything from @racketmodname[racket/base] is provided. Various forms | ||
are adjusted to attach @warn-tech{syntax warnings} in certain cases. | ||
These adjustments are documented here. | ||
|
||
@defform[(require require-spec ...)]{ | ||
Like in @racketmodname[racket/base], but warns @racket[require:phase-order] | ||
when the given @racket[require-spec] forms are not in | ||
@phase-order-tech-definition{phase order}. Phase order is @racket[for-syntax] | ||
first, @racket[for-template] second, @racket[for-label] third, | ||
@racket[for-meta] fourth, and all other forms fifth.} | ||
|
||
@section{Warnings as a module} | ||
|
||
When @racketmodname[racket/base/warn] is @racket[require]'d as a module, | ||
it provides warning kinds and functions for adding warnings that @hash-lang[] | ||
@racketmodname[racket/base/warn] uses. These are documented here. | ||
|
||
@defthing[require:phase-order warning-kind?]{ | ||
A @kind-tech{warning kind} for when @racket[require] clauses are not | ||
@phase-order-tech{phase ordered}.} | ||
|
||
@defproc[(syntax-warn/require-phase-order [require-syntax syntax?]) syntax?]{ | ||
Examines @racket[require-syntax], which is expected to be a | ||
@racket[(require clause ...)] syntax object, and returns it with warnings | ||
attached in the same way as @racket[require] does in @hash-lang[] | ||
@racketmodname[racket/base/warn].} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,101 +1,38 @@ | ||
#lang scribble/manual | ||
|
||
@(require scribble/examples (for-label syntax/warn racket/base racket/stxparam racket/contract racket/function)) | ||
@(require "base.rkt") | ||
|
||
@(define (warn-tech . pre-content) | ||
(apply tech #:key "syntax-warning" #:normalize? #f pre-content)) | ||
@(define-syntax-rule (syntax-warn-examples example ...) | ||
(examples #:eval (make-base-eval #:lang 'racket/base '(require syntax/warn)) example ...)) | ||
@(define-syntax-rule (document-syntax-parameter id pre-flow ...) | ||
(defform #:kind "syntax parameter" #:id id id pre-flow ...)) | ||
|
||
@title{Syntax Warnings} | ||
@defmodule[syntax/warn] | ||
@title[#:style '(toc)]{Syntax Warnings} | ||
@author[@author+email["Jack Firth" "jackhfirth@gmail.com"]] | ||
|
||
This library provides forms for working with @warn-tech{syntax warnings}. Library | ||
and language developers can make deprecation notices, optimizations, simplifications, | ||
and style rules visible to users, and users can suppress warnings and warning | ||
categories in both individual code snippets and package-wide configuration. | ||
|
||
@section{Warnings} | ||
|
||
A @deftech[#:key "syntax-warning" #:normalize? #f]{syntax warning} is an expansion | ||
time annotation that draws attention to a potential defect in a program's syntax. | ||
Such defects are not technically incorrect behavior, but signal a likely problem. | ||
Examples include using a deprecated library feature, naming variables in a way | ||
that's considered bad style, using a particular language feature in a way known to | ||
cause subtle bugs, and so on. Syntax warnings are first class values attached to | ||
source code at compile time through syntax properties, and can be inspected by | ||
other code and tools. | ||
|
||
@defproc[(syntax-warning [#:message message string?] | ||
[#:stx stx syntax?] | ||
[#:kind kind warning-kind? anonymous-warning] | ||
[#:fix fix syntax? #f]) | ||
syntax-warning?]{ | ||
Constructs a @warn-tech{syntax warning} of kind @racket[kind] that identifies | ||
@racket[stx] as the syntax to blame and @racket[fix] as a suggested replacement | ||
to use in place of @racket[stx]. If @racket[fix] is not provided, the warning | ||
makes no suggestions about how to resolve it.} | ||
|
||
@defproc[(syntax-warning? [v any/c]) boolean?]{ | ||
Predicate that recognizes @warn-tech{syntax warnings}.} | ||
|
||
@defproc[(syntax-warning/fix? [v any/c]) boolean?]{ | ||
Predicate that recognizes @warn-tech{syntax warnings} that include a suggested | ||
fix.} | ||
|
||
@deftogether[ | ||
(@defproc[(syntax-warning-message [warning syntax-warning?]) string?] | ||
@defproc[(syntax-warning-kind [warning syntax-warning?]) warning-kind?] | ||
@defproc[(syntax-warning-stx [warning syntax-warning?]) syntax?] | ||
@defproc[(syntax-warning-fix [warning syntax-warning?]) (or/c syntax? #f)])]{ | ||
Accessors for fields of @warn-tech{syntax warnings}.} | ||
|
||
@defthing[warning-kind? predicate/c]{ | ||
Predicate recognizing warning kinds.} | ||
} | ||
|
||
@defform[(define-warning-kind id)]{ | ||
Binds @racket[id] as a @racket[warning-kind?] value whose name is the quoted | ||
form of @racket[id]. @warn-tech{Syntax warnings} often have similar sources | ||
and causes, and it can be helpful to group them under a warning kind.} | ||
|
||
@defproc[(warning-kind-name [kind warning-kind?]) symbol?]{ | ||
Returns the name of @racket[kind].} | ||
|
||
@defthing[anonymous-warning warning-kind?]{ | ||
The default warning kind for warnings that don't declare themselves as having | ||
a particular kind.} | ||
|
||
@defproc[(syntax-warn [stx syntax?] [warning syntax-warning?]) syntax?]{ | ||
Returns a syntax object equivalent to @racket[stx], but with @racket[warning] | ||
attached as a @warn-tech{syntax warning}. The syntax warning need not blame | ||
@racket[stx] as the source of the problem, this procedure merely provides the | ||
ability to attach warnings to syntax objects via syntax properties. | ||
@syntax-warn-examples[ | ||
(define-warning-kind identifier-capitalization-warning) | ||
(syntax-warn #'(foo Bar) | ||
(syntax-warning #:message "Don't capitalize the \"Bar\" identifier" | ||
#:kind identifier-capitalization-warning | ||
#:stx #'foo))]} | ||
|
||
@defproc[(syntax-warnings [stx syntax?]) (listof syntax?)]{ | ||
Returns a list of all syntax warnings present in @racket[stx]. This includes | ||
syntax warnings in any syntax objects nested within @racket[stx].} | ||
|
||
@defproc[(read-syntax-warnings [#:input-port in input-port? (current-input-port)] | ||
[#:source-name source any/c (object-name in)] | ||
[#:namespace namespace namespace? (current-namespace)]) | ||
(listof syntax-warning?)]{ | ||
Constructs a syntax object from @racket[in] using @racket[read-syntax], fully | ||
expands it using @racket[expand-syntax] in @racket[namespace], and returns a | ||
list of all syntax warnings found in the fully expanded module.} | ||
|
||
@defproc[(read-syntax-warnings/file [filepath path-string?] | ||
[#:namespace namespace namespace? (current-namespace)]) | ||
(listof syntax-warning?)]{ | ||
Like @racket[read-syntax-warnings], but reads @racket[filepath] as a module. | ||
Sets the @racket[current-directory] to the directory part of @racket[filepath] | ||
and uses @racket[filepath] as the source name.} | ||
This library includes forms and functions for working with | ||
@warn-tech-definition{syntax warnings}. A syntax warning is a | ||
compile-time source code annotation meant to draw attention to | ||
potential defects. Syntax warnings can be used to point out bad | ||
code style, sub-optimal constructs, excessively verbose code, or | ||
use of deprecated features. Additionally included in this library | ||
are the @exec{raco warn} and @exec{raco fix} commands for finding | ||
and fixing warnings, and the @hash-lang[] @racketmodname[racket/base/warn] | ||
language which provides many forms in @racketmodname[racket/base] | ||
with warnings attached in various ways. | ||
|
||
@source-code-link{https://github.com/jackfirth/syntax-warn} | ||
|
||
This library is provided as several packages. These packages are | ||
organized as follows: | ||
|
||
@itemize[ | ||
@item{@code{syntax-warn-base} --- The core API of syntax warnings, | ||
as defined by the @racketmodname[syntax/warn] module.} | ||
@item{@code{syntax-warn-cli} --- The @exec{raco} command line tools | ||
for working with warnings.} | ||
@item{@code{syntax-warn-lang} --- The @racketmodname[racket/base/warn] | ||
language.} | ||
@item{@code{syntax-warn-doc} --- The documentation part of the library.} | ||
@item{@code{syntax-warn} --- A wrapper package that implies installation | ||
of all of the above packages.}] | ||
|
||
@table-of-contents[] | ||
@include-section["reference.scrbl"] | ||
@include-section["cli.scrbl"] | ||
@include-section["lang.scrbl"] |
Oops, something went wrong.