diff --git a/sources/rules/generic-array-type.ts b/sources/rules/generic-array-type.ts new file mode 100644 index 0000000..369c5c6 --- /dev/null +++ b/sources/rules/generic-array-type.ts @@ -0,0 +1,128 @@ +/** + * @fileoverview Array types should always be written in generic syntax to avoid + * any confusion with array assignments, array indexer, or type selectors. + * @author Sophie Bremer + */ + + +'use strict'; + + +/* * + * + * Imports + * + * */ + + +import * as FS from 'fs'; +import * as TS from 'typescript'; +import RuleContext from '../RuleContext'; +import RuleOptions from '../RuleOptions'; +import SourceLine from '../SourceLine'; +import SourceToken from '../SourceToken'; + + +/* * + * + * Declarations + * + * */ + + +type GenericArrayTypeContext = RuleContext; + + +/* * + * + * Constants + * + * */ + + +const message = 'Do not use the [] shortcut for the array type. Instead write the generic Array<...> to improve readability.'; + +const optionsDefaults: RuleOptions = {}; + +const optionsSchema = {}; + +const pattern = /_?[A-Z]\w*\[\]/u; + + +/* * + * + * Functions + * + * */ + + +// function fix( +// context: GenericArrayTypeContext +// ): void { +// FS.writeFileSync( +// context.sourceCode.fileName + '.json', +// JSON.stringify( +// docletASTs, +// void 0, +// ' ' +// ) +// ); +// } + +function lint ( + context: GenericArrayTypeContext +) { + const sourceLines = context.sourceCode.lines; + + for ( + let line = 0, + lineEnd = sourceLines.length, + sourceLine: SourceLine, + sourceLineTokens: Array; + line < lineEnd; + ++line + ) { + sourceLine = sourceLines[line]; + sourceLineTokens = sourceLine.tokens; + + for ( + let index = 0, + indexEnd = sourceLineTokens.length - 2, + firstToken: SourceToken, + secondToken: SourceToken, + thirdToken: SourceToken; + index < indexEnd; + ++index + ) { + firstToken = sourceLineTokens[index]; + secondToken = sourceLineTokens[index+1]; + thirdToken = sourceLineTokens[index+2]; + + if ( + firstToken.kind === TS.SyntaxKind.Identifier && + secondToken.kind === TS.SyntaxKind.OpenBracketToken && + thirdToken.kind === TS.SyntaxKind.CloseBracketToken + ) { + const position = sourceLine.getPosition(context.sourceCode, secondToken); + + if (position) { + context.report(position.line, position.column, message); + } + } + + } + } +} + +/* * + * + * Default Export + * + * */ + +export = RuleContext.setupRuleExport( + 'layout', + optionsSchema, + optionsDefaults, + lint +);