Skip to content

Commit 1f8cb9f

Browse files
committed
added DynamicCheck
refactored callback of ComplexTypeUtils to include name and position info
1 parent 3e17290 commit 1f8cb9f

File tree

5 files changed

+208
-65
lines changed

5 files changed

+208
-65
lines changed

checkstyle/ComplexTypeUtils.hx

Lines changed: 63 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -10,149 +10,149 @@ import haxe.macro.Expr;
1010

1111
class ComplexTypeUtils {
1212

13-
public static function walkFile(file:{pack:Array<String>, decls:Array<TypeDecl> }, cb:ComplexType -> Void) {
13+
public static function walkFile(file:{pack:Array<String>, decls:Array<TypeDecl> }, cb:ComplexTypeCallback) {
1414
for (decl in file.decls) walkTypeDecl(decl, cb);
1515
}
1616

17-
public static function walkTypeDecl(td:TypeDecl, cb:ComplexType -> Void) {
17+
public static function walkTypeDecl(td:TypeDecl, cb:ComplexTypeCallback) {
1818
switch(td.decl){
1919
case EClass(d):
20-
walkClass(d, cb);
20+
walkClass(d, td.pos, cb);
2121
case EEnum(d):
22-
walkEnum(d, cb);
22+
walkEnum(d, td.pos, cb);
2323
case EAbstract(a):
24-
walkAbstract(a, cb);
24+
walkAbstract(a, td.pos, cb);
2525
case EImport(sl, mode):
2626
walkImport(sl, mode, cb);
2727
case ETypedef(d):
28-
walkTypedef(d, cb);
28+
walkTypedef(d, td.pos, cb);
2929
case EUsing(path):
30-
walkTypePath(path, cb);
30+
walkTypePath(path, path.name, td.pos, cb);
3131
}
3232
}
3333

34-
static function walkMeta(meta:Metadata, cb:ComplexType -> Void) {
34+
static function walkMeta(meta:Metadata, cb:ComplexTypeCallback) {
3535
for (m in meta) for (p in m.params) walkExpr(p, cb);
3636
}
3737

38-
static function walkCommonDefinition<A, B>(d:Definition<A, B>, cb:ComplexType -> Void) {
39-
for (p in d.params) walkTypeParamDecl(p, cb);
38+
static function walkCommonDefinition<A, B>(d:Definition<A, B>, pos:Position, cb:ComplexTypeCallback) {
39+
for (p in d.params) walkTypeParamDecl(p, pos, cb);
4040
walkMeta(d.meta, cb);
4141
}
4242

43-
public static function walkClass(d:Definition<ClassFlag, Array<Field>>, cb:ComplexType -> Void) {
44-
walkCommonDefinition(d, cb);
43+
public static function walkClass(d:Definition<ClassFlag, Array<Field>>, pos:Position, cb:ComplexTypeCallback) {
44+
walkCommonDefinition(d, pos, cb);
4545
for (f in d.flags) switch f {
46-
case HExtends(t) | HImplements(t): walkTypePath(t, cb);
46+
case HExtends(t) | HImplements(t): walkTypePath(t, d.name, pos, cb);
4747
default:
4848
}
4949
for (f in d.data) walkField(f, cb);
5050
}
5151

52-
public static function walkEnum(d:Definition<EnumFlag, Array<EnumConstructor>>, cb:ComplexType -> Void) {
53-
walkCommonDefinition(d, cb);
52+
public static function walkEnum(d:Definition<EnumFlag, Array<EnumConstructor>>, pos:Position, cb:ComplexTypeCallback) {
53+
walkCommonDefinition(d, pos, cb);
5454
for (ec in d.data) {
5555
walkMeta(ec.meta, cb);
56-
for (arg in ec.args) walkComplexType(arg.type, cb);
57-
for (param in ec.params) walkTypeParamDecl(param, cb);
58-
if (ec.type != null) walkComplexType(ec.type, cb);
56+
for (arg in ec.args) walkComplexType(arg.type, ec.name, pos, cb);
57+
for (param in ec.params) walkTypeParamDecl(param, pos, cb);
58+
if (ec.type != null) walkComplexType(ec.type, ec.name, pos, cb);
5959
}
6060
}
6161

62-
public static function walkAbstract(d:Definition<AbstractFlag, Array<Field>>, cb:ComplexType -> Void) {
63-
walkCommonDefinition(d, cb);
62+
public static function walkAbstract(d:Definition<AbstractFlag, Array<Field>>, pos:Position, cb:ComplexTypeCallback) {
63+
walkCommonDefinition(d, pos, cb);
6464
for (f in d.flags) switch f {
65-
case AFromType(ct) | AToType(ct) | AIsType(ct): walkComplexType(ct, cb);
65+
case AFromType(ct) | AToType(ct) | AIsType(ct): walkComplexType(ct, f.getName(), pos, cb);
6666
default:
6767
}
6868
for (f in d.data) walkField(f, cb);
6969
}
7070

71-
public static function walkImport(sl, mode, cb:ComplexType -> Void) {
71+
public static function walkImport(sl, mode, cb:ComplexTypeCallback) {
7272
//Do nothing
7373
}
7474

75-
public static function walkTypedef(d:Definition<EnumFlag, ComplexType>, cb:ComplexType -> Void) {
76-
walkCommonDefinition(d, cb);
77-
walkComplexType(d.data, cb);
75+
public static function walkTypedef(d:Definition<EnumFlag, ComplexType>, pos:Position, cb:ComplexTypeCallback) {
76+
walkCommonDefinition(d, pos, cb);
77+
walkComplexType(d.data, d.name, pos, cb);
7878
}
7979

80-
public static function walkTypePath(tp:TypePath, cb:ComplexType -> Void) {
80+
public static function walkTypePath(tp:TypePath, name:String, pos:Position, cb:ComplexTypeCallback) {
8181
if (tp.params != null) {
8282
for (p in tp.params) {
8383
switch(p){
84-
case TPType(t): walkComplexType(t, cb);
84+
case TPType(t): walkComplexType(t, name, pos, cb);
8585
case TPExpr(e): walkExpr(e, cb);
8686
}
8787
}
8888
}
8989
}
9090

91-
public static function walkVar(v:Var, cb:ComplexType -> Void) {
92-
if (v.type != null) walkComplexType(v.type, cb);
91+
public static function walkVar(v:Var, pos:Position, cb:ComplexTypeCallback) {
92+
if (v.type != null) walkComplexType(v.type, v.name, pos, cb);
9393
if (v.expr != null) walkExpr(v.expr, cb);
9494
}
9595

96-
public static function walkTypeParamDecl(tp:TypeParamDecl, cb:ComplexType -> Void) {
97-
if (tp.constraints != null) for (c in tp.constraints) walkComplexType(c, cb);
98-
if (tp.params != null) for (t in tp.params) walkTypeParamDecl(t, cb);
96+
public static function walkTypeParamDecl(tp:TypeParamDecl, pos:Position, cb:ComplexTypeCallback) {
97+
if (tp.constraints != null) for (c in tp.constraints) walkComplexType(c, tp.name, pos, cb);
98+
if (tp.params != null) for (t in tp.params) walkTypeParamDecl(t, pos, cb);
9999
}
100100

101-
public static function walkFunction(f:Function, cb:ComplexType -> Void) {
101+
public static function walkFunction(f:Function, name:String, pos:Position, cb:ComplexTypeCallback) {
102102
for (a in f.args) {
103-
if (a.type != null) walkComplexType(a.type, cb);
103+
if (a.type != null) walkComplexType(a.type, a.name, pos, cb);
104104
if (a.value != null) walkExpr(a.value, cb);
105105
}
106-
if (f.ret != null) walkComplexType(f.ret, cb);
106+
if (f.ret != null) walkComplexType(f.ret, name, pos, cb);
107107
if (f.expr != null) walkExpr(f.expr, cb);
108-
if (f.params != null) for (tp in f.params) walkTypeParamDecl(tp, cb);
108+
if (f.params != null) for (tp in f.params) walkTypeParamDecl(tp, pos, cb);
109109
}
110110

111-
public static function walkCase(c:Case, cb:ComplexType -> Void) {
111+
public static function walkCase(c:Case, cb:ComplexTypeCallback) {
112112
for (v in c.values) walkExpr(v, cb);
113113
if (c.guard != null) walkExpr(c.guard, cb);
114114
if (c.expr != null) walkExpr(c.expr, cb);
115115
}
116116

117-
public static function walkCatch(c:Catch, cb:ComplexType -> Void) {
118-
walkComplexType(c.type, cb);
117+
public static function walkCatch(c:Catch, pos:Position, cb:ComplexTypeCallback) {
118+
walkComplexType(c.type, c.name, pos, cb);
119119
walkExpr(c.expr, cb);
120120
}
121121

122-
public static function walkField(f:Field, cb:ComplexType -> Void) {
122+
public static function walkField(f:Field, cb:ComplexTypeCallback) {
123123
switch(f.kind){
124124
case FVar(t, e):
125-
if (t != null) walkComplexType(t, cb);
125+
if (t != null) walkComplexType(t, f.name, f.pos, cb);
126126
if (e != null) walkExpr(e, cb);
127-
case FFun(f):
128-
walkFunction(f, cb);
127+
case FFun(fun):
128+
walkFunction(fun, f.name, f.pos, cb);
129129
case FProp(get, set, t, e):
130-
if (t != null) walkComplexType(t, cb);
130+
if (t != null) walkComplexType(t, f.name, f.pos, cb);
131131
if (e != null) walkExpr(e, cb);
132132
}
133133
}
134134

135-
public static function walkComplexType(t:ComplexType, cb:ComplexType -> Void) {
136-
cb(t);
135+
public static function walkComplexType(t:ComplexType, name:String, pos:Position, cb:ComplexTypeCallback) {
136+
cb(t, name, pos);
137137

138138
switch(t){
139-
case TPath(p): walkTypePath(p, cb);
139+
case TPath(p): walkTypePath(p, name, pos, cb);
140140
case TFunction(args, ret):
141-
for (a in args) walkComplexType(a, cb);
142-
walkComplexType(ret, cb);
141+
for (a in args) walkComplexType(a, name, pos, cb);
142+
walkComplexType(ret, name, pos, cb);
143143
case TAnonymous(fields):
144144
for (f in fields) walkField(f, cb);
145145
case TParent(t):
146-
walkComplexType(t, cb);
146+
walkComplexType(t, name, pos, cb);
147147
case TExtend(p, fields):
148-
for (tp in p) walkTypePath(tp, cb);
148+
for (tp in p) walkTypePath(tp, name, pos, cb);
149149
for (f in fields) walkField(f, cb);
150150
case TOptional(t):
151-
walkComplexType(t, cb);
151+
walkComplexType(t, name, pos, cb);
152152
}
153153
}
154154

155-
public static function walkExpr(e:Expr, cb:ComplexType -> Void) {
155+
public static function walkExpr(e:Expr, cb:ComplexTypeCallback) {
156156
switch(e.expr){
157157
case EConst(c):
158158
case EArray(e1, e2): walkExpr(e1, cb); walkExpr(e2, cb);
@@ -167,12 +167,12 @@ class ComplexTypeUtils {
167167
walkExpr(e, cb);
168168
for (p in params) walkExpr(p, cb);
169169
case ENew(t, params):
170-
walkTypePath(t, cb);
170+
walkTypePath(t, "", e.pos, cb);
171171
for (p in params) walkExpr(p, cb);
172172
case EUnop(op, postFix, e): walkExpr(e, cb);
173173
case EVars(vars):
174-
for (v in vars) walkVar(v, cb);
175-
case EFunction(name, f): walkFunction(f, cb);
174+
for (v in vars) walkVar(v, e.pos, cb);
175+
case EFunction(name, f): walkFunction(f, name, e.pos, cb);
176176
case EBlock(exprs):
177177
for (e in exprs) walkExpr(e, cb);
178178
case EFor(it, expr): walkExpr(it, cb); walkExpr(expr, cb);
@@ -188,7 +188,7 @@ class ComplexTypeUtils {
188188
if (edef != null && edef.expr != null) walkExpr(edef, cb);
189189
case ETry(e, catches):
190190
walkExpr(e, cb);
191-
for (c in catches) walkCatch(c, cb);
191+
for (c in catches) walkCatch(c, e.pos, cb);
192192
case EReturn(e):
193193
if (e != null) walkExpr(e, cb);
194194
case EBreak:
@@ -197,19 +197,21 @@ class ComplexTypeUtils {
197197
case EThrow(e): walkExpr(e, cb);
198198
case ECast(e, t):
199199
walkExpr(e, cb);
200-
if (t != null) walkComplexType(t, cb);
200+
if (t != null) walkComplexType(t, t.getName(), e.pos, cb);
201201
case EDisplay(e, isCall): walkExpr(e, cb);
202-
case EDisplayNew(t): walkTypePath(t, cb);
202+
case EDisplayNew(t): walkTypePath(t, "", e.pos, cb);
203203
case ETernary(econd, eif, eelse):
204204
walkExpr(econd, cb);
205205
walkExpr(eif, cb);
206206
walkExpr(eelse, cb);
207207
case ECheckType(e, t):
208208
walkExpr(e, cb);
209-
walkComplexType(t, cb);
209+
walkComplexType(t, t.getName(), e.pos, cb);
210210
case EMeta(s, e):
211211
if (s.params != null) for (mp in s.params) walkExpr(mp, cb);
212212
walkExpr(e, cb);
213213
}
214214
}
215-
}
215+
}
216+
217+
typedef ComplexTypeCallback = ComplexType -> String -> Position -> Void;

checkstyle/checks/Check.hx

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,31 @@ class Check {
5959
}
6060

6161
function isLineSuppressed(i:Int):Bool {
62-
var startPos:Int = 0;
62+
var pos:Int = 0;
6363
for (j in 0 ... i + 1) {
64-
startPos += _checker.lines[j].length;
64+
pos += _checker.lines[j].length;
6565
}
66+
for (td in _checker.ast.decls) {
67+
switch (td.decl){
68+
case EClass(d):
69+
for (field in d.data) {
70+
if (pos > field.pos.max) continue;
71+
if (pos < field.pos.min) continue;
72+
return isCheckSuppressed (field);
73+
}
74+
default:
75+
}
76+
}
77+
return false;
78+
}
6679

80+
function isPosSuppressed(pos:Position):Bool {
6781
for (td in _checker.ast.decls) {
6882
switch (td.decl){
6983
case EClass(d):
7084
for (field in d.data) {
71-
if (startPos > field.pos.max) continue;
72-
if (startPos < field.pos.min) continue;
85+
if (pos.min > field.pos.max) continue;
86+
if (pos.min < field.pos.min) continue;
7387
return isCheckSuppressed (field);
7488
}
7589
default:

checkstyle/checks/DynamicCheck.hx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package checkstyle.checks;
2+
3+
import checkstyle.LintMessage.SeverityLevel;
4+
import haxeparser.Data;
5+
import haxe.macro.Expr;
6+
import checkstyle.ComplexTypeUtils;
7+
8+
@name("Dynamic")
9+
@desc("Checks for use of Dynamic type")
10+
class DynamicCheck extends Check {
11+
12+
public var severity:String;
13+
14+
public function new () {
15+
super ();
16+
severity = "INFO";
17+
}
18+
19+
override function _actualRun() {
20+
ComplexTypeUtils.walkFile (_checker.ast, callbackComplexType);
21+
}
22+
23+
function callbackComplexType(t:ComplexType, name:String, pos:Position):Void {
24+
if (t == null) return;
25+
if (isPosSuppressed (pos)) return;
26+
switch (t) {
27+
case TPath(p):
28+
if (Std.string (p).indexOf ("name => Dynamic") > -1) _error (name, pos);
29+
default:
30+
}
31+
}
32+
33+
function _error(name:String, pos:Position) {
34+
logPos('Dynamic type used: ${name}',
35+
pos, Reflect.field(SeverityLevel, severity));
36+
}
37+
}

0 commit comments

Comments
 (0)