Skip to content

Commit

Permalink
Handle default: keyword within switch statement. fixes #273
Browse files Browse the repository at this point in the history
  • Loading branch information
mastef authored and SlavaRa committed Oct 24, 2017
1 parent 7c0ad1b commit b1bda93
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ report/
test/issues/generated/
run.n
*.hxproj
out/
2 changes: 2 additions & 0 deletions src/as3hx/As3.hx
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ typedef SwitchCase = {
typedef SwitchDefault = {
var el : Array<Expr>;
var meta : Array<Expr>;
@:optional var vals : Array<Expr>;
@:optional var before : SwitchCase;
}

enum Definition {
Expand Down
67 changes: 55 additions & 12 deletions src/as3hx/Writer.hx
Original file line number Diff line number Diff line change
Expand Up @@ -1172,7 +1172,7 @@ class Writer
if(cfg.debugExpr)
write(" /* " + Std.string(expr) + " */ ");

if(expr == null) return None;
if (expr == null) return None;
var rv = Semi;
switch(expr) {
case ETypedExpr(e, t): rv = writeExpr(e);
Expand Down Expand Up @@ -1276,7 +1276,14 @@ class Writer
f(def.el[def.el.length - 1], def.el);
}
}
newCases = loopCases(cases.slice(0), def == null ? null : def.el.slice(0), testVar, newCases);

if (def != null && def.before == null) {
// default is in the end
newCases = loopCases(cases.copy(), def.el.copy(), testVar, newCases);
} else {
// default is not in the end, so don't catch fall-through
newCases = loopCases(cases.copy(), null, testVar, newCases);
}

if(writeTestVar) {
write("var ");
Expand All @@ -1299,6 +1306,14 @@ class Writer

lvl++;
for(c in newCases) {

if(def != null &&
def.before != null &&
def.before.el.toString() == c.el.toString()) {
writeSwitchDefault(def);
def = null;
}

writeMetaData(c.meta); //write commnent and newline before "case"
write("case ");
for(i in 0...c.vals.length) {
Expand All @@ -1323,16 +1338,9 @@ class Writer
if (didIndent)
lvl--;
}
if (def != null)
{
writeMetaData(def.meta); //write commnent and newline before "default"
write("default:");
lvl++;
for (i in 0...def.el.length)
{
writeFinish(writeExpr(def.el[i]));
}
lvl--;
if(def != null) {
writeSwitchDefault(def);
def = null;
}
lvl--;
write(closeb());
Expand Down Expand Up @@ -1457,6 +1465,41 @@ class Writer
return rv;
}

function writeSwitchDefault(def:SwitchDefault) {
if(def.vals != null && def.vals.length > 0) {
writeNL();
writeIndent();
write("/* covers case ");
for (i in 0 ... def.vals.length) {
write(i>0 ? ", " : "");
writeExpr(def.vals[i]);
}
write(":");
write(" */");
}

var newMeta = [];
var lastNL = false;
for(d in def.meta) {
switch(d) {
case ENL(e):
if(!lastNL) newMeta.push(d);
lastNL = true;
default:
lastNL = false;
newMeta.push(d);
}
}
writeMetaData(newMeta); //write comment and newline before "default"
write("default:");
lvl++;
for (i in 0...def.el.length)
{
writeFinish(writeExpr(def.el[i]));
}
lvl--;
}

function writeEBlock(e:Array<Expr>):BlockEnd {
var result = Semi;
if(!isInterface) {
Expand Down
32 changes: 29 additions & 3 deletions src/as3hx/parsers/StructureParser.hx
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ class StructureParser {
var e = EParent(parseExpr(false));
tokenizer.ensure(TPClose);

var def = null, cl = [], meta = [];
var def:SwitchDefault = null, cl = [], meta = [];
tokenizer.ensure(TBrOpen);

//parse all "case" and "default"
Expand All @@ -185,14 +185,40 @@ class StructureParser {
case TId(s):
if (s == "default") {
tokenizer.ensure(TColon);
def = { el : parseCaseBlock(), meta : meta };
def = { el : parseCaseBlock(), meta : meta, before: null };
meta = [];
}
else if (s == "case"){
var val = parseExpr(false);
tokenizer.ensure(TColon);
var el = parseCaseBlock();
cl.push( { val : val, el : el, meta : meta } );

// default already set, and is empty
// we assign this case to default
if(def != null && def.el.length == 0) {
def.el = el;
def.meta = def.meta.concat(meta);
if(def.vals == null) def.vals = [];
def.vals.push(val);
}
// default already set, and has same
// content as this case
else if(def != null && def.el == el){
def.meta = def.meta.concat(meta);
def.el = el;
if(def.vals == null) def.vals = [];
def.vals.push(val);
}
// normal case, default not set yet, or differs
else {
var caseObj = { val : val, el : el, meta : meta }
// default already set, but case follows it
// mark that default is before this case
if(def != null && def.before == null) {
def.before = caseObj;
}
cl.push(caseObj);
}

//reset for next case or default
meta = [];
Expand Down
29 changes: 29 additions & 0 deletions test/issues/Issue273.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package {
public class Issue273 {
public function Issue273() {
var param1 = "j";
switch(param1)
{
case "a":
return 1;
case "b":
return 2;
case "c":
return 3;
case "d":
return 4;
case "e":
return 5;
case "f":
return 6;
case "g":
return 7;
case "h":
return 8;
default:
case "i":
return 9;
}
}
}
}
30 changes: 30 additions & 0 deletions test/issues/Issue273.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

class Issue273
{
public function new()
{
var param1 = "j";
switch (param1)
{
case "a":
return 1;
case "b":
return 2;
case "c":
return 3;
case "d":
return 4;
case "e":
return 5;
case "f":
return 6;
case "g":
return 7;
case "h":
return 8;
/* covers case "i": */
default:
return 9;
}
}
}
5 changes: 5 additions & 0 deletions test/unit/as3hx/AS3HXTest.hx
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,11 @@ class AS3HXTest {
generate("Issue2.as", "Issue2.hx");
}

@Test("https://github.com/HaxeFoundation/as3hx/issues/273")
public function issue273() {
generate("Issue273.as", "Issue273.hx");
}

function generate(as3FileName:String, expectedHaxeFileName:String) {
var issuesDirectory = FileSystem.absolutePath("test/issues");
var generatedDirectoryPath = '$issuesDirectory/generated';
Expand Down

0 comments on commit b1bda93

Please sign in to comment.