Start JSDoc type linting (#6770)

Co-Authored-By: Christopher J. Brody <chris@brody.consulting>
Co-Authored-By: Christopher Quadflieg <christopher.quadflieg@adsoul.com>
Co-Authored-By: Georgii Dolzhykov <thorn.mailbox@gmail.com>
master
Chris Brody 2019-11-02 04:44:27 -04:00 committed by Simon Lydell
parent cf32f29d41
commit e50ad942b7
5 changed files with 129 additions and 1 deletions

View File

@ -3,6 +3,8 @@ steps:
- template: ../steps/install-dependencies.yml
- script: yarn check-deps
displayName: "Check dependencies"
- script: yarn check-types
displayName: "Check JSDoc types"
- script: yarn lint
displayName: "Lint code"
- script: yarn lint-docs

View File

@ -122,6 +122,7 @@
"perf-repeat": "yarn && yarn build && cross-env NODE_ENV=production node ./dist/bin-prettier.js --debug-repeat ${PERF_REPEAT:-1000} --loglevel debug ${PERF_FILE:-./index.js} > /dev/null",
"perf-repeat-inspect": "yarn && yarn build && cross-env NODE_ENV=production node --inspect-brk ./dist/bin-prettier.js --debug-repeat ${PERF_REPEAT:-1000} --loglevel debug ${PERF_FILE:-./index.js} > /dev/null",
"perf-benchmark": "yarn && yarn build && cross-env NODE_ENV=production node ./dist/bin-prettier.js --debug-benchmark --loglevel debug ${PERF_FILE:-./index.js} > /dev/null",
"check-types": "tsc",
"lint": "cross-env EFF_NO_LINK_RULES=true eslint . --format friendly",
"lint-docs": "prettylint {.,docs,website,website/blog}/*.md",
"lint-dist": "eslint --no-eslintrc --no-ignore --env=browser \"dist/!(bin-prettier|index|third-party).js\"",

View File

@ -1,5 +1,19 @@
"use strict";
/**
* TBD properly tagged union for Doc object type is needed here.
*
* @typedef {object} DocObject
* @property {string} type
* @property {boolean} [hard]
* @property {boolean} [literal]
*
* @typedef {string | DocObject} Doc
*/
/**
* @param {Doc} val
*/
function assertDoc(val) {
/* istanbul ignore if */
if (
@ -11,6 +25,10 @@ function assertDoc(val) {
}
}
/**
* @param {Doc[]} parts
* @returns Doc
*/
function concat(parts) {
if (process.env.NODE_ENV !== "production") {
parts.forEach(assertDoc);
@ -25,6 +43,10 @@ function concat(parts) {
return { type: "concat", parts };
}
/**
* @param {Doc} contents
* @returns Doc
*/
function indent(contents) {
if (process.env.NODE_ENV !== "production") {
assertDoc(contents);
@ -33,6 +55,11 @@ function indent(contents) {
return { type: "indent", contents };
}
/**
* @param {number} n
* @param {Doc} contents
* @returns Doc
*/
function align(n, contents) {
if (process.env.NODE_ENV !== "production") {
assertDoc(contents);
@ -41,6 +68,11 @@ function align(n, contents) {
return { type: "align", contents, n };
}
/**
* @param {Doc} contents
* @param {object} [opts] - TBD ???
* @returns Doc
*/
function group(contents, opts) {
opts = opts || {};
@ -57,18 +89,36 @@ function group(contents, opts) {
};
}
/**
* @param {Doc} contents
* @returns Doc
*/
function dedentToRoot(contents) {
return align(-Infinity, contents);
}
/**
* @param {Doc} contents
* @returns Doc
*/
function markAsRoot(contents) {
// @ts-ignore - TBD ???:
return align({ type: "root" }, contents);
}
/**
* @param {Doc} contents
* @returns Doc
*/
function dedent(contents) {
return align(-1, contents);
}
/**
* @param {Doc[]} states
* @param {object} [opts] - TBD ???
* @returns Doc
*/
function conditionalGroup(states, opts) {
return group(
states[0],
@ -76,6 +126,10 @@ function conditionalGroup(states, opts) {
);
}
/**
* @param {Doc[]} parts
* @returns Doc
*/
function fill(parts) {
if (process.env.NODE_ENV !== "production") {
parts.forEach(assertDoc);
@ -84,6 +138,12 @@ function fill(parts) {
return { type: "fill", parts };
}
/**
* @param {Doc} [breakContents]
* @param {Doc} [flatContents]
* @param {object} [opts] - TBD ???
* @returns Doc
*/
function ifBreak(breakContents, flatContents, opts) {
opts = opts || {};
@ -104,6 +164,10 @@ function ifBreak(breakContents, flatContents, opts) {
};
}
/**
* @param {Doc} contents
* @returns Doc
*/
function lineSuffix(contents) {
if (process.env.NODE_ENV !== "production") {
assertDoc(contents);
@ -123,6 +187,11 @@ const literalline = concat([
]);
const cursor = { type: "cursor", placeholder: Symbol("cursor") };
/**
* @param {Doc} sep
* @param {Doc[]} arr
* @returns Doc
*/
function join(sep, arr) {
const res = [];
@ -137,6 +206,11 @@ function join(sep, arr) {
return concat(res);
}
/**
* @param {Doc} doc
* @param {number} size
* @param {number} tabWidth
*/
function addAlignmentToDoc(doc, size, tabWidth) {
let aligned = doc;
if (size > 0) {

View File

@ -4,7 +4,7 @@ const { getStringWidth } = require("../common/util");
const { convertEndOfLineToChars } = require("../common/end-of-line");
const { concat, fill, cursor } = require("./doc-builders");
/** @type {{[groupId: PropertyKey]: MODE}} */
/** @type {Record<symbol, typeof MODE_BREAK | typeof MODE_FLAT>} */
let groupModeMap;
const MODE_BREAK = 1;

51
tsconfig.json Normal file
View File

@ -0,0 +1,51 @@
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"noEmit": true,
"target": "es5",
"module": "commonjs",
"resolveJsonModule": true,
// TBD it is desired to enabled strict type checking at some point:
"strict": false
},
"exclude": [
// [TBD] JavaScript sources *not* affected by src/language-*:
"src/main/ast-to-doc.js",
"src/main/core.js",
"src/common/create-ignorer.js",
"src/common/parser-create-error.js",
"src/config/resolve-config.js",
"src/main/options-normalizer.js",
"src/common/get-file-info.js",
"src/main/multiparser.js",
"src/main/options.js",
// [TBD] src/language-* source directory trees with known JSDoc type issues:
"src/language-css",
"src/language-graphql",
"src/language-handlebars",
"src/language-html",
"src/language-js",
"src/language-markdown",
"src/language-yaml",
// [TBD] JavaScript sources affected by JSDoc issues in src/language-*:
"src/common/internal-plugins.js",
"src/common/load-plugins.js",
"src/cli/index.js",
"src/cli/util.js",
// [TBD] top-level JavaScript sources affected by JSDoc issues
// in other sources:
"src/index.js",
"src/standalone.js",
"index.js",
"standalone.js",
"bin/",
"dist/",
"docs/",
"scripts/",
"tests/",
"tests_config/",
"tests_integration/",
"website/"
]
}