Skip to content

Commit

Permalink
Update docs for v5.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Noah Chen committed Mar 31, 2017
1 parent 31c757f commit c9a42e9
Show file tree
Hide file tree
Showing 34 changed files with 354 additions and 152 deletions.
2 changes: 1 addition & 1 deletion _data/develop_sidebar.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
},
{
"title": "Custom Rules - Migrating to AbstractWalker",
"url": "/custom-rules/performance/migration.html"
"url": "/custom-rules/migration.html"
},
{
"title": "Custom Formatters",
Expand Down
15 changes: 11 additions & 4 deletions _data/formatters.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
{
"formatterName": "json",
"description": "Formats errors as simple JSON.",
"sample": "\n[\n {\n \"endPosition\": {\n \"character\": 13,\n \"line\": 0,\n \"position\": 13\n },\n \"failure\": \"Missing semicolon\",\n \"fix\": {\n \"innerRuleName\": \"semicolon\",\n \"innerReplacements\": [\n {\n \"innerStart\": 13,\n \"innerLength\": 0,\n \"innerText\": \";\"\n }\n ]\n },\n \"name\": \"myFile.ts\",\n \"ruleName\": \"semicolon\",\n \"startPosition\": {\n \"character\": 13,\n \"line\": 0,\n \"position\": 13\n }\n }\n]",
"sample": "\n[\n {\n \"endPosition\": {\n \"character\": 13,\n \"line\": 0,\n \"position\": 13\n },\n \"failure\": \"Missing semicolon\",\n \"fix\": {\n \"innerStart\": 13,\n \"innerLength\": 0,\n \"innerText\": \";\"\n },\n \"name\": \"myFile.ts\",\n \"ruleName\": \"semicolon\",\n \"startPosition\": {\n \"character\": 13,\n \"line\": 0,\n \"position\": 13\n }\n }\n]",
"consumer": "machine"
},
{
Expand All @@ -36,13 +36,13 @@
"formatterName": "pmd",
"description": "Formats errors as through they were PMD output.",
"descriptionDetails": "Imitates the XML output from PMD. All errors have a priority of 1.",
"sample": "\n<pmd version=\"tslint\">\n <file name=\"myFile.ts\">\n <violation begincolumn=\"14\" beginline=\"1\" priority=\"1\" rule=\"Missing semicolon\"></violation>\n </file>\n</pmd>",
"sample": "\n<pmd version=\"tslint\">\n <file name=\"myFile.ts\">\n <violation begincolumn=\"14\" beginline=\"1\" priority=\"3\" rule=\"Missing semicolon\"></violation>\n </file>\n</pmd>",
"consumer": "machine"
},
{
"formatterName": "prose",
"description": "The default formatter which outputs simple human-readable messages.",
"sample": "myFile.ts[1, 14]: Missing semicolon",
"sample": "ERROR: myFile.ts[1, 14]: Missing semicolon",
"consumer": "human"
},
{
Expand All @@ -52,11 +52,18 @@
"sample": "\nmyFile.ts\n1:14 semicolon Missing semicolon",
"consumer": "human"
},
{
"formatterName": "tap",
"description": "Formats output as TAP stream.",
"descriptionDetails": "Provides error messages output in TAP13 format which can be consumed by any TAP formatter.",
"sample": "\nTAP version 13\n1..1\nnot ok 1 - Some error\n ---\n message: Variable has any type\n severity: error\n data:\n ruleName: no-any\n fileName: test-file.ts\n line: 10\n character: 10\n failureString: Some error\n rawLines: Some raw output\n ...",
"consumer": "machine"
},
{
"formatterName": "verbose",
"description": "The human-readable formatter which includes the rule name in messages.",
"descriptionDetails": "The output is the same as the prose formatter with the rule name included",
"sample": "(semicolon) myFile.ts[1, 14]: Missing semicolon",
"sample": "ERROR: (semicolon) myFile.ts[1, 14]: Missing semicolon",
"consumer": "human"
},
{
Expand Down
136 changes: 99 additions & 37 deletions _data/rules.json

Large diffs are not rendered by default.

19 changes: 6 additions & 13 deletions develop/custom-rules/performance.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
## Performance tips

### Don't call the LanguageService repeatedly
The LanguageService is designed to serve editors. By design it does as little work to serve requests as possible.
For most requests no cache is used.

Let's say you need all usages of a variable. The LanguageService needs to check the whole AST subtree in which the variable is in scope.
Doing that once is barely noticable. But doing it over and over again, will result in pretty bad performance (looking at you `no-unused-variable`).

### Use the TypeChecker only when needed
The TypeChecker is a really mighty tool, but that comes with a cost. To create a TypeChecker the Program first has to locate, read, parse and bind all SourceFiles referenced.
To avoid that cost, try to avoid the TypeChecker where possible.
Expand All @@ -21,7 +14,7 @@ Some rules work directly on the content of the source file.
`max-file-line-count` and `linebreak-style` don't need to walk the AST at all.

Other rules define exceptions: `no-consecutive-blank-lines` ignores template strings.
To optimize for the best case, this rule can first look for failures in the source.
To optimize for the best case, this rule can first look for failures in the source.
If and only if there are any failures, walk the AST to find the location of all template strings to filter the failures.

### Implement your own walking algorithm
Expand All @@ -46,7 +39,7 @@ class MyWalker extends Lint.AbstractWalker<MyOptionsType> {
### Don't walk the whole AST if possible
__The Spec is your friend:__
The language spec defines where each statement can occur. If you are interested in `import` statements for example, you only need to search
The language spec defines where each statement can occur. If you are interested in `import` statements for example, you only need to search
in `sourceFile.statements` and nested `NamespaceDeclaration`s.
__Don't visit AST branches you're not interested in:__
Expand Down Expand Up @@ -76,12 +69,12 @@ Instead of stuffing the whole logic in a single closure, consider splitting it u
Each function should handle similar kinds of nodes. Don't worry too much about the function call, since V8 eventually inlines the function
if possible.
The AST nodes have different properties, therefore they have a different hidden class in V8. A function can only be optimized for a certain
The AST nodes have different properties, therefore they have a different hidden class in V8. A function can only be optimized for a certain
amount of different hidden classes. Above that threshold the function will be deoptimized and is never optimized again.
### Pass the optional `sourceFile` parameter
There are serveral methods that have an optional parameter `sourceFile`. Don't omit this parameter if you care for performance.
If ommitted, typescript needs to walk up the node's parent chain until it reaches the SourceFile. This *can* be quite costly when done
If ommitted, typescript needs to walk up the node's parent chain until it reaches the SourceFile. This *can* be quite costly when done
frequently on deeply nested nodes.
Some examples:
Expand All @@ -106,15 +99,15 @@ declare node: ts.Identifier;
node.getText() === node.text; // prefer node.text where available
```
__Bonus points:__ If you know the width of the node (either from the `text` property or because it is a keyword of known width),
__Bonus points:__ If you know the width of the node (either from the `text` property or because it is a keyword of known width),
you can use `node.getEnd() - width` to calculate the node's start.
`node.getEnd()` is effectively for free as it only returns the `end` property. This way you avoid the cost of skipping leading trivia.
### Make use of tail calls
Tail calls are function or method calls at the end of the control flow of a function. It's only a tail call if the return value of that call
is directly returned unchanged. Browsers can optimize this pattern for performance.
Further optimization is specced in ES2015 as "Proper Tail Calls".
With proper tail calls the browser reuses the stack frame of the current function. When done right this allows for infinite recursion.
With proper tail calls the browser reuses the stack frame of the current function. When done right this allows for infinite recursion.
```ts
function foo() {
if (condition)
Expand Down
14 changes: 14 additions & 0 deletions develop/testing-rules/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,20 @@ Then, at the bottom of our test file, we specify what full message each shortcut

Again, we can run `grunt test` to make sure our rule is producing the output we expect. If it isn't we'll see the difference between the output from the rule and the output we marked.

##### Typescript version requirement #####

Sometimes a rule requires a minimum version of the typescript compiler or your test contains syntax that older versions of the typescript parser cannot handle.
When testing with multiple versions of typescript - like `tslint` does in CI - those tests will fail.

To avoid failing tests, each test file can specify a version requirement for typescript **in the first line**. If you don't specify one, the test will always be executed.

Example:
```
[typescript]: >= 2.1.0
```

The syntax should look familiar, because it is basically the shorthand syntax from the chapter above. It needs to start with `[typescript]:`.
The following part can be any [version range](https://github.com/npm/node-semver#ranges). The prerelease suffix will be removed before matching to allow testing with nightly builds.

### Tips & Tricks ###

Expand Down
11 changes: 3 additions & 8 deletions formatters/json/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,9 @@
},
"failure": "Missing semicolon",
"fix": {
"innerRuleName": "semicolon",
"innerReplacements": [
{
"innerStart": 13,
"innerLength": 0,
"innerText": ";"
}
]
"innerStart": 13,
"innerLength": 0,
"innerText": ";"
},
"name": "myFile.ts",
"ruleName": "semicolon",
Expand Down
2 changes: 1 addition & 1 deletion formatters/pmd/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<pmd version="tslint">
<file name="myFile.ts">
<violation begincolumn="14" beginline="1" priority="1" rule="Missing semicolon"></violation>
<violation begincolumn="14" beginline="1" priority="3" rule="Missing semicolon"></violation>
</file>
</pmd>
consumer: machine
Expand Down
2 changes: 1 addition & 1 deletion formatters/prose/index.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
formatterName: prose
description: The default formatter which outputs simple human-readable messages.
sample: 'myFile.ts[1, 14]: Missing semicolon'
sample: 'ERROR: myFile.ts[1, 14]: Missing semicolon'
consumer: human
layout: formatter
title: 'Formatter: prose'
Expand Down
24 changes: 24 additions & 0 deletions formatters/tap/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
formatterName: tap
description: Formats output as TAP stream.
descriptionDetails: Provides error messages output in TAP13 format which can be consumed by any TAP formatter.
sample: |-

TAP version 13
1..1
not ok 1 - Some error
---
message: Variable has any type
severity: error
data:
ruleName: no-any
fileName: test-file.ts
line: 10
character: 10
failureString: Some error
rawLines: Some raw output
...
consumer: machine
layout: formatter
title: 'Formatter: tap'
---
2 changes: 1 addition & 1 deletion formatters/verbose/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
formatterName: verbose
description: The human-readable formatter which includes the rule name in messages.
descriptionDetails: The output is the same as the prose formatter with the rule name included
sample: '(semicolon) myFile.ts[1, 14]: Missing semicolon'
sample: 'ERROR: (semicolon) myFile.ts[1, 14]: Missing semicolon'
consumer: human
layout: formatter
title: 'Formatter: verbose'
Expand Down
2 changes: 1 addition & 1 deletion rules/comment-format/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
Exceptions to `"check-lowercase"` or `"check-uppercase"` can be managed with object that may be passed as last argument.

One of two options can be provided in this object:

* `"ignore-words"` - array of strings - words that will be ignored at the beginning of the comment.
* `"ignore-pattern"` - string - RegExp pattern that will be ignored at the beginning of the comment.
options:
Expand Down
6 changes: 3 additions & 3 deletions rules/completed-docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

* `string` to enable for that type
* `object` keying types to when their documentation is required:
* `"methods"` and `"properties may specify:
* `"privacies":
* `"methods"` and `"properties"` may specify:
* `"privacies"`:
* `"all"`
* `"private"`
* `"protected"`
* `"public"`
* `"locations:
* `"locations"`:
* `"all"`
* `"instance"`
* `"static"`
Expand Down
27 changes: 24 additions & 3 deletions rules/curly/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,34 @@
In the code above, the author almost certainly meant for both `foo++` and `bar++`
to be executed only if `foo === bar`. However, he forgot braces and `bar++` will be executed
no matter what. This rule could prevent such a mistake.
optionsDescription: Not configurable.
options: null
optionsDescription: |-

The rule may be set to `true`, or to the following:

* `"ignore-same-line"` skips checking braces for control-flow statements
that are on one line and start on the same line as their control-flow keyword

options:
type: array
items:
type: string
enum:
- ignore-same-line
optionExamples:
- 'true'
- '[true, "ignore-same-line"]'
type: functionality
typescriptOnly: false
layout: rule
title: 'Rule: curly'
optionsJSON: 'null'
optionsJSON: |-
{
"type": "array",
"items": {
"type": "string",
"enum": [
"ignore-same-line"
]
}
}
---
1 change: 1 addition & 0 deletions rules/eofline/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
options: null
optionExamples:
- 'true'
hasFix: true
type: maintainability
typescriptOnly: false
layout: rule
Expand Down
1 change: 1 addition & 0 deletions rules/linebreak-style/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- '[true, "CRLF"]'
type: maintainability
typescriptOnly: false
hasFix: true
layout: rule
title: 'Rule: linebreak-style'
optionsJSON: |-
Expand Down
2 changes: 1 addition & 1 deletion rules/max-file-line-count/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
description: Requires files to remain under a certain number of lines
rationale: |-

Limiting the number of lines allowed in a file allows files to remain small,
Limiting the number of lines allowed in a file allows files to remain small,
single purpose, and maintainable.
optionsDescription: An integer indicating the maximum number of lines.
options:
Expand Down
14 changes: 9 additions & 5 deletions rules/member-access/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,24 @@
rationale: Explicit visibility declarations can make code more readable and accessible for those new to TS.
optionsDescription: |-

Two arguments may be optionally provided:
These arguments may be optionally provided:

* `"check-accessor"` enforces explicit visibility on get/set accessors (can only be public)
* `"check-constructor"` enforces explicit visibility on constructors (can only be public)
* `"no-public"` forbids public accessibility to be specified, because this is the default.
* `"check-accessor"` enforces explicit visibility on get/set accessors
* `"check-constructor"` enforces explicit visibility on constructors
options:
type: array
items:
type: string
enum:
- no-public
- check-accessor
- check-constructor
minLength: 0
maxLength: 2
maxLength: 3
optionExamples:
- 'true'
- '[true, "no-public"]'
- '[true, "check-accessor"]'
type: typescript
typescriptOnly: true
Expand All @@ -30,11 +33,12 @@
"items": {
"type": "string",
"enum": [
"no-public",
"check-accessor",
"check-constructor"
]
},
"minLength": 0,
"maxLength": 2
"maxLength": 3
}
---
2 changes: 1 addition & 1 deletion rules/member-ordering/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
]
}]
type: typescript
typescriptOnly: true
typescriptOnly: false
layout: rule
title: 'Rule: member-ordering'
optionsJSON: |-
Expand Down
11 changes: 11 additions & 0 deletions rules/no-reference-import/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
ruleName: no-reference-import
description: Don't <reference types="foo" /> if you import "foo" anyway.
optionsDescription: Not configurable.
options: null
type: style
typescriptOnly: true
layout: rule
title: 'Rule: no-reference-import'
optionsJSON: 'null'
---
5 changes: 4 additions & 1 deletion rules/no-trailing-whitespace/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

Possible settings are:

* `"ignore-template-strings"`: Allows trailing whitespace in template strings.
* `"ignore-comments"`: Allows trailing whitespace in comments.
* `"ignore-jsdoc"`: Allows trailing whitespace only in JSDoc comments.
hasFix: true
Expand All @@ -16,6 +17,7 @@
enum:
- ignore-comments
- ignore-jsdoc
- ignore-template-strings
optionExamples:
- 'true'
- '[true, "ignore-comments"]'
Expand All @@ -31,7 +33,8 @@
"type": "string",
"enum": [
"ignore-comments",
"ignore-jsdoc"
"ignore-jsdoc",
"ignore-template-strings"
]
}
}
Expand Down
Loading

0 comments on commit c9a42e9

Please sign in to comment.