Skip to content

Commit

Permalink
feat(scope): Add allow methods/properties.
Browse files Browse the repository at this point in the history
  • Loading branch information
cartant committed Jul 23, 2018
1 parent a764fd7 commit 410d440
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 3 deletions.
16 changes: 15 additions & 1 deletion source/rules/rxjsNoUnsafeScopeRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,19 @@ export class Rule extends Lint.Rules.TypedRule {
options: {
properties: {
allowDo: { type: "boolean" },
allowMethods: { type: "boolean" },
allowParameters: { type: "boolean" },
allowProperties: { type: "boolean" },
allowTap: { type: "boolean" }
},
type: "object"
},
optionsDescription: Lint.Utils.dedent`
An optional object with optional \`allowDo\`, \`allowParameters\` and \`allowTap\` properties all of which default to \`true\`.
If the \`allowDo\` and \`allowTap\` options are \`true\`, the rule is not applied within \`do\` and \`tap\` operators respectively.
If the \`allowParameters\` option is \`true\`, referencing function parameters from outer scopes is allowed.`,
If the \`allowParameters\` option is \`true\`, referencing function parameters from outer scopes is allowed.
If the \`allowMethods\` option is \`true\`, calling methods via \`this\` is allowed.
If the \`allowProperties\` option is \`true\`, accessing properties via \`this\` is allowed.`,
requiresTypeInfo: true,
ruleName: "rxjs-no-unsafe-scopes",
type: "functionality",
Expand All @@ -43,7 +47,9 @@ export class Rule extends Lint.Rules.TypedRule {
class Walker extends ScopeWalker {

private allowDo = true;
private allowMethods = true;
private allowParameters = true;
private allowProperties = false;
private allowTap = true;

constructor(sourceFile: ts.SourceFile, rawOptions: Lint.IOptions, program: ts.Program) {
Expand All @@ -53,7 +59,9 @@ class Walker extends ScopeWalker {
const [options] = this.getOptions();
if (options) {
this.allowDo = (options.allowDo !== undefined) ? options.allowDo : this.allowDo;
this.allowMethods = (options.allowMethods !== undefined) ? options.allowMethods : this.allowMethods;
this.allowParameters = (options.allowParameters !== undefined) ? options.allowParameters : this.allowParameters;
this.allowProperties = (options.allowProperties !== undefined) ? options.allowProperties : this.allowProperties;
this.allowTap = (options.allowTap !== undefined) ? options.allowTap : this.allowTap;
}
}
Expand Down Expand Up @@ -98,12 +106,18 @@ class Walker extends ScopeWalker {
}

if (isWithinCallExpressionExpression(node)) {
if (isThis(node)) {
return !this.allowMethods;
}
return false;
}
if (tsutils.isNewExpression(node.parent)) {
return false;
}
if (tsutils.isPropertyAccessExpression(node.parent)) {
if (isThis(node)) {
return !this.allowProperties;
}
if (node === node.parent.name) {
return false;
}
Expand Down
17 changes: 17 additions & 0 deletions test/v6/fixtures/no-unsafe-scope/allow/fixture.ts.lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { of } from "rxjs";
import { map } from "rxjs/operators";

class User {
constructor(private name: string) {
of("Hello").pipe(
map(value => {
console.log(this.name);
return value;
})
).subscribe();
of("Hello").pipe(map(value => `${value}, ${this.name}.`)).subscribe();
}
foo(): string { return "foo"; }
}

[no-unsafe-scope]: Unsafe scopes are forbidden
13 changes: 13 additions & 0 deletions test/v6/fixtures/no-unsafe-scope/allow/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"baseUrl": ".",
"lib": ["es2015"],
"noEmit": true,
"paths": {
"rxjs": ["../../node_modules/rxjs"]
},
"skipLibCheck": true,
"target": "es5"
},
"include": ["fixture.ts"]
}
13 changes: 13 additions & 0 deletions test/v6/fixtures/no-unsafe-scope/allow/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"defaultSeverity": "error",
"jsRules": {},
"rules": {
"rxjs-no-unsafe-scope": {
"options": [{
"allowProperties": true
}],
"severity": "error"
}
},
"rulesDirectory": "../../../../../build/rules"
}
14 changes: 12 additions & 2 deletions test/v6/fixtures/no-unsafe-scope/disallow/fixture.ts.lint
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,21 @@ import { map, tap } from "rxjs/operators";
let outer: any;

of(1).pipe(tap(value => outer = value)).subscribe();
~~~~~ [no-unsafe-scope]
~~~~~ [no-unsafe-scope]

function piped(outer: number): Observable<number> {
return of(1).pipe(map(value => outer + value));
~~~~~ [no-unsafe-scope]
~~~~~ [no-unsafe-scope]
}

class User {
constructor(private name: string, private service: { bar(): string }) {
of("Hello").pipe(map(value => `${value}, ${this.foo()}.`)).subscribe();
~~~~ [no-unsafe-scope]
of("Hello").pipe(map(value => `${value}, ${this.service.bar()}.`)).subscribe();
~~~~ [no-unsafe-scope]
}
foo(): string { return "foo"; }
}

[no-unsafe-scope]: Unsafe scopes are forbidden
1 change: 1 addition & 0 deletions test/v6/fixtures/no-unsafe-scope/disallow/tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"rxjs-no-unsafe-scope": {
"options": [{
"allowDo": false,
"allowMethods": false,
"allowParameters": false,
"allowTap": false
}],
Expand Down

0 comments on commit 410d440

Please sign in to comment.