Repository: ember-cli/eslint-plugin-ember (js)

Issue:
Auto-fixing 'no-get' with 'useOptionalChaining' broken with arrays
## Repro steps:
With
```
rules: {
  'ember/no-get': ['error', { useOptionalChaining: true }],
};
```
try to `--fix` the following code:
```
myFunc(myParam) {
  get(myParam, '0.myProperty');
}
```

## Expected results:
Probably something like
```
myParam['0']?.myProperty;
```

## Actual results:
```
myParam.0?.myProperty;
```
which crashes because `0` is not a valid identifier name

Pull request:
Fix autofix for array element access at beginning of path string in `no-get` rule
Fixes #997.

Before:

```js
this.get('0.foo')
```

After (old incorrect autofix):

```js
this.0?.foo
```

After (fixed autofix):

```js
this[0]?.foo
```

CC: @mongoose700

Patch:
diff --git a/lib/rules/no-get.js b/lib/rules/no-get.js
index c1a03c1c..492a5dbd 100644
--- a/lib/rules/no-get.js
+++ b/lib/rules/no-get.js
@@ -63,15 +63,16 @@ function fixGet({
   let replacementPath = isInLeftSideOfAssignmentExpression ? path : path.replace(/\./g, '?.');
 
   // Replace any array element access (foo.1 => foo[1] or foo?.[1]).
-  replacementPath = replacementPath.replace(
-    /\.(\d+)/g,
-    isInLeftSideOfAssignmentExpression ? '[$1]' : '.[$1]'
-  );
+  replacementPath = replacementPath
+    .replace(/\.(\d+)/g, isInLeftSideOfAssignmentExpression ? '[$1]' : '.[$1]') // Usages in middle of path.
+    .replace(/^(\d+)\?\./, isInLeftSideOfAssignmentExpression ? '[$1]' : '[$1]?.'); // Usage at beginning of path.
 
   // Add parenthesis around the object text in case of something like this: get(foo || {}, 'bar')
   const objectTextSafe = isValidJSPath(objectText) ? objectText : `(${objectText})`;
 
-  return fixer.replaceText(node, `${objectTextSafe}.${replacementPath}`);
+  const objectPathSeparator = replacementPath.startsWith('[') ? '' : '.';
+
+  return fixer.replaceText(node, `${objectTextSafe}${objectPathSeparator}${replacementPath}`);
 }
 
 module.exports = {


Test patch:
diff --git a/tests/lib/rules/no-get.js b/tests/lib/rules/no-get.js
index 81ace756..eb25e4c3 100644
--- a/tests/lib/rules/no-get.js
+++ b/tests/lib/rules/no-get.js
@@ -436,6 +436,18 @@ ruleTester.run('no-get', rule, {
         },
       ],
     },
+    {
+      // Handle array element access at beginning of string, with optional chaining.
+      code: "this.get('0.foo')",
+      options: [{ useOptionalChaining: true }],
+      output: 'this[0]?.foo',
+      errors: [
+        {
+          message: ERROR_MESSAGE_GET,
+          type: 'CallExpression',
+        },
+      ],
+    },
     {
       // Handle array element access (left side of an assignment).
       code: "this.get('foo.0.bar')[123] = 'hello world';",