From 54b0d0201cfef863e475190510d8dc2a0ba95a90 Mon Sep 17 00:00:00 2001 From: Michele Locati Date: Mon, 26 Sep 2016 10:40:46 +0200 Subject: [PATCH 1/2] Continue phpdoc --- src/Exception/CssSyntaxError.php | 18 ++++-- src/LazyResult.php | 81 +++++++++++++++-------- src/MapGenerator.php | 45 ++++++++++++- src/Node.php | 18 +++++- src/PreviousMap.php | 56 +++++++++++++--- src/Processor.php | 57 +++++++---------- src/Result.php | 76 ++++++++++++++++------ src/Root.php | 26 ++++++-- src/Rule.php | 67 +++++++++++-------- src/Stringifier.php | 103 ++++++++++++++++++++++++++++++ src/Warning.php | 32 +++++++--- test/tests/CssSyntaxErrorTest.php | 2 +- test/tests/RuleTest.php | 15 +++-- 13 files changed, 446 insertions(+), 150 deletions(-) diff --git a/src/Exception/CssSyntaxError.php b/src/Exception/CssSyntaxError.php index 960d5f4..bf82308 100644 --- a/src/Exception/CssSyntaxError.php +++ b/src/Exception/CssSyntaxError.php @@ -8,15 +8,14 @@ /** * The CSS parser throws this error for broken CSS. * - * Custom parsers can throw this error for broken custom syntax using - * the {@link Node#error} method. + * Custom parsers can throw this error for broken custom syntax using Node->error method. * * PostCSS will use the input source map to detect the original error location. - * If you wrote a Sass file, compiled it to CSS and then parsed it with PostCSS, - * PostCSS will show the original position in the Sass file. + * If you wrote a Sass file, compiled it to CSS and then parsed it with PostCSS, PostCSS will show the original position in the Sass file. * - * If you need the position in the PostCSS input - * (e.g., to debug the previous compiler), use `error.input.file`. + * If you need the position in the PostCSS input (e.g., to debug the previous compiler), use `$error->input['file']`. + * + * @link https://github.com/postcss/postcss/blob/master/lib/css-syntax-error.es6 */ class CssSyntaxError extends Exception { @@ -90,6 +89,8 @@ public function setMessage($message) $this->message = (string) $message; } + /** + */ public function updateMessage() { $plugin = ($this->postcssPlugin instanceof PluginInterface) ? $this->postcssPlugin->getName() : (string) $this->postcssPlugin; @@ -208,6 +209,11 @@ public function showSourceCode($color = null) return implode("\n", $output); } + /** + * {@inheritdoc} + * + * @see Exception::__toString() + */ public function __toString() { $fqn = get_class($this); diff --git a/src/LazyResult.php b/src/LazyResult.php index 6c7cf58..5b67fdc 100644 --- a/src/LazyResult.php +++ b/src/LazyResult.php @@ -2,8 +2,9 @@ namespace PostCSS; -use React\Promise\Promise; use PostCSS\Plugin\PluginInterface; +use React\Promise\Promise; +use React\Promise\PromiseInterface; /** * A Promise proxy for the result of PostCSS transformations. @@ -50,6 +51,18 @@ class LazyResult */ protected $processing = null; + /** + * Current plugin index. + * + * @var int + */ + protected $plugin; + + /** + * @param Processor $processor + * @param mixed $css + * @param array $opts + */ public function __construct(Processor $processor, $css, array $opts = []) { $this->stringified = false; @@ -122,8 +135,7 @@ public function __get($name) } /** - * Processes input CSS through synchronous plugins - * and calls {@link Result#warnings()}. + * Processes input CSS through synchronous plugins and calls Result->warnings(). * * @return Warning[] warnings from plugins */ @@ -133,10 +145,10 @@ public function warnings() } /** - * Alias for the {@link LazyResult#css} property. + * Alias for the LazyResult->css property. * * @example - * lazy + '' === lazy.css; + * (string) $lazy === $lazy->css; * * @return string output CSS */ @@ -146,22 +158,18 @@ public function __toString() } /** - * Processes input CSS through synchronous and asynchronous plugins - * and calls `onFulfilled` with a Result instance. If a plugin throws - * an error, the `onRejected` callback will be executed. + * Processes input CSS through synchronous and asynchronous plugins and calls `onFulfilled` with a Result instance. + * If a plugin throws an error, the `onRejected` callback will be executed. * * It implements standard Promise API. * - * @param {onFulfilled} onFulfilled - callback will be executed - * when all plugins will finish work - * @param {onRejected} onRejected - callback will be execited on any error + * @param callable $onFulfilled Callback will be executed when all plugins will finish work + * @param callable $onRejected Callback will be execited on any error * * @return Promise Promise API to make queue * * @example - * postcss([cssnext]).process(css).then(result => { - * console.log(result.css); - * }); + * (new \PostCSS\Processor([Cssnext::class]))->process($css)->then(function ($result) { echo $result->css; })->done(); */ public function then($onFulfilled, $onRejected) { @@ -169,20 +177,18 @@ public function then($onFulfilled, $onRejected) } /** - * Processes input CSS through synchronous and asynchronous plugins - * and calls onRejected for each error thrown in any plugin. - * + * Processes input CSS through synchronous and asynchronous plugins and calls onRejected for each error thrown in any plugin. * It implements standard Promise API. * - * @param {onRejected} onRejected - callback will be execited on any error + * @param callable $onRejected Callback will be execited on any error * * @return Promise Promise API to make queue * * @example - * postcss([cssnext]).process(css).then(result => { - * console.log(result.css); - * }).catch(error => { - * console.error(error); + * (new \PostCSS\Processor([Cssnext::class]))->process($css)->then(function ($result) { + * echo $result->css); + * })->catchError(function ($error) { + * echo (string) $error; * }); */ public function catchError($onRejected) @@ -193,6 +199,10 @@ public function catchError($onRejected) ); } + /** + * @param \Exception $error + * @param PluginInterface|string $plugin + */ public function handleError(\Exception $error, $plugin) { try { @@ -216,6 +226,12 @@ public function handleError(\Exception $error, $plugin) } } + /** + * @param callable $resolve + * @param callable $reject + * + * @return mixed + */ public function asyncTick($resolve, $reject) { if ($this->plugin >= count($this->result->processor->plugins)) { @@ -228,7 +244,7 @@ public function asyncTick($resolve, $reject) $promise = $this->run($plugin); $this->plugin += 1; - if ($promise instanceof Promise) { + if ($promise instanceof PromiseInterface) { $me = $this; $promise->then( function () use ($me, $resolve, $reject) { @@ -249,6 +265,9 @@ function ($error) use ($me, $plugin, $reject) { } } + /** + * @return Promise + */ public function async() { if ($this->processed) { @@ -284,6 +303,11 @@ function () use ($me) { return $this->processing; } + /** + * @throws \Exception + * + * @return \PostCSS\Result + */ public function sync() { if ($this->processed) { @@ -292,7 +316,7 @@ public function sync() $this->processed = true; if ($this->processing) { - throw new \Exception('Use process(css).then(cb) to work with async plugins'); + throw new \Exception('Use process($css)->then($cb) to work with async plugins'); } if ($this->error) { @@ -303,13 +327,20 @@ public function sync() for ($i = 0; $i < count($processor->plugins); ++$i) { $promise = $this->run($processor->plugins[$i]); if ($promise instanceof Promise) { - throw new \Exception('Use process(css).then(cb) to work with async plugins'); + throw new \Exception('Use process($css)->then($cb) to work with async plugins'); } } return $this->result; } + /** + * @param PluginInterface $plugin + * + * @throws \Exception + * + * @return mixed + */ public function run(PluginInterface $plugin) { $this->result->lastPlugin = $plugin; diff --git a/src/MapGenerator.php b/src/MapGenerator.php index 5528b74..df16c23 100644 --- a/src/MapGenerator.php +++ b/src/MapGenerator.php @@ -2,8 +2,8 @@ namespace PostCSS; -use PostCSS\SourceMap\Consumer\Consumer; use PostCSS\Path\NodeJS as Path; +use PostCSS\SourceMap\Consumer\Consumer; /** * @link https://github.com/postcss/postcss/blob/master/lib/map-generator.es6 @@ -45,6 +45,11 @@ class MapGenerator */ protected $map = null; + /** + * @param callable $stringify + * @param Root $root + * @param array $opts + */ public function __construct(callable $stringify, Root $root, array $opts = []) { $this->stringify = $stringify; @@ -53,6 +58,9 @@ public function __construct(callable $stringify, Root $root, array $opts = []) $this->opts = $opts; } + /** + * @return bool + */ public function isMap() { if (isset($this->opts['map'])) { @@ -64,6 +72,9 @@ public function isMap() } } + /** + * @return PreviousMap[] + */ public function previous() { if ($this->previousMaps === null) { @@ -82,6 +93,9 @@ public function previous() return $this->previousMaps; } + /** + * @return bool + */ public function isInline() { if (isset($this->mapOpts['inline'])) { @@ -109,6 +123,9 @@ public function isInline() } } + /** + * @return bool + */ public function isSourcesContent() { if (isset($this->mapOpts['sourcesContent'])) { @@ -151,7 +168,7 @@ public function setSourcesContent() $me = $this; $already = []; $this->root->walk(function (Node $node) use ($me, &$already) { - if ($node->source) { + if ($node->source && isset($node->source['input'])) { $from = $node->source['input']->from; if ($from && !isset($already[$from])) { $already[$from] = true; @@ -180,6 +197,9 @@ public function applyPrevMaps() } } + /** + * @return bool + */ public function isAnnotation() { if ($this->isInline()) { @@ -222,6 +242,9 @@ public function addAnnotation() $this->css .= $eol.'/*# sourceMappingURL='.$content.' */'; } + /** + * @return string + */ public function outputFile() { if (isset($this->opts['to']) && $this->opts['to']) { @@ -233,6 +256,9 @@ public function outputFile() } } + /** + * @return array First array item is the css. If not inline, there's a second item (a SourceMap\Generator instance) + */ public function generateMap() { $this->generateString(); @@ -254,6 +280,11 @@ public function generateMap() } } + /** + * @param string $file + * + * @return string + */ public function relative($file) { if (preg_match('/^\w+:\/\//', $file)) { @@ -274,7 +305,12 @@ public function relative($file) } } - public function sourcePath($node) + /** + * @param Node $node + * + * @return string + */ + public function sourcePath(Node $node) { if (isset($this->mapOpts['from']) && $this->mapOpts['from']) { return $this->mapOpts['from']; @@ -364,6 +400,9 @@ function ($str, Node $node = null, $type = null) use ($me, &$line, &$column) { ); } + /** + * @return array First array item is the css. If not inline, there's a second item (a SourceMap\Generator instance) + */ public function generate() { $this->clearAnnotation(); diff --git a/src/Node.php b/src/Node.php index 9d6e043..601cdd2 100644 --- a/src/Node.php +++ b/src/Node.php @@ -45,13 +45,29 @@ class Node * - `before`: the space symbols before the node. * - `left`: the space symbols between `/*` and the comment’s text. * - `right`: the space symbols between the comment’s text. + * - Root: + * - `after`: the space symbols after the last child to the end of file. + * - `semicolon`: is the last child has an (optional) semicolon. + * - Rule: + * - `before`: the space symbols before the node. It also stores `*` and `_` symbols before the declaration (IE hack). + * - `after`: the space symbols after the last child of the node to the end of the node. + * - `between`: the symbols between the property and value for declarations, selector and `{` for rules, or last parameter and `{` for at-rules. + * - `semicolon`: contains true if the last child has an (optional) semicolon. * * PostCSS cleans at-rule parameters from comments and extra spaces, but it stores origin content in raws properties. * As such, if you don’t change a declaration’s value, PostCSS will use the raw value with comments. * * @example - * $root = \PostCSS\Parser::parse(' @media\nprint {\n}') + * $root = \PostCSS\Parser::parse(' @media\nprint {\n}'); * $root->first->first->raws //=> ['before' => ' ', 'between' => ' ', 'afterName' = > "\n", 'after' => "\n"] + * + * @example + * \PostCSS\Parser::parse('a {}\n').raws //=> ['after' => "\n"] + * \PostCSS\Parser::parse('a {}').raws //=> ['after => ''] + * + * @example + * $root = \PostCSS\Parser::parse('a {\n color:black\n}'); + * $root->first->first->raws //=> ['before' => '', 'between' => ' ', 'after' => "\n"] * * @var Raws */ diff --git a/src/PreviousMap.php b/src/PreviousMap.php index 41a5ea3..106f330 100644 --- a/src/PreviousMap.php +++ b/src/PreviousMap.php @@ -2,9 +2,9 @@ namespace PostCSS; -use PostCSS\SourceMap\Consumer\Consumer as MozillaSourceMapConsumer; -use PostCSS\SourceMap\Generator as MozillaSourceMapGenerator; use PostCSS\Path\NodeJS as Path; +use PostCSS\SourceMap\Consumer\Consumer as SourceMapConsumer; +use PostCSS\SourceMap\Generator as SourceMapGenerator; /** * Source map information from input CSS. @@ -13,6 +13,10 @@ * This class will automatically find source map in input CSS or in file system near input file (according `from` option). * * @link https://github.com/postcss/postcss/blob/master/lib/previous-map.es6 + * + * @example + * $root = \PostCSS\Parser::parse($css, ['from' => 'a.sass.css']); + * $root->input->map //=> PreviousMap */ class PreviousMap { @@ -22,6 +26,8 @@ class PreviousMap public $annotation = ''; /** + * Was source map inlined by data-uri to input CSS. + * * @var bool */ public $inline; @@ -32,13 +38,13 @@ class PreviousMap public $text = null; /** - * @var MozillaSourceMapConsumer|null + * @var SourceMapConsumer|null */ private $consumerCache = null; /** * @param string $css Input CSS source - * @param processOptions $opts {@link Processor#process} options + * @param array $opts Options */ public function __construct($css, array $opts) { @@ -56,12 +62,12 @@ public function __construct($css, array $opts) * * It is lazy method, so it will create object only on first call and then it will use cache. * - * @return MozillaSourceMapConsumer object woth source map information + * @return SourceMapConsumer object woth source map information */ public function consumer() { if ($this->consumerCache === null) { - $this->consumerCache = MozillaSourceMapConsumer::construct($this->text); + $this->consumerCache = SourceMapConsumer::construct($this->text); } return $this->consumerCache; @@ -70,7 +76,7 @@ public function consumer() /** * Does source map contains `sourcesContent` with input source text. * - * @return {boolean} Is `sourcesContent` present + * @return bool Is `sourcesContent` present */ public function withContent() { @@ -79,11 +85,20 @@ public function withContent() return !empty($sc); } + /** + * @param string $string + * @param string $start + * + * @return bool + */ public function startWith($string, $start) { return is_string($string) && $string !== '' && substr($string, 0, strlen($start)) === $start; } + /** + * @param string $css + */ public function loadAnnotation($css) { if (preg_match('/\/\*\s*# sourceMappingURL=(.*)\s*\*\//', $css, $match)) { @@ -91,6 +106,13 @@ public function loadAnnotation($css) } } + /** + * @param string $text + * + * @throws Exception\UnsupportedSourceMapEncoding + * + * @return string + */ public function decodeInline($text) { $utfd64 = 'data:application/json;charset=utf-8;base64,'; @@ -116,6 +138,15 @@ public function decodeInline($text) } } + /** + * @param string $file + * @param mixed $prev + * + * @throws Exception\UnableToLoadPreviousSourceMap + * @throws Exception\UnsupportedPreviousSourceMapFormat + * + * @return string|false + */ public function loadMap($file, $prev) { if ($prev === false) { @@ -132,9 +163,9 @@ public function loadMap($file, $prev) } else { throw new Exception\UnableToLoadPreviousSourceMap($prevPath); } - } elseif ($prev instanceof MozillaSourceMapConsumer) { - return (string) MozillaSourceMapGenerator::fromSourceMap($prev); - } elseif ($prev instanceof MozillaSourceMapGenerator) { + } elseif ($prev instanceof SourceMapConsumer) { + return (string) SourceMapGenerator::fromSourceMap($prev); + } elseif ($prev instanceof SourceMapGenerator) { return (string) $prev; } elseif ($this->isMap($prev)) { return json_encode($prev); @@ -157,6 +188,11 @@ public function loadMap($file, $prev) } } + /** + * @param array|mixed $map + * + * @return bool + */ public function isMap($map) { $result = false; diff --git a/src/Processor.php b/src/Processor.php index 739d1d4..3264157 100644 --- a/src/Processor.php +++ b/src/Processor.php @@ -9,6 +9,11 @@ * * @link https://github.com/postcss/postcss/blob/master/lib/processor.es6 * @link https://github.com/postcss/postcss/blob/master/lib/postcss.es6 + * + * @example + * $processor = new \PostCSS\Processor([Autoprefixer::class, Precss::class]); + * $processor->process($css1)->then(function ($result) { echo $result->css; })->done(); + * $processor->process($css2)->then(function ($result) { echo $result->css; })->done(); */ class Processor { @@ -25,7 +30,7 @@ class Processor public $plugins; /** - * @param PluginInterface[]|callable[]|Processor[]} $plugins PostCSS plugins + * @param PluginInterface[]|callable[]|Processor[]} $plugins PostCSS plugins. Processor->usePlugin for plugin format */ public function __construct($plugins = []) { @@ -40,31 +45,24 @@ public function __construct($plugins = []) /** * Adds a plugin to be used as a CSS processor. * - * PostCSS plugin can be in 4 formats: - * * A plugin created by {@link postcss.plugin} method. - * * A function. PostCSS will pass the function a {@link Root} - * as the first argument and current {@link Result} instance - * as the second. - * * An object with a `postcss` method. PostCSS will use that method - * as described in #2. - * * Another {@link Processor} instance. PostCSS will copy plugins - * from that instance into this one. + * PostCSS plugin can be in the following formats: + * - An \PostCSS\PluginInterface instance. + * - The name of a \PostCSS\PluginInterface class. + * - A callable that returns a \PostCSS\PluginInterface instance. + * - Another Processor} instance. PostCSS will copy plugins from that instance into this one. * - * Plugins can also be added by passing them as arguments when creating - * a `postcss` instance (see [`postcss(plugins)`]). + * Plugins can also be added by passing them as arguments when creating \PostCSS\Processor instance. * * Asynchronous plugins should return a `\React\Promise\Promise` instance. * - * @param {Plugin|pluginFunction|Processor} plugin - PostCSS plugin - * or {@link Processor} - * with plugins + * @param PluginInterface|string|callable|Processor $plugin PostCSS plugin Processor with plugins * * @example - * const processor = postcss() - * .use(autoprefixer) - * .use(precss); + * $processor = (new \PostCSS\Processor()) + * ->usePlugin(Autoprefixer::class) + * ->usePlugin(Precss::class); * - * @return {Processes} current processor to make methods chain + * @return static Current processor to make methods chain */ public function usePlugin($plugin) { @@ -74,26 +72,17 @@ public function usePlugin($plugin) } /** - * Parses source CSS and returns a {@link LazyResult} Promise proxy. - * Because some plugins can be asynchronous it doesn't make - * any transformations. Transformations will be applied - * in the {@link LazyResult} methods. + * Parses source CSS and returns a LazyResult Promise proxy. + * Because some plugins can be asynchronous it doesn't make any transformations. + * Transformations will be applied in the LazyResult methods. * - * @param {string|toString|Result} css - String with input CSS or - * any object with a `toString()` - * method, like a Buffer. - * Optionally, send a {@link Result} - * instance and the processor will - * take the {@link Root} from it - * @param {processOptions} [opts] - options + * @param string|Root|Result|LazyResult $css String with input CSS or any object with a `__toString()` method. Optionally, send a Result instance and the processor will take the Root from it + * @param array $opts] Options * * @return LazyResult \React\Promise\Promise proxy * * @example - * processor.process(css, { from: 'a.css', to: 'a.out.css' }) - * .then(result => { - * console.log(result.css); - * }); + * $processor->process($css, ['from' => 'a.css', 'to' => 'a.out.css'])->then(function ($result) { echo $result->css; })->done(); */ public function process($css, array $opts = []) { diff --git a/src/Result.php b/src/Result.php index a1dd053..a571c69 100644 --- a/src/Result.php +++ b/src/Result.php @@ -6,48 +6,76 @@ /** * Provides the result of the PostCSS transformations. - * A Result instance is returned by {@link LazyResult#then} or {@link Root#toResult} methods. + * A Result instance is returned by LazyResult->then or Root->toResult methods. * * @link https://github.com/postcss/postcss/blob/master/lib/result.es6 * * @example - * postcss([cssnext]).process(css).then(function (result) { - * console.log(result.css); + * (new \PostCSS\Processor([cssnext]))->process($css)->then(function ($result) { + * echo $result->css; * }); * @example - * var result2 = postcss.parse(css).toResult(); + * $result2 = \PostCSS\Parser::parse($css).toResult(); * * @property string $content An alias for the Result->css property. Use it with syntaxes that generate non-CSS output */ class Result { /** + * The Processor instance used for this transformation. + * * @var Processor */ public $processor; /** + * Contains messages from plugins (e.g., warnings or custom messages). Each message should have type and plugin properties. + * * @var array */ public $messages; /** + * Root node after all transformations. + * + * @example + * $root->toResult()->root === root; + * * @var Root|null */ public $root; /** + * Options from the Processor->process or Root->toResult} call that produced this Result instance. + * + * @example + * $root->toResult($opts)->opts == $opts; + * * @var array */ public $opts; /** - * @var string|null A CSS string representing of {@link Result#root} + * A CSS string representing of Result->root. + * + * @example + * \PostCSS\Parser::parse('a{}')->toResult()->css //=> 'a{}' + * + * @var string|null */ public $css; /** - * @var SourceMap\Generator|null An instance of `SourceMapGenerator` class from the `source-map` library, representing changes o the {@link Result#root} instance + * An instance of `SourceMapGenerator` class from the `source-map` library, representing changes o the Result->root instance. + * + * @example + * $result->map->toJSON() //=> ['version' => 3, 'file' => 'a.css', ...] + * @example + * if ($result->map) { + * file_put_contents($result->opts['to'].'.map', (string) $result->map); + * } + * + * @var SourceMap\Generator|null */ public $map; @@ -57,10 +85,9 @@ class Result public $lastPlugin = null; /** - * @param {Processor} processor - processor used for this transformation - * @param {Root} root - Root node after all transformations - * @param {processOptions} opts - options from the {@link Processor#process} - * or {@link Root#toResult} + * @param Processor $processor Processor used for this transformation + * @param Root $root Root node after all transformations + * @param array $opts Options from the Processor->process or Root->toResult */ public function __construct(Processor $processor = null, Root $root = null, array $opts = []) { @@ -73,9 +100,9 @@ public function __construct(Processor $processor = null, Root $root = null, arra } /** - * Returns for {@link Result#css} content. + * Returns for Result->css content. * - * @return string string representing of {@link Result#root} + * @return string string representing of Result->root */ public function __toString() { @@ -83,14 +110,16 @@ public function __toString() } /** - * Creates an instance of {@link Warning} and adds it to {@link Result#messages}. + * Creates an instance of {@link Warning} and adds it to Result->messages. + * + * @param string $text Warning message + * @param array $opts Warning options { * - * @param string $text - warning message - * @param array $opts - warning options - * @param Node opts.node - CSS node that caused the warning - * @param string opts.word - word in CSS source that caused the warning - * @param int opts.index - index in CSS node string that caused the warning - * @param string opts.plugin - name of the plugin that created this warning. {@link Result#warn} fills this property automatically + * @var Node $node CSS node that caused the warning + * @var string $word Word in CSS source that caused the warning + * @var int $index Index in CSS node string that caused the warning + * @var string $plugin Name of the plugin that created this warning. Result->warn fills this property automatically. + * } * * @return Warning created warning */ @@ -109,9 +138,14 @@ public function warn($text, array $opts = []) } /** - * Returns warnings from plugins. Filters {@link Warning} instances from {@link Result#messages}. + * Returns warnings from plugins. Filters Warning instances from Result->messages. + * + * @example + * foreach ($result->warnings() as warn) { + * echo (string) $warn; + * } * - * @return {Warning[]} warnings from plugins + * @return Warning[] warnings from plugins */ public function warnings() { diff --git a/src/Root.php b/src/Root.php index 0daf821..1729fcb 100644 --- a/src/Root.php +++ b/src/Root.php @@ -6,9 +6,17 @@ * Represents a CSS file and contains all its parsed nodes. * * @link https://github.com/postcss/postcss/blob/master/lib/root.es6 + * + * @example + * $root = \PostCSS\Parser::parse('a{color:black} b{z-index:2}'); + * $root->type //=> 'root' + * count($root->nodes) //=> 2 */ class Root extends Container { + /** + * @param array $defaults + */ public function __construct(array $defaults = []) { parent::__construct($defaults); @@ -18,6 +26,11 @@ public function __construct(array $defaults = []) } } + /** + * {@inheritdoc} + * + * @see Container::removeChild() + */ public function removeChild($child) { $child = $this->index($child); @@ -34,6 +47,11 @@ public function removeChild($child) return parent::removeChild($child); } + /** + * {@inheritdoc} + * + * @see Container::normalize() + */ public function normalize($child, $sample = null, $type = null) { $nodes = parent::normalize($child); @@ -65,9 +83,9 @@ public function normalize($child, $sample = null, $type = null) } /** - * Returns a {@link Result} instance representing the root's CSS. + * Returns a Result instance representing the root's CSS. * - * @param ProcessOptions $opts Options with only `to` and `map` keys + * @param array $opts Options with only `to` and `map` keys. Same values as LazyResult::__constructor * * @return Result Result with current root's CSS */ @@ -79,7 +97,7 @@ public function toResult(array $opts = []) } /** - * @deprecated Use Root#removeChild + * @deprecated Use Root->removeChild */ public function remove() { @@ -92,7 +110,7 @@ public function remove() } /** - * @deprecated Use Root#source->input->map + * @deprecated Use Root->source->input->map */ public function prevMap() { diff --git a/src/Rule.php b/src/Rule.php index c5ce5c9..ebcde21 100644 --- a/src/Rule.php +++ b/src/Rule.php @@ -6,14 +6,28 @@ * Represents a CSS rule: a selector followed by a declaration block. * * @link https://github.com/postcss/postcss/blob/master/lib/rule.es6 + * + * @example + * $root = \PostCSS\Parser::parse('a{}'); + * $rule = $root->first; + * $rule->type //=> 'rule' + * (string) $rule //=> 'a{}' + * + * @property string[] $selectors An array containing the rule's individual selectors. Groups of selectors are split at commas + * @property @deprecated string $_selector Rule->_selector is deprecated. Use Rule->raws->selector */ class Rule extends Container { /** + * The rule’s full selector represented as a string. + * * @var string|null */ public $selector = null; + /** + * @param array $defaults + */ public function __construct(array $defaults = []) { $selectors = null; @@ -27,41 +41,38 @@ public function __construct(array $defaults = []) $this->nodes = []; } if ($selectors !== null) { - $this->setSelectors($selectors); + $this->selectors = $selectors; } } - /** - * An array containing the rule's individual selectors. - * Groups of selectors are split at commas. - */ - public function getSelectors() - { - return ListUtil::comma($this->selector); - } - - public function setSelectors(array $values) + public function __get($name) { - if (!isset($this->selector) || !$this->selector || !preg_match('/,\s*/', $this->selector, $match)) { - $match = null; + switch ($name) { + case 'selectors': + return ListUtil::comma($this->selector); + case '_selector': + return $this->raws->selector; + default: + return parent::__get($name); } - $sep = ($match !== null) ? $match[0] : ','.$this->raw('between', 'beforeOpen'); - $this->selector = implode($sep, $values); } - /** - * @deprecated Rule#_selector is deprecated. Use Rule#raws.selector - */ - public function _getSelector() - { - return $this->raws->selector; - } - - /** - * @deprecated Rule#_selector is deprecated. Use Rule#raws.selector - */ - public function _setSelector($val) + public function __set($name, $value) { - $this->raws->selector = $val; + switch ($name) { + case 'selectors': + if (!$this->selector || !preg_match('/,\s*/', $this->selector, $match)) { + $match = null; + } + $sep = ($match !== null) ? $match[0] : ','.$this->raw('between', 'beforeOpen'); + $this->selector = implode($sep, (array) $value); + break; + case '_selector': + $this->raws->selector = $value; + break; + default: + parent::__set($name, $value); + break; + } } } diff --git a/src/Stringifier.php b/src/Stringifier.php index fdf9c70..3435d60 100644 --- a/src/Stringifier.php +++ b/src/Stringifier.php @@ -32,6 +32,11 @@ class Stringifier 'commentRight' => ' ', ]; + /** + * @param string $str + * + * @return string + */ protected static function capitalize($str) { $str = (string) $str; @@ -46,12 +51,20 @@ protected static function capitalize($str) return $str; } + /** + * @param callable|null $builder + * @param callable|null $stringifier + */ public function __construct(callable $builder = null, callable $stringifier = null) { $this->builder = $builder; $this->stringifier = $stringifier; } + /** + * @param Node $node + * @param bool $semicolon + */ public function stringify(Node $node, $semicolon = null) { if ($this->stringifier !== null) { @@ -63,6 +76,9 @@ public function stringify(Node $node, $semicolon = null) } } + /** + * @param Node $node + */ protected function root(Node $node) { $this->body($node); @@ -72,6 +88,9 @@ protected function root(Node $node) } } + /** + * @param Node $node + */ protected function comment(Node $node) { $left = $this->raw($node, 'left', 'commentLeft'); @@ -79,6 +98,10 @@ protected function comment(Node $node) call_user_func($this->builder, '/*'.$left.$node->text.$right.'*/', $node); } + /** + * @param Node $node + * @param bool $semicolon + */ protected function decl(Node $node, $semicolon) { $between = $this->raw($node, 'between', 'colon'); @@ -92,11 +115,18 @@ protected function decl(Node $node, $semicolon) call_user_func($this->builder, $string, $node); } + /** + * @param Node $node + */ protected function rule(Node $node) { $this->block($node, $this->rawValue($node, 'selector')); } + /** + * @param Node $node + * @param bool $semicolon + */ protected function atrule(Node $node, $semicolon) { $name = '@'.$node->name; @@ -116,6 +146,9 @@ protected function atrule(Node $node, $semicolon) } } + /** + * @param Node $node + */ protected function body(Node $node) { $nodeNodesCount = count($node->nodes); @@ -137,6 +170,10 @@ protected function body(Node $node) } } + /** + * @param Node $node + * @param string $start + */ protected function block(Node $node, $start) { $between = $this->raw($node, 'between', 'beforeOpen'); @@ -154,6 +191,13 @@ protected function block(Node $node, $start) call_user_func($this->builder, '}', $node, 'end'); } + /** + * @param Node $node + * @param string $own + * @param string|null $detect + * + * @return mixed + */ public function raw(Node $node, $own, $detect = null) { if ($detect === null) { @@ -215,6 +259,11 @@ public function raw(Node $node, $own, $detect = null) return $value; } + /** + * @param Node $root + * + * @return bool|null + */ protected function rawSemicolon(Node $root) { $value = null; @@ -232,6 +281,11 @@ protected function rawSemicolon(Node $root) return $value; } + /** + * @param Node $root + * + * @return string|null + */ protected function rawEmptyBody(Node $root) { $value = null; @@ -249,6 +303,11 @@ protected function rawEmptyBody(Node $root) return $value; } + /** + * @param Node $root + * + * @return string|null + */ protected function rawIndent(Node $root) { $indent = $root->raws->indent; @@ -272,6 +331,12 @@ protected function rawIndent(Node $root) return $value; } + /** + * @param Container $root + * @param Node $node + * + * @return string|null + */ protected function rawBeforeComment(Container $root, Node $node) { $value = null; @@ -293,6 +358,12 @@ protected function rawBeforeComment(Container $root, Node $node) return $value; } + /** + * @param Container $root + * @param Node $node + * + * @return string|null + */ protected function rawBeforeDecl(Container $root, Node $node) { $value = null; @@ -314,6 +385,11 @@ protected function rawBeforeDecl(Container $root, Node $node) return $value; } + /** + * @param Container $root + * + * @return string|null + */ protected function rawBeforeRule(Container $root) { $value = null; @@ -334,6 +410,11 @@ protected function rawBeforeRule(Container $root) return $value; } + /** + * @param Container $root + * + * @return string|null + */ protected function rawBeforeClose(Container $root) { $value = null; @@ -354,6 +435,11 @@ protected function rawBeforeClose(Container $root) return $value; } + /** + * @param Container $root + * + * @return string|null + */ protected function rawBeforeOpen(Container $root) { $value = null; @@ -371,6 +457,11 @@ protected function rawBeforeOpen(Container $root) return $value; } + /** + * @param Container $root + * + * @return string|null + */ protected function rawColon(Container $root) { $value = null; @@ -386,6 +477,12 @@ protected function rawColon(Container $root) return $value; } + /** + * @param Node $node + * @param string $detect + * + * @return string + */ protected function beforeAfter(Node $node, $detect) { if ($node->type === 'decl') { @@ -417,6 +514,12 @@ protected function beforeAfter(Node $node, $detect) return $value; } + /** + * @param Node $node + * @param string $prop + * + * @return mixed|null + */ public function rawValue(Node $node, $prop) { $value = isset($node->$prop) ? $node->$prop : null; diff --git a/src/Warning.php b/src/Warning.php index 9369825..8c95314 100644 --- a/src/Warning.php +++ b/src/Warning.php @@ -3,13 +3,13 @@ namespace PostCSS; /** - * Represents a plugin's warning. It can be created using {@link Node#warn}. + * Represents a plugin's warning. It can be created using Node->warn. * * @link https://github.com/postcss/postcss/blob/master/lib/warning.es6 * * @example - * if ( decl.important ) { - * decl.warn(result, 'Avoid !important', { word: '!important' }); + * if ($decl->important ) { + * $decl->warn($result, 'Avoid !important', ['word' => '!important']); * } */ class Warning @@ -17,7 +17,7 @@ class Warning /** * The warning message. * - * @var + * @var string */ public $text; @@ -43,23 +43,35 @@ class Warning public $node = null; /** - * The name of the plugin that created it will fill this property automatically. this warning. When you call {@link Node#warn}. + * The name of the plugin that created it will fill this property automatically when you call Node->warn. * * @var string|null */ public $plugin = null; + /** + * Index in CSS node string that caused the warning. + * + * @var int|null + */ public $index = null; + /** + * Word in CSS source that caused the warning. + * + * @var string|null + */ public $word = null; /** * @param string $text Warning message - * @param array $opts Warning options - * @param {Node} opts.node CSS node that caused the warning - * @param string $opts.word Word in CSS source that caused the warning - * @param {number} opts.index Index in CSS node string that caused the warning - * @param string $opts.plugin Name of the plugin that created this warning. {@link Result#warn} fills this property automatically + * @param array $opts Warning options. { + * + * @var Node $node CSS node that caused the warning + * @var string $word Word in CSS source that caused the warning + * @var int $index Index in CSS node string that caused the warning + * @var string $plugin Name of the plugin that created this warning. Result->warn fills this property automatically. + * } */ public function __construct($text, array $opts = []) { diff --git a/test/tests/CssSyntaxErrorTest.php b/test/tests/CssSyntaxErrorTest.php index 83d0793..a107e26 100644 --- a/test/tests/CssSyntaxErrorTest.php +++ b/test/tests/CssSyntaxErrorTest.php @@ -16,7 +16,7 @@ class CssSyntaxErrorTest extends \PHPUnit_Framework_TestCase { /** * @param string $css - * @param array $opts + * @param array $opts * * @return CssSyntaxError|null */ diff --git a/test/tests/RuleTest.php b/test/tests/RuleTest.php index ef39820..647f591 100644 --- a/test/tests/RuleTest.php +++ b/test/tests/RuleTest.php @@ -16,13 +16,13 @@ public function testInitializesWithProperties() public function testReturnsArrayInSelectors() { $rule = new Rule(['selector' => 'a,b']); - $this->assertSame(['a', 'b'], $rule->getSelectors()); + $this->assertSame(['a', 'b'], $rule->selectors); } public function testTrimsSelectors() { $rule = new Rule(['selector' => ".a\n, .b , .c"]); - $this->assertSame(['.a', '.b', '.c'], $rule->getSelectors()); + $this->assertSame(['.a', '.b', '.c'], $rule->selectors); } public function testIsSmartAboutSelectorsCommas() @@ -32,35 +32,36 @@ public function testIsSmartAboutSelectorsCommas() ]); $this->assertSame( ['[foo=\'a, b\']', 'a:-moz-any(:focus, [href*=\',\'])'], - $rule->getSelectors() + $rule->selectors ); } public function testReceiveArrayInSelectors() { $rule = new Rule(['selector' => 'i, b']); - $rule->setSelectors(['em', 'strong']); + $rule->selectors = ['em', 'strong']; $this->assertSame('em, strong', $rule->selector); } public function testSavesSeparatorInSelectors() { $rule = new Rule(['selector' => "i,\nb"]); - $rule->setSelectors(['em', 'strong']); + $rule->selectors = ['em', 'strong']; $this->assertSame("em,\nstrong", $rule->selector); } public function testUsesBetweenToDetectSeparatorInSelectors() { $rule = new Rule(['selector' => 'b', 'raws' => ['between' => '']]); - $rule->setSelectors(['b', 'strong']); + $rule->selectors = ['b', 'strong']; $this->assertSame('b,strong', $rule->selector); } public function testUsesSpaceInSeparatorBeDefaultInSelectors() { $rule = new Rule(['selector' => 'b']); - $rule->setSelectors(['b', 'strong']); + $rule->selectors = ['b', 'strong']; + $rule->_selector = 1; $this->assertSame('b, strong', $rule->selector); } From 625f83b37d054a459a8b4d34090bcf038fb59aa9 Mon Sep 17 00:00:00 2001 From: Michele Locati Date: Mon, 26 Sep 2016 10:49:15 +0200 Subject: [PATCH 2/2] StyleCI --- src/Exception/CssSyntaxError.php | 1 + src/Node.php | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Exception/CssSyntaxError.php b/src/Exception/CssSyntaxError.php index bf82308..fb9df78 100644 --- a/src/Exception/CssSyntaxError.php +++ b/src/Exception/CssSyntaxError.php @@ -90,6 +90,7 @@ public function setMessage($message) } /** + * Updates the message. */ public function updateMessage() { diff --git a/src/Node.php b/src/Node.php index 601cdd2..35a0d69 100644 --- a/src/Node.php +++ b/src/Node.php @@ -60,11 +60,9 @@ class Node * @example * $root = \PostCSS\Parser::parse(' @media\nprint {\n}'); * $root->first->first->raws //=> ['before' => ' ', 'between' => ' ', 'afterName' = > "\n", 'after' => "\n"] - * * @example * \PostCSS\Parser::parse('a {}\n').raws //=> ['after' => "\n"] * \PostCSS\Parser::parse('a {}').raws //=> ['after => ''] - * * @example * $root = \PostCSS\Parser::parse('a {\n color:black\n}'); * $root->first->first->raws //=> ['before' => '', 'between' => ' ', 'after' => "\n"]