diff --git a/.gitattributes b/.gitattributes
index 4f0ebb8..d00cf8f 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -8,3 +8,5 @@
/box.json.dist export-ignore
/composer-require-checker.json export-ignore
/phpunit.xml.dist export-ignore
+/psalm-baseline.xml export-ignore
+/psalm.xml export-ignore
diff --git a/.github/workflows/integrate.yaml b/.github/workflows/integrate.yaml
index fe19a1f..791ef4e 100644
--- a/.github/workflows/integrate.yaml
+++ b/.github/workflows/integrate.yaml
@@ -87,6 +87,32 @@ jobs:
- name: "Run maglnet/composer-require-checker"
run: ".phive/composer-require-checker check --config-file=$(pwd)/composer-require-checker.json"
+ static-code-analysis:
+ name: "Static Code Analysis"
+
+ runs-on: "ubuntu-latest"
+
+ strategy:
+ matrix:
+ php-version:
+ - "7.4"
+
+ steps:
+ - name: "Checkout"
+ uses: "actions/checkout@v3"
+
+ - name: "Set up PHP"
+ uses: "shivammathur/setup-php@v2"
+ with:
+ coverage: "none"
+ php-version: "${{ matrix.php-version }}"
+
+ - name: "Install dependencies with composer"
+ run: "composer install --ansi --no-progress"
+
+ - name: "Run vimeo/psalm"
+ run: ".phive/psalm --config=psalm.xml --output-format=github --shepherd --show-info=false --stats --threads=4"
+
tests:
name: "Tests"
diff --git a/.gitignore b/.gitignore
index 111ddaf..a712590 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+/.build/
/vendor/
/.php-cs-fixer.cache
/.phpunit.result.cache
diff --git a/.phive/phars.xml b/.phive/phars.xml
index 458214c..bb52848 100644
--- a/.phive/phars.xml
+++ b/.phive/phars.xml
@@ -2,4 +2,5 @@
+
diff --git a/.phive/psalm b/.phive/psalm
new file mode 100755
index 0000000..5ffb50f
Binary files /dev/null and b/.phive/psalm differ
diff --git a/README.md b/README.md
index 02d9e91..fd57972 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +3,7 @@
[![Integrate](https://github.com/friendsoftwig/twigcs/workflows/Integrate/badge.svg)](https://github.com/friendsoftwig/twigcs/actions)
[![Code Coverage](https://codecov.io/github/friendsoftwig/twigcs/branch/main/graph/badge.svg)](https://codecov.io/github/friendsoftwig/twigcs)
+[![Type Coverage](https://shepherd.dev/github/friendsoftwig/twigcs/coverage.svg)](https://shepherd.dev/github/friendsoftwig/twigcs)
The missing checkstyle for twig!
diff --git a/psalm-baseline.xml b/psalm-baseline.xml
new file mode 100644
index 0000000..610c19c
--- /dev/null
+++ b/psalm-baseline.xml
@@ -0,0 +1,1847 @@
+
+
+
+
+ \gettype($finder)
+
+
+ TemplateResolverInterface
+
+
+ $finder
+
+
+ $display
+
+
+ string
+
+
+ $this->display
+
+
+ $this->loader
+
+
+ \is_object($finder)
+
+
+ new static()
+
+
+
+
+ $path
+ $path
+
+
+ $cwd
+ $path
+ $value
+
+
+ $cwd
+ $finders
+ $path
+ $specificRulesets
+
+
+ getFinders
+ getPath
+ getReporter
+ getRuleset
+ getSeverity
+ getSeverityLimit
+ separatedContextLessInclude
+ setOption
+
+
+ $configFile
+ $configFile
+ $configFile
+ $path
+ $path
+ $pattern
+ $rulesetClassName
+ $rulesetClassName
+ $this->cwd
+ $this->getPath()
+ $this->options['exclude']
+ $this->options['exclude']
+ $this->options['path']
+ $this->options['path']
+
+
+ $name
+
+
+ $this->options['path'][0]
+
+
+ $configDir
+ $cwd
+ $pattern
+ $rulesetClassName
+ $rulesetClassName
+ $value
+
+
+ string
+
+
+ $configDir
+ $configDir
+ $cwd
+
+
+ $this->options['display']
+
+
+ [$configFile]
+ string[]
+
+
+ getReporter
+ getRuleset
+ getTemplateResolver
+
+
+ include $path
+
+
+
+
+ $command->getName()
+
+
+
+
+ setContainer
+
+
+ $container
+
+
+
+
+ getRealPath
+
+
+ configure
+
+
+ $file
+ $finder
+ $realPath
+ $realPath
+ $realPath
+ $severityLimit
+ $validator->validate($ruleset, $tokens)
+
+
+ $file
+ $finder
+ $finders
+ $lexer
+ $realPath
+ $ruleset
+ $severityLimit
+ $tokens
+ $validator
+ $violation
+
+
+ getSeverity
+ report
+ tokenize
+ validate
+
+
+
+
+ configure
+
+
+ $error->getColumn()
+ $error->getReason()
+ $expr
+ $input->getOption('twig-version')
+ $node->getExpr()
+ $node->getExpr()
+ $node->getOffset()
+ $node->getOffset()
+ $node->getOffsetsMap()
+ $node->getType()
+ $path
+ $rootNode->getTrace()
+ $ruleChecker->getLog()
+
+
+ $expr
+ $node
+ $nodes
+ $path
+ $rootNode
+
+
+ flatten
+ getColumn
+ getExpr
+ getExpr
+ getOffset
+ getOffset
+ getOffsetsMap
+ getReason
+ getTrace
+ getType
+
+
+
+
+ function () {
+ function () {
+ function () {
+ function () {
+ function () {
+ function () {
+ function () {
+ function () {
+ function () {
+
+
+ get
+
+
+ call_user_func($this[$key])
+
+
+
+
+ lexBlock
+ lexComment
+ lexExpression
+ lexVar
+ moveCursor
+ pushToken
+
+
+ $match[0][1] - $this->cursor
+ $this->code
+ $this->code
+ $this->code
+ $this->code
+ $this->code
+ $this->columnno
+ $this->columnno
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->lineno
+ $this->lineno
+ $this->regexes['lex_block']
+ $this->regexes['lex_comment']
+ $this->regexes['lex_var']
+ $this->source
+
+
+ $this->regexes['lex_block']
+ $this->regexes['lex_comment']
+ $this->regexes['lex_var']
+
+
+ $this->tokens[]
+
+
+ $this->columnno
+ $this->columnno
+ $this->cursor
+ $this->cursor
+ $this->lineno
+
+
+ strrpos($text, "\n")
+
+
+
+
+ getRealOffset
+
+
+
+
+ !$this->parent
+ $this->parent
+
+
+ $size
+ $size
+
+
+ $capture->getRealOffset()
+ $capture->getRealOffset()
+ $capture->getSource()
+ $capture->getSource()
+ $capture->getText()
+ $subExpr
+ $text
+
+
+ $text[0]
+
+
+ $capture
+ $capture
+ $errors
+ $subExpr
+ $text
+
+
+ getRealOffset
+ getRealOffset
+ getSource
+ getSource
+ getText
+ getText
+
+
+ $parent
+
+
+ $callback
+
+
+ $ruleChecker
+ $ruleChecker
+
+
+ $errors
+
+
+
+
+ match
+
+
+ $this->captureTypes[$key]
+
+
+ $whole
+
+
+
+
+ $errors
+ $unrecognizedExpressions
+
+
+ $this->errors
+
+
+ $this->errors[]
+ $this->unrecognizedExpressions[]
+
+
+ array
+
+
+ getColumn
+ getColumn
+
+
+ $this->unrecognizedExpressions
+
+
+
+
+ $len
+ $str
+
+
+ check
+ compute
+ explain
+ getLog
+ split
+ subCheck
+
+
+ $i
+ $len
+ $rule->getRule()
+ $rule[0]
+ $rule[1]
+ $rule[2]
+ $str
+ $str
+
+
+ $rule[0]
+ $rule[1]
+ $rule[2]
+
+
+ $grouped[$match->getType()]
+ $vars[$char]
+ $vars[$char]
+
+
+ $char
+ $grouped[$match->getType()][]
+ $i
+ $match
+ $matches
+ $rule
+ $rule
+ $ruleset
+ $types[]
+
+
+ call_user_func($rule->getCallback(), $this, $report, $grouped)
+
+
+ getCallback
+ getRule
+ getType
+ increaseOffset
+ match
+ setOffsetsMap
+
+
+ $char
+ $len
+ $vars[$char]
+
+
+
+
+ $this->offset
+
+
+ $delegateChildren
+ $expr
+ $i
+ $offset
+
+
+ fromString
+ getOffsetAt
+ getOffsetsMap
+
+
+ $child->getTrace()
+ $item
+ $kind
+
+
+ $this->offsetsMap[$i]
+
+
+ $child
+ $children
+ $expressions
+ $item
+ $kind
+ $offsetCounter
+ $offsetCounter
+ $offsetCounter
+ $offsets[]
+ $offsets[]
+ $result[]
+ $this->offset
+
+
+ flatten
+ getKind
+ getTrace
+
+
+ $kind
+ $offsetCounter
+ $offsetCounter
+
+
+
+
+ explain
+
+
+ $node->getExpr()
+ $node->getOffsetsMap()
+ $node->getType()
+
+
+ $expr
+ $node
+ $nodes
+
+
+ flatten
+ getExpr
+ getOffsetsMap
+ getType
+
+
+
+
+ function ($rule) use ($vars) {
+
+
+ $vars
+
+
+ $config
+
+
+ $rule
+ $this->config['array']['after_opening']
+ $this->config['array']['after_opening']
+ $this->config['array']['before_closing']
+ $this->config['array']['before_closing']
+ $this->config['array']['empty']
+ $this->config['array']['empty']
+ $this->config['arrow_function']['after_arrow']
+ $this->config['arrow_function']['before_arrow']
+ $this->config['binary']['after_op']
+ $this->config['binary']['before_op']
+ $this->config['elseif']
+ $this->config['empty_list_whitespaces']
+ $this->config['empty_list_whitespaces']
+ $this->config['for']['after_coma']
+ $this->config['for']['after_coma']
+ $this->config['for']['after_for']
+ $this->config['for']['after_for']
+ $this->config['for']['after_for']
+ $this->config['for']['after_for']
+ $this->config['for']['after_if']
+ $this->config['for']['after_if']
+ $this->config['for']['after_in']
+ $this->config['for']['after_in']
+ $this->config['for']['after_in']
+ $this->config['for']['after_in']
+ $this->config['for']['after_key_var']
+ $this->config['for']['after_key_var']
+ $this->config['for']['after_value_var']
+ $this->config['for']['after_value_var']
+ $this->config['for']['after_value_var']
+ $this->config['for']['after_value_var']
+ $this->config['for']['before_if']
+ $this->config['for']['before_if']
+ $this->config['from']['after_as']
+ $this->config['from']['after_source']
+ $this->config['from']['after_source']
+ $this->config['from']['after_source']
+ $this->config['from']['before_as']
+ $this->config['from']['before_names']
+ $this->config['from']['before_names']
+ $this->config['from']['before_names']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['from']['before_source']
+ $this->config['func']['before_parentheses']
+ $this->config['hash']['after_coma']
+ $this->config['hash']['after_coma']
+ $this->config['hash']['after_coma']
+ $this->config['hash']['after_key']
+ $this->config['hash']['after_key']
+ $this->config['hash']['after_key']
+ $this->config['hash']['after_key']
+ $this->config['hash']['after_key']
+ $this->config['hash']['after_key']
+ $this->config['hash']['after_opening']
+ $this->config['hash']['after_value']
+ $this->config['hash']['after_value']
+ $this->config['hash']['after_value']
+ $this->config['hash']['before_closing']
+ $this->config['hash']['before_value']
+ $this->config['hash']['before_value']
+ $this->config['hash']['before_value']
+ $this->config['hash']['before_value']
+ $this->config['hash']['before_value']
+ $this->config['hash']['before_value']
+ $this->config['hash']['empty']
+ $this->config['hash']['empty']
+ $this->config['if']
+ $this->config['import']['after_as']
+ $this->config['import']['after_as']
+ $this->config['import']['after_as']
+ $this->config['import']['after_coma']
+ $this->config['import']['after_source']
+ $this->config['import']['after_source']
+ $this->config['import']['after_source']
+ $this->config['import']['before_coma']
+ $this->config['import']['before_source']
+ $this->config['list']['after_coma']
+ $this->config['list']['after_coma']
+ $this->config['list']['after_value']
+ $this->config['list']['after_value']
+ $this->config['macro']['after_macro']
+ $this->config['macro']['after_name']
+ $this->config['named_args']['after_=']
+ $this->config['named_args']['after_=']
+ $this->config['named_args']['after_value']
+ $this->config['named_args']['before_=']
+ $this->config['named_args']['before_=']
+ $this->config['parentheses']['after_value']
+ $this->config['parentheses']['before_value']
+ $this->config['parentheses']['empty']
+ $this->config['print']['after']
+ $this->config['print']['before']
+ $this->config['property']['after_.']
+ $this->config['property']['after_|']
+ $this->config['property']['before_.']
+ $this->config['property']['before_|']
+ $this->config['range']['after_op']
+ $this->config['range']['before_op']
+ $this->config['set']['after_equal']
+ $this->config['set']['after_set']
+ $this->config['set']['after_var_name']
+ $this->config['slice']['after_:']
+ $this->config['slice']['after_[']
+ $this->config['slice']['before_:']
+ $this->config['slice']['before_]']
+ $this->config['tag']['after']
+ $this->config['tag']['after']
+ $this->config['tag']['after']
+ $this->config['tag']['before']
+ $this->config['tag']['before']
+ $this->config['tag']['before']
+ $this->config['tag_default_arg_spacing']
+ $this->config['ternary']['after_:']
+ $this->config['ternary']['after_?']
+ $this->config['ternary']['after_?:']
+ $this->config['ternary']['before_:']
+ $this->config['ternary']['before_?']
+ $this->config['ternary']['before_?:']
+ $this->config['unary']['between']
+
+
+ $this->config['array']
+ $this->config['array']
+ $this->config['array']
+ $this->config['array']
+ $this->config['array']
+ $this->config['array']
+ $this->config['arrow_function']
+ $this->config['arrow_function']
+ $this->config['binary']
+ $this->config['binary']
+ $this->config['elseif']
+ $this->config['empty_list_whitespaces']
+ $this->config['empty_list_whitespaces']
+ $this->config['for']
+ $this->config['for']
+ $this->config['for']
+ $this->config['for']
+ $this->config['for']
+ $this->config['for']
+ $this->config['for']
+ $this->config['for']
+ $this->config['for']
+ $this->config['for']
+ $this->config['for']
+ $this->config['for']
+ $this->config['for']
+ $this->config['for']
+ $this->config['for']
+ $this->config['for']
+ $this->config['for']
+ $this->config['for']
+ $this->config['for']
+ $this->config['for']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['from']
+ $this->config['func']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['hash']
+ $this->config['if']
+ $this->config['import']
+ $this->config['import']
+ $this->config['import']
+ $this->config['import']
+ $this->config['import']
+ $this->config['import']
+ $this->config['import']
+ $this->config['import']
+ $this->config['import']
+ $this->config['list']
+ $this->config['list']
+ $this->config['list']
+ $this->config['list']
+ $this->config['macro']
+ $this->config['macro']
+ $this->config['named_args']
+ $this->config['named_args']
+ $this->config['named_args']
+ $this->config['named_args']
+ $this->config['named_args']
+ $this->config['parentheses']
+ $this->config['parentheses']
+ $this->config['parentheses']
+ $this->config['print']
+ $this->config['print']
+ $this->config['property']
+ $this->config['property']
+ $this->config['property']
+ $this->config['property']
+ $this->config['range']
+ $this->config['range']
+ $this->config['set']
+ $this->config['set']
+ $this->config['set']
+ $this->config['slice']
+ $this->config['slice']
+ $this->config['slice']
+ $this->config['slice']
+ $this->config['tag']
+ $this->config['tag']
+ $this->config['tag']
+ $this->config['tag']
+ $this->config['tag']
+ $this->config['tag']
+ $this->config['tag_default_arg_spacing']
+ $this->config['ternary']
+ $this->config['ternary']
+ $this->config['ternary']
+ $this->config['ternary']
+ $this->config['ternary']
+ $this->config['ternary']
+ $this->config['twigMajorVersion']
+ $this->config['twigMajorVersion']
+ $this->config['twigMajorVersion']
+ $this->config['twigMajorVersion']
+ $this->config['twigMajorVersion']
+ $this->config['twigMajorVersion']
+ $this->config['unary']
+
+
+
+
+ $arraySpacingPattern
+ $arrowFunctionSpacingPattern
+ $binaryOpSpacingPattern
+ $elseifSpacingPattern
+ $embedSpacingPattern
+ $emptyArraySpacingPattern
+ $emptyHashSpacingPattern
+ $emptyListWhitespaces
+ $emptyParenthesesSpacingPattern
+ $forSpacingPattern
+ $fromSpacingPattern
+ $funcSpacingPattern
+ $hashSpacingPattern
+ $ifSpacingPattern
+ $importSpacingPattern
+ $includeSpacingPattern
+ $listSpacingPattern
+ $macroSpacingPattern
+ $namedArgsSpacingPattern
+ $parenthesesSpacingPattern
+ $printStatementSpacingPattern
+ $propertySpacingPattern
+ $rangeOpSpacingPattern
+ $setSpacingPattern
+ $sliceSpacingPattern
+ $tagDefaultArgSpacing
+ $tagSpacingPattern
+ $ternarySpacingPattern
+ $twigMajorVersion
+ $unaryOpSpacingPattern
+
+
+ getProcessedConfiguration
+
+
+ $this->arraySpacingPattern
+ $this->arrowFunctionSpacingPattern
+ $this->binaryOpSpacingPattern
+ $this->elseifSpacingPattern
+ $this->embedSpacingPattern
+ $this->emptyArraySpacingPattern
+ $this->emptyHashSpacingPattern
+ $this->emptyParenthesesSpacingPattern
+ $this->forSpacingPattern
+ $this->fromSpacingPattern
+ $this->funcSpacingPattern
+ $this->hashSpacingPattern
+ $this->ifSpacingPattern
+ $this->importSpacingPattern
+ $this->includeSpacingPattern
+ $this->listSpacingPattern
+ $this->macroSpacingPattern
+ $this->namedArgsSpacingPattern
+ $this->parenthesesSpacingPattern
+ $this->printStatementSpacingPattern
+ $this->propertySpacingPattern
+ $this->rangeOpSpacingPattern
+ $this->setSpacingPattern
+ $this->sliceSpacingPattern
+ $this->tagSpacingPattern
+ $this->ternarySpacingPattern
+ $this->unaryOpSpacingPattern
+
+
+ $config['empty_list_whitespaces']
+ $config['tag_default_arg_spacing']
+ $config['twigMajorVersion']
+
+
+
+
+ sanitize
+
+
+
+
+ $char
+ $char
+ $char
+ $item
+ $next
+ $next
+ $prev
+ $prev
+ $string
+
+
+ close
+ debug
+ enqueue
+ enqueueString
+ getHead
+ push
+ rollback
+ shouldClose
+ shouldRollback
+ strlen
+
+
+ $char
+ $string
+
+
+ $content
+ $head
+ $head
+ $i
+ $item
+ $item
+ $previousHead->head
+ $this->head
+
+
+ debug
+ strlen
+
+
+ $content->debug()
+ is_string($item) ? 1 : ($item->strlen())
+
+
+ $head
+
+
+
+
+ $violation->getColumn()
+ $violation->getLine()
+
+
+ report
+
+
+ $checkstyle->asXML()
+
+
+ addChild
+
+
+
+
+ report
+
+
+
+
+ report
+
+
+
+
+ report
+
+
+
+
+ 0
+ 1
+
+
+ $violation->getColumn() ?? 0
+ $violation->getLine() ?? 1
+
+
+ report
+
+
+ $violation->getColumn()
+ $violation->getLine()
+
+
+ $key
+
+
+
+
+ $failure[0]
+
+
+ $violation->getColumn()
+ $violation->getLine()
+
+
+ report
+
+
+ $testsuites->asXML()
+
+
+ addChild
+
+
+
+
+ report
+
+
+ $entry->violations[]
+ $result->files[]
+
+
+ $entry
+
+
+ $entry->violations
+
+
+ $entry
+
+
+
+
+ report
+
+
+
+
+ skip
+ skipTo
+ skipToOneOf
+
+
+
+
+ $functions
+ $severity
+
+
+ $functions
+
+
+ $severity
+ $this->functions
+ $this->functions
+ $token->getValue()
+
+
+ $this->functions[]
+
+
+
+
+ $token->getValue()
+ $token->getValue()
+
+
+
+
+ $error->getReason()
+ $token->getValue()
+
+
+ $expression['map'][$error->getColumn()]
+ $expression['map'][$error->getColumn()]
+
+
+ $error
+
+
+ getColumn
+ getColumn
+ getReason
+
+
+ null !== $toAppend
+
+
+ $char
+
+
+
+
+ $token->getValue()
+ $token->getValue()
+
+
+
+
+ $this->loader
+ $token->getColumn()
+ $token->getLine()
+ $token->getValue()
+
+
+ $builder
+ $declaration
+ $root
+ $token
+
+
+ build
+ flatten
+ getColumn
+ getLine
+ getRootUnusedDeclarations
+ getToken
+ getValue
+
+
+ $this->loader
+
+
+ $this->loader
+
+
+
+
+ $this->loader
+ $token->getColumn()
+ $token->getLine()
+ $token->getValue()
+
+
+ $builder
+ $declaration
+ $root
+ $token
+
+
+ build
+ flatten
+ getColumn
+ getLine
+ getRootUnusedDeclarations
+ getToken
+ getValue
+
+
+ $this->loader
+
+
+ $this->loader
+
+
+
+
+ $twigMajorVersion
+
+
+ setTemplateResolver
+
+
+ $this->twigMajorVersion
+
+
+
+
+ setTemplateResolver
+
+
+
+
+ $name
+
+
+ $name
+
+
+ $this->name
+
+
+ string
+
+
+ $this->name
+
+
+
+
+ $block->flatten()->getQueue()
+
+
+ $block
+ $item
+ $item
+ $item
+ $item
+ $item
+ $queue[]
+
+
+ flatten
+ getQueue
+
+
+ $item
+
+
+
+
+ $this->queue
+
+
+ self
+
+
+ declare
+ isolate
+ referenceBlock
+ use
+
+
+ $this->parent
+
+
+
+
+ $depth
+ $name
+
+
+ build
+ createMacroScopeBuilder
+ createVariableScopeBuilder
+ handleMacros
+ handleVariables
+
+
+ $blockNameToken->getValue()
+ $depth
+ $depth
+ $file
+ $file
+ $from->getValue()
+ $name
+ $next->getValue()
+ $next->getValue()
+ $templateName->getValue()
+ $templateName->getValue()
+ $token->getValue()
+ $token->getValue()
+ $token->getValue()
+ $token->getValue()
+ $tokens
+ $tokens->look(4)->getValue()
+ $tokens->look(4)->getValue()
+ $tokens->look(4)->getValue()
+
+
+ $blockType
+ $blockType
+ $file
+ $file
+ $tokens
+
+
+ getType
+ getValue
+ getValue
+ getValue
+ getValue
+
+
+
+
+ $name
+
+
+ $name
+
+
+ $this->name
+
+
+ string
+
+
+ $this->name
+
+
+
+
+ $loader
+ $loader
+
+
+ Source
+
+
+ exists
+ exists
+ load
+
+
+ $loader->load($path)
+
+
+
+
+ $path
+
+
+ $path
+
+
+ Source
+
+
+ exists
+ load
+
+
+ $this->namespaces[$namespace]->load($subPath)
+
+
+ $namespace
+ $namespace
+
+
+
+
+ $columnno
+ $lineno
+ $source
+
+
+ Source|null
+ int
+ int
+ string|null
+ string|null
+ string|null
+
+
+ getCode
+ getName
+ getPath
+
+
+ $this->columnno
+ $this->lineno
+ $this->source
+ $this->source ? $this->source->getCode() : null
+ $this->source ? $this->source->getName() : null
+ $this->source ? $this->source->getPath() : null
+
+
+
+
+ $type
+ $value
+ $values
+
+
+ $value
+
+
+ getValue
+
+
+ $this->value
+
+
+ $values
+
+
+
+
+ $primary
+ $primary
+ $secondary
+ $secondary
+ $type
+ $value
+
+
+ $current
+ $source
+ $tokens
+
+
+ injectTokens
+ nextIf
+
+
+ $column
+ $column
+ $column
+ $line
+ $line
+ $line
+ $this->current
+ $this->current
+ $this->source
+ $this->source
+ $this->source
+ $this->tokens
+ $this->tokens
+ $this->tokens
+ $token->getType()
+ $token->getValue()
+ $type
+ $value
+
+
+ $this->tokens[$this->current + $number - 1]
+ $this->tokens[$this->current + $number]
+ $this->tokens[$this->current - 1]
+ $this->tokens[$this->current - 1]
+ $this->tokens[$this->current]
+ $this->tokens[$this->current]
+ $this->tokens[$this->current]
+ $this->tokens[$this->current]
+ $this->tokens[$this->current]
+
+
+ $this->tokens[$this->current + $number - 1]
+ $this->tokens[$this->current + $number]
+ $this->tokens[$this->current + $number]
+ $this->tokens[$this->current - 1]
+ $this->tokens[$this->current - 1]
+ $this->tokens[$this->current]
+ $this->tokens[$this->current]
+ $this->tokens[$this->current]
+ $this->tokens[$this->current]
+ $this->tokens[$this->current]
+ $this->tokens[++$this->current]
+
+
+ $column
+ $column
+ $column
+ $line
+ $line
+ $line
+ $token
+ $token
+ $token
+
+
+ Source
+ Token
+ Token
+ Token
+ Token
+ bool
+
+
+ getColumn
+ getColumn
+ getColumn
+ getLine
+ getLine
+ getLine
+ getType
+ getType
+ getValue
+ getValue
+ test
+ test
+ test
+
+
+ $this->current
+ $this->current
+ $this->current
+ $this->current
+ $this->current
+ $this->current
+
+
+ $this->source
+ $this->tokens[$this->current + $number]
+ $this->tokens[$this->current - 1]
+ $this->tokens[$this->current]
+ $this->tokens[$this->current]->test($primary, $secondary)
+ $token
+
+
+
+
+ '([{'
+ ')]}'
+
+
+ $state
+ $text
+ $type
+ $value
+
+
+ $brackets
+ $code
+ $columnno
+ $currentVarBlockLine
+ $cursor
+ $end
+ $lineno
+ $options
+ $position
+ $positions
+ $regexes
+ $source
+ $state
+ $states
+ $tokens
+
+
+ getOperatorRegex
+ lexBlock
+ lexComment
+ lexData
+ lexExpression
+ lexInterpolation
+ lexRawData
+ lexString
+ lexVar
+ moveCursor
+ popState
+ pushState
+ pushToken
+ tokenize
+
+
+ $expect
+ $expect
+ $expect
+ $expect
+ $lineno
+ $lineno
+ $lineno
+ $match[0][1] - $this->cursor
+ $match[0][1] - $this->cursor
+ $operator[$length - 1]
+ $position[1] - $this->cursor
+ $text
+ $text
+ $this->brackets
+ $this->brackets
+ $this->brackets
+ $this->brackets
+ $this->code
+ $this->code
+ $this->code
+ $this->code
+ $this->code
+ $this->code
+ $this->code
+ $this->code
+ $this->code
+ $this->code
+ $this->code
+ $this->code
+ $this->code
+ $this->code
+ $this->code
+ $this->code
+ $this->code
+ $this->code
+ $this->code
+ $this->code
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->columnno
+ $this->columnno
+ $this->columnno
+ $this->columnno
+ $this->columnno
+ $this->columnno
+ $this->columnno
+ $this->columnno
+ $this->columnno
+ $this->currentVarBlockLine
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->lineno
+ $this->lineno
+ $this->lineno
+ $this->lineno
+ $this->lineno
+ $this->lineno
+ $this->options['interpolation'][0]
+ $this->options['interpolation'][1]
+ $this->options['tag_block'][0]
+ $this->options['tag_block'][0]
+ $this->options['tag_block'][1]
+ $this->options['tag_block'][1]
+ $this->options['tag_block'][1]
+ $this->options['tag_block'][1]
+ $this->options['tag_comment'][0]
+ $this->options['tag_comment'][1]
+ $this->options['tag_comment'][1]
+ $this->options['tag_variable'][0]
+ $this->options['tag_variable'][1]
+ $this->options['whitespace_line_trim']
+ $this->options['whitespace_trim']
+ $this->options['whitespace_trim']
+ $this->positions[0]
+ $this->positions[0]
+ $this->regexes['interpolation_end']
+ $this->regexes['interpolation_start']
+ $this->regexes['lex_block']
+ $this->regexes['lex_block_line']
+ $this->regexes['lex_block_raw']
+ $this->regexes['lex_comment']
+ $this->regexes['lex_raw_data']
+ $this->regexes['lex_tokens_start']
+ $this->regexes['lex_var']
+ $this->regexes['operator']
+ $this->source
+ $this->source
+ $this->source
+ $this->source
+ $this->source
+ $this->source
+ $this->source
+ $this->source
+ $this->states
+ $this->states
+ $type
+
+
+ $bracket[0]
+ $expect
+ $expect
+ $expect
+ $lineno
+ $lineno
+ $lineno
+ $position[0]
+ $position[1]
+ $position[1]
+ $this->code[$this->cursor + 1]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->options['interpolation']
+ $this->options['interpolation']
+ $this->options['interpolation'][0]
+ $this->options['interpolation'][1]
+ $this->options['tag_block']
+ $this->options['tag_block'][0]
+ $this->options['tag_block'][1]
+ $this->options['tag_comment']
+ $this->options['tag_comment'][0]
+ $this->options['tag_comment'][1]
+ $this->options['tag_variable']
+ $this->options['tag_variable'][0]
+ $this->options['tag_variable'][1]
+ $this->options['whitespace_line_trim']
+ $this->options['whitespace_trim']
+ $this->options['whitespace_trim']
+ $this->positions[0]
+ $this->positions[0]
+ $this->positions[0]
+ $this->positions[0]
+ $this->positions[1]
+ $this->positions[2]
+ $this->positions[2]
+ $this->regexes['interpolation_end']
+ $this->regexes['interpolation_start']
+ $this->regexes['lex_block']
+ $this->regexes['lex_block_line']
+ $this->regexes['lex_block_raw']
+ $this->regexes['lex_comment']
+ $this->regexes['lex_raw_data']
+ $this->regexes['lex_tokens_start']
+ $this->regexes['lex_var']
+ $this->regexes['operator']
+
+
+ $this->brackets[]
+ $this->brackets[]
+ $this->brackets[]
+ $this->states[]
+ $this->tokens[]
+
+
+ $this->code[$this->cursor + 1]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->code[$this->cursor]
+ $this->positions[0][++$this->position]
+ $this->positions[0][++$this->position]
+ $this->positions[1][$this->position]
+ $this->positions[2][$this->position]
+ $this->positions[2][$this->position]
+ $this->positions[2][$this->position]
+
+
+ $bracket
+ $position
+ $position
+ list($expect, $lineno)
+ list($expect, $lineno)
+ list($expect, $lineno)
+
+
+ $position[0]
+ $position[1]
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->cursor
+ $this->lineno
+ $this->options['whitespace_line_chars']
+ $this->options['whitespace_line_chars']
+ $this->options['whitespace_line_chars']
+ $this->options['whitespace_line_chars']
+ $this->options['whitespace_line_chars']
+ $this->options['whitespace_line_trim']
+ $this->options['whitespace_line_trim']
+ $this->options['whitespace_line_trim']
+ $this->options['whitespace_line_trim']
+ $this->options['whitespace_line_trim']
+ $this->options['whitespace_line_trim']
+ $this->options['whitespace_trim']
+ $this->options['whitespace_trim']
+ $this->options['whitespace_trim']
+ $this->options['whitespace_trim']
+ $this->options['whitespace_trim']
+ $this->position
+ $this->position
+
+
+ $operator[$length - 1]
+
+
+ self::STATE_BLOCK
+ self::STATE_INTERPOLATION
+ self::STATE_STRING
+ self::STATE_VAR
+
+
+
+
+ $continue
+ $found
+ $tokenValue === $tokens->getCurrent()->getValue()
+
+
+ skip
+ skipTo
+ skipToOneOf
+
+
+ $possibility['type']
+ $possibility['value']
+
+
+ $possibility
+ $tokenType
+ $tokenValue
+
+
+ $found
+
+
+ $token
+ $token
+
+
+
+
+ $collectedData
+
+
+ $this->collectedData[get_class($rule)]
+
+
+ array
+
+
+ $this->collectedData
+
+
+
+
+ $column
+ $filename
+ $line
+ $reason
+
+
+ $this->column
+ $this->filename
+ $this->line
+ $this->reason
+
+
+
diff --git a/psalm.xml b/psalm.xml
new file mode 100644
index 0000000..b1a3036
--- /dev/null
+++ b/psalm.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+