Skip to content

Instantly share code, notes, and snippets.

@cmb69
Created October 2, 2014 12:52
Show Gist options
  • Save cmb69/7561b2a07c5f1fba76c7 to your computer and use it in GitHub Desktop.
Save cmb69/7561b2a07c5f1fba76c7 to your computer and use it in GitHub Desktop.
Distinguish property with implicit resp. explicit public visibility
<?php
require './vendor/autoload.php';
// The code samples to parse.
// => bool(false)
$code = '<?php class Foo {public $bar;}';
// => bool(true)
$code = '<?php class Foo {var $bar;}';
function isImplicitlyPublicProperty(array $tokens, PhpParser\Node\Stmt\Property $prop) {
$i = $prop->getAttribute('startOffset');
return isset($tokens[$i]) && $tokens[$i][0] == T_VAR;
}
class MyNodeVisitor extends PhpParser\NodeVisitorAbstract
{
public function leaveNode(PhpParser\Node $node) {
global $tokens;
if ($node instanceof PhpParser\Node\Stmt\Property) {
var_dump(isImplicitlyPublicProperty($tokens, $node));
}
}
}
// We need this special lexer
class LexerWithTokenOffsets extends PhpParser\Lexer {
public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) {
$tokenId = parent::getNextToken($value, $startAttributes, $endAttributes);
$startAttributes['startOffset'] = $endAttributes['endOffset'] = $this->pos;
return $tokenId;
}
}
// HACK to get token list, which we need for isImplicitlyPublicProperty.
// There must be a better way.
$tokens = token_get_all($code);
$parser = new PhpParser\Parser(new LexerWithTokenOffsets());
$traverser = new PhpParser\NodeTraverser();
$traverser->addVisitor(new MyNodeVisitor());
try {
$stmts = $parser->parse($code);
$stmts = $traverser->traverse($stmts);
} catch (PhpParser\Error $e) {
echo 'Parse Error: ', $e->getMessage();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment