PhpGrammarTest.php
<?php
namespace Tlf\Lexer\Test;
class PhpGrammarOld extends Tester {
protected $thingies = [
'Property.IntType'=>[
'expect_failure'=>true,
'start'=>['class_modifier', 'whitespace'],
'input'=>' public int $blm = "an important movement.";',
'expect'=>[
'properties'=>[
0=>[
'type'=>'property',
'modifiers'=>'public ',
'docblock'=> '',
'name'=>'blm',
'declaration'=>'public int $blm = "an important movement.";',
],
],
],
],
'Property.NoType'=>[
'start'=>['class_modifier', 'whitespace'],
'input'=>' public $blm = "an important movement.";',
'expect'=>[
'properties'=>[
0=>[
'type'=>'property',
'modifiers'=>'public ',
'docblock'=> '',
'name'=>'blm',
'declaration'=>'public $blm = "an important movement.";',
],
],
],
],
'String.Nowdoc'=>[
'start'=>'strings',
'input'=>"<<<'PHP'\nyep yep\nPHP;",
'expect.previous'=>[
'string'=>"<<<'PHP'\nyep yep\nPHP",
]
],
'String.Heredoc'=>[
'start'=>'strings',
'input'=>"<<<PHP\nyep yep\nPHP;",
'expect.previous'=>[
'string'=>"<<<PHP\nyep yep\nPHP",
]
],
'String.EndsWithBackslash'=>[
'start'=>'strings',
'input'=>"'a\\\\'",
'expect.previous'=>[
'string'=>"'a\\\\'",
],
],
'String.HasABackslash'=>[
'start'=>'strings',
'input'=>"'\\a'",
'expect.previous'=>[
'string'=>"'\\a'",
],
],
'String.EscapedSingleQuote'=>[
'start'=>'strings',
'input'=>"'abc \\'quote start '",
'expect.previous'=>[
'string'=>"'abc \\'quote start '",
],
],
'String.SingleQuotesInside'=>[
'start'=>'strings',
'input'=>'"abc \'quoted\' 123"',
'expect.previous'=>[
'string'=>'"abc \'quoted\' 123"',
],
],
'String.DoubleQuotesInside'=>[
'start'=>'strings',
'input'=>"'abc \"quoted\" 123'",
'expect.previous'=>[
'string'=>"'abc \"quoted\" 123'",
],
],
'String.Simple'=>[
'start'=>'strings',
'input'=>"'abc def 123'",
'expect.previous'=>[
'string'=>"'abc def 123'",
],
],
'Method.ContainsNestedBlock'=>[
'start'=>'class_modifier',
'input'=>
<<<PHP
public function nest(){
if (true){
while(false){
echo "okay";
}
}
}
PHP,
'expect'=>[
'methods'=>[
0=>[
'type'=>'method',
'modifiers'=>'public function ',
'docblock'=>'',
'name'=>'nest',
'definition'=>'public function nest()',
'arglist'=>'',
]
],
],
],
'Php.Open.Docblock.Namespace'=>[
'start'=>'php_open',
'input'=>"<?php \n /** This is a namespace */ namespace abc;",
'expect'=>[
'namespace.docblock'=>[
'type'=>'docblock',
'description'=>'This is a namespace',
],
'namespace'=>'abc',
],
],
'Php.Open.Convoluted'=>[
'start'=>'php_open',
'input'=>"/*asdflku<\\?php<?php namespace abc;",
'expect'=>[
'namespace'=>'abc',
'namespace.docblock'=>'',
],
],
'Php.Open.Simple'=>[
'start'=>'php_open',
'input'=>"<?php namespace abc;",
'expect'=>[
'namespace'=>'abc',
'namespace.docblock'=>'',
],
],
'Class.Extends.IntoAst'=>[
'expect_failure'=>true,
'start'=>['class'],
'input'=>'class Abc extends Def {',
'expect'=>[
'class'=>[[
'type'=>'class', 'docblock'=>null, 'namespace'=>'', 'name'=>'Abc', 'extends'=>'Def', 'declaration'=>'class Abc extends Def '
]],
]
],
'Class.Extends.IntoDeclaration'=>[
// 'expect_failure'=>true,
'start'=>['class'],
'input'=>'class Abc extends Def {',
'expect'=>[
'class'=>[[
'type'=>'class', 'docblock'=>null, 'namespace'=>'', 'name'=>'Abc', 'declaration'=>'class Abc extends Def '
]],
]
],
'Class.Abstract'=>[
'expect_failure'=>true,
'start'=>['class'],
'input'=>'abstract class Def {',
'expect'=>[
'class'=>[[
'type'=>'class', 'docblock'=>null, 'namespace'=>'', 'name'=>'Abc', 'declaration'=>'class Abc '
]],
],
],
'Class.ExtendsWithNoSpaceAfterExtendedClass'=>[
'start'=>['php_open'],
'input'=>'<?php class Abc extends Alphabet{}',
'expect'=>[
'class'=>[[
'type'=>'class', 'docblock'=>null, 'namespace'=>'', 'name'=>'Abc', 'declaration'=>'class Abc extends Alphabet'
]],
],
],
'Class.MinimalMinusASpace'=>[
'start'=>['class'],
'input'=>'class Abc{}',
'expect'=>[
'class'=>[[
'type'=>'class', 'docblock'=>null, 'namespace'=>'', 'name'=>'Abc', 'declaration'=>'class Abc'
]],
],
],
'Class.Minimal'=>[
'start'=>['class'],
'input'=>'class Abc {',
'expect'=>[
'class'=>[[
'type'=>'class', 'docblock'=>null, 'namespace'=>'', 'name'=>'Abc', 'declaration'=>'class Abc '
]],
],
],
'Namespace.WithDocblockAfterNs'=>[
'expect_failure'=>true,
'start'=>['namespace'],
'input'=>"namespace/**docblock*/Abc\Def;",
'expect'=>[
"namespace"=> 'Abc\\Def',
'namespace.docblock'=>'docblock',
],
],
'Namespace.WithNewLines'=>[
'start'=>['namespace'],
'input'=>"namespace \nAbc\n\\\\\nDef_09;",
'expect'=>[
"namespace"=> 'Abc\\Def_09',
'namespace.docblock'=>'',
],
],
'Namespace.WithDocblocksAtTheEnd'=>[
'start'=>['namespace'],
'input'=>"namespace Abc\\/**docblock**/Def_09/**more docblock*/;",
'expect'=>[
'namespace.docblock'=>[
'type'=>'docblock',
'description'=>'more docblock',
],
"namespace"=> 'Abc\\Def_09',
],
],
'Namespace.WithDocblocksInTheMiddle'=>[
'start'=>['namespace'],
'input'=>"namespace Abc\\/**docblock**/Def_09;",
'expect'=>[
'namespace.docblock'=>[
'type'=>'docblock',
'description'=>'docblock*',
],
"namespace"=> 'Abc\\Def_09',
],
],
'Namespace.SeparatedName'=>[
'start'=>['namespace'],
'input'=>"namespace Abc\\Def\_09;",
'expect'=>[
"namespace"=> 'Abc\\Def\\_09',
'namespace.docblock'=>'',
],
],
'Namespace.Simple'=>[
'start'=>['namespace'],
'input'=>"namespace AbcDef_09;",
'expect'=>[
"namespace"=> 'AbcDef_09',
'namespace.docblock'=>'',
],
],
];
public function testPhpDirectives(){
$phpGram = new \Tlf\Lexer\PhpGrammar();
$grammars = [
$phpGram,
];
$phpGram->buildDirectives();
$this->runDirectiveTests($grammars, $this->thingies);
}
public function testPhpPhpGrammar16Jul21(){
$dir = dirname(__DIR__).'/php/';
$file = $dir.'PhpGrammar.16jul21.php';
$targetTree = include($dir.'PhpGrammar.16jul21.tree.php');
$lexer = new \Tlf\Lexer();
$lexer->debug = true;
// This is for devving v0.6:
// $lexer->stop_loop = 2900;
// $lexer->stop_loop = 4675;
// $lexer->stop_loop = 4700; //just before 4700, problems start. There is a block closer thats being caught as a comment
//
// $lexer->stop_loop = 5450; //between 5450 & 5500, we're getting stuck & execution just is not completing
//5483 is where it gets stuck, due to a bug in docblock which has since been fixed
if (isset($this->options['stop_loop'])){
$lexer->stop_loop = (int)$this->options['stop_loop'];
}
// $lexer->stop_loop = 9999999;
$lexer->useCache = false; // useCache only matters when lexing a file
$lexer->addGrammar($phpGrammar = new \Tlf\Lexer\PhpGrammar());
$ast = $lexer->lexFile($file);
$tree = $ast->getTree(); // not what we normally want with json
echo "\n\n\n --- file AST ---\n\n";
print_r($tree);
//
// write the current tree to a file
//
file_put_contents($dir.'PhpGrammar.16jul21.tree2.php',var_export($tree,true));
echo "\n----\n\n\n";
$this->compare(
$targetTree,
$tree
);
}
public function testPhpStarterGrammar16Jul21(){
$dir = dirname(__DIR__).'/php/';
$file = $dir.'StarterGrammar.16jul21.php';
$targetTree = include($dir.'StarterGrammar.16jul21.tree.php');
$lexer = new \Tlf\Lexer();
$lexer->debug = true;
// This is for devving v0.6:
// $lexer->stop_loop = 1400;
// $lexer->stop_loop = 1415; // 1396 introduces a nested block in `onLexerStart()` method. Its an if block.
// $lexer->stop_loop = 1450; //1446 is the nested block end
// $lexer->stop_loop = 1466; //during the nested if block?
// $lexer->stop_loop = 1475; //class declaration is messed up between 1450 & 1475
// $lexer->stop_loop = 1500; // already has extra whitespace
// $lexer->stop_loop = 1600; // We're already parsing trimBuffer() method & class declaration is messed up
// $lexer->stop_loop = 9999999;
$lexer->useCache = false; // useCache only matters when lexing a file
$lexer->addGrammar($phpGrammar = new \Tlf\Lexer\PhpGrammar());
$ast = $lexer->lexFile($file);
$tree = $ast->getTree(); // not what we normally want with json
echo "\n\n\n --- file AST ---\n\n";
print_r($tree);
//
// write the current tree to a file
//
file_put_contents($dir.'StarterGrammar.16jul21.tree2.php',var_export($tree,true));
echo "\n----\n\n\n";
$this->compare(
$targetTree,
$tree
);
}
public function testPhpSampleClass(){
$dir = dirname(__DIR__).'/php/';
$file = $dir.'SampleClass.php';
$targetTree = include($dir.'SampleClass.tree.php');
$lexer = new \Tlf\Lexer();
$lexer->debug = true;
//the string rewrite
// $lexer->stop_loop = 305; // on loop 293, we start listening for strings. string_double STOPS on loop 299
//on loop 300,
// This is for devving v0.6:
// $lexer->stop_loop = 18;
// $lexer->stop_loop = 33;
// $lexer->stop_loop = 21;
// $lexer->stop_loop = 31;
// $lexer->stop_loop = 41;
// $lexer->stop_loop = 51;
// $lexer->stop_loop = 111; // catching 'class'
// $lexer->stop_loop = 120;
// $lexer->stop_loop = 135; // block starts at 132
// $lexer->stop_loop = 150; // use trait is about 150
// $lexer->stop_loop = 185; // 181 is new line for first comment
// $lexer->stop_loop = 206; // process # second comment at 203
// $lexer->stop_loop = 261; // Process first property's docblock
// $lexer->stop_loop = 280; // 277 'modifier' starts
// $lexer->stop_loop = 300; // first property processed on 299
// $lexer->stop_loop = 335; // second property is complete
// $lexer->stop_loop = 395; // static public property is finished by loop 385
// $lexer->stop_loop = 445; // method docblock finishes on 441
// $lexer->stop_loop = 460; // `public ` is captured on 454, starting method modifier
// $lexer->stop_loop = 492; // method block (opening curly brace) starts on 473
// $lexer->stop_loop = 525; // closing method curly brace is loop 516
// $lexer->stop_loop = 553; // issues around `=` around 550
// $lexer->stop_loop = 585; // see 542 for `const `. `=` is loop 551. string closes on 578
// $lexer->stop_loop = 800;
// $lexer->stop_loop = 1200;
// $lexer->stop_loop = 9999999;
$lexer->useCache = false; // useCache only matters when lexing a file
$lexer->addGrammar($phpGrammar = new \Tlf\Lexer\PhpGrammar());
$ast = $lexer->lexFile($file);
$tree = $ast->getTree(); // not what we normally want with json
echo "\n\n\n --- file AST ---\n\n";
print_r($tree);
//
// write the current tree to a file
//
file_put_contents($dir.'SampleClass.tree2.php',var_export($tree,true));
echo "\n----\n\n\n";
$this->compare(
$targetTree,
$tree
);
}
}