Skip to content

Commit

Permalink
Resolve properties assigned in current function as if they were simpl…
Browse files Browse the repository at this point in the history
…e vars

With context and stuff
  • Loading branch information
klesun committed Aug 5, 2018
1 parent 4c879a7 commit eeee3f9
Show file tree
Hide file tree
Showing 5 changed files with 269 additions and 8 deletions.
24 changes: 21 additions & 3 deletions src/org/klesun/deep_assoc_completion/resolvers/FieldRes.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package org.klesun.deep_assoc_completion.resolvers;

import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.php.lang.psi.elements.Function;
import com.jetbrains.php.lang.psi.elements.Method;
import com.jetbrains.php.lang.psi.elements.PhpExpression;
import com.jetbrains.php.lang.psi.elements.impl.*;
Expand All @@ -10,6 +12,7 @@
import org.klesun.deep_assoc_completion.helpers.MultiType;
import org.klesun.deep_assoc_completion.resolvers.var_res.AssRes;
import org.klesun.lang.Lang;
import org.klesun.lang.Opt;
import org.klesun.lang.Tls;

import java.util.List;
Expand All @@ -36,6 +39,13 @@ private static L<FieldReferenceImpl> findReferences(PsiFile file, String name)
.flt(ref -> name.equals(ref.getName()));
}

private static boolean areInSameScope(PsiElement a, PsiElement b)
{
Opt<Function> aFunc = Tls.findParent(a, Function.class, v -> true);
Opt<Function> bFunc = Tls.findParent(b, Function.class, v -> true);
return aFunc.equals(bFunc);
}

public MultiType resolve(FieldReferenceImpl fieldRef)
{
L<DeepType> result = list();
Expand Down Expand Up @@ -65,14 +75,22 @@ public MultiType resolve(FieldReferenceImpl fieldRef)
L<Assign> asses = opt(resolved.getContainingFile())
.map(file -> findReferences(file, fieldRef.getName()))
.def(L())
.fap(psi -> Tls.findParent(psi, Method.class, a -> true)
.fap(assPsi -> Tls.findParent(assPsi, Method.class, a -> true)
.flt(meth -> meth.getName().equals("__construct"))
.map(meth -> fieldRef.getClassReference())
.fop(toCast(PhpExpression.class))
.fop(ref -> opt(ctx.findExprType(ref)))
.fap(mt -> mt.getArgsPassedToCtor())
.wap(ctxs -> ctxs.size() > 0 ? ctxs : list(implCtx))
.fop(methCtx -> (new AssRes(methCtx)).collectAssignment(psi, false)));
.wap(ctxs -> {
if (areInSameScope(fieldRef, assPsi)) {
ctxs.add(ctx);
}
if (ctxs.size() == 0) {
ctxs = list(implCtx);
}
return ctxs;
})
.fop(methCtx -> (new AssRes(methCtx)).collectAssignment(assPsi, false)));

List<DeepType> types = AssRes.assignmentsToTypes(asses);
result.addAll(types);
Expand Down
14 changes: 14 additions & 0 deletions src/org/klesun/lang/Opt.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.klesun.lang;

import java.util.Objects;

import static org.klesun.lang.Lang.*;

/**
Expand Down Expand Up @@ -136,4 +138,16 @@ private static class Then
{
// TODO: implement!
}

public boolean equals(Object other)
{
return opt(other)
.fop(that -> Tls.cast(Opt.class, that))
.flt(that -> {
if (!this.has()) return !that.has();
if (!that.has()) return false;
return Objects.equals(this.unw(), that.unw());
})
.has();
}
}
37 changes: 32 additions & 5 deletions tests/src/Lib/UnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use Lib\Utils\ArrayUtil;
use Lib\Utils\Fp;
use Lib\Utils\MemoizedFunctions;
use LocalLib\Lexer\Lexeme;
use LocalLib\Lexer\Lexer;

class UnitTest
{
Expand Down Expand Up @@ -263,26 +265,51 @@ public static function provideInstRecursion()
return $list;
}

/**
* following not resolved yet
*/
public function provideLexer(string $modsPart)
{
$onlyRaw = function($matches){return ['raw' => $matches[0], 'parsed' => null];};
$lexer = new Lexer([
(new Lexeme('departureDate', '/^¥V(\d{1,2}[A-Z]{3}\d{0,2})/'))->preprocessData($onlyRaw),
(new Lexeme('returnDate', '/^¥R(\d{1,2}[A-Z]{3}\d{0,2})/'))->preprocessData($onlyRaw),
]);
// $this->context used as a local variable - we can support that
$lexed = $lexer->lex($modsPart);
$lexed['lexemes'][0][''];
$lexed['lexemes'][0]['lexeme'] === '';
$typeToData = array_combine(
array_column($lexed['lexemes'], 'lexeme'),
array_column($lexed['lexemes'], 'data')
);
$list[] = [$typeToData, ['departureDate' => [], 'returnDate' => []]];
return $list;
}

public static function provideCachedFuncCall()
public static function provideCachedFuncCallSimple()
{
$list = [];
$args = ['CHD054'];
$tdData1 = MemoizedFunctions::ramCachedFunctionCall(
'asd', [static::class, 'fetchTdData'], $args
);
$tdData1[''];
// $list[] = [$tdData1, ['is_published' => [], 'prefix' => [], 'correct_cmd' => []]];
$list[] = [$tdData1, ['is_published' => [], 'prefix' => [], 'correct_cmd' => []]];

$tdData2 = MemoizedFunctions::cachedFunctionCall(
'asd', [static::class, 'fetchTdData'], $args, 60*60
);
$tdData2[''];
$list[] = [$tdData2, ['is_published' => [], 'prefix' => [], 'correct_cmd' => []]];
return $list;
}

/**
* following not resolved yet
*/

public static function provideCachedFuncCall()
{
$list = [];
$args = ['CHD054'];
$tdData3 = MemoizedFunctions::cachedBothWays(
[static::class, 'fetchTdData'], $args, 60*60
);
Expand Down
135 changes: 135 additions & 0 deletions tests/src/LocalLib/Lexer/Lexeme.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?php
namespace LocalLib\Lexer;

use Lib\Utils\Fp;

class Lexeme
{
private $regex;
private $name;
private $constraints = [];
/** @var callable|null */
private $dataPreprocessor = null;

public function __construct($name, $regex)
{
$this->regex = $regex;
$this->name = $name;
//$this->preprocessDataRemoveNumericKeys();
//$this->preprocessDataReturnOnlyToken();
$this->preprocessDataReturnDefault();
}

private function passesConstraints($context)
{
$passesConstraint = function($constraint) use ($context) {return $constraint($context);};
return Fp::all($passesConstraint, $this->constraints);
}

public function hasConstraint(callable $constraint)
{
$this->constraints[] = $constraint;
return $this;
}

public function hasPreviousLexemeConstraint($lexemes)
{
$constraint = function($context) use ($lexemes) {
$previousLexeme = array_pop($context['lexemes']);
return in_array($previousLexeme['lexeme'], $lexemes);
};
return $this->hasConstraint($constraint);
}

public function preprocessData(callable $dataPreprocessor)
{
$this->dataPreprocessor = $dataPreprocessor;
return $this;
}

public function preprocessDataFilterTokens($tokens)
{
$dataPreprocessor = function($data) use ($tokens) {
$result = [];
foreach ($tokens as $token) {
$result[$token] = $data[$token] ?? null;
}
return $result;
};
return $this->preprocessData($dataPreprocessor);
}

public function preprocessDataEmpty()
{
$dataPreprocessor = function($data){return $data;};
return $this->preprocessData($dataPreprocessor);
}

public function preprocessDataRemoveNumericKeys()
{
$dataPreprocessor = function($data){
$result = [];
foreach ($data as $key => $value) {
if (!is_integer($key)) {
$result[$key] = $value;
}
}
return $result;
};
return $this->preprocessData($dataPreprocessor);
}

public function preprocessDataReturnOnlyToken()
{
$dataPreprocessor = function($data) {
$result = [];
foreach ($data as $key => $value) {
if (!is_integer($key)) {
$result[$key] = $value;
}
}

if (count($result) === 1) {
return array_pop($result);
} else {
return null;
}
};
return $this->preprocessData($dataPreprocessor);
}

public function preprocessDataReturnDefault()
{
$dataPreprocessor = function($data) {
$result = [];
foreach ($data as $key => $value) {
if (!is_integer($key)) {
$result[$key] = $value;
}
}

if (count($result) === 1) {
return array_pop($result);
} elseif (count($result) > 1) {
return $result;
} else {
return null;
}
};
return $this->preprocessData($dataPreprocessor);
}

public function match($text, $context = null)
{
$dataPreprocessor = $this->dataPreprocessor;
if (preg_match($this->regex, $text, $matches) && $this->passesConstraints($context) && $matches[0] !== '') {
return [
'lexeme' => $this->name,
'data' => $dataPreprocessor($matches),
'textLeft' => mb_substr($text, mb_strlen($matches[0])),
];
} else {
return null;
}
}
}
67 changes: 67 additions & 0 deletions tests/src/LocalLib/Lexer/Lexer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php
namespace LocalLib\Lexer;

use Lib\Utils\Fp;

class Lexer
{
private $context;
private $lexemes;
private $logger;

public function __construct($lexemes)
{
$this->lexemes = $lexemes;
}

public function setLog($log)
{
$this->logger = $log;

return $this;
}

public function log($msg, $data = null)
{
$log = $this->logger;
if ($log) {
$log($msg, $data);
}
}

private function matchLexeme($text)
{
foreach ($this->lexemes as $lexeme) {
$r = $lexeme->match($text, $this->context);
if ($r) {
return $r;
}
}
return null;
}

public function lex($text)
{
$this->context = [
'text' => $text,
'lexemes' => [],
];

while(true){
$lexeme = $this->matchLexeme($this->context['text']);
if ($lexeme) {
$this->log('Lexeme: '.$lexeme['lexeme'], $lexeme);
$this->context['text'] = $lexeme['textLeft'];
$this->context['lexemes'][] = $lexeme;
} else {
$this->log('ERROR: '.$this->context['text']);
break;
}
}

// Not sure if appropriate
$removeTextLeft = function($data){unset($data['textLeft']); return $data;};
$this->context['lexemes'] = Fp::map($removeTextLeft, $this->context['lexemes']);
return $this->context;
}
}

0 comments on commit eeee3f9

Please sign in to comment.