Repository: eslint/eslint (js)

Issue:
linter.verifyAndFix incorrectly requires third argument
<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).

    This template is for bug reports. If you are reporting a bug, please continue on. If you are here for another reason, please see below:

    1. To propose a new rule: http://eslint.org/docs/developer-guide/contributing/new-rules
    2. To request a change: http://eslint.org/docs/developer-guide/contributing/changes
    3. If you have any questions, please stop by our chatroom: https://gitter.im/eslint/eslint

    Note that leaving sections blank will make it difficult for us to troubleshoot and we may have to close the issue.
-->

**Tell us about your environment**

* **ESLint Version:** master
* **Node Version:** 8.1.2
* **npm Version:** 5.0.3

**What parser (default, Babel-ESLint, etc.) are you using?**

N/A

**Please show your full configuration:**

N/A

**What did you do? Please include the actual source code causing the issue.**

<!-- Paste the source code below: -->
```js
const eslint = require("eslint");
const linter = new eslint.Linter();

linter.verifyAndFix("foo", { rules: { semi: "error" } })
```

**What did you expect to happen?**

I expected an object containing fix info to be returned:

```json
{ "fixed": true, "messages": [], "output": "foo;" }
```

**What actually happened? Please include the actual, raw output from ESLint.**

An error was thrown:

```
TypeError: Cannot read property 'filename' of undefined
    at Linter.verifyAndFix (/path/to/eslint/lib/linter.js:1221:46)
    at repl:1:8
    at ContextifyScript.Script.runInThisContext (vm.js:44:33)
    at REPLServer.defaultEval (repl.js:239:29)
    at bound (domain.js:301:14)
    at REPLServer.runBound [as eval] (domain.js:314:12)
    at REPLServer.onLine (repl.js:433:10)
    at emitOne (events.js:120:20)
    at REPLServer.emit (events.js:210:7)
    at REPLServer.Interface._onLine (readline.js:278:10)
```

It seems like the third "options" argument for `linter.verifyAndFix` is accidentally required. It's optional for `linter.verify`, so it should also be optional for `linter.verifyAndFix`.

As a workaround, one can use:

```js
linter.verifyAndFix(text, config, {});
```

Pull request:
Fix: don't require a third argument in linter.verifyAndFix (fixes #8805)
<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

**What is the purpose of this pull request? (put an "X" next to item)**

[x] Bug fix (https://github.com/eslint/eslint/issues/8805)

**What changes did you make? (Give an overview)**

Previously, `linter.verifyAndFix` would crash if no third argument was provided, because some debugging lines assumed that the argument always existed. This updates the method to make the third argument optional.

**Is there anything you'd like reviewers to focus on?**

Nothing in particular

Patch:
diff --git a/docs/developer-guide/nodejs-api.md b/docs/developer-guide/nodejs-api.md
index f48670896..0f006d781 100644
--- a/docs/developer-guide/nodejs-api.md
+++ b/docs/developer-guide/nodejs-api.md
@@ -159,7 +159,7 @@ var messages = linter.verifyAndFix("var foo", {
     rules: {
         semi: 2
     }
-}, { filename: "foo.js" });
+});
 ```
 
 Output object from this method:
diff --git a/docs/developer-guide/working-with-plugins.md b/docs/developer-guide/working-with-plugins.md
index c3bbccc48..0c8bfad22 100644
--- a/docs/developer-guide/working-with-plugins.md
+++ b/docs/developer-guide/working-with-plugins.md
@@ -221,9 +221,9 @@ Add these keywords into your `package.json` file to make it easy for others to f
 
 ### Working with Custom Parsers
 
-If you want to use your own parser and provide additional capabilities for your rules, you can specify your own custom parser. By default, the ESLint parser will use its parse method that takes in the source code as a first parameter and additional optional parameters as a second parameter to create an AST. You can specify a `parse` configuration to use your own custom parser. If a `parseForESLint` method is exposed, this method will be used to parse. Otherwise, the parser will use the parse method. `parseForESLint` behaves like `parse` and takes in the the source code and optional ESLint configurations. When `parseForESLint` is called, the method should return an object that contains the required property `ast` and an optional `services` property. `ast` should contain the AST. The `services` property contains the parser-dependent services. The value of the service property is available to rules as `context.parserServices`
+If you want to use your own parser and provide additional capabilities for your rules, you can specify your own custom parser. If a `parseForESLint` method is exposed on the parser, this method will be used to parse the code. Otherwise, the `parse` method will be used. Both methods should take in the the source code as the first argument, and an optional configuration object as the second argument (provided as `parserOptions` in a config file). The `parse` method should simply return the AST. The `parseForESLint` method should return an object that contains the required property `ast` and an optional `services` property. `ast` should contain the AST. The `services` property can contain any parser-dependent services (such as type checkers for nodes). The value of the `services` property is available to rules as `context.parserServices`.
 
-If no parseForESLint function is found, the parser will use the default parse method with the source code and the parser options. You can find a ESLint parser project [here](https://github.com/eslint/typescript-eslint-parser).
+You can find an ESLint parser project [here](https://github.com/eslint/typescript-eslint-parser).
 
     {
 
diff --git a/lib/linter.js b/lib/linter.js
index d2f1f4657..b8b3a5676 100755
--- a/lib/linter.js
+++ b/lib/linter.js
@@ -1205,6 +1205,7 @@ class Linter extends EventEmitter {
             fixedResult,
             fixed = false,
             passNumber = 0;
+        const debugTextDescription = options && options.filename || `${text.slice(0, 10)}...`;
 
         /**
          * This loop continues until one of the following is true:
@@ -1218,10 +1219,10 @@ class Linter extends EventEmitter {
         do {
             passNumber++;
 
-            debug(`Linting code for ${options.filename} (pass ${passNumber})`);
+            debug(`Linting code for ${debugTextDescription} (pass ${passNumber})`);
             messages = this.verify(text, config, options);
 
-            debug(`Generating fixed text for ${options.filename} (pass ${passNumber})`);
+            debug(`Generating fixed text for ${debugTextDescription} (pass ${passNumber})`);
             fixedResult = SourceCodeFixer.applyFixes(this.getSourceCode(), messages);
 
             // stop if there are any syntax errors.


Test patch:
diff --git a/tests/lib/linter.js b/tests/lib/linter.js
index 4acc46b3f..88ce63cb1 100644
--- a/tests/lib/linter.js
+++ b/tests/lib/linter.js
@@ -3776,6 +3776,20 @@ describe("eslint", () => {
             assert.equal(messages.output, "var a;", "Fixes were applied correctly");
             assert.isTrue(messages.fixed);
         });
+
+        it("does not require a third argument", () => {
+            const fixResult = linter.verifyAndFix("var a", {
+                rules: {
+                    semi: 2
+                }
+            });
+
+            assert.deepEqual(fixResult, {
+                fixed: true,
+                messages: [],
+                output: "var a;"
+            });
+        });
     });
 
     describe("Edge cases", () => {