From f03e95476a2d27f25dcad90528b3dfbf73714952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20DELSOL?= Date: Fri, 11 Mar 2022 06:57:50 +0100 Subject: [PATCH 1/3] Fix badge, add PHPStan --- README.md | 4 ++-- composer.json | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1833464..6c2802a 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,12 @@ [![License](https://poser.pugx.org/wsdltophp/wsdlhandler/license)](https://packagist.org/packages/wsdltophp/wsdlhandler) [![Latest Stable Version](https://poser.pugx.org/wsdltophp/wsdlhandler/version.png)](https://packagist.org/packages/wsdltophp/wsdlhandler) -[![Build Status](https://travis-ci.com/WsdlToPhp/WsdlHandler.svg)](https://travis-ci.com/github/WsdlToPhp/WsdlHandler) +[![TeamCity build status](https://teamcity.mikael-delsol.fr/app/rest/builds/buildType:id:WsdlHandler_Build/statusIcon.svg)](https://github.com/WsdlToPhp/WsdlHandler) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/WsdlToPhp/WsdlHandler/badges/quality-score.png)](https://scrutinizer-ci.com/g/WsdlToPhp/WsdlHandler/) [![Code Coverage](https://scrutinizer-ci.com/g/WsdlToPhp/WsdlHandler/badges/coverage.png)](https://scrutinizer-ci.com/g/WsdlToPhp/WsdlHandler/) [![Total Downloads](https://poser.pugx.org/wsdltophp/wsdlhandler/downloads)](https://packagist.org/packages/wsdltophp/wsdlhandler) [![StyleCI](https://styleci.io/repos/87977980/shield)](https://styleci.io/repos/87977980) -[![SymfonyInsight](https://insight.symfony.com/projects/3dd23426-0808-4715-9a11-e51dc84cb0b4/mini.svg)](https://insight.symfony.com/projects/3dd23426-0808-4715-9a11-e51dc84cb0b4) +[![SymfonyInsight](https://insight.symfony.com/projects/b3232a2b-83c4-4546-92ae-c3f1357f62e9/mini.svg)](https://insight.symfony.com/projects/b3232a2b-83c4-4546-92ae-c3f1357f62e9) WsdlHandler uses the [decorator design pattern](https://en.wikipedia.org/wiki/Decorator_pattern) upon [DomHandler](https://github.com/WsdlToPhp/DomHandler). diff --git a/composer.json b/composer.json index 8ac68c1..330a920 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "~2.0", + "phpstan/phpstan": "^1.4", "phpunit/phpunit": "^9" }, "config": { @@ -44,7 +45,8 @@ }, "scripts": { "test": "vendor/bin/phpunit", - "lint": "vendor/bin/php-cs-fixer fix --ansi --diff --verbose" + "lint": "vendor/bin/php-cs-fixer fix --ansi --diff --verbose", + "phpstan": "vendor/bin/phpstan analyze src --level=2" }, "support": { "email": "contact@wsdltophp.com" From fd01933da1044f9b67f9e15bf16130747e85eb0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20DELSOL?= Date: Thu, 24 Mar 2022 21:34:53 +0100 Subject: [PATCH 2/3] Update PHP CS Fixer and corresponding setting file Add PHPStan --- .php_cs => .php-cs-fixer.php | 2 +- .travis.yml | 34 --------- composer.json | 2 +- phpstan.neon.dist | 12 ++++ src/AbstractDocument.php | 92 ++++++++++++------------- src/Tag/AbstractTag.php | 2 +- src/Tag/AbstractTagImport.php | 6 +- src/Tag/AbstractTagOperationElement.php | 2 +- src/Tag/TagAttributeGroup.php | 2 + src/Tag/TagHeader.php | 8 +-- src/Tag/TagList.php | 2 +- src/Tag/TagPart.php | 4 +- src/Tag/TagRestriction.php | 2 +- src/Tag/TagUnion.php | 2 +- src/Wsdl.php | 3 +- tests/Tag/TagAttributeGroupTest.php | 13 ++-- tests/Tag/TagAttributeTest.php | 1 + tests/Tag/TagDocumentationTest.php | 1 + tests/Tag/TagHeaderTest.php | 5 ++ tests/Tag/TagUnionTest.php | 3 + 20 files changed, 96 insertions(+), 102 deletions(-) rename .php_cs => .php-cs-fixer.php (85%) delete mode 100644 .travis.yml create mode 100644 phpstan.neon.dist diff --git a/.php_cs b/.php-cs-fixer.php similarity index 85% rename from .php_cs rename to .php-cs-fixer.php index a2d2922..56564b1 100644 --- a/.php_cs +++ b/.php-cs-fixer.php @@ -4,7 +4,7 @@ ->exclude('vendor') ->in(__DIR__); -return PhpCsFixer\Config::create() +return (new PhpCsFixer\Config()) ->setUsingCache(false) ->setRules(array( '@PhpCsFixer' => true, diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 636c2b6..0000000 --- a/.travis.yml +++ /dev/null @@ -1,34 +0,0 @@ -language: php - -jobs: - include: - - name: 'Tests under PHP 7.4' - php: '7.4' - dist: bionic - - name: 'Tests under PHP 8.0' - php: '8.0' - dist: bionic - - name: 'Tests under PHP nightly' - php: 'nightly' - dist: bionic - - fast_finish: true - allow_failures: - - php: 'nightly' - -cache: - directories: - - $HOME/.composer/cache - -install: - - composer install - -script: - - php -dmemory_limit=-1 -dxdebug.mode=coverage ./vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover - -after_script: - - wget https://scrutinizer-ci.com/ocular.phar - - php -dmemory_limit=-1 ocular.phar code-coverage:upload --format=php-clover coverage.clover - -after_success: - - bash <(curl -s https://codecov.io/bash) diff --git a/composer.json b/composer.json index 330a920..352806a 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "wsdltophp/domhandler": "~2.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~2.0", + "friendsofphp/php-cs-fixer": "~3.0", "phpstan/phpstan": "^1.4", "phpunit/phpunit": "^9" }, diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..1f17da0 --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,12 @@ +parameters: + ignoreErrors: + - + message: "#^Method WsdlToPhp\\\\DomHandler\\\\AbstractDomDocumentHandler\\:\\:getElementByNameAndAttributes\\(\\) invoked with 3 parameters, 2 required\\.$#" + count: 1 + path: src/Tag/AbstractTagOperationElement.php + + - + message: "#^Method WsdlToPhp\\\\DomHandler\\\\AbstractDomDocumentHandler\\:\\:getElementByNameAndAttributes\\(\\) invoked with 3 parameters, 2 required\\.$#" + count: 1 + path: src/Tag/TagPart.php + diff --git a/src/AbstractDocument.php b/src/AbstractDocument.php index 65a2432..d3f9ae2 100644 --- a/src/AbstractDocument.php +++ b/src/AbstractDocument.php @@ -12,53 +12,53 @@ abstract class AbstractDocument extends DomDocumentHandler { - const TAG_ADDRESS = 'address'; - const TAG_ALL = 'all'; - const TAG_ANNOTATION = 'annotation'; - const TAG_ANY = 'any'; - const TAG_ANY_ATTRIBUTE = 'anyAttribute'; - const TAG_APPINFO = 'appinfo'; - const TAG_ATTRIBUTE = 'attribute'; - const TAG_ATTRIBUTE_GROUP = 'attributeGroup'; - const TAG_BINDING = 'binding'; - const TAG_BODY = 'body'; - const TAG_CHOICE = 'choice'; - const TAG_COMPLEX_CONTENT = 'complexContent'; - const TAG_COMPLEX_TYPE = 'complexType'; - const TAG_DEFINITIONS = 'definitions'; - const TAG_DOCUMENTATION = 'documentation'; - const TAG_ELEMENT = 'element'; - const TAG_ENUMERATION = 'enumeration'; - const TAG_EXTENSION = 'extension'; - const TAG_FIELD = 'field'; - const TAG_GROUP = 'group'; - const TAG_HEADER = 'header'; - const TAG_IMPORT = 'import'; - const TAG_INCLUDE = 'include'; - const TAG_INPUT = 'input'; - const TAG_KEY = 'key'; - const TAG_KEYREF = 'keyref'; - const TAG_LIST = 'list'; - const TAG_MEMBER_TYPES = 'memberTypes'; - const TAG_MESSAGE = 'message'; - const TAG_NOTATION = 'notation'; - const TAG_OPERATION = 'operation'; - const TAG_OUTPUT = 'output'; - const TAG_PART = 'part'; - const TAG_PORT = 'port'; - const TAG_PORT_TYPE = 'portType'; - const TAG_REDEFINE = 'redefine'; - const TAG_RESTRICTION = 'restriction'; - const TAG_SELECTOR = 'selector'; - const TAG_SEQUENCE = 'sequence'; - const TAG_SCHEMA = 'schema'; - const TAG_SIMPLE_CONTENT = 'simpleContent'; - const TAG_SIMPLE_TYPE = 'simpleType'; - const TAG_TYPES = 'types'; - const TAG_UNION = 'union'; - const TAG_UNIQUE = 'unique'; + public const TAG_ADDRESS = 'address'; + public const TAG_ALL = 'all'; + public const TAG_ANNOTATION = 'annotation'; + public const TAG_ANY = 'any'; + public const TAG_ANY_ATTRIBUTE = 'anyAttribute'; + public const TAG_APPINFO = 'appinfo'; + public const TAG_ATTRIBUTE = 'attribute'; + public const TAG_ATTRIBUTE_GROUP = 'attributeGroup'; + public const TAG_BINDING = 'binding'; + public const TAG_BODY = 'body'; + public const TAG_CHOICE = 'choice'; + public const TAG_COMPLEX_CONTENT = 'complexContent'; + public const TAG_COMPLEX_TYPE = 'complexType'; + public const TAG_DEFINITIONS = 'definitions'; + public const TAG_DOCUMENTATION = 'documentation'; + public const TAG_ELEMENT = 'element'; + public const TAG_ENUMERATION = 'enumeration'; + public const TAG_EXTENSION = 'extension'; + public const TAG_FIELD = 'field'; + public const TAG_GROUP = 'group'; + public const TAG_HEADER = 'header'; + public const TAG_IMPORT = 'import'; + public const TAG_INCLUDE = 'include'; + public const TAG_INPUT = 'input'; + public const TAG_KEY = 'key'; + public const TAG_KEYREF = 'keyref'; + public const TAG_LIST = 'list'; + public const TAG_MEMBER_TYPES = 'memberTypes'; + public const TAG_MESSAGE = 'message'; + public const TAG_NOTATION = 'notation'; + public const TAG_OPERATION = 'operation'; + public const TAG_OUTPUT = 'output'; + public const TAG_PART = 'part'; + public const TAG_PORT = 'port'; + public const TAG_PORT_TYPE = 'portType'; + public const TAG_REDEFINE = 'redefine'; + public const TAG_RESTRICTION = 'restriction'; + public const TAG_SELECTOR = 'selector'; + public const TAG_SEQUENCE = 'sequence'; + public const TAG_SCHEMA = 'schema'; + public const TAG_SIMPLE_CONTENT = 'simpleContent'; + public const TAG_SIMPLE_TYPE = 'simpleType'; + public const TAG_TYPES = 'types'; + public const TAG_UNION = 'union'; + public const TAG_UNIQUE = 'unique'; - const ATTRIBUTE_TARGET_NAMESPACE = 'targetNamespace'; + public const ATTRIBUTE_TARGET_NAMESPACE = 'targetNamespace'; public function getNamespaceUri(string $namespace): string { diff --git a/src/Tag/AbstractTag.php b/src/Tag/AbstractTag.php index 75cda9b..001d3ce 100644 --- a/src/Tag/AbstractTag.php +++ b/src/Tag/AbstractTag.php @@ -13,7 +13,7 @@ abstract class AbstractTag extends ElementHandler { - const MAX_DEEP = 5; + public const MAX_DEEP = 5; public function getDomDocumentHandler(): AbstractDocument { diff --git a/src/Tag/AbstractTagImport.php b/src/Tag/AbstractTagImport.php index 550ec14..5e1354c 100644 --- a/src/Tag/AbstractTagImport.php +++ b/src/Tag/AbstractTagImport.php @@ -6,9 +6,9 @@ abstract class AbstractTagImport extends Tag { - const ATTRIBUTE_LOCATION = 'location'; - const ATTRIBUTE_SCHEMA_LOCATION = 'schemaLocation'; - const ATTRIBUTE_SCHEMA_LOCATION_ = 'schemalocation'; + public const ATTRIBUTE_LOCATION = 'location'; + public const ATTRIBUTE_SCHEMA_LOCATION = 'schemaLocation'; + public const ATTRIBUTE_SCHEMA_LOCATION_ = 'schemalocation'; public function getLocationAttributeValue(): string { diff --git a/src/Tag/AbstractTagOperationElement.php b/src/Tag/AbstractTagOperationElement.php index 7604cd9..5d35c27 100644 --- a/src/Tag/AbstractTagOperationElement.php +++ b/src/Tag/AbstractTagOperationElement.php @@ -8,7 +8,7 @@ abstract class AbstractTagOperationElement extends Tag { - const ATTRIBUTE_MESSAGE = 'message'; + public const ATTRIBUTE_MESSAGE = 'message'; public function getParentOperation(): ?TagOperation { diff --git a/src/Tag/TagAttributeGroup.php b/src/Tag/TagAttributeGroup.php index 9471b98..dad300a 100644 --- a/src/Tag/TagAttributeGroup.php +++ b/src/Tag/TagAttributeGroup.php @@ -23,6 +23,8 @@ public function getReferencingElements(): array 'ref' => sprintf('*%s', $this->getAttributeName()), ]); } + + /** @var AbstractTag $attributeGroup */ foreach ($attributeGroups as $attributeGroup) { $parent = $attributeGroup->getSuitableParent(); /* diff --git a/src/Tag/TagHeader.php b/src/Tag/TagHeader.php index a1c1fee..1d86790 100644 --- a/src/Tag/TagHeader.php +++ b/src/Tag/TagHeader.php @@ -9,10 +9,10 @@ class TagHeader extends AbstractTagOperationElement { - const ATTRIBUTE_PART = 'part'; - const REQUIRED_HEADER = 'required'; - const OPTIONAL_HEADER = 'optional'; - const ATTRIBUTE_REQUIRED = 'wsdl:required'; + public const ATTRIBUTE_PART = 'part'; + public const REQUIRED_HEADER = 'required'; + public const OPTIONAL_HEADER = 'optional'; + public const ATTRIBUTE_REQUIRED = 'wsdl:required'; public function getParentInput(): ?TagInput { diff --git a/src/Tag/TagList.php b/src/Tag/TagList.php index 629e1db..c0b34df 100644 --- a/src/Tag/TagList.php +++ b/src/Tag/TagList.php @@ -8,7 +8,7 @@ class TagList extends Tag { - const ATTRIBUTE_ITEM_TYPE = 'itemType'; + public const ATTRIBUTE_ITEM_TYPE = 'itemType'; public function getAttributeItemType(): string { diff --git a/src/Tag/TagPart.php b/src/Tag/TagPart.php index 9757cb1..74c3e84 100644 --- a/src/Tag/TagPart.php +++ b/src/Tag/TagPart.php @@ -9,8 +9,8 @@ class TagPart extends Tag { - const ATTRIBUTE_ELEMENT = 'element'; - const ATTRIBUTE_TYPE = 'type'; + public const ATTRIBUTE_ELEMENT = 'element'; + public const ATTRIBUTE_TYPE = 'type'; /** * @return null|AttributeHandler|int|string diff --git a/src/Tag/TagRestriction.php b/src/Tag/TagRestriction.php index 9f8f5a9..2fe7109 100644 --- a/src/Tag/TagRestriction.php +++ b/src/Tag/TagRestriction.php @@ -8,7 +8,7 @@ class TagRestriction extends Tag { - const ATTRIBUTE_BASE = 'base'; + public const ATTRIBUTE_BASE = 'base'; public function isEnumeration(): bool { diff --git a/src/Tag/TagUnion.php b/src/Tag/TagUnion.php index c557997..1455c9f 100644 --- a/src/Tag/TagUnion.php +++ b/src/Tag/TagUnion.php @@ -8,7 +8,7 @@ class TagUnion extends Tag { - const ATTRIBUTE_MEMBER_TYPES = 'memberTypes'; + public const ATTRIBUTE_MEMBER_TYPES = 'memberTypes'; public function getAttributeMemberTypes(): array { diff --git a/src/Wsdl.php b/src/Wsdl.php index 70b23ad..60ad176 100644 --- a/src/Wsdl.php +++ b/src/Wsdl.php @@ -53,9 +53,10 @@ public function getElementsByNameAndAttributes(string $name, array $attributes, $attributes, $node, ]); + /** @var Schema $externalSchema */ foreach ($this->getExternalSchemas() as $index => $externalSchema) { - if (0 < ($nodes = $externalSchema->searchTagsByXpath($name, $attributes, $node))->length) { + if (0 < ($nodes = $externalSchema->searchTagsByXpath($name, $attributes, $node))->count()) { $elements = array_merge($elements, $this->getElementsHandlers($nodes)); } } diff --git a/tests/Tag/TagAttributeGroupTest.php b/tests/Tag/TagAttributeGroupTest.php index d28fe72..0559f79 100644 --- a/tests/Tag/TagAttributeGroupTest.php +++ b/tests/Tag/TagAttributeGroupTest.php @@ -237,14 +237,17 @@ public function testGetReferencingElementsMustReturnReferencingElementsFromAttri ]; $testedCount = 0; + /** @var TagAttributeGroup $attributeGroup */ foreach ($attributeGroups as $attributeGroup) { - if ('' !== $attributeGroup->getAttributeName()) { - $elements = $attributeGroup->getReferencingElements(); - $this->assertCount($attributeGroupCounts[$attributeGroup->getAttributeName()], $elements, sprintf('Failed with attributeGroup is "%s"', $attributeGroup->getAttributeName())); - $this->assertContainsOnlyInstancesOf(Tag::class, $elements); - ++$testedCount; + if ('' === $attributeGroup->getAttributeName()) { + continue; } + + $elements = $attributeGroup->getReferencingElements(); + $this->assertCount($attributeGroupCounts[$attributeGroup->getAttributeName()], $elements, sprintf('Failed with attributeGroup is "%s"', $attributeGroup->getAttributeName())); + $this->assertContainsOnlyInstancesOf(Tag::class, $elements); + ++$testedCount; } $this->assertCount($testedCount, $attributeGroupCounts); } diff --git a/tests/Tag/TagAttributeTest.php b/tests/Tag/TagAttributeTest.php index a161f43..38b0520 100644 --- a/tests/Tag/TagAttributeTest.php +++ b/tests/Tag/TagAttributeTest.php @@ -18,6 +18,7 @@ final class TagAttributeTest extends AbstractTestCase public function testGetSuitableParentAsAttributeGroupMustReturnAttributeGroupParent() { $schema = self::wsdlWhlInstance(); + /** @var TagAttribute $attribute */ $attribute = $schema->getElementByNameAndAttributes(AbstractDocument::TAG_ATTRIBUTE, [ 'name' => 'ShortText', diff --git a/tests/Tag/TagDocumentationTest.php b/tests/Tag/TagDocumentationTest.php index d2bfb50..c2f65a7 100644 --- a/tests/Tag/TagDocumentationTest.php +++ b/tests/Tag/TagDocumentationTest.php @@ -35,6 +35,7 @@ public function testGetSuitableParentMustReturn() ]; $assertCount = 0; + /** @var TagDocumentation $documentation */ foreach ($documentations as $index => $documentation) { $parent = $documentation->getSuitableParent(); diff --git a/tests/Tag/TagHeaderTest.php b/tests/Tag/TagHeaderTest.php index a0a2e7e..20917b5 100644 --- a/tests/Tag/TagHeaderTest.php +++ b/tests/Tag/TagHeaderTest.php @@ -106,6 +106,7 @@ public function testGetAttributeRequiredMustReturnTrueOrFalse() $sessionHeader = $operation->getChildByNameAndAttributes(AbstractDocument::TAG_HEADER, [ 'part' => 'SessionHeader', ]); + /** @var TagHeader $clusterHeader */ $clusterHeader = $operation->getChildByNameAndAttributes(AbstractDocument::TAG_HEADER, [ 'part' => 'ClusterHeader', @@ -132,6 +133,7 @@ public function testGetHeaderTypeMustReturnHeaderType() $sessionHeader = $operation->getChildByNameAndAttributes(AbstractDocument::TAG_HEADER, [ 'part' => 'SessionHeader', ]); + /** @var TagHeader $clusterHeader */ $clusterHeader = $operation->getChildByNameAndAttributes(AbstractDocument::TAG_HEADER, [ 'part' => 'ClusterHeader', @@ -158,6 +160,7 @@ public function testGetHeaderNameMustReturnHeaderName() $sessionHeader = $operation->getChildByNameAndAttributes(AbstractDocument::TAG_HEADER, [ 'part' => 'SessionHeader', ]); + /** @var TagHeader $clusterHeader */ $clusterHeader = $operation->getChildByNameAndAttributes(AbstractDocument::TAG_HEADER, [ 'part' => 'ClusterHeader', @@ -184,6 +187,7 @@ public function testGetHeaderRequiredMustReturnRequiredOrOptional() $sessionHeader = $operation->getChildByNameAndAttributes(AbstractDocument::TAG_HEADER, [ 'part' => 'SessionHeader', ]); + /** @var TagHeader $clusterHeader */ $clusterHeader = $operation->getChildByNameAndAttributes(AbstractDocument::TAG_HEADER, [ 'part' => 'ClusterHeader', @@ -210,6 +214,7 @@ public function testGetAttributeMessageNamespaceMustReturnMessageNamespace() $sessionHeader = $operation->getChildByNameAndAttributes(AbstractDocument::TAG_HEADER, [ 'part' => 'SessionHeader', ]); + /** @var TagHeader $clusterHeader */ $clusterHeader = $operation->getChildByNameAndAttributes(AbstractDocument::TAG_HEADER, [ 'part' => 'ClusterHeader', diff --git a/tests/Tag/TagUnionTest.php b/tests/Tag/TagUnionTest.php index 03cec2a..c689f69 100644 --- a/tests/Tag/TagUnionTest.php +++ b/tests/Tag/TagUnionTest.php @@ -57,6 +57,7 @@ public function testHasMemberTypesAsChildrenMustReturnFalse() $this->assertContainsOnlyInstancesOf(TagUnion::class, $unions); $tests = 0; + /** @var TagUnion $union */ foreach ($unions as $union) { switch ($union->getSuitableParent()->getAttributeName()) { @@ -86,6 +87,7 @@ public function testHasMemberTypesAsChildrenMustReturnTrue() $this->assertContainsOnlyInstancesOf(TagUnion::class, $unions); $tests = 0; + /** @var TagUnion $union */ foreach ($unions as $union) { switch ($union->getSuitableParent()->getAttributeName()) { @@ -115,6 +117,7 @@ public function testGetMemberTypesChildrenMustReturnTheChildren() $this->assertContainsOnlyInstancesOf(TagUnion::class, $unions); $tests = 0; + /** @var TagUnion $union */ foreach ($unions as $union) { switch ($union->getSuitableParent()->getAttributeName()) { From c8db90a09a01d2ffee7794fd0aa5252ad2a7ee5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20DELSOL?= Date: Thu, 24 Mar 2022 21:54:32 +0100 Subject: [PATCH 3/3] update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1d00f5..e21aa6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## 1.0.5 - 2022/03/24 +- Update PHP CS Fixer and corresponding setting file +- Add PHPStan + ## 1.0.4 - 2021/07/14 - issue #3 - Choice tag must ignore sequence tag