Skip to content

Commit a1b0d9f

Browse files
committed
bug #238 Fixing bad empty line when source file uses tabs (weaverryan)
This PR was merged into the 1.0-dev branch. Discussion ---------- Fixing bad empty line when source file uses tabs Woo! Fixes #170 PHP-Parser is responsible for determining indentation for new code. When tabs are used, it sees this as 1 indent, and uses 1 space to indent. This had two side-effects: 1) My original `str_replace` code was not smart enough to handle that. Easy fix using regex 2) In general, any new code (e.g. getter method) is indented with 1 space. Commits ------- 9f95fcd Fixing bad empty line when used with tabs
2 parents 7773936 + 9f95fcd commit a1b0d9f

File tree

5 files changed

+95
-3
lines changed

5 files changed

+95
-3
lines changed

src/Util/ClassSourceManipulator.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -658,8 +658,10 @@ private function updateSourceCodeFromNewStmts()
658658
$this->oldTokens
659659
);
660660

661-
// this fake property is a placeholder for a linebreak
662-
$newCode = str_replace([' private $__EXTRA__LINE;', 'use __EXTRA__LINE;', ' $__EXTRA__LINE;'], '', $newCode);
661+
// replace the 3 "fake" items that may be in the code (allowing for different indentation)
662+
$newCode = preg_replace('/(\ |\t)*private\ \$__EXTRA__LINE;/', '', $newCode);
663+
$newCode = preg_replace('/use __EXTRA__LINE;/', '', $newCode);
664+
$newCode = preg_replace('/(\ |\t)*\$__EXTRA__LINE;/', '', $newCode);
663665

664666
// process comment lines
665667
foreach ($this->pendingComments as $i => $comment) {
@@ -829,7 +831,7 @@ private function addMethod(Node\Stmt\ClassMethod $methodNode)
829831
$newStatements[] = $methodNode;
830832

831833
if (null === $existingIndex) {
832-
// just them on the end!
834+
// add them to the end!
833835

834836
$classNode->stmts = array_merge($classNode->stmts, $newStatements);
835837
} else {

src/Util/PrettyPrinter.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,32 @@
1919
*/
2020
final class PrettyPrinter extends Standard
2121
{
22+
/**
23+
* Overridden to fix indentation problem with tabs.
24+
*
25+
* If the original source code uses tabs, then the tokenizer
26+
* will see this as "1" indent level, and will indent new lines
27+
* with just 1 space. By changing 1 indent to 4, we effectively
28+
* "correct" this problem when printing.
29+
*
30+
* For code that is even further indented (e.g. 8 spaces),
31+
* the printer uses the first indentation (here corrected
32+
* from 1 space to 4) and already (without needing any other
33+
* changes) adds 4 spaces onto that. This is why we don't
34+
* also need to handle indent levels of 5, 9, etc: these
35+
* do not occur (at least in the code we generate);
36+
*
37+
* @param int $level
38+
*/
39+
protected function setIndentLevel(int $level)
40+
{
41+
if (1 === $level) {
42+
$level = 4;
43+
}
44+
45+
parent::setIndentLevel($level);
46+
}
47+
2248
/**
2349
* Overridden to change coding standards.
2450
*

tests/Util/ClassSourceManipulatorTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,4 +515,22 @@ public function getAddOneToOneRelationTests()
515515
->setIsOwning(true)
516516
];
517517
}
518+
519+
public function testGenerationWithTabs()
520+
{
521+
$source = file_get_contents(__DIR__.'/fixtures/source/ProductWithTabs.php');
522+
$expectedSource = file_get_contents(__DIR__.'/fixtures/with_tabs/ProductWithTabs.php');
523+
524+
$manipulator = new ClassSourceManipulator($source);
525+
526+
$method = (new \ReflectionObject($manipulator))->getMethod('addProperty');
527+
$method->setAccessible(true);
528+
$method->invoke($manipulator, 'name', ['@ORM\Column(type="string", length=255)']);
529+
530+
$method = (new \ReflectionObject($manipulator))->getMethod('addGetter');
531+
$method->setAccessible(true);
532+
$method->invoke($manipulator, 'id', 'int', false);
533+
534+
$this->assertSame($expectedSource, $manipulator->getSourceCode());
535+
}
518536
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace App\Entity;
4+
5+
use Doctrine\ORM\Mapping as ORM;
6+
7+
/**
8+
* @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
9+
*/
10+
class Product
11+
{
12+
/**
13+
* @ORM\Id()
14+
* @ORM\GeneratedValue()
15+
* @ORM\Column(type="integer")
16+
*/
17+
private $id;
18+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace App\Entity;
4+
5+
use Doctrine\ORM\Mapping as ORM;
6+
7+
/**
8+
* @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
9+
*/
10+
class Product
11+
{
12+
/**
13+
* @ORM\Id()
14+
* @ORM\GeneratedValue()
15+
* @ORM\Column(type="integer")
16+
*/
17+
private $id;
18+
19+
/**
20+
* @ORM\Column(type="string", length=255)
21+
*/
22+
private $name;
23+
24+
public function getId(): int
25+
{
26+
return $this->id;
27+
}
28+
}

0 commit comments

Comments
 (0)