diff --git a/External/Plugins/HaXeContext/Context.cs b/External/Plugins/HaXeContext/Context.cs index 53538d1023..fd982ee6b9 100644 --- a/External/Plugins/HaXeContext/Context.cs +++ b/External/Plugins/HaXeContext/Context.cs @@ -710,7 +710,7 @@ public override FileModel GetCodeModel(FileModel result, string src, bool script { result.haXe = true; base.GetCodeModel(result, src, scriptMode); - if (result.Members != null) + // members { for (var i = 0; i < result.Members.Count; i++) { @@ -726,9 +726,9 @@ public override FileModel GetCodeModel(FileModel result, string src, bool script } } } - if (result.Classes != null) + // classes { - for (int i = 0, length = result.Classes.Count; i < length; i++) + for (var i = 0; i < result.Classes.Count; i++) { var @class = result.Classes[i]; var flags = @class.Flags; @@ -758,6 +758,7 @@ public override FileModel GetCodeModel(FileModel result, string src, bool script } } } + else if ((flags & FlagType.Enum) != 0) @class.ExtendsType = "EnumValue"; else if (flags == FlagType.Class && @class.Members.Count > 0) { /** @@ -1502,6 +1503,13 @@ internal static bool TryResolveStaticExtensions(ClassModel type, FileModel inFil { result = type; var imports = Context.ResolveImports(inFile); + if ((type.Flags & FlagType.Enum) != 0 && (type.Flags & FlagType.Abstract) == 0 + && Context.ResolveType("haxe.EnumTools.EnumValueTools", null) is ClassModel @using && !@using.IsVoid()) + { + @using = (ClassModel)@using.Clone(); + @using.Flags |= FlagType.Using; + imports.Add(@using); + } if (imports.Count == 0) return false; var extensions = new MemberList(); for (var i = imports.Count - 1; i >= 0; i--) @@ -1549,7 +1557,26 @@ bool CanBeExtended(ClassModel target, MemberModel extension, Visibility access) { var firstParamType = extension.Parameters[0].Type; if (string.IsNullOrEmpty(firstParamType)) return false; - if (firstParamType != "Dynamic" && !firstParamType.StartsWithOrdinal("Dynamic<")) + if (!string.IsNullOrEmpty(extension.Template) && Context.ResolveType(firstParamType, null).IsVoid()) + { + // transform methodName(a:T, b) to methodName(a:ConcreteType, b) + var template = extension.Template.Substring(1, extension.Template.Length - 2); + var parts = Context is Context ctx && ctx.GetCurrentSDKVersion() >= "4.0.0" + ? template.Split(new[] {'&'}, StringSplitOptions.RemoveEmptyEntries) + : template.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries); + foreach (var part in parts) + { + if (!part.Contains(':')) continue; + var templateToType = part.Split(new[] {':'}, StringSplitOptions.RemoveEmptyEntries); + if (templateToType[0] != firstParamType) continue; + if (templateToType.Length == 2) firstParamType = templateToType[1]; + break; + } + } + if ((target.Flags & FlagType.Enum) != 0 && (target.Flags & FlagType.Abstract) == 0 && firstParamType == "EnumValue") + { + } + else if (firstParamType != "Dynamic" && !firstParamType.StartsWithOrdinal("Dynamic<")) { var targetType = type.Type; var index = targetType.IndexOf('<'); diff --git a/Tests/External/Plugins/HaxeContext.Tests/Completion/CodeCompleteTests.cs b/Tests/External/Plugins/HaxeContext.Tests/Completion/CodeCompleteTests.cs index b020a3b3fc..cac98cc462 100644 --- a/Tests/External/Plugins/HaxeContext.Tests/Completion/CodeCompleteTests.cs +++ b/Tests/External/Plugins/HaxeContext.Tests/Completion/CodeCompleteTests.cs @@ -1225,6 +1225,18 @@ static IEnumerable OnCharAndReplaceTextIssue2750TestCases } } + static IEnumerable OnCharAndReplaceTextIssue2757TestCases + { + get + { + yield return new TestCaseData("BeforeOnCharAndReplaceText_issue2757_1", '.', false) + .Returns(CodeCompleteTests.ReadAllText("AfterOnCharAndReplaceText_issue2757_1")) + .SetName("enumValue. Issue 2757. Case 1") + .SetDescription("https://github.com/fdorg/flashdevelop/issues/2757"); + + } + } + [ Test, TestCaseSource(nameof(OnCharAndReplaceTextTestCases)), @@ -1250,6 +1262,7 @@ static IEnumerable OnCharAndReplaceTextIssue2750TestCases TestCaseSource(nameof(OnCharAndReplaceTextIssue2577TestCases)), TestCaseSource(nameof(OnCharAndReplaceTextIssue2726TestCases)), TestCaseSource(nameof(OnCharAndReplaceTextIssue2750TestCases)), + TestCaseSource(nameof(OnCharAndReplaceTextIssue2757TestCases)), ] public string OnCharAndReplaceText(string fileName, char addedChar, bool autoHide) { diff --git a/Tests/External/Plugins/HaxeContext.Tests/HaxeContext.Tests.csproj b/Tests/External/Plugins/HaxeContext.Tests/HaxeContext.Tests.csproj index b750b66b66..a3d3b7a8d3 100644 --- a/Tests/External/Plugins/HaxeContext.Tests/HaxeContext.Tests.csproj +++ b/Tests/External/Plugins/HaxeContext.Tests/HaxeContext.Tests.csproj @@ -1270,6 +1270,8 @@ + + diff --git a/Tests/External/Plugins/HaxeContext.Tests/Test Files/completion/AfterOnCharAndReplaceText_issue2757_1.hx b/Tests/External/Plugins/HaxeContext.Tests/Test Files/completion/AfterOnCharAndReplaceText_issue2757_1.hx new file mode 100644 index 0000000000..9bdad17d46 --- /dev/null +++ b/Tests/External/Plugins/HaxeContext.Tests/Test Files/completion/AfterOnCharAndReplaceText_issue2757_1.hx @@ -0,0 +1,9 @@ +package; +class Issue2757_1 { + function foo() { + var e:PIssue2757; + e.equals + } +} + +private enum PIssue2757 {} \ No newline at end of file diff --git a/Tests/External/Plugins/HaxeContext.Tests/Test Files/completion/BeforeOnCharAndReplaceText_issue2757_1.hx b/Tests/External/Plugins/HaxeContext.Tests/Test Files/completion/BeforeOnCharAndReplaceText_issue2757_1.hx new file mode 100644 index 0000000000..5add2d2bfe --- /dev/null +++ b/Tests/External/Plugins/HaxeContext.Tests/Test Files/completion/BeforeOnCharAndReplaceText_issue2757_1.hx @@ -0,0 +1,9 @@ +package; +class Issue2757_1 { + function foo() { + var e:PIssue2757; + e.$(EntryPoint) + } +} + +private enum PIssue2757 {} \ No newline at end of file