From a6721d21d00216008986b14e62b4466367bad599 Mon Sep 17 00:00:00 2001
From: Peter Leibiger <kuhnroyal@gmail.com>
Date: Wed, 9 Dec 2020 16:31:08 +0100
Subject: [PATCH] [dart] Handle enumVarNames for negative names

---
 .../codegen/languages/DartClientCodegen.java  | 17 +++--
 .../codegen/dart/DartModelTest.java           | 71 ++++++++++++-------
 .../lib/model/enum_test.dart                  |  6 +-
 .../lib/model/enum_test.dart                  | 18 ++---
 4 files changed, 68 insertions(+), 44 deletions(-)

diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartClientCodegen.java
index b5a9e61b448..7b5654c7279 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartClientCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartClientCodegen.java
@@ -352,10 +352,6 @@ public class DartClientCodegen extends DefaultCodegen {
 
     @Override
     public String toVarName(String name) {
-        return  toVarName(name, "n");
-    }
-
-    private String toVarName(String name, String numberPrefix) {
         // replace - with _ e.g. created-at => created_at
         name = name.replace("-", "_");
 
@@ -380,7 +376,7 @@ public class DartClientCodegen extends DefaultCodegen {
         name = camelize(name, true);
 
         if (name.matches("^\\d.*")) {
-            name = numberPrefix + name;
+            name = "n" + name;
         }
 
         if (isReservedWord(name) || importMapping().containsKey(name)) {
@@ -535,7 +531,16 @@ public class DartClientCodegen extends DefaultCodegen {
         if (value.length() == 0) {
             return "empty";
         }
-        return toVarName(value, "number");
+        if (("number".equalsIgnoreCase(datatype) ||
+                "double".equalsIgnoreCase(datatype) ||
+                "int".equalsIgnoreCase(datatype)) &&
+                value.matches("^-?\\d.*")) {
+            // Only rename numeric values when the datatype is numeric
+            // AND the name is not changed by enum extensions (matches a numeric value).
+            boolean isNegative = value.startsWith("-");
+            return toVarName("number" + (isNegative ? "_negative" : "") + value);
+        }
+        return toVarName(value);
     }
 
     @Override
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/DartModelTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/DartModelTest.java
index 375c7c00cd0..f9489dd65fb 100644
--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/DartModelTest.java
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/DartModelTest.java
@@ -341,38 +341,57 @@ public class DartModelTest {
         Assert.assertEquals(codegen.toVarName(name), expectedName);
     }
 
+    private static class EnumVarName {
+        final String name;
+        final String expected;
+        final String dataType;
+
+        EnumVarName(String name, String expected, String dataType) {
+            this.name = name;
+            this.expected = expected;
+            this.dataType = dataType;
+        }
+    }
+
     @DataProvider(name = "enumVarNames")
-    public static Object[][] enumVarNames() {
-        return new Object[][] {
-                {"", "empty"},
-                {"Double", "double_"},
-                {"double", "double_"},
-                {"dynamic", "dynamic_"},
-                {"String", "string"},
-                {"string", "string"},
-                {"hello", "hello"},
-                {"FOO", "FOO"},
-                {"FOO_BAR", "FOO_BAR"},
-                {"FOO_BAR_BAZ_", "FOO_BAR_BAZ_"},
-                {"123hello", "number123hello"},
-                {"_hello", "hello"},
-                {"_double", "double_"},
-                {"_123hello", "number123hello"},
-                {"_5FOO", "number5fOO"},
-                {"_FOO", "FOO"},
-                {"_$foo", "dollarFoo"},
-                {"_$_foo_", "dollarFoo"},
-                {"$special[property.name]", "dollarSpecialLeftSquareBracketPropertyPeriodNameRightSquareBracket"},
-                {"$", "dollar"},
-                {">=", "greaterThanEqual"},
-                {"foo bar", "fooBar"},
+    public static Object[] enumVarNames() {
+        return new Object[] {
+                new EnumVarName("", "empty", "String"),
+                new EnumVarName("Double", "double_", "String"),
+                new EnumVarName("double", "double_", "String"),
+                new EnumVarName("dynamic", "dynamic_", "String"),
+                new EnumVarName("String", "string", "String"),
+                new EnumVarName("string", "string", "String"),
+                new EnumVarName("hello", "hello", "String"),
+                new EnumVarName("FOO", "FOO", "String"),
+                new EnumVarName("FOO_BAR", "FOO_BAR", "String"),
+                new EnumVarName("FOO_BAR_BAZ_", "FOO_BAR_BAZ_", "String"),
+                new EnumVarName("123hello", "n123hello", "String"),
+                new EnumVarName("_hello", "hello", "String"),
+                new EnumVarName("_double", "double_", "String"),
+                new EnumVarName("_123hello", "n123hello", "String"),
+                new EnumVarName("_5FOO", "n5fOO", "String"),
+                new EnumVarName("_FOO", "FOO", "String"),
+                new EnumVarName("_$foo", "dollarFoo", "String"),
+                new EnumVarName("_$_foo_", "dollarFoo", "String"),
+                new EnumVarName("$special[property.name]", "dollarSpecialLeftSquareBracketPropertyPeriodNameRightSquareBracket", "String"),
+                new EnumVarName("$", "dollar", "String"),
+                new EnumVarName(">=", "greaterThanEqual", "String"),
+                new EnumVarName("foo bar", "fooBar", "String"),
+                new EnumVarName("1", "number1", "int"),
+                new EnumVarName("2", "number2", "int"),
+                new EnumVarName("-1", "numberNegative1", "int"),
+                new EnumVarName("-99", "numberNegative99", "int"),
+                new EnumVarName("1", "number1", "double"),
+                new EnumVarName("1.1", "number1Period1", "double"),
+                new EnumVarName("-1.2", "numberNegative1Period2", "double"),
         };
     }
 
     @Test(dataProvider = "enumVarNames", description = "test enum names are correctly escaped")
-    public void convertEnumVarNames(String name, String expectedName) {
+    public void convertEnumVarNames(EnumVarName enumVar) {
         final DefaultCodegen codegen = new DartClientCodegen();
-        Assert.assertEquals(codegen.toEnumVarName(name, null), expectedName);
+        Assert.assertEquals(codegen.toEnumVarName(enumVar.name, enumVar.dataType), enumVar.expected);
     }
 
     @Test(description = "model names support `--model-name-prefix` and `--model-name-suffix`")
diff --git a/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake/lib/model/enum_test.dart b/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake/lib/model/enum_test.dart
index a9ce7fc6c60..01f58974f2d 100644
--- a/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake/lib/model/enum_test.dart
+++ b/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake/lib/model/enum_test.dart
@@ -99,7 +99,7 @@ class EnumTestEnumInteger extends EnumClass {
   @BuiltValueEnumConst(wireNumber: 1)
   static const EnumTestEnumInteger number1 = _$enumTestEnumInteger_number1;
   @BuiltValueEnumConst(wireNumber: -1)
-  static const EnumTestEnumInteger number1 = _$enumTestEnumInteger_number1;
+  static const EnumTestEnumInteger numberNegative1 = _$enumTestEnumInteger_numberNegative1;
 
   static Serializer<EnumTestEnumInteger> get serializer => _$enumTestEnumIntegerSerializer;
 
@@ -113,9 +113,9 @@ class EnumTestEnumInteger extends EnumClass {
 class EnumTestEnumNumber extends EnumClass {
 
   @BuiltValueEnumConst(wireName: '1.1')
-  static const EnumTestEnumNumber number1period1 = _$enumTestEnumNumber_number1period1;
+  static const EnumTestEnumNumber number1Period1 = _$enumTestEnumNumber_number1Period1;
   @BuiltValueEnumConst(wireName: '-1.2')
-  static const EnumTestEnumNumber number1period2 = _$enumTestEnumNumber_number1period2;
+  static const EnumTestEnumNumber numberNegative1Period2 = _$enumTestEnumNumber_numberNegative1Period2;
 
   static Serializer<EnumTestEnumNumber> get serializer => _$enumTestEnumNumberSerializer;
 
diff --git a/samples/openapi3/client/petstore/dart2/petstore_client_lib_fake/lib/model/enum_test.dart b/samples/openapi3/client/petstore/dart2/petstore_client_lib_fake/lib/model/enum_test.dart
index 957c0277871..3dbf11e656c 100644
--- a/samples/openapi3/client/petstore/dart2/petstore_client_lib_fake/lib/model/enum_test.dart
+++ b/samples/openapi3/client/petstore/dart2/petstore_client_lib_fake/lib/model/enum_test.dart
@@ -316,12 +316,12 @@ class EnumTestEnumIntegerEnum {
   String toJson() => value;
 
   static const number1 = EnumTestEnumIntegerEnum._(1);
-  static const number1 = EnumTestEnumIntegerEnum._(-1);
+  static const numberNegative1 = EnumTestEnumIntegerEnum._(-1);
 
   /// List of all possible values in this [enum][EnumTestEnumIntegerEnum].
   static const values = <EnumTestEnumIntegerEnum>[
     number1,
-    number1,
+    numberNegative1,
   ];
 
   static EnumTestEnumIntegerEnum fromJson(dynamic value) =>
@@ -355,7 +355,7 @@ class EnumTestEnumIntegerEnumTypeTransformer {
   EnumTestEnumIntegerEnum decode(dynamic data, {bool allowNull}) {
     switch (data) {
       case 1: return EnumTestEnumIntegerEnum.number1;
-      case -1: return EnumTestEnumIntegerEnum.number1;
+      case -1: return EnumTestEnumIntegerEnum.numberNegative1;
       default:
         if (allowNull == false) {
           throw ArgumentError('Unknown enum value to decode: $data');
@@ -389,13 +389,13 @@ class EnumTestEnumNumberEnum {
 
   String toJson() => value;
 
-  static const number1period1 = EnumTestEnumNumberEnum._('1.1');
-  static const number1period2 = EnumTestEnumNumberEnum._('-1.2');
+  static const number1Period1 = EnumTestEnumNumberEnum._('1.1');
+  static const numberNegative1Period2 = EnumTestEnumNumberEnum._('-1.2');
 
   /// List of all possible values in this [enum][EnumTestEnumNumberEnum].
   static const values = <EnumTestEnumNumberEnum>[
-    number1period1,
-    number1period2,
+    number1Period1,
+    numberNegative1Period2,
   ];
 
   static EnumTestEnumNumberEnum fromJson(dynamic value) =>
@@ -428,8 +428,8 @@ class EnumTestEnumNumberEnumTypeTransformer {
   /// and users are still using an old app with the old code.
   EnumTestEnumNumberEnum decode(dynamic data, {bool allowNull}) {
     switch (data) {
-      case '1.1': return EnumTestEnumNumberEnum.number1period1;
-      case '-1.2': return EnumTestEnumNumberEnum.number1period2;
+      case '1.1': return EnumTestEnumNumberEnum.number1Period1;
+      case '-1.2': return EnumTestEnumNumberEnum.numberNegative1Period2;
       default:
         if (allowNull == false) {
           throw ArgumentError('Unknown enum value to decode: $data');
-- 
GitLab