diff --git a/src/refactor/refactor/ExtractInterface.hx b/src/refactor/refactor/ExtractInterface.hx index ddd3034..249605f 100644 --- a/src/refactor/refactor/ExtractInterface.hx +++ b/src/refactor/refactor/ExtractInterface.hx @@ -291,7 +291,33 @@ class ExtractInterface { for (field in fields) { buf.add("\t"); var text:String = RefactorHelper.extractText(context.converter, extractData.content, field.pos.min, field.pos.max); - text = text.replace(" public ", " "); + var index = text.lastIndexOf("function "); + if (index < 0) { + index = text.lastIndexOf("var "); + } + if (index < 0) { + index = text.lastIndexOf("final "); + } + if (index > 0) { + var commentIndex:Int = text.lastIndexOf("*/", index); + var comment = ""; + if (commentIndex < 0) { + commentIndex = 0; + } + if (commentIndex > 0) { + comment = text.substr(0, commentIndex); + } + var modifier = text.substring(commentIndex, index); + final funcSignature = text.substr(index); + modifier = modifier.replace("public", ""); + modifier = modifier.replace("inline", ""); + modifier = modifier.replace("override", ""); + modifier = modifier.replace("abstract", ""); + text = comment + modifier + funcSignature; + if (!funcSignature.endsWith(";")) { + text += ";"; + } + } buf.add(text); if (field.isSharp) { buf.add("\n"); diff --git a/src/refactor/rename/RenameHelper.hx b/src/refactor/rename/RenameHelper.hx index 48cc2f1..4f93a2d 100644 --- a/src/refactor/rename/RenameHelper.hx +++ b/src/refactor/rename/RenameHelper.hx @@ -113,6 +113,18 @@ class RenameHelper { } name = name.substr(0, index); + function addMatchToChangelist(type:Type) { + if (!types.contains(type)) { + return; + } + var pos:IdentifierPos = { + fileName: use.pos.fileName, + start: use.pos.start + name.length + 1, + end: use.pos.end + }; + pos.end = pos.start + fromName.length; + changelist.addChange(use.pos.fileName, ReplaceText(context.what.toName, pos, false), use); + } var search:SearchTypeOf = { name: name, pos: use.pos.start, @@ -122,20 +134,21 @@ class RenameHelper { switch (typeHint) { case null: case ClasspathType(type, _): - for (t in types) { - if (t != type) { - continue; - } - var pos:IdentifierPos = { - fileName: use.pos.fileName, - start: use.pos.start + name.length + 1, - end: use.pos.end - }; - pos.end = pos.start + fromName.length; - changelist.addChange(use.pos.fileName, ReplaceText(context.what.toName, pos, false), use); + addMatchToChangelist(type); + case LibType(name, fullName, params): + if (name != "Null") { + return; } - case LibType(_, _) | UnknownType(_): - case FunctionType(_, _) | StructType(_): + if (params == null || params.length != 1) { + return; + } + switch (params[0]) { + case ClasspathType(type, _): + addMatchToChangelist(type); + case LibType(_) | FunctionType(_) | StructType(_) | UnknownType(_): + } + + case UnknownType(_) | FunctionType(_, _) | StructType(_): } }); } diff --git a/src/refactor/typing/TypingHelper.hx b/src/refactor/typing/TypingHelper.hx index 5d5d28a..5c74bc8 100644 --- a/src/refactor/typing/TypingHelper.hx +++ b/src/refactor/typing/TypingHelper.hx @@ -164,7 +164,18 @@ class TypingHelper { case ClasspathType(t, params): return findField(context, t, part).then(findFieldForPart); case LibType(t, fullPath, params): - return Promise.reject('unable to determine type of "$part" in ${searchTypeOf.defineType.name.name}@${searchTypeOf.pos}'); + if (t != "Null") { + return Promise.reject('unable to determine type of "$part" in ${searchTypeOf.defineType.name.name}@${searchTypeOf.pos}'); + } + if (params == null || params.length != 1) { + return Promise.reject('unable to determine type of "$part" in ${searchTypeOf.defineType.name.name}@${searchTypeOf.pos}'); + } + switch (params[0]) { + case ClasspathType(t, typeParams): + return findField(context, t, part).then(findFieldForPart); + case LibType(_) | FunctionType(_) | StructType(_) | UnknownType(_): + return Promise.reject('unable to determine type of "$part" in ${searchTypeOf.defineType.name.name}@${searchTypeOf.pos}'); + } case StructType(fields): return Promise.reject('unable to determine type of "$part" in ${searchTypeOf.defineType.name.name}@${searchTypeOf.pos}'); case FunctionType(args, retVal): @@ -363,7 +374,9 @@ class TypingHelper { if ((hint.uses == null) || (hint.uses.length <= 0)) { return Promise.reject(); } - return typeFromTypeHint(context, hint.uses[0]); + return typeFromTypeHint(context, hint.uses[0]).then(function(typeHint) { + return Promise.resolve(LibType("Null", "Null", [typeHint])); + }); } var parts:Array = hint.name.split("."); diff --git a/test/refactor/refactor/RefactorExtractMethodTest.hx b/test/refactor/refactor/RefactorExtractMethodTest.hx index cb50996..d297513 100644 --- a/test/refactor/refactor/RefactorExtractMethodTest.hx +++ b/test/refactor/refactor/RefactorExtractMethodTest.hx @@ -209,6 +209,64 @@ class RefactorExtractMethodTest extends RefactorTestBase { checkRefactor(RefactorExtractMethod, {fileName: "testcases/methods/Main.hx", posStart: 1365, posEnd: 1543}, edits, async); } + function testDemoSimple(async:Async) { + var edits:Array = [ + makeReplaceTestEdit("testcases/methods/Demo.hx", "doSomethingExtract();\n", 161, 252, true), + makeInsertTestEdit("testcases/methods/Demo.hx", + "function doSomethingExtract() {\n" + + "doNothing();\n" + + " trace(\"I'm here\");\n" + + " doNothing();\n" + + " trace(\"yep, still here\");\n" + + " doNothing();\n" + + "}\n", + 467, true), + ]; + checkRefactor(RefactorExtractMethod, {fileName: "testcases/methods/Demo.hx", posStart: 160, posEnd: 252}, edits, async); + } + + function testDemoSwitch(async:Async) { + var edits:Array = [ + makeReplaceTestEdit("testcases/methods/Demo.hx", "doSomethingExtract(cond, val, text);\n", 262, 463, true), + makeInsertTestEdit("testcases/methods/Demo.hx", + "function doSomethingExtract(cond:Bool, val:Int, text:Null) {\n" + + "return switch [cond, val] {\n" + + " case [true, 0]:\n" + + " std.Math.random() * val;\n" + + " case [true, _]:\n" + + " val + val;\n" + + " case [false, 10]:\n" + + " Std.parseFloat(text);\n" + + " case [_, _]:\n" + + " std.Math.NEGATIVE_INFINITY;\n" + + " }\n" + + "}\n", + 467, true), + ]; + checkRefactor(RefactorExtractMethod, {fileName: "testcases/methods/Demo.hx", posStart: 262, posEnd: 463}, edits, async); + } + + function testDemoReturnSwitch(async:Async) { + var edits:Array = [ + makeReplaceTestEdit("testcases/methods/Demo.hx", "return doSomethingExtract(cond, val, text);\n", 255, 463, true), + makeInsertTestEdit("testcases/methods/Demo.hx", + "function doSomethingExtract(cond:Bool, val:Int, text:Null) {\n" + + "return switch [cond, val] {\n" + + " case [true, 0]:\n" + + " std.Math.random() * val;\n" + + " case [true, _]:\n" + + " val + val;\n" + + " case [false, 10]:\n" + + " Std.parseFloat(text);\n" + + " case [_, _]:\n" + + " std.Math.NEGATIVE_INFINITY;\n" + + " }\n" + + "}\n", + 467, true), + ]; + checkRefactor(RefactorExtractMethod, {fileName: "testcases/methods/Demo.hx", posStart: 254, posEnd: 463}, edits, async); + } + function testCalculateMath(async:Async) { var edits:Array = [ makeReplaceTestEdit("testcases/methods/Math.hx", "calculateExtract(a, b);\n", 106, 122, true),