Repository: prettier/prettier (JavaScript)
Date: 2017-01-25 22:41:31+00:00
Task type: Bug Fix

Issue:
Array access breaking issue
Input:
```js
const mostExpandedasdasdfasdfasdfasdf = doc.expandedStates[doc.expandedStates.length - 1];
```

Output:
```js
const mostExpandedasdasdfasdfasdfasdf = doc.expandedStates[doc.expandedStates.length -
  1];
```

Expected Output:
```js
const mostExpandedasdasdfasdfasdfasdf = doc.expandedStates[
  doc.expandedStates.length - 1
];
```

https://jlongster.github.io/prettier/#%7B%22content%22%3A%22const%20mostExpandedasdasdfasdfasdfasdf%20%3D%20doc.expandedStates%5Bdoc.expandedStates.length%20-%201%5D%3B%22%2C%22options%22%3A%7B%22printWidth%22%3A80%2C%22tabWidth%22%3A2%2C%22singleQuote%22%3Afalse%2C%22trailingComma%22%3Afalse%2C%22bracketSpacing%22%3Atrue%7D%7D

If it's a function call, it's handled as expected:

https://jlongster.github.io/prettier/#%7B%22content%22%3A%22const%20mostExpandedasdasdfasdfasdfasdf%20%3D%20doc.expandedStates(doc.expandedStates.length%20-%201)%3B%22%2C%22options%22%3A%7B%22printWidth%22%3A80%2C%22tabWidth%22%3A2%2C%22singleQuote%22%3Afalse%2C%22trailingComma%22%3Afalse%2C%22bracketSpacing%22%3Atrue%7D%7D


Issue discussion:
Would you expect
```js
const mostExpandedasdasdfasdfasdfasdf = doc.expandedStates["aLongLongPropertyName"].something();
```
to be formatted to
```js
const mostExpandedasdasdfasdfasdfasdf = doc.expandedStates[
  "aLongLongPropertyName"
].something();
```

It makes sense to me. But is that what one would expect?

In that case I think I would expect what is currently done with function calls:

https://jlongster.github.io/prettier/#%7B%22content%22%3A%22const%20mostExpandedasdasdfasdfasdfasdf%20%3D%20doc.expandedStates(%5C%22aLongLongPropertyName%5C%22).something()%3B%22%2C%22options%22%3A%7B%22printWidth%22%3A80%2C%22tabWidth%22%3A2%2C%22singleQuote%22%3Afalse%2C%22trailingComma%22%3Afalse%2C%22bracketSpacing%22%3Atrue%7D%7D

```js
const mostExpandedasdasdfasdfasdfasdf = doc
  .expandedStates["aLongLongPropertyName"]
  .something();
```

or for it to recognize that the array access can be rewritten as a property access in this case:

```js
const mostExpandedasdasdfasdfasdfasdf = doc
  .expandedStates
  .aLongLongPropertyName
  .something();
```

Solution patch:
diff --git a/src/printer.js b/src/printer.js
index 28990dde8b65..5d17641f9f32 100644
--- a/src/printer.js
+++ b/src/printer.js
@@ -175,7 +175,7 @@ function genericPrintNoParens(path, options, print) {
     case "MemberExpression": {
       return concat([
         path.call(print, "object"),
-        printMemberLookup(path, print)
+        printMemberLookup(path, options, print)
       ]);
     }
     case "MetaProperty":
@@ -1981,10 +1981,14 @@ function printClass(path, print) {
   return parts;
 }
 
-function printMemberLookup(path, print) {
+function printMemberLookup(path, options, print) {
   const property = path.call(print, "property");
   const n = path.getValue();
-  return concat(n.computed ? [ "[", property, "]" ] : [ ".", property ]);
+
+  return concat(
+    n.computed
+    ? [ "[", group(concat([indent(options.tabWidth, concat([ softline, property ])), softline])), "]" ]
+    : [ ".", property ]);
 }
 
 // We detect calls on member expressions specially to format a
@@ -2043,7 +2047,7 @@ function printMemberChain(node, options, print) {
       .from(leftmostParent)
       .call(print, "callee", "object");
     const nodesPrinted = nodes.map(node => ({
-      property: printMemberLookup(FastPath.from(node.member), print),
+      property: printMemberLookup(FastPath.from(node.member), options, print),
       args: printArgumentsList(FastPath.from(node.call), options, print)
     }));
     const fullyExpanded = concat([


Test patch:
diff --git a/tests/member/__snapshots__/jsfmt.spec.js.snap b/tests/member/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
index 000000000000..c5533f8a00b3
--- /dev/null
+++ b/tests/member/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,9 @@
+exports[`test expand.js 1`] = `
+"const veryVeryVeryVeryVeryVeryVeryLong = doc.expandedStates[doc.expandedStates.length - 1];
+const small = doc.expandedStates[doc.expandedStates.length - 1];~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+const veryVeryVeryVeryVeryVeryVeryLong = doc.expandedStates[
+  doc.expandedStates.length - 1
+];
+const small = doc.expandedStates[doc.expandedStates.length - 1];
+"
+`;
diff --git a/tests/member/expand.js b/tests/member/expand.js
new file mode 100644
index 000000000000..16b399d470ab
--- /dev/null
+++ b/tests/member/expand.js
@@ -0,0 +1,2 @@
+const veryVeryVeryVeryVeryVeryVeryLong = doc.expandedStates[doc.expandedStates.length - 1];
+const small = doc.expandedStates[doc.expandedStates.length - 1];
\ No newline at end of file
diff --git a/tests/member/jsfmt.spec.js b/tests/member/jsfmt.spec.js
new file mode 100644
index 000000000000..989047bccc52
--- /dev/null
+++ b/tests/member/jsfmt.spec.js
@@ -0,0 +1,1 @@
+run_spec(__dirname);