Skip to content

Commit 31ddc19

Browse files
committed
added completion for $this
Added Scope entity and dummy scope detection
1 parent aa1bbc7 commit 31ddc19

17 files changed

Lines changed: 347 additions & 100 deletions

src/App.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public function handle($request, $response, $data){
1818
$this->getCommandName($request)
1919
);
2020
$this->container = $command->getContainer();
21-
$arguments = $this->parseDataString($data);
21+
$arguments = $this->parseQuery($request->getQuery(), $data);
2222
$arguments["project"] = $this->loadProject($arguments);
2323
try{
2424
$result = $command->run(
@@ -85,8 +85,11 @@ protected function getCommandName($request){
8585
$commandName = trim($request->getPath(), '\/');
8686
return $commandName;
8787
}
88-
protected function parseDataString($data){
89-
parse_str($data, $query);
88+
protected function parseQuery($query, $data){
89+
parse_str($data, $content);
90+
if(!array_key_exists('contents', $content))
91+
$content = ['contents' => ''];
92+
$query['contents'] = $content['contents'];
9093
$keys = ["path", "contents", "filepath", "line", "column"];
9194
foreach($keys AS $key){
9295
if(!array_key_exists($key, $query)){

src/Complete/Completer/Completer.php

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Complete\Completer;
44

55
use Entity\Completion\Context;
6+
use Entity\Completion\Scope;
67
use Entity\Project;
78

89
class Completer{
@@ -17,21 +18,18 @@ public function __construct(
1718
$this->namespaceCompleter = $namespaceCompleter;
1819
$this->objectCompleter = $objectCompleter;
1920
}
20-
public function getEntries(Project $project, Context $context){
21+
public function getEntries(Project $project, Context $context, Scope $scope){
2122
if($context->isNamespace()){
22-
printf("Namespace completion");
2323
return $this->getAllNamespaces($project, $context);
2424
}
2525
elseif($context->isClassName()){
26-
printf("Classname completion");
2726
return $this->getAllClasses($project, $context);
2827
}
2928
elseif($context->isInterfaceName()){
30-
printf("Interfaces completion");
3129
return $this->getAllInterfaces($project, $context);
3230
}
3331
elseif($context->isThis() || $context->isObject()){
34-
return $this->getObjectCompletion($project, $context);
32+
return $this->getObjectCompletion($project, $context, $scope);
3533
}
3634
return [];
3735
}
@@ -44,8 +42,8 @@ protected function getAllClasses(Project $project, Context $context){
4442
protected function getAllInterfaces(Project $project, Context $context){
4543
return $this->interfaceNameCompleter->getEntries($project, $context);
4644
}
47-
protected function getObjectCompletion(Project $project, Context $context){
48-
return $this->objectCompleter->getEntries($project, $context);
45+
protected function getObjectCompletion(Project $project, Context $context, Scope $scope){
46+
return $this->objectCompleter->getEntries($project, $context, $scope);
4947
}
5048

5149
private $classNameCompleter;
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
namespace Complete\Completer;
4+
5+
use Entity\Project;
6+
use Entity\Completion\Context;
7+
use Entity\Completion\Entry;
8+
use Entity\Completion\Scope;
9+
10+
class ObjectCompleter {
11+
public function getEntries(Project $project, Context $context, Scope $scope){
12+
if($context->isThis()){
13+
return $this->getEntriesForThis($project, $context, $scope);
14+
}
15+
return $this->getEntriesForVar($project, $context, $scope);
16+
}
17+
protected function getEntriesForVar(
18+
Project $project,
19+
Context $context,
20+
Scope $scope
21+
){
22+
$index = $project->getIndex();
23+
$varName = $context->getToken()->parent->symbol;
24+
if(empty($varName)){
25+
return [];
26+
}
27+
$varName = substr($varName, 1);
28+
$var = $scope->getVar($varName);
29+
if(empty($var)){
30+
return [];
31+
}
32+
$fqcn = $var->getFQCN();
33+
if(empty($fqcn)){
34+
return [];
35+
}
36+
$class = $index->findClassByFQCN($fqcn);
37+
$entries = [];
38+
foreach($class->methods->all() AS $method){
39+
$entry = new Entry($method->name, $method->getSignature());
40+
$entries[] = $entry;
41+
}
42+
foreach($class->properties->all() AS $property){
43+
$entry = new Entry($property->name);
44+
$entries[] = $entry;
45+
}
46+
return $entries;
47+
}
48+
protected function getEntriesForThis(
49+
Project $project,
50+
Context $context,
51+
Scope $scope
52+
){
53+
$index = $project->getIndex();
54+
$fqcn = $scope->getFQCN();
55+
if(empty($fqcn)){
56+
echo "Empty Oo\n";
57+
return [];
58+
}
59+
$class = $index->findClassByFQCN($scope->getFQCN());
60+
$entries = [];
61+
foreach($class->methods->all() AS $method){
62+
$entry = new Entry($method->name, $method->getSignature());
63+
$entries[] = $entry;
64+
}
65+
foreach($class->properties->all() AS $property){
66+
$entry = new Entry($property->name);
67+
$entries[] = $entry;
68+
}
69+
return $entries;
70+
}
71+
}

src/Complete/ContentManager.php

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,27 @@
33
namespace Complete;
44

55
use Entity\Project;
6+
use Entity\Completion\Scope;
67
use Parser\Parser;
78
use Generator\IndexGenerator;
89
use Entity\Completion\Entry;
910
use Entity\Completion\Context;
1011
use Complete\Completer\Completer;
12+
use Complete\Resolver\ContextResolver;
13+
use Complete\Resolver\ScopeResolver;
1114

1215
class ContentManager {
13-
private $parser;
14-
private $generator;
15-
private $contextResolver;
16-
private $completer;
17-
1816
public function __construct(
1917
Parser $parser,
2018
IndexGenerator $generator,
2119
ContextResolver $contextResolver,
20+
ScopeResolver $scopeResolver,
2221
Completer $completer
2322
){
2423
$this->parser = $parser;
2524
$this->generator = $generator;
2625
$this->contextResolver = $contextResolver;
26+
$this->scopeResolver = $scopeResolver;
2727
$this->completer = $completer;
2828
}
2929
public function createCompletion(
@@ -42,9 +42,14 @@ public function createCompletion(
4242
);
4343
try {
4444
$this->updateFileIndex($project, $lines, $file);
45+
$scope = $this->findScope(
46+
$project, implode("\n", $lines), $line, $file
47+
);
48+
}
49+
catch(\Exception $e){
50+
$scope = new Scope;
4551
}
46-
catch(\Exception $e){}
47-
$entries = $this->findEntries($project, $completionLine, $column, $lines);
52+
$entries = $this->findEntries($project, $scope, $completionLine, $column, $lines);
4853
}
4954
elseif(!empty($content)) {
5055
$this->updateFileIndex($project, $content, $file);
@@ -55,9 +60,12 @@ public function createCompletion(
5560
"context" => []
5661
];
5762
}
58-
protected function findEntries(Project $project, $badLine, $column, $lines){
63+
protected function findEntries(Project $project, Scope $scope, $badLine, $column, $lines){
5964
$context = $this->contextResolver->getContext($badLine, $column);
60-
return $this->completer->getEntries($project, $context);
65+
return $this->completer->getEntries($project, $context, $scope);
66+
}
67+
protected function findScope(Project $project, $content, $line, $file){
68+
return $this->scopeResolver->findScope($project, $content, $line, $file);
6169
}
6270
/**
6371
* @TODO
@@ -97,4 +105,10 @@ protected function updateFileIndex(Project $project, $lines, $file){
97105
$nodes
98106
);
99107
}
108+
109+
private $parser;
110+
private $generator;
111+
private $contextResolver;
112+
private $scopeResolver;
113+
private $completer;
100114
}
Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace Complete;
3+
namespace Complete\Resolver;
44

55
use Entity\Completion\Token;
66
use Entity\Completion\Context;
@@ -10,7 +10,7 @@ public function getContext($badLine){
1010
if(empty($badLine)){
1111
throw new \Exception("Could not define empty line context");
1212
}
13-
printf("\n%s\n", $badLine);
13+
printf("\nBad line: %s\n", $badLine);
1414
$token = $this->getCompletionToken($badLine);
1515
$context = new Context($token, $token->symbol);
1616
return $this->defineContextType($context, $token);
@@ -32,7 +32,6 @@ protected function getCompletionToken($badLine){
3232
return $token;
3333
}
3434
protected function addSymbol(Token $parent, $symbol){
35-
print_r($symbol);
3635
if(is_array($symbol)){
3736
$code = $symbol[0];
3837
$symbol = $symbol[1];
@@ -47,11 +46,11 @@ protected function addSymbol(Token $parent, $symbol){
4746
$parent->symbol .= $symbol;
4847
return $parent;
4948
}
50-
if(is_int($code)){
51-
printf("%s\n", token_name($code));
52-
}
5349
$token = new Token;
54-
if($code === ';' || $code === ','){
50+
if($this->isBreakSymbol($code)){
51+
while($parent->type != -1){
52+
$parent = $parent->parent;
53+
}
5554
return $parent;
5655
}
5756
switch($code){
@@ -78,13 +77,12 @@ protected function addSymbol(Token $parent, $symbol){
7877
return $token;
7978
}
8079
protected function defineContextType(Context $context, Token $token){
81-
print_r($token);
8280
switch($token->type){
8381
case self::S_VAR:
8482
$context->addType(Context::TYPE_VAR);
8583
break;
8684
case self::S_OBJECT:
87-
if($token->symbol === '$this'){
85+
if($token->parent->symbol === '$this'){
8886
$context->addType(Context::TYPE_THIS);
8987
}
9088
else {
@@ -109,6 +107,9 @@ protected function defineContextType(Context $context, Token $token){
109107
}
110108
return $context;
111109
}
110+
private function isBreakSymbol($symbol){
111+
return in_array($symbol, [';', ',', '=', '-']);
112+
}
112113
const S_VAR = '$';
113114
const S_OBJECT = '->';
114115
const S_STATIC = '::';
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Complete\Resolver;
4+
5+
use Entity\Project;
6+
use Entity\Completion\Scope;
7+
use Parser\ScopeParser;
8+
9+
class ScopeResolver {
10+
public function __construct(ScopeParser $parser){
11+
$this->parser = $parser;
12+
}
13+
public function findScope(Project $project, $content, $line, $file){
14+
$scope = new Scope;
15+
$index = $project->getIndex();
16+
$fqcn = $index->findFQCNByFile($file);
17+
if(empty($fqcn)){
18+
return $scope;
19+
}
20+
$scope->setFQCN($fqcn);
21+
$scope = $this->parser->parseContent($project, $scope, $content, $line);
22+
return $scope;
23+
}
24+
25+
private $parser;
26+
}

src/Entity/Collection/MethodsCollection.php

Lines changed: 6 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,40 +14,12 @@ public function remove(MethodData $method){
1414
unset($this->methods[$method->name]);
1515
}
1616
}
17-
public function toArray(){
18-
$map = [
19-
"modifier" => [
20-
"public" => [],
21-
"private" => [],
22-
"protected" => [],
23-
"abstract" => [],
24-
"final" => [],
25-
"static" => []
26-
],
27-
"all" => [
28-
]
29-
];
30-
foreach($this->methods AS $method){
31-
if($method->isPublic()){
32-
$map["modifier"]["public"][] = $method->name;
33-
}
34-
if($method->isProtected()){
35-
$map["modifier"]["protected"][] = $method->name;
36-
}
37-
if($method->isPrivate()){
38-
$map["modifier"]["private"][] = $method->name;
39-
}
40-
if($method->isStatic()){
41-
$map["modifier"]["public"][] = $method->name;
42-
}
43-
if($method->isFinal()){
44-
$map["modifier"]["final"][] = $method->name;
45-
}
46-
if($method->isAbstract()){
47-
$map["modifier"]["abstract"][] = $method->name;
48-
}
49-
$map["all"][$method->name] = $method->toArray();
17+
public function get($name){
18+
if(array_key_exists($name, $this->methods)){
19+
return $this->methods[$name];
5020
}
51-
return $map;
21+
}
22+
public function all(){
23+
return $this->methods;
5224
}
5325
}

src/Entity/Collection/PropertiesCollection.php

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,7 @@ class PropertiesCollection {
99
public function add(ClassProperty $prop){
1010
$this->map[$prop->name] = $prop;
1111
}
12-
public function toArray(){
13-
$map = [
14-
'modifier' => [
15-
'public' => [],
16-
'protected' => [],
17-
'private' => [],
18-
'static' => []
19-
],
20-
'all' => []
21-
];
22-
foreach($this->map AS $prop){
23-
if($prop->isPublic()){
24-
$map['modifier']['public'][] = $prop->name;
25-
}
26-
if($prop->isProtected()){
27-
$map['modifier']['protected'][] = $prop->name;
28-
}
29-
if($prop->isPrivate()){
30-
$map['modifier']['private'][] = $prop->name;
31-
}
32-
if($prop->isStatic()){
33-
$map['modifier']['static'][] = $prop->name;
34-
}
35-
$map['all'][$prop->name] = $prop->toArray();
36-
}
37-
return $map;
12+
public function all(){
13+
return $this->map;
3814
}
3915
}

src/Entity/Completion/Context.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ class Context {
1616
private $type = 0;
1717
private $postfix = "";
1818
private $token;
19-
private $scope;
2019
public function __construct(Token $token, $postfix){
2120
$this->token = $token;
2221
$this->postfix = $postfix;

0 commit comments

Comments
 (0)