Skip to content

Commit

Permalink
[analyzer] don't mark non-final instance fields as pure (fixes #9029)
Browse files Browse the repository at this point in the history
  • Loading branch information
RealyUniqueName committed Mar 21, 2020
1 parent 042358b commit e15c021
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 6 deletions.
15 changes: 9 additions & 6 deletions src/optimization/analyzerTexpr.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1213,7 +1213,7 @@ module Purity = struct
taint node;
raise Exit

let apply_to_field com is_ctor c cf =
let apply_to_field com is_ctor is_static c cf =
let node = get_node c cf in
let check_field c cf =
let node' = get_node c cf in
Expand All @@ -1233,8 +1233,9 @@ module Purity = struct
taint_raise node
end
and loop e = match e.eexpr with
| TMeta((Meta.Pure,_,_),_) ->
()
| TMeta((Meta.Pure,_,_) as m,_) ->
if get_purity_from_meta [m] = Impure then taint_raise node
else ()
| TThrow _ ->
taint_raise node;
| TBinop((OpAssign | OpAssignOp _),e1,e2) ->
Expand Down Expand Up @@ -1269,6 +1270,8 @@ module Purity = struct
match cf.cf_kind with
| Method MethDynamic | Var _ ->
taint node;
| _ when not (is_static || is_ctor || has_class_field_flag cf CfFinal) ->
taint node
| _ ->
match cf.cf_expr with
| None ->
Expand All @@ -1287,9 +1290,9 @@ module Purity = struct
()

let apply_to_class com c =
List.iter (apply_to_field com false c) c.cl_ordered_fields;
List.iter (apply_to_field com false c) c.cl_ordered_statics;
(match c.cl_constructor with Some cf -> apply_to_field com true c cf | None -> ())
List.iter (apply_to_field com false false c) c.cl_ordered_fields;
List.iter (apply_to_field com false true c) c.cl_ordered_statics;
(match c.cl_constructor with Some cf -> apply_to_field com true false c cf | None -> ())

let infer com =
Hashtbl.clear node_lut;
Expand Down
12 changes: 12 additions & 0 deletions tests/server/src/Main.hx
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,18 @@ class ServerTests extends HaxeServerTestCase {
Assert.isTrue(messages.exists(message -> r.match(message)));
}

function testIssue9029_analyzer_preventPurityOnOverridden() {
vfs.putContent("Main.hx", getTemplate("issues/Issue9029/Main.hx"));
vfs.putContent("Game.hx", getTemplate("issues/Issue9029/Game.hx"));
vfs.putContent("Screen.hx", getTemplate("issues/Issue9029/Screen.hx"));
var args = ["-main", "Main", "-D", "analyzer-optimize", "--interp"];
runHaxe(args);
vfs.putContent("Game.hx", getTemplate("issues/Issue9029/Game.hx.modified"));
runHaxeJson([], ServerMethods.Invalidate, {file: new FsPath("Game.hx")});
runHaxe(args);
assertSuccess();
}

// function testIssue8616() {
// vfs.putContent("Main.hx", getTemplate("issues/Issue8616/Main.hx"));
// vfs.putContent("A.hx", getTemplate("issues/Issue8616/A.hx"));
Expand Down
5 changes: 5 additions & 0 deletions tests/server/test/templates/issues/Issue9029/Game.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class Game extends Screen {
override function onStart() {
// trace(123);
}
}
5 changes: 5 additions & 0 deletions tests/server/test/templates/issues/Issue9029/Game.hx.modified
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class Game extends Screen {
override function onStart() {
trace(123);
}
}
5 changes: 5 additions & 0 deletions tests/server/test/templates/issues/Issue9029/Main.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class Main {
static function main() {
final game = new Game();
}
}
7 changes: 7 additions & 0 deletions tests/server/test/templates/issues/Issue9029/Screen.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Screen {
public function new() {
onStart();
}

function onStart():Void {}
}

0 comments on commit e15c021

Please sign in to comment.