From bdcefa4616b5c1f5142f7d99009f1443d32a8156 Mon Sep 17 00:00:00 2001
From: Klaus Purer <klaus.purer@gmail.com>
Date: Fri, 24 Feb 2017 19:31:45 +0100
Subject: [PATCH] fix(ClassCreateInstanceSniff): Improve missing parenthesis
 detection within arrays (#2855714)

---
 .../Classes/ClassCreateInstanceSniff.php      | 18 ++++++++--------
 .../Classes/ClassCreateInstanceUnitTest.inc   | 21 +++++++++++++++++++
 .../ClassCreateInstanceUnitTest.inc.fixed     | 21 +++++++++++++++++++
 .../Classes/ClassCreateInstanceUnitTest.php   |  1 +
 4 files changed, 52 insertions(+), 9 deletions(-)

diff --git a/coder_sniffer/Drupal/Sniffs/Classes/ClassCreateInstanceSniff.php b/coder_sniffer/Drupal/Sniffs/Classes/ClassCreateInstanceSniff.php
index bfc38d0a..9476c7d2 100644
--- a/coder_sniffer/Drupal/Sniffs/Classes/ClassCreateInstanceSniff.php
+++ b/coder_sniffer/Drupal/Sniffs/Classes/ClassCreateInstanceSniff.php
@@ -45,16 +45,16 @@ class Drupal_Sniffs_Classes_ClassCreateInstanceSniff implements PHP_CodeSniffer_
     {
         $tokens = $phpcsFile->getTokens();
 
+        $commaOrColon = $phpcsFile->findNext([T_SEMICOLON, T_COLON, T_COMMA], ($stackPtr + 1));
+        if ($commaOrColon === false) {
+            // Syntax error, nothing we can do.
+            return;
+        }
+
         // Search for an opening parenthesis in the current statement until the
-        // next semicolon.
-        $nextParenthesis = $phpcsFile->findNext(T_OPEN_PARENTHESIS, $stackPtr, null, false, null, true);
-        // If there is a parenthesis owner then this is not a constructor call,
-        // but rather some array or somehting else. There seems to be a bug in PHPCS
-        // that finds PHP 7 array return type hints as parenthesis owner, exclude
-        // that.
-        if ($nextParenthesis === false || (isset($tokens[$nextParenthesis]['parenthesis_owner']) === true
-            && $tokens[$tokens[$nextParenthesis]['parenthesis_owner']]['code'] !== T_RETURN_TYPE)
-        ) {
+        // next semicolon or comma.
+        $nextParenthesis = $phpcsFile->findNext(T_OPEN_PARENTHESIS, ($stackPtr + 1), $commaOrColon);
+        if ($nextParenthesis === false) {
             $error       = 'Calling class constructors must always include parentheses';
             $constructor = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr + 1), null, true, null, true);
             // We can invoke the fixer if we know this is a static constructor
diff --git a/coder_sniffer/Drupal/Test/Classes/ClassCreateInstanceUnitTest.inc b/coder_sniffer/Drupal/Test/Classes/ClassCreateInstanceUnitTest.inc
index 5c9bdae4..638b5365 100644
--- a/coder_sniffer/Drupal/Test/Classes/ClassCreateInstanceUnitTest.inc
+++ b/coder_sniffer/Drupal/Test/Classes/ClassCreateInstanceUnitTest.inc
@@ -14,3 +14,24 @@ $obj2 = $obj1->add(new Vendor\DateTools\DateInterval);
 $obj2 = $obj1->add(new \Vendor\DateTools\DateInterval);
 
 $bar = new $foo[$x + 1][$y + 1];
+
+/**
+ * Test class.
+ */
+class Test2 {
+
+  /**
+   * Using PHP 7 return type hints is fine.
+   *
+   * @return ValidatorInterface[]
+   *   The validators.
+   */
+  public function getValidators(): array {
+    return [
+      new PublishedNodesValidator,
+      new MinimumNodesValidator($this->nrOfArticles),
+      new AccessibleOnCurrentDomainValidator($this->sectionService),
+    ];
+  }
+
+}
diff --git a/coder_sniffer/Drupal/Test/Classes/ClassCreateInstanceUnitTest.inc.fixed b/coder_sniffer/Drupal/Test/Classes/ClassCreateInstanceUnitTest.inc.fixed
index a15cb054..eceee63b 100644
--- a/coder_sniffer/Drupal/Test/Classes/ClassCreateInstanceUnitTest.inc.fixed
+++ b/coder_sniffer/Drupal/Test/Classes/ClassCreateInstanceUnitTest.inc.fixed
@@ -21,3 +21,24 @@ $obj2 = $obj1->add(new DateInterval());
 $obj2 = $obj1->add(new DateInterval());
 
 $bar = new $foo[$x + 1][$y + 1]();
+
+/**
+ * Test class.
+ */
+class Test2 {
+
+  /**
+   * Using PHP 7 return type hints is fine.
+   *
+   * @return ValidatorInterface[]
+   *   The validators.
+   */
+  public function getValidators(): array {
+    return [
+      new PublishedNodesValidator(),
+      new MinimumNodesValidator($this->nrOfArticles),
+      new AccessibleOnCurrentDomainValidator($this->sectionService),
+    ];
+  }
+
+}
diff --git a/coder_sniffer/Drupal/Test/Classes/ClassCreateInstanceUnitTest.php b/coder_sniffer/Drupal/Test/Classes/ClassCreateInstanceUnitTest.php
index 486de414..d30627d8 100644
--- a/coder_sniffer/Drupal/Test/Classes/ClassCreateInstanceUnitTest.php
+++ b/coder_sniffer/Drupal/Test/Classes/ClassCreateInstanceUnitTest.php
@@ -27,6 +27,7 @@ class Drupal_Sniffs_Classes_ClassCreateInstanceUnitTest extends CoderSniffUnitTe
                 13 => 1,
                 14 => 1,
                 16 => 1,
+                31 => 1,
                );
 
     }//end getErrorList()
-- 
GitLab