Skip to content

Commit e100b80

Browse files
authored
[TASK] Add and implement Positionable interface (#1232)
This the backport of #1221 and #1225.
1 parent aa12119 commit e100b80

File tree

18 files changed

+603
-168
lines changed

18 files changed

+603
-168
lines changed

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,29 @@ This project adheres to [Semantic Versioning](https://semver.org/).
77

88
### Added
99

10+
- Methods `getLineNumber` and `getColumnNumber` which return a nullable `int`
11+
for the following classes:
12+
`Comment`, `CSSList`, `SourceException`, `Charset`, `CSSNamespace`, `Import`,
13+
`Rule`, `DeclarationBlock`, `RuleSet`, `CSSFunction`, `Value` (#1225)
14+
- `Positionable` interface for CSS items that may have a position
15+
(line and perhaps column number) in the parsed CSS (#1221)
16+
1017
### Changed
1118

19+
- Implement `Positionable` in the following CSS item classes:
20+
`Comment`, `CSSList`, `SourceException`, `Charset`, `CSSNamespace`, `Import`,
21+
`Rule`, `DeclarationBlock`, `RuleSet`, `CSSFunction`, `Value` (#1225)
22+
1223
### Deprecated
1324

25+
- `getLineNo()` is deprecated in these classes (use `getLineNumber()` instead):
26+
`Comment`, `CSSList`, `SourceException`, `Charset`, `CSSNamespace`, `Import`,
27+
`Rule`, `DeclarationBlock`, `RuleSet`, `CSSFunction`, `Value` (#1225, #1233)
28+
- `Rule::getColNo()` is deprecated (use `getColumnNumber()` instead)
29+
(#1225, #1233)
30+
- Providing zero as the line number argument to `Rule::setPosition()` is
31+
deprecated (pass `null` instead if there is no line number) (#1225, #1233)
32+
1433
### Removed
1534

1635
### Fixed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
"ext-iconv": "*"
2828
},
2929
"require-dev": {
30-
"phpunit/phpunit": "5.7.27 || 6.5.14 || 7.5.20 || 8.5.41"
30+
"phpunit/phpunit": "5.7.27 || 6.5.14 || 7.5.20 || 8.5.41",
31+
"rawr/cross-data-providers": "^2.0.0"
3132
},
3233
"suggest": {
3334
"ext-mbstring": "for parsing UTF-8 CSS"

src/CSSList/CSSList.php

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
use Sabberworm\CSS\Parsing\SourceException;
1010
use Sabberworm\CSS\Parsing\UnexpectedEOFException;
1111
use Sabberworm\CSS\Parsing\UnexpectedTokenException;
12+
use Sabberworm\CSS\Position\Position;
13+
use Sabberworm\CSS\Position\Positionable;
1214
use Sabberworm\CSS\Property\AtRule;
1315
use Sabberworm\CSS\Property\Charset;
1416
use Sabberworm\CSS\Property\CSSNamespace;
@@ -29,8 +31,10 @@
2931
*
3032
* It can also contain `Import` and `Charset` objects stemming from at-rules.
3133
*/
32-
abstract class CSSList implements Renderable, Commentable
34+
abstract class CSSList implements Commentable, Positionable, Renderable
3335
{
36+
use Position;
37+
3438
/**
3539
* @var array<array-key, Comment>
3640
*
@@ -45,21 +49,14 @@ abstract class CSSList implements Renderable, Commentable
4549
*/
4650
protected $aContents;
4751

48-
/**
49-
* @var int
50-
*
51-
* @internal since 8.8.0
52-
*/
53-
protected $iLineNo;
54-
5552
/**
5653
* @param int $iLineNo
5754
*/
5855
public function __construct($iLineNo = 0)
5956
{
6057
$this->aComments = [];
6158
$this->aContents = [];
62-
$this->iLineNo = $iLineNo;
59+
$this->setPosition($iLineNo);
6360
}
6461

6562
/**
@@ -258,14 +255,6 @@ private static function identifierIs($sIdentifier, $sMatch)
258255
?: preg_match("/^(-\\w+-)?$sMatch$/i", $sIdentifier) === 1;
259256
}
260257

261-
/**
262-
* @return int
263-
*/
264-
public function getLineNo()
265-
{
266-
return $this->iLineNo;
267-
}
268-
269258
/**
270259
* Prepends an item to the list of contents.
271260
*

src/Comment/Comment.php

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,12 @@
44

55
use Sabberworm\CSS\OutputFormat;
66
use Sabberworm\CSS\Renderable;
7+
use Sabberworm\CSS\Position\Position;
8+
use Sabberworm\CSS\Position\Positionable;
79

8-
class Comment implements Renderable
10+
class Comment implements Positionable, Renderable
911
{
10-
/**
11-
* @var int
12-
*
13-
* @internal since 8.8.0
14-
*/
15-
protected $iLineNo;
12+
use Position;
1613

1714
/**
1815
* @var string
@@ -28,7 +25,7 @@ class Comment implements Renderable
2825
public function __construct($sComment = '', $iLineNo = 0)
2926
{
3027
$this->sComment = $sComment;
31-
$this->iLineNo = $iLineNo;
28+
$this->setPosition($iLineNo);
3229
}
3330

3431
/**
@@ -39,14 +36,6 @@ public function getComment()
3936
return $this->sComment;
4037
}
4138

42-
/**
43-
* @return int
44-
*/
45-
public function getLineNo()
46-
{
47-
return $this->iLineNo;
48-
}
49-
5039
/**
5140
* @param string $sComment
5241
*

src/Parsing/SourceException.php

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,23 @@
22

33
namespace Sabberworm\CSS\Parsing;
44

5-
class SourceException extends \Exception
5+
use Sabberworm\CSS\Position\Position;
6+
use Sabberworm\CSS\Position\Positionable;
7+
8+
class SourceException extends \Exception implements Positionable
69
{
7-
/**
8-
* @var int
9-
*/
10-
private $iLineNo;
10+
use Position;
1111

1212
/**
1313
* @param string $sMessage
1414
* @param int $iLineNo
1515
*/
1616
public function __construct($sMessage, $iLineNo = 0)
1717
{
18-
$this->iLineNo = $iLineNo;
18+
$this->setPosition($iLineNo);
1919
if (!empty($iLineNo)) {
2020
$sMessage .= " [line no: $iLineNo]";
2121
}
2222
parent::__construct($sMessage);
2323
}
24-
25-
/**
26-
* @return int
27-
*/
28-
public function getLineNo()
29-
{
30-
return $this->iLineNo;
31-
}
3224
}

src/Position/Position.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sabberworm\CSS\Position;
6+
7+
/**
8+
* Provides a standard reusable implementation of `Positionable`.
9+
*
10+
* @internal
11+
*
12+
* @phpstan-require-implements Positionable
13+
*/
14+
trait Position
15+
{
16+
/**
17+
* @var int<1, max>|null
18+
*/
19+
protected $lineNumber;
20+
21+
/**
22+
* @var int<0, max>|null
23+
*/
24+
protected $columnNumber;
25+
26+
/**
27+
* @return int<1, max>|null
28+
*/
29+
public function getLineNumber()
30+
{
31+
return $this->lineNumber;
32+
}
33+
34+
/**
35+
* @return int<0, max>
36+
*/
37+
public function getLineNo()
38+
{
39+
$lineNumber = $this->getLineNumber();
40+
41+
return $lineNumber !== null ? $lineNumber : 0;
42+
}
43+
44+
/**
45+
* @return int<0, max>|null
46+
*/
47+
public function getColumnNumber()
48+
{
49+
return $this->columnNumber;
50+
}
51+
52+
/**
53+
* @return int<0, max>
54+
*/
55+
public function getColNo()
56+
{
57+
$columnNumber = $this->getColumnNumber();
58+
59+
return $columnNumber !== null ? $columnNumber : 0;
60+
}
61+
62+
/**
63+
* @param int<0, max>|null $lineNumber
64+
* @param int<0, max>|null $columnNumber
65+
*/
66+
public function setPosition($lineNumber, $columnNumber = null)
67+
{
68+
// The conditional is for backwards compatibility (backcompat); `0` will not be allowed in future.
69+
$this->lineNumber = $lineNumber !== 0 ? $lineNumber : null;
70+
$this->columnNumber = $columnNumber;
71+
}
72+
}

src/Position/Positionable.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sabberworm\CSS\Position;
6+
7+
/**
8+
* Represents a CSS item that may have a position in the source CSS document (line number and possibly column number).
9+
*
10+
* A standard implementation of this interface is available in the `Position` trait.
11+
*/
12+
interface Positionable
13+
{
14+
/**
15+
* @return int<1, max>|null
16+
*/
17+
public function getLineNumber();
18+
19+
/**
20+
* @return int<0, max>
21+
*
22+
* @deprecated in version 8.9.0, will be removed in v9.0. Use `getLineNumber()` instead.
23+
*/
24+
public function getLineNo();
25+
26+
/**
27+
* @return int<0, max>|null
28+
*/
29+
public function getColumnNumber();
30+
31+
/**
32+
* @return int<0, max>
33+
*
34+
* @deprecated in version 8.9.0, will be removed in v9.0. Use `getColumnNumber()` instead.
35+
*/
36+
public function getColNo();
37+
38+
/**
39+
* @param int<0, max>|null $lineNumber
40+
* Providing zero for this parameter is deprecated in version 8.9.0, and will not be supported from v9.0.
41+
* Use `null` instead when no line number is available.
42+
* @param int<0, max>|null $columnNumber
43+
*/
44+
public function setPosition($lineNumber, $columnNumber = null);
45+
}

src/Property/CSSNamespace.php

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@
44

55
use Sabberworm\CSS\Comment\Comment;
66
use Sabberworm\CSS\OutputFormat;
7+
use Sabberworm\CSS\Position\Position;
8+
use Sabberworm\CSS\Position\Positionable;
79

810
/**
911
* `CSSNamespace` represents an `@namespace` rule.
1012
*/
11-
class CSSNamespace implements AtRule
13+
class CSSNamespace implements AtRule, Positionable
1214
{
15+
use Position;
16+
1317
/**
1418
* @var string
1519
*/
@@ -41,18 +45,10 @@ public function __construct($mUrl, $sPrefix = null, $iLineNo = 0)
4145
{
4246
$this->mUrl = $mUrl;
4347
$this->sPrefix = $sPrefix;
44-
$this->iLineNo = $iLineNo;
48+
$this->setPosition($iLineNo);
4549
$this->aComments = [];
4650
}
4751

48-
/**
49-
* @return int
50-
*/
51-
public function getLineNo()
52-
{
53-
return $this->iLineNo;
54-
}
55-
5652
/**
5753
* @return string
5854
*

src/Property/Charset.php

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use Sabberworm\CSS\Comment\Comment;
66
use Sabberworm\CSS\OutputFormat;
7+
use Sabberworm\CSS\Position\Position;
8+
use Sabberworm\CSS\Position\Positionable;
79
use Sabberworm\CSS\Value\CSSString;
810

911
/**
@@ -14,8 +16,10 @@
1416
* - May only appear at the very top of a Document’s contents.
1517
* - Must not appear more than once.
1618
*/
17-
class Charset implements AtRule
19+
class Charset implements AtRule, Positionable
1820
{
21+
use Position;
22+
1923
/**
2024
* @var CSSString
2125
*/
@@ -42,18 +46,10 @@ class Charset implements AtRule
4246
public function __construct(CSSString $oCharset, $iLineNo = 0)
4347
{
4448
$this->oCharset = $oCharset;
45-
$this->iLineNo = $iLineNo;
49+
$this->setPosition($iLineNo);
4650
$this->aComments = [];
4751
}
4852

49-
/**
50-
* @return int
51-
*/
52-
public function getLineNo()
53-
{
54-
return $this->iLineNo;
55-
}
56-
5753
/**
5854
* @param string|CSSString $oCharset
5955
*

0 commit comments

Comments
 (0)