Skip to content

Commit fd82f14

Browse files
committed
Core(Tests): introduce DisallowShadowing rule
Added DisallowShadowing rule (no implementation yet). Added tests for it.
1 parent 9d29f9e commit fd82f14

File tree

5 files changed

+162
-0
lines changed

5 files changed

+162
-0
lines changed

src/FSharpLint.Core/FSharpLint.Core.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
<Compile Include="Rules\Conventions\AvoidSinglePipeOperator.fs" />
5656
<Compile Include="Rules\Conventions\SuggestUseAutoProperty.fs" />
5757
<Compile Include="Rules\Conventions\UsedUnderscorePrefixedElements.fs" />
58+
<Compile Include="Rules\Conventions\DisallowShadowing.fs" />
5859
<Compile Include="Rules\Conventions\RaiseWithTooManyArguments\RaiseWithTooManyArgumentsHelper.fs" />
5960
<Compile Include="Rules\Conventions\RaiseWithTooManyArguments\FailwithWithSingleArgument.fs" />
6061
<Compile Include="Rules\Conventions\RaiseWithTooManyArguments\RaiseWithSingleArgument.fs" />
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
module FSharpLint.Rules.DisallowShadowing
2+
3+
open System
4+
5+
open FSharpLint.Framework
6+
open FSharpLint.Framework.Suggestion
7+
open FSharp.Compiler.Syntax
8+
open FSharp.Compiler.Text
9+
open FSharp.Compiler.CodeAnalysis
10+
open FSharpLint.Framework.Ast
11+
open FSharpLint.Framework.Rules
12+
13+
let runner (args: AstNodeRuleParams) =
14+
15+
failwith "Not yet implemented"
16+
17+
let rule =
18+
{ Name = "DisallowShadowing"
19+
Identifier = Identifiers.DisallowShadowing
20+
RuleConfig = { AstNodeRuleConfig.Runner = runner; Cleanup = ignore } }
21+
|> AstNodeRule

src/FSharpLint.Core/Rules/Identifiers.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,4 @@ let UnnestedFunctionNames = identifier 80
8888
let NestedFunctionNames = identifier 81
8989
let UsedUnderscorePrefixedElements = identifier 82
9090
let UnneededRecKeyword = identifier 83
91+
let DisallowShadowing = identifier 84

tests/FSharpLint.Core.Tests/FSharpLint.Core.Tests.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
<Compile Include="Rules\Conventions\AvoidSinglePipeOperator.fs" />
4545
<Compile Include="Rules\Conventions\SuggestUseAutoProperty.fs" />
4646
<Compile Include="Rules\Conventions\UsedUnderscorePrefixedElements.fs" />
47+
<Compile Include="Rules\Conventions\DisallowShadowing.fs" />
4748
<Compile Include="Rules\Conventions\Naming\NamingHelpers.fs" />
4849
<Compile Include="Rules\Conventions\Naming\InterfaceNames.fs" />
4950
<Compile Include="Rules\Conventions\Naming\ExceptionNames.fs" />
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
module FSharpLint.Core.Tests.Rules.Conventions.DisallowShadowing
2+
3+
open NUnit.Framework
4+
5+
open FSharpLint.Rules
6+
7+
[<TestFixture>]
8+
type TestConventionsDisallowShadowing() =
9+
inherit TestAstNodeRuleBase.TestAstNodeRuleBase(DisallowShadowing.rule)
10+
11+
[<Test>]
12+
member this.``Should produce error for shadowed variable``() =
13+
this.Parse """
14+
let foo = 0
15+
16+
module Foo =
17+
let foo = 1"""
18+
19+
Assert.IsTrue this.ErrorsExist
20+
21+
[<Test>]
22+
member this.``Should produce error for shadowed variable, inside function``() =
23+
this.Parse """
24+
let bar () =
25+
let foo = 0
26+
let foo = 1
27+
foo"""
28+
29+
Assert.IsTrue this.ErrorsExist
30+
31+
[<Test>]
32+
member this.``Should produce error for shadowed variable (function argument)``() =
33+
this.Parse """
34+
let foo = 0
35+
let bar foo = foo + 1"""
36+
37+
Assert.IsTrue this.ErrorsExist
38+
39+
[<Test>]
40+
member this.``Should produce error for shadowed variable (function argument, inside function)``() =
41+
this.Parse """
42+
let baz () =
43+
let foo = 0
44+
let bar foo = foo + 1
45+
()"""
46+
47+
Assert.IsTrue this.ErrorsExist
48+
49+
[<Test>]
50+
member this.``Should produce error for shadowed variable (function argument, nested)``() =
51+
this.Parse """
52+
let baz foo =
53+
let bar foo = foo + 1
54+
()"""
55+
56+
Assert.IsTrue this.ErrorsExist
57+
58+
[<Test>]
59+
member this.``Should produce error for shadowed variable (function argument, tuple)``() =
60+
this.Parse """
61+
let foo = 0
62+
let bar (foo, baz) = foo + baz"""
63+
64+
Assert.IsTrue this.ErrorsExist
65+
66+
[<Test>]
67+
member this.``Should produce error for shadowed variable (lambda function argument)``() =
68+
this.Parse """
69+
let foo = 0
70+
(fun foo -> foo + 1) 0 |> ignore"""
71+
72+
Assert.IsTrue this.ErrorsExist
73+
74+
[<Test>]
75+
member this.``Should produce error for shadowed variable inside lambda function``() =
76+
this.Parse """
77+
(fun foo ->
78+
let foo = foo + 1
79+
foo) 0 |> ignore"""
80+
81+
Assert.IsTrue this.ErrorsExist
82+
83+
[<Test>]
84+
member this.``Should produce error for shadowed variable (match pattern)``() =
85+
this.Parse """
86+
let foo = 0
87+
match 1 with
88+
| foo -> foo"""
89+
90+
Assert.IsTrue this.ErrorsExist
91+
92+
[<Test>]
93+
member this.``Should produce error for shadowed variable (as match pattern)``() =
94+
this.Parse """
95+
let foo = 0
96+
match (1, 2) with
97+
| (x, y) as foo -> foo"""
98+
99+
Assert.IsTrue this.ErrorsExist
100+
101+
[<Test>]
102+
member this.``Should produce error for shadowed variable inside match pattern``() =
103+
this.Parse """
104+
match 1 with
105+
| foo ->
106+
let foo = foo + 1
107+
foo"""
108+
109+
Assert.IsTrue this.ErrorsExist
110+
111+
[<Test>]
112+
member this.``Should produce error for shadowed variable inside type definition``() =
113+
this.Parse """
114+
type Foo(foo) =
115+
let foo = foo + 1
116+
117+
member this.Bar = foo"""
118+
119+
Assert.IsTrue this.ErrorsExist
120+
121+
[<Test>]
122+
member this.``Should produce error for shadowed variable inside member definition``() =
123+
this.Parse """
124+
type Foo() =
125+
member this.Bar(foo) =
126+
let foo = foo + 1
127+
foo"""
128+
129+
Assert.IsTrue this.ErrorsExist
130+
131+
[<Test>]
132+
member this.``Should not produce error when variable with same name exists in another module``() =
133+
this.Parse """
134+
module Foo =
135+
let foo = 0
136+
let foo = 1"""
137+
138+
Assert.IsTrue this.NoErrorsExist

0 commit comments

Comments
 (0)