/** * @param Node $node * A node to analyze * * @return void */ public function visitArray(Node $node) { $children = $node->children; if (count($children) <= 1) { // This plugin will never emit errors if there are 0 or 1 elements. return; } $hasEntryWithoutKey = false; $keySet = []; foreach ($children as $entry) { $key = $entry->children['key']; // Skip array entries without literal keys. if ($key === null) { $hasEntryWithoutKey = true; continue; } if (!is_scalar($key)) { // Skip non-literal keys. (TODO: Could check for constants (e.g. A::B) being used twice) continue; } if (isset($keySet[$key])) { $normalizedKey = self::normalizeKey($key); $this->plugin->emitIssue($this->code_base, $this->context, 'PhanPluginDuplicateArrayKey', "Duplicate/Equivalent array key literal({$normalizedKey}) detected in array - the earlier entry will be ignored.", Issue::SEVERITY_NORMAL, Issue::REMEDIATION_A, 15071); } $keySet[$key] = true; } if ($hasEntryWithoutKey && count($keySet) > 0) { // This is probably a typo in most codebases. (e.g. ['foo' => 'bar', 'baz']) // In phan, InternalFunctionSignatureMap.php does this deliberately with the first parameter being the return type. $this->plugin->emitIssue($this->code_base, $this->context, 'PhanPluginMixedKeyNoKey', "Should not mix array entries of the form [key => value,] with entries of the form [value,].", Issue::SEVERITY_NORMAL, Issue::REMEDIATION_A, 15071); } }
/** * @param Node $node * A node to analyze * * @return void */ public function visitVar(Node $node) { if ($node->children['name'] instanceof Node) { $this->plugin->emitIssue($this->code_base, $this->context, 'PhanPluginDollarDollar', "\$\$ Variables are not allowed."); } }
/** * @param Node $node * A node to analyze * * @return void */ public function visitInstanceof(Node $node) { // Debug::printNode($node); $class_name = $node->children['class']->children['name'] ?? null; // If we can't figure out the name of the class, don't // bother continuing. if (empty($class_name)) { return; } // As an example, enforce that we cannot call // instanceof against 'object'. if ($class_name == 'object') { $this->plugin->emitIssue($this->code_base, $this->context, 'PhanPluginInstanceOfObject', "Cannot call instanceof against `object`"); } }