Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add usePipeDecoratorRule, refactored linting erros, updated to rc5 #271

Merged
merged 1 commit into from
Mar 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@
},
"homepage": "https://github.com/mgechev/codelyzer#readme",
"devDependencies": {
"@angular/compiler": "^4.0.0-rc.2",
"@angular/core": "^4.0.0-rc.2",
"@angular/compiler": "^4.0.0-rc.5",
"@angular/core": "^4.0.0-rc.5",
"@types/chai": "^3.4.33",
"@types/less": "0.0.31",
"@types/mocha": "^2.2.32",
Expand Down
2 changes: 1 addition & 1 deletion src/angular/styles/chars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export const $AT = 64;
export const $BT = 96;

export function isWhitespace(code: number): boolean {
return (code >= $TAB && code <= $SPACE) || (code == $NBSP);
return (code >= $TAB && code <= $SPACE) || (code === $NBSP);
}

export function isDigit(code: number): boolean {
Expand Down
8 changes: 4 additions & 4 deletions src/angular/styles/parseUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ export abstract class ParseError {
while (ctxLen < 100 && ctxStart > 0) {
ctxStart--;
ctxLen++;
if (source[ctxStart] == '\n') {
if (++ctxLines == 3) {
if (source[ctxStart] === '\n') {
if (++ctxLines === 3) {
break;
}
}
Expand All @@ -59,8 +59,8 @@ export abstract class ParseError {
while (ctxLen < 100 && ctxEnd < source.length - 1) {
ctxEnd++;
ctxLen++;
if (source[ctxEnd] == '\n') {
if (++ctxLines == 3) {
if (source[ctxEnd] === '\n') {
if (++ctxLines === 3) {
break;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/angular/templates/basicTemplateAstVisitor.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as ast from '@angular/compiler';
import * as ts from 'typescript';
import * as Lint from 'tslint';
import * as e from '@angular/compiler/typings/src/expression_parser/ast';
import * as e from '@angular/compiler/src/expression_parser/ast';

import { ExpTypes } from '../expressionTypes';
import { ComponentMetadata } from '../metadata';
Expand Down
2 changes: 1 addition & 1 deletion src/angular/templates/recursiveAngularExpressionVisitor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as Lint from 'tslint';
import * as ts from 'typescript';
import * as e from '@angular/compiler/typings/src/expression_parser/ast';
import * as e from '@angular/compiler/src/expression_parser/ast';

import {SourceMappingVisitor} from '../sourceMappingVisitor';
import {ComponentMetadata} from '../metadata';
Expand Down
2 changes: 1 addition & 1 deletion src/angular/templates/referenceCollectorVisitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export class ReferenceCollectorVisitor implements ast.TemplateAstVisitor {
element.children.forEach(e => this.visit(e, context));
this._variables = this._variables.concat(references);
}

get variables() {
return this._variables;
}
Expand Down
5 changes: 3 additions & 2 deletions src/angular/templates/templateParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import * as compiler from '@angular/compiler';

import { Config, DirectiveDeclaration } from '../config';
import { SemVerDSL } from '../../util/ngVersion';
import { NO_ERRORS_SCHEMA } from "@angular/core";
import { ɵConsole } from "@angular/core";
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ɵConsole } from '@angular/core';
let refId = 0;

const dummyMetadataFactory = (declaration: DirectiveDeclaration) => {
Expand Down Expand Up @@ -72,6 +72,7 @@ export const parseTemplate = (template: string, directives: DirectiveDeclaration
const templateMetadata: compiler.CompileTemplateMetadata = {
encapsulation: 0,
template: template,
isInline: false,
templateUrl: '',
styles: [],
styleUrls: [],
Expand Down
8 changes: 4 additions & 4 deletions src/componentClassSuffixRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@ export class Rule extends Lint.Rules.AbstractRule {

static FAILURE: string = 'The name of the class %s should end with the suffix %s ($$02-03$$)';

static validate(className: string, suffixList: string[]): boolean {
return suffixList.some(suffix => className.endsWith(suffix));
}

static walkerBuilder: F2<ts.SourceFile, IOptions, Ng2Walker> =
all(
validateComponent((meta: ComponentMetadata, suffixList?: string[]) =>
Expand All @@ -50,6 +46,10 @@ export class Rule extends Lint.Rules.AbstractRule {
})
));

static validate(className: string, suffixList: string[]): boolean {
return suffixList.some(suffix => className.endsWith(suffix));
}

public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(
Rule.walkerBuilder(sourceFile, this.getOptions())
Expand Down
22 changes: 11 additions & 11 deletions src/componentSelectorRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,30 @@ export class Rule extends SelectorRule {
* It is easier to recognize that a symbol is a component by looking at the template's HTML.
`,
options: {
"type": "array",
"items": [
'type': 'array',
'items': [
{
"enum": ["element", "attribute"]
'enum': ['element', 'attribute']
},
{
"oneOf": [
'oneOf': [
{
"type": "array",
"items": {
"type": "string"
'type': 'array',
'items': {
'type': 'string'
}
},
{
"type": "string"
'type': 'string'
}
]
},
{
"enum": ["kebab-case", "camelCase"]
'enum': ['kebab-case', 'camelCase']
}
],
"minItems": 3,
"maxItems": 3
'minItems': 3,
'maxItems': 3
},
optionExamples: [
`["element", "my-prefix", "kebab-case"]`,
Expand Down
22 changes: 11 additions & 11 deletions src/directiveSelectorRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,30 @@ export class Rule extends SelectorRule {
* It is easier to recognize that a symbol is a directive by looking at the template's HTML.
`,
options: {
"type": "array",
"items": [
'type': 'array',
'items': [
{
"enum": ["element", "attribute"]
'enum': ['element', 'attribute']
},
{
"oneOf": [
'oneOf': [
{
"type": "array",
"items": {
"type": "string"
'type': 'array',
'items': {
'type': 'string'
}
},
{
"type": "string"
'type': 'string'
}
]
},
{
"enum": ["kebab-case", "camelCase"]
'enum': ['kebab-case', 'camelCase']
}
],
"minItems": 3,
"maxItems": 3
'minItems': 3,
'maxItems': 3
},
optionExamples: [
`["element", "my-prefix", "kebab-case"]`,
Expand Down
2 changes: 1 addition & 1 deletion src/importDestructuringSpacingRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class ImportDestructuringSpacingWalker extends Lint.SkippableTokenAwareRuleWalke

public visitImportDeclaration(node: ts.ImportDeclaration) {
const importClause = node.importClause;
if (importClause != null && importClause.namedBindings != null) {
if (importClause !== null && importClause.namedBindings !== null) {
const text = importClause.namedBindings.getText();

if (!this.checkForWhiteSpace(text)) {
Expand Down
2 changes: 1 addition & 1 deletion src/noAccessMissingMemberRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {Ng2Walker} from './angular/ng2Walker';
import {RecursiveAngularExpressionVisitor} from './angular/templates/recursiveAngularExpressionVisitor';
import {ExpTypes} from './angular/expressionTypes';
import {getDeclaredMethodNames, getDeclaredPropertyNames} from './util/classDeclarationUtils';
import * as e from '@angular/compiler/typings/src/expression_parser/ast';
import * as e from '@angular/compiler/src/expression_parser/ast';

import {Config} from './angular/config';

Expand Down
4 changes: 2 additions & 2 deletions src/noAttributeParameterDecoratorRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ export class Rule extends Lint.Rules.AbstractRule {
// We only care about 1 since we highlight the whole 'parameter'
return decoratorsFailed.fmap(() =>
new Failure(p, sprintf(Rule.FAILURE_STRING,
parentName, (<any>p.name).text, (<any>p.name).text)))
parentName, (<any>p.name).text, (<any>p.name).text)));
})
);
return listToMaybe(failures)
return listToMaybe(failures);
});
})
);
Expand Down
2 changes: 1 addition & 1 deletion src/noUnusedCssRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class ElementFilterVisitor extends BasicTemplateAstVisitor {
return !selectorTypes[s] || !strategy(ast);
}) && (ast.children || [])
.every(c => ast instanceof ElementAst && this.shouldVisit(<ElementAst>c, strategies, selectorTypes)
|| ast instanceof EmbeddedTemplateAst &&
|| ast instanceof EmbeddedTemplateAst &&
(ast.children || []).every(c => this.shouldVisit(<ElementAst>c, strategies, selectorTypes)));
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/pipeImpureRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class ClassMetadataWalker extends Ng2Walker {
let argument = this.extractArgument(pipe);
if (argument.kind === SyntaxKind.current().ObjectLiteralExpression) {
argument.properties.filter(n => n.name.text === 'pure')
.forEach(this.validateProperty.bind(this, className))
.forEach(this.validateProperty.bind(this, className));
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/pipeNamingRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ export class Rule extends Lint.Rules.AbstractRule {
description: `Enforce consistent case and prefix for pipes.`,
rationale: `Consistent conventions make it easy to quickly identify and reference assets of different types.`,
options: {
"type": "array",
"items": [
{"enum": ["kebab-case", "attribute"]},
{"type": "string"}
'type': 'array',
'items': [
{'enum': ['kebab-case', 'attribute']},
{'type': 'string'}
],
"minItems": 1
'minItems': 1
},
optionExamples: [
`["camelCase", "myPrefix"]`,
Expand Down
2 changes: 1 addition & 1 deletion src/templatesUsePublicRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {stringDistance} from './util/utils';
import {getDeclaredProperties, getDeclaredMethods} from './util/classDeclarationUtils';
import {Ng2Walker} from './angular/ng2Walker';
import {RecursiveAngularExpressionVisitor} from './angular/templates/recursiveAngularExpressionVisitor';
import * as e from '@angular/compiler/typings/src/expression_parser/ast';
import * as e from '@angular/compiler/src/expression_parser/ast';
import SyntaxKind = require('./util/syntaxKind');

enum DeclarationType {
Expand Down
16 changes: 8 additions & 8 deletions src/useLifeCycleInterfaceRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class ClassMetadataWalker extends Lint.RuleWalker {
super.visitClassDeclaration(node);
}

private extractInterfaces(node:ts.ClassDeclaration,syntaxKind:SyntaxKind.SyntaxKind):string[]{
private extractInterfaces(node:ts.ClassDeclaration,syntaxKind:SyntaxKind.SyntaxKind): string[] {
let interfaces:string[] = [];
if (node.heritageClauses) {
let interfacesClause = node.heritageClauses.filter(h=>h.token === syntaxKind.ImplementsKeyword);
Expand All @@ -66,26 +66,26 @@ export class ClassMetadataWalker extends Lint.RuleWalker {
return interfaces;
}

private validateMethods( methods:any[],interfaces:string[],className:string){
methods.forEach(m => {
private validateMethods( methods: any[], interfaces: string[], className: string) {
methods.forEach( m => {
let n = (<any>m.name).text;
if(n && this.isMethodValidHook(m,interfaces)){
if(n && this.isMethodValidHook(m, interfaces)) {
let hookName = n.substr(2, n.lenght);
this.addFailure(
this.createFailure(
m.name.getStart(),
m.name.getWidth(),
sprintf.apply(this, [Rule.FAILURE, hookName,Rule.HOOKS_PREFIX + hookName, className])));
sprintf.apply(this, [Rule.FAILURE, hookName, Rule.HOOKS_PREFIX + hookName, className])));
}
});
}

private isMethodValidHook(m:any,interfaces:string[]):boolean{
private isMethodValidHook(m:any,interfaces:string[]): boolean {
let n = (<any>m.name).text;
let isNg:boolean = n.substr(0, 2) === Rule.HOOKS_PREFIX;
let isNg: boolean = n.substr(0, 2) === Rule.HOOKS_PREFIX;
let hookName = n.substr(2, n.lenght);
let isHook = Rule.LIFE_CYCLE_HOOKS_NAMES.indexOf(hookName) !== -1;
let isNotIn:boolean = interfaces.indexOf(hookName) === -1;
let isNotIn: boolean = interfaces.indexOf(hookName) === -1;
return isNg && isHook && isNotIn;
}

Expand Down
66 changes: 66 additions & 0 deletions src/usePipeDecoratorRule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import * as Lint from 'tslint';
import * as ts from 'typescript';
import {sprintf} from 'sprintf-js';
import SyntaxKind = require('./util/syntaxKind');

const getInterfaceName = (t: any) => {
if (t.expression && t.expression.name) {
return t.expression.name.text;
}
return t.expression.text;
};

export class Rule extends Lint.Rules.AbstractRule {
public static metadata: Lint.IRuleMetadata = {
ruleName: 'use-pipe-decorator',
type: 'maintainability',
description: `Ensure that classes implementing PipeTransform interface, use Pipe decorator`,
rationale: `Interfaces prescribe typed method signatures. Use those signatures to flag spelling and syntax mistakes.`,
options: null,
optionsDescription: `Not configurable.`,
typescriptOnly: true,
};


static FAILURE: string = 'The %s class implements the PipeTransform interface, so it should use the @Pipe decorator';
static PIPE_INTERFACE_NAME = 'PipeTransform';

public apply(sourceFile:ts.SourceFile):Lint.RuleFailure[] {
return this.applyWithWalker(
new ClassMetadataWalker(sourceFile,
this.getOptions()));
}
}

export class ClassMetadataWalker extends Lint.RuleWalker {

visitClassDeclaration(node:ts.ClassDeclaration) {
if (this.hasIPipeTransform(node)) {
let decorators = <any[]>node.decorators || [];
let className:string = node.name.text;
let pipes:Array<string> = decorators.map(d =>
(<any>d.expression).text ||
((<any>d.expression).expression || {}).text).filter( t=> t === 'Pipe');
if (pipes.length === 0) {
this.addFailure(
this.createFailure(
node.getStart(),
node.getWidth(),
sprintf.apply(this, [Rule.FAILURE, className])));
}
}
super.visitClassDeclaration(node);
}

private hasIPipeTransform(node: ts.ClassDeclaration): boolean {
let interfaces = [];
if (node.heritageClauses) {
let interfacesClause = node.heritageClauses
.filter(h => h.token === SyntaxKind.current().ImplementsKeyword);
if (interfacesClause.length !== 0) {
interfaces = interfacesClause[0].types.map(getInterfaceName);
}
}
return interfaces.indexOf(Rule.PIPE_INTERFACE_NAME) !== -1;
}
}
4 changes: 2 additions & 2 deletions src/usePipeTransformInterfaceRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class ClassMetadataWalker extends Lint.RuleWalker {
((<any>d.expression).expression || {}).text).filter(t=> t === 'Pipe');
if (pipes.length !== 0) {
let className:string = node.name.text;
if(!this.hasIPipeTransform(node)){
if (!this.hasIPipeTransform(node)) {
this.addFailure(
this.createFailure(
node.getStart(),
Expand All @@ -53,7 +53,7 @@ export class ClassMetadataWalker extends Lint.RuleWalker {
super.visitClassDeclaration(node);
}

private hasIPipeTransform(node:ts.ClassDeclaration):boolean{
private hasIPipeTransform(node:ts.ClassDeclaration): boolean {
let interfaces = [];
if (node.heritageClauses) {
let interfacesClause = node.heritageClauses
Expand Down
Loading