1
0
mirror of https://github.com/danog/psalm.git synced 2024-12-14 10:17:33 +01:00
psalm/src/Psalm/Issue/CodeIssue.php

134 lines
3.7 KiB
PHP
Raw Normal View History

2016-06-10 00:08:25 +02:00
<?php
2016-07-26 00:37:44 +02:00
namespace Psalm\Issue;
2016-06-10 00:08:25 +02:00
use Psalm\CodeLocation;
2016-06-10 00:08:25 +02:00
abstract class CodeIssue
{
const CODE_EXCEPTION = 1;
2016-11-02 07:29:00 +01:00
/**
* @var CodeLocation
2016-11-02 07:29:00 +01:00
*/
protected $code_location;
2016-11-01 05:39:41 +01:00
2016-11-02 07:29:00 +01:00
/**
* @var string
*/
2016-06-10 00:08:25 +02:00
protected $message;
2016-11-01 05:39:41 +01:00
/**
* @param string $message
* @param CodeLocation $code_location
2016-11-01 05:39:41 +01:00
*/
public function __construct($message, CodeLocation $code_location)
2016-06-10 00:08:25 +02:00
{
$this->code_location = $code_location;
2016-06-10 00:08:25 +02:00
$this->message = $message;
}
2016-11-02 07:29:00 +01:00
/**
* @return int
*/
2016-06-10 00:08:25 +02:00
public function getLineNumber()
{
return $this->code_location->line_number;
}
/**
* @return int[]
*/
public function getFileRange()
{
return [$this->code_location->file_start, $this->code_location->file_end];
}
/**
* @return string
*/
public function getFilePath()
{
return $this->code_location->file_path;
2016-06-10 00:08:25 +02:00
}
2016-11-02 07:29:00 +01:00
/**
* @return string
*/
2016-06-10 00:08:25 +02:00
public function getFileName()
{
return $this->code_location->file_name;
2016-06-10 00:08:25 +02:00
}
2016-11-02 07:29:00 +01:00
/**
* @return string
*/
2016-06-10 00:08:25 +02:00
public function getMessage()
{
return $this->code_location->file_name . ':' . $this->code_location->line_number .' - ' . $this->message;
}
/**
* @return string
* @psalm-suppress MixedArrayAccess
*/
public function getFileSnippet()
{
$selection_start = $this->code_location->file_start;
$selection_end = $this->code_location->file_end;
$preview_start = $this->code_location->preview_start;
$file_contents = (string)file_get_contents($this->code_location->file_path);
$preview_end = (int)strpos(
$file_contents,
"\n",
$this->code_location->single_line ? $selection_start : $selection_end
);
if ($this->code_location->comment_line_number && $preview_start < $selection_start) {
2016-12-07 01:41:52 +01:00
$preview_lines = explode(
"\n",
substr($file_contents, $preview_start, $selection_start - $preview_start - 1)
);
$preview_offset = 0;
$i = 0;
$comment_line_offset = $this->code_location->comment_line_number - $this->code_location->line_number;
for ($i = 0; $i < $comment_line_offset; $i++) {
$preview_offset += strlen($preview_lines[$i]) + 1;
}
$preview_offset += (int)strpos($preview_lines[$i], '@');
$selection_start = $preview_offset + $preview_start;
$selection_end = (int)strpos($file_contents, "\n", $selection_start);
2016-12-07 01:41:52 +01:00
} elseif ($this->code_location->regex) {
$preview_snippet = substr($file_contents, $selection_start, $selection_end - $selection_start);
if (preg_match($this->code_location->regex, $preview_snippet, $matches, PREG_OFFSET_CAPTURE)) {
$selection_start = $selection_start + (int)$matches[1][1];
$selection_end = $selection_start + strlen((string)$matches[1][0]);
}
}
// reset preview start to beginning of line
$preview_start = (int)strrpos(
$file_contents,
"\n",
min($preview_start, $selection_start) - strlen($file_contents)
) + 1;
$code_line = substr($file_contents, $preview_start, $preview_end - $preview_start);
$code_line_error_start = $selection_start - $preview_start;
$code_line_error_length = $selection_end - $selection_start + 1;
return substr($code_line, 0, $code_line_error_start) .
"\e[97;41m" . substr($code_line, $code_line_error_start, $code_line_error_length) .
"\e[0m" . substr($code_line, $code_line_error_length + $code_line_error_start) . PHP_EOL;
2016-06-10 00:08:25 +02:00
}
}