From c8c8b9c7351445bb36c648b213eac22ba83dbe0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20Dziewo=C5=84ski?= Date: Fri, 28 Oct 2022 06:31:05 +0200 Subject: [PATCH] Avoid Phan PhanUndeclaredMethod false positives The insertBefore() and appendChild() methods return their first argument, but Phan only knows that they return a DOMNode, even though we passed in a DOMElement. Rearrange slightly to avoid this pattern. Change-Id: I04c58458e1ba0d728374ead756afb6facf970766 --- .phan/config.php | 6 ------ includes/ImageMap.php | 18 +++++++++++++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.phan/config.php b/.phan/config.php index b5c72b6..ced85a2 100644 --- a/.phan/config.php +++ b/.phan/config.php @@ -2,10 +2,4 @@ $cfg = require __DIR__ . '/../vendor/mediawiki/mediawiki-phan-config/src/config.php'; -// Phan gets confused because DOMNode::setAttribute doesn't -// exist, it's DOMElement::setAttribute, and some functions -// are documented to return DOMNode but they actually return -// DOMElement. -$cfg['suppress_issue_types'][] = 'PhanUndeclaredMethod'; - return $cfg; diff --git a/includes/ImageMap.php b/includes/ImageMap.php index 4c7649a..1cfe93c 100644 --- a/includes/ImageMap.php +++ b/includes/ImageMap.php @@ -22,12 +22,14 @@ namespace MediaWiki\Extension\ImageMap; use ConfigFactory; use DOMDocumentFragment; +use DOMElement; use MediaWiki\Hook\ParserFirstCallInitHook; use MediaWiki\MediaWikiServices; use OutputPage; use Parser; use Sanitizer; use Title; +use Wikimedia\Assert\Assert; use Wikimedia\Parsoid\Utils\DOMCompat; use Wikimedia\Parsoid\Utils\DOMUtils; use Xml; @@ -318,10 +320,12 @@ class ImageMap implements ParserFirstCallInitHook { $anchor = $imageNode; } - $div = $parent->insertBefore( $domDoc->createElement( 'div' ), $anchor ); + $div = $domDoc->createElement( 'div' ); + $parent->insertBefore( $div, $anchor ); $div->setAttribute( 'class', 'noresize' ); if ( $defaultLinkAttribs ) { - $defaultAnchor = $div->appendChild( $domDoc->createElement( 'a' ) ); + $defaultAnchor = $domDoc->createElement( 'a' ); + $div->appendChild( $defaultAnchor ); foreach ( $defaultLinkAttribs as $name => $value ) { $defaultAnchor->setAttribute( $name, $value ); } @@ -340,6 +344,7 @@ class ImageMap implements ParserFirstCallInitHook { } else { $anchor = $imageNode->parentNode; $wrapper = $anchor->parentNode; + Assert::precondition( $wrapper instanceof DOMElement, 'Anchor node has a parent' ); $classes = $wrapper->getAttribute( 'class' ); @@ -401,20 +406,23 @@ class ImageMap implements ParserFirstCallInitHook { $marginTop = -20; } $div->setAttribute( 'style', "height: {$thumbHeight}px; width: {$thumbWidth}px; " ); - $descWrapper = $div->appendChild( $domDoc->createElement( 'div' ) ); + $descWrapper = $domDoc->createElement( 'div' ); + $div->appendChild( $descWrapper ); $descWrapper->setAttribute( 'style', "margin-left: {$marginLeft}px; " . "margin-top: {$marginTop}px; " . "text-align: left;" ); - $descAnchor = $descWrapper->appendChild( $domDoc->createElement( 'a' ) ); + $descAnchor = $domDoc->createElement( 'a' ); + $descWrapper->appendChild( $descAnchor ); $descAnchor->setAttribute( 'href', $imageTitle->getLocalURL() ); $descAnchor->setAttribute( 'title', wfMessage( 'imagemap_description' )->inContentLanguage()->text() ); - $descImg = $descAnchor->appendChild( $domDoc->createElement( 'img' ) ); + $descImg = $domDoc->createElement( 'img' ); + $descAnchor->appendChild( $descImg ); $descImg->setAttribute( 'alt', wfMessage( 'imagemap_description' )->inContentLanguage()->text()