Skip to content

Commit

Permalink
refactor: walkers/visitors being exported (#793)
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelss95 authored and mgechev committed Mar 23, 2019
1 parent 201d6ee commit c07ac5e
Show file tree
Hide file tree
Showing 39 changed files with 233 additions and 212 deletions.
19 changes: 10 additions & 9 deletions src/angularWhitespaceRule.ts
Expand Up @@ -3,7 +3,7 @@ import * as Lint from 'tslint';
import * as ts from 'typescript';
import { Config } from './angular/config';
import { ExpTypes } from './angular/expressionTypes';
import { NgWalker } from './angular/ngWalker';
import { NgWalker, NgWalkerConfig } from './angular/ngWalker';
import { BasicTemplateAstVisitor } from './angular/templates/basicTemplateAstVisitor';
import { RecursiveAngularExpressionVisitor } from './angular/templates/recursiveAngularExpressionVisitor';

Expand Down Expand Up @@ -162,7 +162,7 @@ class SemicolonTemplateVisitor extends BasicTemplateAstVisitor implements Config
}
}

class WhitespaceTemplateVisitor extends BasicTemplateAstVisitor {
class TemplateVisitorCtrl extends BasicTemplateAstVisitor {
private visitors: (BasicTemplateAstVisitor & ConfigurableVisitor)[] = [
new InterpolationWhitespaceVisitor(this.getSourceFile(), this.getOptions(), this.context, this.templateStart),
new SemicolonTemplateVisitor(this.getSourceFile(), this.getOptions(), this.context, this.templateStart)
Expand Down Expand Up @@ -259,7 +259,7 @@ class PipeWhitespaceVisitor extends RecursiveAngularExpressionVisitor implements
}
}

class TemplateExpressionVisitor extends RecursiveAngularExpressionVisitor {
class ExpressionVisitorCtrl extends RecursiveAngularExpressionVisitor {
private visitors: (RecursiveAngularExpressionVisitor & ConfigurableVisitor)[] = [
new PipeWhitespaceVisitor(this.getSourceFile(), this.getOptions(), this.context, this.basePosition)
];
Expand Down Expand Up @@ -310,12 +310,13 @@ export class Rule extends Lint.Rules.AbstractRule {
};

apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(
new NgWalker(sourceFile, this.getOptions(), {
expressionVisitorCtrl: TemplateExpressionVisitor,
templateVisitorCtrl: WhitespaceTemplateVisitor
})
);
const walkerConfig: NgWalkerConfig = {
expressionVisitorCtrl: ExpressionVisitorCtrl,
templateVisitorCtrl: TemplateVisitorCtrl
};
const walker = new NgWalker(sourceFile, this.getOptions(), walkerConfig);

return this.applyWithWalker(walker);
}

isEnabled(): boolean {
Expand Down
8 changes: 5 additions & 3 deletions src/componentClassSuffixRule.ts
@@ -1,11 +1,11 @@
import { sprintf } from 'sprintf-js';
import * as Lint from 'tslint';
import * as ts from 'typescript';
import { NgWalker } from './angular';
import { ComponentMetadata } from './angular/metadata';
import { Maybe, F2 } from './util/function';
import { F2, Maybe } from './util/function';
import { Failure } from './walkerFactory/walkerFactory';
import { all, validateComponent } from './walkerFactory/walkerFn';
import { NgWalker } from '.';

export class Rule extends Lint.Rules.AbstractRule {
static readonly metadata: Lint.IRuleMetadata = {
Expand Down Expand Up @@ -51,6 +51,8 @@ export class Rule extends Lint.Rules.AbstractRule {
}

apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(Rule.walkerBuilder(sourceFile, this.getOptions()));
const walker = Rule.walkerBuilder(sourceFile, this.getOptions());

return this.applyWithWalker(walker);
}
}
6 changes: 4 additions & 2 deletions src/componentMaxInlineDeclarationsRule.ts
Expand Up @@ -66,7 +66,9 @@ export class Rule extends AbstractRule {
static readonly FAILURE_STRING = `Exceeds the maximum allowed inline lines for %s. Defined limit: %s / total lines: %s (${STYLE_GUIDE_LINK})`;

apply(sourceFile: SourceFile): RuleFailure[] {
return this.applyWithWalker(new MaxInlineDeclarationsWalker(sourceFile, this.getOptions()));
const walker = new Walker(sourceFile, this.getOptions());

return this.applyWithWalker(walker);
}

isEnabled(): boolean {
Expand All @@ -81,7 +83,7 @@ export class Rule extends AbstractRule {
}
}

export class MaxInlineDeclarationsWalker extends NgWalker {
class Walker extends NgWalker {
private readonly animationsLinesLimit = DEFAULT_ANIMATIONS_LIMIT;
private readonly stylesLinesLimit = DEFAULT_STYLES_LIMIT;
private readonly templateLinesLimit = DEFAULT_TEMPLATE_LIMIT;
Expand Down
6 changes: 4 additions & 2 deletions src/contextualDecoratorRule.ts
Expand Up @@ -39,11 +39,13 @@ export class Rule extends AbstractRule {
static readonly FAILURE_STRING = 'The decorator "%s" is not allowed for class "%s" because it is decorated with "%s"';

apply(sourceFile: SourceFile): RuleFailure[] {
return this.applyWithWalker(new ContextualDecoratorWalker(sourceFile, this.getOptions()));
const walker = new Walker(sourceFile, this.getOptions());

return this.applyWithWalker(walker);
}
}

export class ContextualDecoratorWalker extends NgWalker {
class Walker extends NgWalker {
protected visitMethodDecorator(decorator: Decorator): void {
this.validateDecorator(decorator);
super.visitMethodDecorator(decorator);
Expand Down
10 changes: 6 additions & 4 deletions src/contextualLifecycleRule.ts
@@ -1,7 +1,8 @@
import { sprintf } from 'sprintf-js';
import { IRuleMetadata, RuleFailure } from 'tslint/lib';
import { AbstractRule } from 'tslint/lib/rules';
import { ClassDeclaration, Decorator, SourceFile } from 'typescript';
import { SourceFile } from 'typescript';
import { InjectableMetadata, ModuleMetadata, PipeMetadata } from './angular';
import { NgWalker } from './angular/ngWalker';
import {
getClassName,
Expand All @@ -14,7 +15,6 @@ import {
MetadataTypeKeys,
MetadataTypes
} from './util/utils';
import { InjectableMetadata, ModuleMetadata, PipeMetadata } from './angular';

interface FailureParameters {
readonly className: string;
Expand All @@ -41,11 +41,13 @@ export class Rule extends AbstractRule {
static readonly FAILURE_STRING = 'The method "%s" is not allowed for class "%s" because it is decorated with "%s"';

apply(sourceFile: SourceFile): RuleFailure[] {
return this.applyWithWalker(new ContextualLifecycleWalker(sourceFile, this.getOptions()));
const walker = new Walker(sourceFile, this.getOptions());

return this.applyWithWalker(walker);
}
}

class ContextualLifecycleWalker extends NgWalker {
class Walker extends NgWalker {
protected visitNgInjectable(metadata: InjectableMetadata): void {
this.validateDecorator(metadata, METADATA_TYPE_LIFECYCLE_MAPPER.Injectable);
super.visitNgInjectable(metadata);
Expand Down
9 changes: 5 additions & 4 deletions src/directiveClassSuffixRule.ts
@@ -1,11 +1,10 @@
import { sprintf } from 'sprintf-js';
import * as Lint from 'tslint';
import * as ts from 'typescript';
import { DirectiveMetadata } from './angular/metadata';
import { NgWalker } from './angular/ngWalker';
import { getSymbolName } from './util/utils';

import { DirectiveMetadata } from './angular/metadata';

const ValidatorSuffix = 'Validator';

export class Rule extends Lint.Rules.AbstractRule {
Expand Down Expand Up @@ -34,11 +33,13 @@ export class Rule extends Lint.Rules.AbstractRule {
}

apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(new ClassMetadataWalker(sourceFile, this.getOptions()));
const walker = new Walker(sourceFile, this.getOptions());

return this.applyWithWalker(walker);
}
}

export class ClassMetadataWalker extends NgWalker {
class Walker extends NgWalker {
protected visitNgDirective(metadata: DirectiveMetadata) {
const name = metadata.controller.name!;
const className = name.text;
Expand Down
7 changes: 4 additions & 3 deletions src/noInputPrefixRule.ts
@@ -1,7 +1,6 @@
import { sprintf } from 'sprintf-js';
import { IOptions, IRuleMetadata, RuleFailure, Rules, Utils } from 'tslint/lib';
import { Decorator, PropertyDeclaration, SourceFile } from 'typescript';

import { NgWalker } from './angular/ngWalker';

export class Rule extends Rules.AbstractRule {
Expand Down Expand Up @@ -30,7 +29,9 @@ export class Rule extends Rules.AbstractRule {
static readonly FAILURE_STRING = '@Inputs should not be prefixed by %s';

apply(sourceFile: SourceFile): RuleFailure[] {
return this.applyWithWalker(new NoInputPrefixWalker(sourceFile, this.getOptions()));
const walker = new Walker(sourceFile, this.getOptions());

return this.applyWithWalker(walker);
}

isEnabled(): boolean {
Expand Down Expand Up @@ -62,7 +63,7 @@ export const getFailureMessage = (prefixes: string[]): string => {
return sprintf(Rule.FAILURE_STRING, getReadablePrefixes(prefixes));
};

class NoInputPrefixWalker extends NgWalker {
class Walker extends NgWalker {
private readonly blacklistedPrefixes: string[];

constructor(source: SourceFile, options: IOptions) {
Expand Down
6 changes: 4 additions & 2 deletions src/noInputRenameRule.ts
Expand Up @@ -26,7 +26,9 @@ export class Rule extends AbstractRule {
`;

apply(sourceFile: SourceFile): RuleFailure[] {
return this.applyWithWalker(new InputMetadataWalker(sourceFile, this.getOptions()));
const walker = new Walker(sourceFile, this.getOptions());

return this.applyWithWalker(walker);
}
}

Expand Down Expand Up @@ -74,7 +76,7 @@ const whiteListAliases = new Set<string>([
'aria-valuetext'
]);

export class InputMetadataWalker extends NgWalker {
class Walker extends NgWalker {
private directiveSelectors!: ReadonlyArray<DirectiveMetadata['selector']>;

protected visitNgDirective(metadata: DirectiveMetadata): void {
Expand Down
6 changes: 4 additions & 2 deletions src/noLifecycleCallRule.ts
Expand Up @@ -18,11 +18,13 @@ export class Rule extends AbstractRule {
static readonly FAILURE_STRING = 'Avoid explicit calls to lifecycle methods';

apply(sourceFile: SourceFile): RuleFailure[] {
return this.applyWithWalker(new ExpressionCallMetadataWalker(sourceFile, this.getOptions()));
const walker = new Walker(sourceFile, this.getOptions());

return this.applyWithWalker(walker);
}
}

class ExpressionCallMetadataWalker extends NgWalker {
class Walker extends NgWalker {
visitCallExpression(node: CallExpression): void {
this.validateCallExpression(node);
super.visitCallExpression(node);
Expand Down
6 changes: 4 additions & 2 deletions src/noOutputNativeRule.ts
Expand Up @@ -202,11 +202,13 @@ export class Rule extends AbstractRule {
static readonly FAILURE_STRING = 'In the class "%s", the output property "%s" should not be named or renamed as a native event';

apply(sourceFile: SourceFile): RuleFailure[] {
return this.applyWithWalker(new NoOutputNativeWalker(sourceFile, this.getOptions()));
const walker = new Walker(sourceFile, this.getOptions());

return this.applyWithWalker(walker);
}
}

class NoOutputNativeWalker extends NgWalker {
class Walker extends NgWalker {
protected visitNgOutput(property: PropertyDeclaration, output: Decorator, args: string[]): void {
this.validateOutput(property, args);
super.visitNgOutput(property, output, args);
Expand Down
6 changes: 4 additions & 2 deletions src/noOutputOnPrefixRule.ts
Expand Up @@ -20,11 +20,13 @@ export class Rule extends Lint.Rules.AbstractRule {
static readonly FAILURE_STRING = 'In the class "%s", the output property "%s" should not be prefixed with on';

apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(new OutputWalker(sourceFile, this.getOptions()));
const walker = new Walker(sourceFile, this.getOptions());

return this.applyWithWalker(walker);
}
}

class OutputWalker extends NgWalker {
class Walker extends NgWalker {
protected visitNgOutput(property: ts.PropertyDeclaration, output: ts.Decorator, args: string[]) {
this.validateOutput(property);
super.visitNgOutput(property, output, args);
Expand Down
6 changes: 4 additions & 2 deletions src/noOutputRenameRule.ts
Expand Up @@ -18,15 +18,17 @@ export class Rule extends Rules.AbstractRule {
static readonly FAILURE_STRING = '@Outputs should not be renamed';

apply(sourceFile: SourceFile): RuleFailure[] {
return this.applyWithWalker(new OutputMetadataWalker(sourceFile, this.getOptions()));
const walker = new Walker(sourceFile, this.getOptions());

return this.applyWithWalker(walker);
}
}

export const getFailureMessage = (): string => {
return Rule.FAILURE_STRING;
};

export class OutputMetadataWalker extends NgWalker {
class Walker extends NgWalker {
private directiveSelectors!: ReadonlySet<DirectiveMetadata['selector']>;

protected visitNgDirective(metadata: DirectiveMetadata): void {
Expand Down
12 changes: 7 additions & 5 deletions src/noPipeImpureRule.ts
@@ -1,10 +1,10 @@
import { sprintf } from 'sprintf-js';
import { IRuleMetadata, RuleFailure } from 'tslint';
import { AbstractRule } from 'tslint/lib/rules';
import { ClassDeclaration, Decorator, SourceFile, SyntaxKind } from 'typescript';
import { NgWalker } from './angular/ngWalker';
import { getClassName, getDecoratorPropertyInitializer } from './util/utils';
import { SourceFile, SyntaxKind } from 'typescript';
import { PipeMetadata } from './angular';
import { NgWalker } from './angular/ngWalker';
import { getClassName } from './util/utils';

interface FailureParameters {
readonly className: string;
Expand All @@ -27,11 +27,13 @@ export class Rule extends AbstractRule {
static readonly FAILURE_STRING = 'Impure pipe declared in class %s';

apply(sourceFile: SourceFile): RuleFailure[] {
return this.applyWithWalker(new ClassMetadataWalker(sourceFile, this.getOptions()));
const walker = new Walker(sourceFile, this.getOptions());

return this.applyWithWalker(walker);
}
}

export class ClassMetadataWalker extends NgWalker {
class Walker extends NgWalker {
protected visitNgPipe(metadata: PipeMetadata): void {
this.validatePipe(metadata);
super.visitNgPipe(metadata);
Expand Down
27 changes: 12 additions & 15 deletions src/noUnusedCssRule.ts
@@ -1,17 +1,15 @@
import { ElementAst, EmbeddedTemplateAst, PropertyBindingType, TemplateAst } from '@angular/compiler';
import * as Lint from 'tslint';
import * as ts from 'typescript';

import { NgWalker } from './angular/ngWalker';
import { ComponentMetadata, StyleMetadata } from './angular/metadata';
import { NgWalker, NgWalkerConfig } from './angular/ngWalker';
import { BasicCssAstVisitor } from './angular/styles/basicCssAstVisitor';
import { CssAst, CssSelectorAst, CssSelectorRuleAst } from './angular/styles/cssAst';
import { BasicTemplateAstVisitor } from './angular/templates/basicTemplateAstVisitor';
import { parseTemplate } from './angular/templates/templateParser';
import { getComponentDecorator, getDecoratorPropertyInitializer, getSymbolName } from './util/utils';

import { ComponentMetadata, StyleMetadata } from './angular/metadata';
import { logger } from './util/logger';
import { SemVerDSL } from './util/ngVersion';
import { getComponentDecorator, getDecoratorPropertyInitializer, getSymbolName } from './util/utils';

interface Strategy {
attribute(ast: ElementAst): boolean;
Expand Down Expand Up @@ -126,7 +124,7 @@ class ElementFilterVisitor extends BasicTemplateAstVisitor {
}

export class Rule extends Lint.Rules.AbstractRule {
public static metadata: Lint.IRuleMetadata = {
static readonly metadata: Lint.IRuleMetadata = {
ruleName: 'no-unused-css',
type: 'maintainability',
description: "Disallows having an unused CSS rule in the component's stylesheet.",
Expand All @@ -136,16 +134,15 @@ export class Rule extends Lint.Rules.AbstractRule {
hasFix: true
};

public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(
new UnusedCssNgVisitor(sourceFile, this.getOptions(), {
cssVisitorCtrl: UnusedCssVisitor
})
);
apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
const walkerConfig: NgWalkerConfig = { cssVisitorCtrl: CssVisitorCtrl };
const walker = new Walker(sourceFile, this.getOptions(), walkerConfig);

return this.applyWithWalker(walker);
}
}

class UnusedCssVisitor extends BasicCssAstVisitor {
class CssVisitorCtrl extends BasicCssAstVisitor {
templateAst!: TemplateAst;

constructor(
Expand Down Expand Up @@ -221,7 +218,7 @@ class UnusedCssVisitor extends BasicCssAstVisitor {
}

// Finds the template and wrapes the parsed content into a root element
export class UnusedCssNgVisitor extends NgWalker {
class Walker extends NgWalker {
private templateAst!: TemplateAst;

visitClassDeclaration(declaration: ts.ClassDeclaration) {
Expand Down Expand Up @@ -283,7 +280,7 @@ export class UnusedCssNgVisitor extends NgWalker {
}

const file = this.getContextSourceFile(styleMetadata.url!, styleMetadata.style.source!);
const visitor = new UnusedCssVisitor(file, this._originalOptions, context, styleMetadata, baseStart);
const visitor = new CssVisitorCtrl(file, this._originalOptions, context, styleMetadata, baseStart);
visitor.templateAst = this.templateAst;
const d = getComponentDecorator(context.controller)!;
const encapsulation = getDecoratorPropertyInitializer(d, 'encapsulation');
Expand Down

0 comments on commit c07ac5e

Please sign in to comment.