Correct code style
parent
5f8e37be9e
commit
b99fb94840
|
@ -1,60 +1,60 @@
|
|||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace LanguageServer\Client;
|
||||
|
||||
use AdvancedJsonRpc\Notification as NotificationBody;
|
||||
use PhpParser\{Error, Comment, Node, ParserFactory, NodeTraverser, Lexer};
|
||||
use PhpParser\NodeVisitor\NameResolver;
|
||||
use LanguageServer\ProtocolWriter;
|
||||
use LanguageServer\Protocol\{TextDocumentItem, TextDocumentIdentifier, VersionedTextDocumentIdentifier, Message};
|
||||
|
||||
/**
|
||||
* Provides method handlers for all window/* methods
|
||||
*/
|
||||
class Window
|
||||
{
|
||||
/**
|
||||
* @var ProtocolWriter
|
||||
*/
|
||||
private $protocolWriter;
|
||||
|
||||
public function __construct(ProtocolWriter $protocolWriter)
|
||||
{
|
||||
$this->protocolWriter = $protocolWriter;
|
||||
}
|
||||
|
||||
/**
|
||||
* The show message notification is sent from a server to a client to ask the client to display a particular message in the user interface.
|
||||
*
|
||||
* @param int $type
|
||||
* @param string $message
|
||||
*/
|
||||
public function showMessage(int $type, string $message)
|
||||
{
|
||||
$this->protocolWriter->write(new Message(new NotificationBody(
|
||||
'window/showMessage',
|
||||
(object)[
|
||||
'type' => $type,
|
||||
'message' => $message
|
||||
]
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* The log message notification is sent from the server to the client to ask the client to log a particular message.
|
||||
*
|
||||
* @param int $type
|
||||
* @param string $message
|
||||
*/
|
||||
public function logMessage(int $type, string $message)
|
||||
{
|
||||
$this->protocolWriter->write(new Message(new NotificationBody(
|
||||
'window/logMessage',
|
||||
(object)[
|
||||
'type' => $type,
|
||||
'message' => $message
|
||||
]
|
||||
)));
|
||||
}
|
||||
}
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace LanguageServer\Client;
|
||||
|
||||
use AdvancedJsonRpc\Notification as NotificationBody;
|
||||
use PhpParser\{Error, Comment, Node, ParserFactory, NodeTraverser, Lexer};
|
||||
use PhpParser\NodeVisitor\NameResolver;
|
||||
use LanguageServer\ProtocolWriter;
|
||||
use LanguageServer\Protocol\{TextDocumentItem, TextDocumentIdentifier, VersionedTextDocumentIdentifier, Message};
|
||||
|
||||
/**
|
||||
* Provides method handlers for all window/* methods
|
||||
*/
|
||||
class Window
|
||||
{
|
||||
/**
|
||||
* @var ProtocolWriter
|
||||
*/
|
||||
private $protocolWriter;
|
||||
|
||||
public function __construct(ProtocolWriter $protocolWriter)
|
||||
{
|
||||
$this->protocolWriter = $protocolWriter;
|
||||
}
|
||||
|
||||
/**
|
||||
* The show message notification is sent from a server to a client to ask the client to display a particular message in the user interface.
|
||||
*
|
||||
* @param int $type
|
||||
* @param string $message
|
||||
*/
|
||||
public function showMessage(int $type, string $message)
|
||||
{
|
||||
$this->protocolWriter->write(new Message(new NotificationBody(
|
||||
'window/showMessage',
|
||||
(object)[
|
||||
'type' => $type,
|
||||
'message' => $message
|
||||
]
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* The log message notification is sent from the server to the client to ask the client to log a particular message.
|
||||
*
|
||||
* @param int $type
|
||||
* @param string $message
|
||||
*/
|
||||
public function logMessage(int $type, string $message)
|
||||
{
|
||||
$this->protocolWriter->write(new Message(new NotificationBody(
|
||||
'window/logMessage',
|
||||
(object)[
|
||||
'type' => $type,
|
||||
'message' => $message
|
||||
]
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -133,22 +133,22 @@ class LanguageServer extends \AdvancedJsonRpc\Dispatcher
|
|||
$numTotalFiles = count($fileList);
|
||||
|
||||
$startTime = microtime(true);
|
||||
|
||||
|
||||
$processFile = function() use (&$fileList, &$processFile, $rootPath, $numTotalFiles, $startTime) {
|
||||
if ($file = array_pop($fileList)) {
|
||||
|
||||
|
||||
$uri = pathToUri($file);
|
||||
$fileNum = $numTotalFiles - count($fileList);
|
||||
$shortName = substr($file, strlen($rootPath)+1);
|
||||
$this->client->window->logMessage(3, "Parsing file $fileNum/$numTotalFiles: $shortName.");
|
||||
|
||||
|
||||
$this->project->getDocument($uri)->updateContent(file_get_contents($file));
|
||||
|
||||
|
||||
Loop\setTimeout($processFile, 0);
|
||||
}
|
||||
else {
|
||||
$duration = (int)(microtime(true) - $startTime);
|
||||
$mem = (int)(memory_get_usage(true)/(1024*1024));
|
||||
$mem = (int)(memory_get_usage(true) / (1024 * 1024));
|
||||
$this->client->window->logMessage(3, "All PHP files parsed in $duration seconds. $mem MiB allocated.");
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,141 +1,140 @@
|
|||
<?php
|
||||
|
||||
namespace LanguageServer;
|
||||
|
||||
use \LanguageServer\Protocol\{Diagnostic, DiagnosticSeverity, Range, Position, SymbolKind, TextEdit};
|
||||
|
||||
use PhpParser\{Error, Comment, Node, ParserFactory, NodeTraverser, Lexer, Parser};
|
||||
use PhpParser\PrettyPrinter\Standard as PrettyPrinter;
|
||||
use PhpParser\NodeVisitor\NameResolver;
|
||||
|
||||
class PhpDocument
|
||||
{
|
||||
private $client;
|
||||
private $project;
|
||||
private $parser;
|
||||
|
||||
private $uri;
|
||||
private $content;
|
||||
private $symbols = [];
|
||||
|
||||
public function __construct(string $uri, Project $project, LanguageClient $client, Parser $parser)
|
||||
{
|
||||
$this->uri = $uri;
|
||||
$this->project = $project;
|
||||
$this->client = $client;
|
||||
$this->parser = $parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all symbols in this document.
|
||||
*
|
||||
* @return SymbolInformation[]
|
||||
*/
|
||||
public function getSymbols()
|
||||
{
|
||||
return $this->symbols;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns symbols in this document filtered by query string.
|
||||
*
|
||||
* @param string $query The search query
|
||||
* @return SymbolInformation[]
|
||||
*/
|
||||
public function findSymbols(string $query)
|
||||
{
|
||||
return array_filter($this->symbols, function($symbol) use(&$query) {
|
||||
return stripos($symbol->name, $query) !== false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the content on this document.
|
||||
*
|
||||
* @param string $content
|
||||
*/
|
||||
public function updateContent(string $content)
|
||||
{
|
||||
$this->content = $content;
|
||||
$this->parse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-parses a source file, updates symbols, reports parsing errors
|
||||
* that may have occured as diagnostics and returns parsed nodes.
|
||||
*
|
||||
* @return \PhpParser\Node[]
|
||||
*/
|
||||
public function parse()
|
||||
{
|
||||
$stmts = null;
|
||||
$errors = [];
|
||||
try {
|
||||
$stmts = $this->parser->parse($this->content);
|
||||
}
|
||||
catch(\PhpParser\Error $e) {
|
||||
// Lexer can throw errors. e.g for unterminated comments
|
||||
// unfortunately we don't get a location back
|
||||
$errors[] = $e;
|
||||
}
|
||||
|
||||
$errors = array_merge($this->parser->getErrors(), $errors);
|
||||
|
||||
$diagnostics = [];
|
||||
foreach ($errors as $error) {
|
||||
$diagnostic = new Diagnostic();
|
||||
$diagnostic->range = new Range(
|
||||
new Position($error->getStartLine() - 1, $error->hasColumnInfo() ? $error->getStartColumn($this->content) - 1 : 0),
|
||||
new Position($error->getEndLine() - 1, $error->hasColumnInfo() ? $error->getEndColumn($this->content) : 0)
|
||||
);
|
||||
$diagnostic->severity = DiagnosticSeverity::ERROR;
|
||||
$diagnostic->source = 'php';
|
||||
// Do not include "on line ..." in the error message
|
||||
$diagnostic->message = $error->getRawMessage();
|
||||
$diagnostics[] = $diagnostic;
|
||||
}
|
||||
$this->client->textDocument->publishDiagnostics($this->uri, $diagnostics);
|
||||
|
||||
// $stmts can be null in case of a fatal parsing error
|
||||
if ($stmts) {
|
||||
$traverser = new NodeTraverser;
|
||||
$finder = new SymbolFinder($this->uri);
|
||||
$traverser->addVisitor(new NameResolver);
|
||||
$traverser->addVisitor(new ColumnCalculator($this->content));
|
||||
$traverser->addVisitor($finder);
|
||||
$traverser->traverse($stmts);
|
||||
|
||||
$this->symbols = $finder->symbols;
|
||||
}
|
||||
|
||||
return $stmts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this document as formatted text.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFormattedText()
|
||||
{
|
||||
$stmts = $this->parse();
|
||||
if (empty($stmts)) {
|
||||
return [];
|
||||
}
|
||||
$prettyPrinter = new PrettyPrinter();
|
||||
$edit = new TextEdit();
|
||||
$edit->range = new Range(new Position(0, 0), new Position(PHP_INT_MAX, PHP_INT_MAX));
|
||||
$edit->newText = $prettyPrinter->prettyPrintFile($stmts);
|
||||
return [$edit];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this document's text content.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace LanguageServer;
|
||||
|
||||
use \LanguageServer\Protocol\{Diagnostic, DiagnosticSeverity, Range, Position, SymbolKind, TextEdit};
|
||||
|
||||
use PhpParser\{Error, Comment, Node, ParserFactory, NodeTraverser, Lexer, Parser};
|
||||
use PhpParser\PrettyPrinter\Standard as PrettyPrinter;
|
||||
use PhpParser\NodeVisitor\NameResolver;
|
||||
|
||||
class PhpDocument
|
||||
{
|
||||
private $client;
|
||||
private $project;
|
||||
private $parser;
|
||||
|
||||
private $uri;
|
||||
private $content;
|
||||
private $symbols = [];
|
||||
|
||||
public function __construct(string $uri, Project $project, LanguageClient $client, Parser $parser)
|
||||
{
|
||||
$this->uri = $uri;
|
||||
$this->project = $project;
|
||||
$this->client = $client;
|
||||
$this->parser = $parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all symbols in this document.
|
||||
*
|
||||
* @return SymbolInformation[]
|
||||
*/
|
||||
public function getSymbols()
|
||||
{
|
||||
return $this->symbols;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns symbols in this document filtered by query string.
|
||||
*
|
||||
* @param string $query The search query
|
||||
* @return SymbolInformation[]
|
||||
*/
|
||||
public function findSymbols(string $query)
|
||||
{
|
||||
return array_filter($this->symbols, function($symbol) use(&$query) {
|
||||
return stripos($symbol->name, $query) !== false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the content on this document.
|
||||
*
|
||||
* @param string $content
|
||||
*/
|
||||
public function updateContent(string $content)
|
||||
{
|
||||
$this->content = $content;
|
||||
$this->parse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-parses a source file, updates symbols, reports parsing errors
|
||||
* that may have occured as diagnostics and returns parsed nodes.
|
||||
*
|
||||
* @return \PhpParser\Node[]
|
||||
*/
|
||||
public function parse()
|
||||
{
|
||||
$stmts = null;
|
||||
$errors = [];
|
||||
try {
|
||||
$stmts = $this->parser->parse($this->content);
|
||||
} catch(\PhpParser\Error $e) {
|
||||
// Lexer can throw errors. e.g for unterminated comments
|
||||
// unfortunately we don't get a location back
|
||||
$errors[] = $e;
|
||||
}
|
||||
|
||||
$errors = array_merge($this->parser->getErrors(), $errors);
|
||||
|
||||
$diagnostics = [];
|
||||
foreach ($errors as $error) {
|
||||
$diagnostic = new Diagnostic();
|
||||
$diagnostic->range = new Range(
|
||||
new Position($error->getStartLine() - 1, $error->hasColumnInfo() ? $error->getStartColumn($this->content) - 1 : 0),
|
||||
new Position($error->getEndLine() - 1, $error->hasColumnInfo() ? $error->getEndColumn($this->content) : 0)
|
||||
);
|
||||
$diagnostic->severity = DiagnosticSeverity::ERROR;
|
||||
$diagnostic->source = 'php';
|
||||
// Do not include "on line ..." in the error message
|
||||
$diagnostic->message = $error->getRawMessage();
|
||||
$diagnostics[] = $diagnostic;
|
||||
}
|
||||
$this->client->textDocument->publishDiagnostics($this->uri, $diagnostics);
|
||||
|
||||
// $stmts can be null in case of a fatal parsing error
|
||||
if ($stmts) {
|
||||
$traverser = new NodeTraverser;
|
||||
$finder = new SymbolFinder($this->uri);
|
||||
$traverser->addVisitor(new NameResolver);
|
||||
$traverser->addVisitor(new ColumnCalculator($this->content));
|
||||
$traverser->addVisitor($finder);
|
||||
$traverser->traverse($stmts);
|
||||
|
||||
$this->symbols = $finder->symbols;
|
||||
}
|
||||
|
||||
return $stmts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this document as formatted text.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFormattedText()
|
||||
{
|
||||
$stmts = $this->parse();
|
||||
if (empty($stmts)) {
|
||||
return [];
|
||||
}
|
||||
$prettyPrinter = new PrettyPrinter();
|
||||
$edit = new TextEdit();
|
||||
$edit->range = new Range(new Position(0, 0), new Position(PHP_INT_MAX, PHP_INT_MAX));
|
||||
$edit->newText = $prettyPrinter->prettyPrintFile($stmts);
|
||||
return [$edit];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this document's text content.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
}
|
||||
|
|
140
src/Project.php
140
src/Project.php
|
@ -1,70 +1,70 @@
|
|||
<?php
|
||||
|
||||
namespace LanguageServer;
|
||||
|
||||
use PhpParser\{Error, Comment, Node, ParserFactory, NodeTraverser, Lexer};
|
||||
use PhpParser\PrettyPrinter\Standard as PrettyPrinter;
|
||||
use PhpParser\NodeVisitor\NameResolver;
|
||||
|
||||
class Project
|
||||
{
|
||||
/**
|
||||
* An associative array [string => PhpDocument]
|
||||
* that maps URIs to loaded PhpDocuments
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $documents;
|
||||
|
||||
/**
|
||||
* Instance of the PHP parser
|
||||
*
|
||||
* @var ParserAbstract
|
||||
*/
|
||||
private $parser;
|
||||
|
||||
/**
|
||||
* Reference to the language server client interface
|
||||
*
|
||||
* @var LanguageClient
|
||||
*/
|
||||
private $client;
|
||||
|
||||
public function __construct(LanguageClient $client)
|
||||
{
|
||||
$this->client = $client;
|
||||
|
||||
$lexer = new Lexer(['usedAttributes' => ['comments', 'startLine', 'endLine', 'startFilePos', 'endFilePos']]);
|
||||
$this->parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7, $lexer, ['throwOnError' => false]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the document indicated by uri. Instantiates a new document if none exists.
|
||||
*
|
||||
* @param string $uri
|
||||
* @return LanguageServer\PhpDocument
|
||||
*/
|
||||
public function getDocument(string $uri)
|
||||
{
|
||||
$uri = urldecode($uri);
|
||||
if (!isset($this->documents[$uri])){
|
||||
$this->documents[$uri] = new PhpDocument($uri, $this, $this->client, $this->parser);
|
||||
}
|
||||
return $this->documents[$uri];
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds symbols in all documents, filtered by query parameter.
|
||||
*
|
||||
* @param string $query
|
||||
* @return SymbolInformation[]
|
||||
*/
|
||||
public function findSymbols(string $query)
|
||||
{
|
||||
$queryResult = [];
|
||||
foreach($this->documents as $uri => $document) {
|
||||
$queryResult = array_merge($queryResult, $document->findSymbols($query));
|
||||
}
|
||||
return $queryResult;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace LanguageServer;
|
||||
|
||||
use PhpParser\{Error, Comment, Node, ParserFactory, NodeTraverser, Lexer};
|
||||
use PhpParser\PrettyPrinter\Standard as PrettyPrinter;
|
||||
use PhpParser\NodeVisitor\NameResolver;
|
||||
|
||||
class Project
|
||||
{
|
||||
/**
|
||||
* An associative array [string => PhpDocument]
|
||||
* that maps URIs to loaded PhpDocuments
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $documents;
|
||||
|
||||
/**
|
||||
* Instance of the PHP parser
|
||||
*
|
||||
* @var ParserAbstract
|
||||
*/
|
||||
private $parser;
|
||||
|
||||
/**
|
||||
* Reference to the language server client interface
|
||||
*
|
||||
* @var LanguageClient
|
||||
*/
|
||||
private $client;
|
||||
|
||||
public function __construct(LanguageClient $client)
|
||||
{
|
||||
$this->client = $client;
|
||||
|
||||
$lexer = new Lexer(['usedAttributes' => ['comments', 'startLine', 'endLine', 'startFilePos', 'endFilePos']]);
|
||||
$this->parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7, $lexer, ['throwOnError' => false]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the document indicated by uri. Instantiates a new document if none exists.
|
||||
*
|
||||
* @param string $uri
|
||||
* @return LanguageServer\PhpDocument
|
||||
*/
|
||||
public function getDocument(string $uri)
|
||||
{
|
||||
$uri = urldecode($uri);
|
||||
if (!isset($this->documents[$uri])) {
|
||||
$this->documents[$uri] = new PhpDocument($uri, $this, $this->client, $this->parser);
|
||||
}
|
||||
return $this->documents[$uri];
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds symbols in all documents, filtered by query parameter.
|
||||
*
|
||||
* @param string $query
|
||||
* @return SymbolInformation[]
|
||||
*/
|
||||
public function findSymbols(string $query)
|
||||
{
|
||||
$queryResult = [];
|
||||
foreach($this->documents as $uri => $document) {
|
||||
$queryResult = array_merge($queryResult, $document->findSymbols($query));
|
||||
}
|
||||
return $queryResult;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ class TextDocument
|
|||
{
|
||||
$this->project->getDocument($textDocument->uri)->updateContent($contentChanges[0]->text);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The document formatting request is sent from the server to the client to format a whole document.
|
||||
|
@ -84,5 +84,4 @@ class TextDocument
|
|||
{
|
||||
return $this->project->getDocument($textDocument->uri)->getFormattedText();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,58 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace LanguageServer\Server;
|
||||
|
||||
use PhpParser\{Error, Comment, Node, ParserFactory, NodeTraverser, Lexer};
|
||||
use PhpParser\PrettyPrinter\Standard as PrettyPrinter;
|
||||
use PhpParser\NodeVisitor\NameResolver;
|
||||
use LanguageServer\{LanguageClient, ColumnCalculator, SymbolFinder, Project};
|
||||
use LanguageServer\Protocol\{
|
||||
TextDocumentItem,
|
||||
TextDocumentIdentifier,
|
||||
VersionedTextDocumentIdentifier,
|
||||
Diagnostic,
|
||||
DiagnosticSeverity,
|
||||
Range,
|
||||
Position,
|
||||
FormattingOptions,
|
||||
TextEdit,
|
||||
SymbolInformation
|
||||
};
|
||||
|
||||
/**
|
||||
* Provides method handlers for all workspace/* methods
|
||||
*/
|
||||
class Workspace
|
||||
{
|
||||
/**
|
||||
* The lanugage client object to call methods on the client
|
||||
*
|
||||
* @var \LanguageServer\LanguageClient
|
||||
*/
|
||||
private $client;
|
||||
|
||||
/**
|
||||
* The current project database
|
||||
*
|
||||
* @var Project
|
||||
*/
|
||||
private $project;
|
||||
|
||||
public function __construct(Project $project, LanguageClient $client)
|
||||
{
|
||||
$this->project = $project;
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
/**
|
||||
* The workspace symbol request is sent from the client to the server to list project-wide symbols matching the query string.
|
||||
* document.
|
||||
*
|
||||
* @param string $query
|
||||
* @return SymbolInformation[]
|
||||
*/
|
||||
public function symbol(string $query): array
|
||||
{
|
||||
return $this->project->findSymbols($query);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace LanguageServer\Server;
|
||||
|
||||
use PhpParser\{Error, Comment, Node, ParserFactory, NodeTraverser, Lexer};
|
||||
use PhpParser\PrettyPrinter\Standard as PrettyPrinter;
|
||||
use PhpParser\NodeVisitor\NameResolver;
|
||||
use LanguageServer\{LanguageClient, ColumnCalculator, SymbolFinder, Project};
|
||||
use LanguageServer\Protocol\{
|
||||
TextDocumentItem,
|
||||
TextDocumentIdentifier,
|
||||
VersionedTextDocumentIdentifier,
|
||||
Diagnostic,
|
||||
DiagnosticSeverity,
|
||||
Range,
|
||||
Position,
|
||||
FormattingOptions,
|
||||
TextEdit,
|
||||
SymbolInformation
|
||||
};
|
||||
|
||||
/**
|
||||
* Provides method handlers for all workspace/* methods
|
||||
*/
|
||||
class Workspace
|
||||
{
|
||||
/**
|
||||
* The lanugage client object to call methods on the client
|
||||
*
|
||||
* @var \LanguageServer\LanguageClient
|
||||
*/
|
||||
private $client;
|
||||
|
||||
/**
|
||||
* The current project database
|
||||
*
|
||||
* @var Project
|
||||
*/
|
||||
private $project;
|
||||
|
||||
public function __construct(Project $project, LanguageClient $client)
|
||||
{
|
||||
$this->project = $project;
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
/**
|
||||
* The workspace symbol request is sent from the client to the server to list project-wide symbols matching the query string.
|
||||
* document.
|
||||
*
|
||||
* @param string $query
|
||||
* @return SymbolInformation[]
|
||||
*/
|
||||
public function symbol(string $query): array
|
||||
{
|
||||
return $this->project->findSymbols($query);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,12 +39,12 @@ class SymbolFinder extends NodeVisitorAbstract
|
|||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $nameStack = array();
|
||||
private $nameStack = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $nodeStack = array();
|
||||
private $nodeStack = [];
|
||||
|
||||
/**
|
||||
* @var int
|
||||
|
@ -58,26 +58,21 @@ class SymbolFinder extends NodeVisitorAbstract
|
|||
|
||||
public function enterNode(Node $node)
|
||||
{
|
||||
array_push($this->nodeStack, $node);
|
||||
$this->nodeStack[] = $node;
|
||||
$containerName = end($this->nameStack);
|
||||
|
||||
// If we enter a named node, push its name onto name stack.
|
||||
// Else push the current name onto stack.
|
||||
if (!empty($node->name) && (is_string($node->name) || method_exists($node->name, '__toString')) && !empty((string)$node->name)) {
|
||||
if (!empty($node->name) && !empty((string)$node->name)) {
|
||||
if (empty($containerName)) {
|
||||
array_push($this->nameStack, (string)$node->name);
|
||||
$this->nameStack[] = (string)$node->name;
|
||||
} else if ($node instanceof Node\Stmt\ClassMethod) {
|
||||
$this->nameStack[] = $containerName . '::' . (string)$node->name;
|
||||
} else {
|
||||
$this->nameStack[] = $containerName . '\\' . (string)$node->name;
|
||||
}
|
||||
else {
|
||||
if ($node instanceof Node\Stmt\ClassMethod) {
|
||||
array_push($this->nameStack, $containerName . '::' . (string)$node->name);
|
||||
}
|
||||
else {
|
||||
array_push($this->nameStack, $containerName . '\\' . (string)$node->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
array_push($this->nameStack, $containerName);
|
||||
} else {
|
||||
$this->nameStack[] = $containerName;
|
||||
}
|
||||
|
||||
$class = get_class($node);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace LanguageServer;
|
||||
|
||||
/**
|
||||
* Recursively Searches files with matching filename, starting at $path.
|
||||
* Recursively Searches files with matching filename, starting at $path.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $pattern
|
||||
|
@ -13,15 +13,15 @@ function findFilesRecursive(string $path, string $pattern): array {
|
|||
$dir = new \RecursiveDirectoryIterator($path);
|
||||
$ite = new \RecursiveIteratorIterator($dir);
|
||||
$files = new \RegexIterator($ite, $pattern, \RegexIterator::GET_MATCH);
|
||||
$fileList = array();
|
||||
foreach($files as $file) {
|
||||
$fileList = [];
|
||||
foreach ($files as $file) {
|
||||
$fileList = array_merge($fileList, $file);
|
||||
}
|
||||
return $fileList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms an absolute file path into a URI as used by the language server protocol.
|
||||
* Transforms an absolute file path into a URI as used by the language server protocol.
|
||||
*
|
||||
* @param string $filepath
|
||||
* @return string
|
||||
|
@ -29,5 +29,5 @@ function findFilesRecursive(string $path, string $pattern): array {
|
|||
function pathToUri(string $filepath): string {
|
||||
$filepath = trim(str_replace('\\', '/', $filepath), '/');
|
||||
$filepath = implode('/', array_map('urlencode', explode('/', $filepath)));
|
||||
return 'file:///'.$filepath;
|
||||
}
|
||||
return 'file:///' . $filepath;
|
||||
}
|
||||
|
|
|
@ -21,8 +21,8 @@ class FileUriTest extends TestCase
|
|||
$uri = \LanguageServer\pathToUri('/usr/local/bin');
|
||||
$this->assertEquals('file:///usr/local/bin', $uri);
|
||||
|
||||
$uri = \LanguageServer\pathToUri('a/b/c/');
|
||||
$this->assertEquals('file:///a/b/c', $uri);
|
||||
$uri = \LanguageServer\pathToUri('a/b/c/test.txt');
|
||||
$this->assertEquals('file:///a/b/c/test.txt', $uri);
|
||||
|
||||
$uri = \LanguageServer\pathToUri('/d/e/f');
|
||||
$this->assertEquals('file:///d/e/f', $uri);
|
||||
|
|
Loading…
Reference in New Issue