Merge branch 'master' into phan-unused-fix
commit
a81f1670b1
|
@ -7,3 +7,4 @@ fixtures/
|
||||||
coverage/
|
coverage/
|
||||||
coverage.xml
|
coverage.xml
|
||||||
images/
|
images/
|
||||||
|
node_modules/
|
||||||
|
|
|
@ -7,7 +7,7 @@ trim_trailing_whitespace = true
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
|
|
||||||
[*.json,*.yml]
|
[*.{json,yml}]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
[composer.json]
|
[composer.json]
|
||||||
|
|
|
@ -4,4 +4,5 @@ vendor/
|
||||||
.phpls/
|
.phpls/
|
||||||
composer.lock
|
composer.lock
|
||||||
stubs
|
stubs
|
||||||
*.ast
|
*.ast
|
||||||
|
node_modules/
|
||||||
|
|
17
.travis.yml
17
.travis.yml
|
@ -11,10 +11,10 @@ services:
|
||||||
cache:
|
cache:
|
||||||
directories:
|
directories:
|
||||||
- $HOME/.composer/cache
|
- $HOME/.composer/cache
|
||||||
|
- $HOME/.npm
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- composer install --prefer-dist --no-interaction
|
- composer install --prefer-dist --no-interaction
|
||||||
- composer run-script parse-stubs
|
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- vendor/bin/phpcs -n
|
- vendor/bin/phpcs -n
|
||||||
|
@ -22,9 +22,12 @@ script:
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- bash <(curl -s https://codecov.io/bash)
|
- bash <(curl -s https://codecov.io/bash)
|
||||||
- |
|
- git config --replace-all remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
|
||||||
if [[ $TRAVIS_TAG == v* ]]; then
|
- git fetch --tags
|
||||||
docker build -t felixfbecker/php-language-server:${TRAVIS_TAG:1} .
|
- nvm install 8 && nvm use 8
|
||||||
docker login -e="$DOCKER_EMAIL" -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD"
|
- npm install
|
||||||
docker push felixfbecker/php-language-server:${TRAVIS_TAG:1}
|
- npm run semantic-release
|
||||||
fi
|
|
||||||
|
branches:
|
||||||
|
except:
|
||||||
|
- /^v\d+\.\d+\.\d+$/
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
[](https://travis-ci.org/felixfbecker/php-language-server)
|
[](https://travis-ci.org/felixfbecker/php-language-server)
|
||||||
[](https://codecov.io/gh/felixfbecker/php-language-server)
|
[](https://codecov.io/gh/felixfbecker/php-language-server)
|
||||||
[](https://gemnasium.com/github.com/felixfbecker/php-language-server)
|
[](https://gemnasium.com/github.com/felixfbecker/php-language-server)
|
||||||
|
[](https://github.com/semantic-release/semantic-release)
|
||||||
[](https://php.net/)
|
[](https://php.net/)
|
||||||
[](https://github.com/felixfbecker/php-language-server/blob/master/LICENSE.txt)
|
[](https://github.com/felixfbecker/php-language-server/blob/master/LICENSE.txt)
|
||||||
[](https://gitter.im/felixfbecker/php-language-server?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
[](https://gitter.im/felixfbecker/php-language-server?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||||
|
|
|
@ -23,11 +23,11 @@
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.0",
|
"php": "^7.0",
|
||||||
"composer/composer": "^1.3",
|
"composer/composer": "^1.3",
|
||||||
"felixfbecker/advanced-json-rpc": "^2.0",
|
"felixfbecker/advanced-json-rpc": "^3.0.0",
|
||||||
"jetbrains/phpstorm-stubs": "dev-master",
|
"jetbrains/phpstorm-stubs": "dev-master",
|
||||||
"microsoft/tolerant-php-parser": "^0.0.6",
|
"microsoft/tolerant-php-parser": "^0.0.6",
|
||||||
"netresearch/jsonmapper": "^1.0",
|
"netresearch/jsonmapper": "^1.0",
|
||||||
"phpdocumentor/reflection-docblock": "~3.1.1",
|
"phpdocumentor/reflection-docblock": "^4.0.0",
|
||||||
"sabre/event": "^5.0",
|
"sabre/event": "^5.0",
|
||||||
"sabre/uri": "^2.0",
|
"sabre/uri": "^2.0",
|
||||||
"squizlabs/php_codesniffer": "3.0.0RC3",
|
"squizlabs/php_codesniffer": "3.0.0RC3",
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
collectors:
|
||||||
|
|
||||||
|
- type: php-composer
|
||||||
|
path: /
|
||||||
|
actors:
|
||||||
|
# pull requests for new major versions
|
||||||
|
- type: php-composer
|
||||||
|
versions: "Y.0.0"
|
||||||
|
settings:
|
||||||
|
commit_message_prefix: "chore: "
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"name": "php-language-server",
|
||||||
|
"version": "0.0.0-development",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"commitmsg": "validate-commit-msg",
|
||||||
|
"semantic-release": "semantic-release pre && ./release-docker.sh && semantic-release post"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"cz-conventional-changelog": "^2.0.0",
|
||||||
|
"husky": "^0.14.3",
|
||||||
|
"last-release-git": "0.0.3",
|
||||||
|
"semantic-release": "^8.2.0",
|
||||||
|
"validate-commit-msg": "^2.14.0"
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"commitizen": {
|
||||||
|
"path": "./node_modules/cz-conventional-changelog"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"release": {
|
||||||
|
"getLastRelease": "last-release-git"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/felixfbecker/php-language-server.git"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
docker build -t felixfbecker/php-language-server:${TRAVIS_TAG:1} .
|
||||||
|
docker login -e="$DOCKER_EMAIL" -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD"
|
||||||
|
docker push felixfbecker/php-language-server:${TRAVIS_TAG:1}
|
|
@ -78,7 +78,7 @@ class Definition
|
||||||
* For functions and methods, this is the return type.
|
* For functions and methods, this is the return type.
|
||||||
* For any other declaration it will be null.
|
* For any other declaration it will be null.
|
||||||
* Can also be a compound type.
|
* Can also be a compound type.
|
||||||
* If it is unknown, will be Types\Mixed.
|
* If it is unknown, will be Types\Mixed_.
|
||||||
*
|
*
|
||||||
* @var \phpDocumentor\Type|null
|
* @var \phpDocumentor\Type|null
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -551,7 +551,7 @@ class DefinitionResolver
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an expression node, resolves that expression recursively to a type.
|
* Given an expression node, resolves that expression recursively to a type.
|
||||||
* If the type could not be resolved, returns Types\Mixed.
|
* If the type could not be resolved, returns Types\Mixed_.
|
||||||
*
|
*
|
||||||
* @param Node\Expression $expr
|
* @param Node\Expression $expr
|
||||||
* @return \phpDocumentor\Reflection\Type|null
|
* @return \phpDocumentor\Reflection\Type|null
|
||||||
|
@ -567,7 +567,7 @@ class DefinitionResolver
|
||||||
if ($expr == null || $expr instanceof PhpParser\MissingToken || $expr instanceof PhpParser\SkippedToken) {
|
if ($expr == null || $expr instanceof PhpParser\MissingToken || $expr instanceof PhpParser\SkippedToken) {
|
||||||
// TODO some members are null or Missing/SkippedToken
|
// TODO some members are null or Missing/SkippedToken
|
||||||
// How do we handle this more generally?
|
// How do we handle this more generally?
|
||||||
return new Types\Mixed;
|
return new Types\Mixed_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// VARIABLE
|
// VARIABLE
|
||||||
|
@ -597,7 +597,7 @@ class DefinitionResolver
|
||||||
// Find the function definition
|
// Find the function definition
|
||||||
if ($expr->callableExpression instanceof Node\Expression) {
|
if ($expr->callableExpression instanceof Node\Expression) {
|
||||||
// Cannot get type for dynamic function call
|
// Cannot get type for dynamic function call
|
||||||
return new Types\Mixed;
|
return new Types\Mixed_;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($expr->callableExpression instanceof Node\QualifiedName) {
|
if ($expr->callableExpression instanceof Node\QualifiedName) {
|
||||||
|
@ -646,7 +646,7 @@ class DefinitionResolver
|
||||||
// MEMBER ACCESS EXPRESSION
|
// MEMBER ACCESS EXPRESSION
|
||||||
if ($expr instanceof Node\Expression\MemberAccessExpression) {
|
if ($expr instanceof Node\Expression\MemberAccessExpression) {
|
||||||
if ($expr->memberName instanceof Node\Expression) {
|
if ($expr->memberName instanceof Node\Expression) {
|
||||||
return new Types\Mixed;
|
return new Types\Mixed_;
|
||||||
}
|
}
|
||||||
$var = $expr->dereferencableExpression;
|
$var = $expr->dereferencableExpression;
|
||||||
|
|
||||||
|
@ -659,10 +659,10 @@ class DefinitionResolver
|
||||||
if ($t instanceof Types\This) {
|
if ($t instanceof Types\This) {
|
||||||
$classFqn = self::getContainingClassFqn($expr);
|
$classFqn = self::getContainingClassFqn($expr);
|
||||||
if ($classFqn === null) {
|
if ($classFqn === null) {
|
||||||
return new Types\Mixed;
|
return new Types\Mixed_;
|
||||||
}
|
}
|
||||||
} else if (!($t instanceof Types\Object_) || $t->getFqsen() === null) {
|
} else if (!($t instanceof Types\Object_) || $t->getFqsen() === null) {
|
||||||
return new Types\Mixed;
|
return new Types\Mixed_;
|
||||||
} else {
|
} else {
|
||||||
$classFqn = substr((string)$t->getFqsen(), 1);
|
$classFqn = substr((string)$t->getFqsen(), 1);
|
||||||
}
|
}
|
||||||
|
@ -689,7 +689,7 @@ class DefinitionResolver
|
||||||
if ($expr instanceof Node\Expression\ScopedPropertyAccessExpression) {
|
if ($expr instanceof Node\Expression\ScopedPropertyAccessExpression) {
|
||||||
$classType = $this->resolveClassNameToType($expr->scopeResolutionQualifier);
|
$classType = $this->resolveClassNameToType($expr->scopeResolutionQualifier);
|
||||||
if (!($classType instanceof Types\Object_) || $classType->getFqsen() === null) {
|
if (!($classType instanceof Types\Object_) || $classType->getFqsen() === null) {
|
||||||
return new Types\Mixed;
|
return new Types\Mixed_;
|
||||||
}
|
}
|
||||||
$fqn = substr((string)$classType->getFqsen(), 1) . '::';
|
$fqn = substr((string)$classType->getFqsen(), 1) . '::';
|
||||||
|
|
||||||
|
@ -701,7 +701,7 @@ class DefinitionResolver
|
||||||
|
|
||||||
$def = $this->index->getDefinition($fqn);
|
$def = $this->index->getDefinition($fqn);
|
||||||
if ($def === null) {
|
if ($def === null) {
|
||||||
return new Types\Mixed;
|
return new Types\Mixed_;
|
||||||
}
|
}
|
||||||
return $def->type;
|
return $def->type;
|
||||||
}
|
}
|
||||||
|
@ -888,7 +888,7 @@ class DefinitionResolver
|
||||||
if ($expr instanceof Node\Expression\SubscriptExpression) {
|
if ($expr instanceof Node\Expression\SubscriptExpression) {
|
||||||
$varType = $this->resolveExpressionNodeToType($expr->postfixExpression);
|
$varType = $this->resolveExpressionNodeToType($expr->postfixExpression);
|
||||||
if (!($varType instanceof Types\Array_)) {
|
if (!($varType instanceof Types\Array_)) {
|
||||||
return new Types\Mixed;
|
return new Types\Mixed_;
|
||||||
}
|
}
|
||||||
return $varType->getValueType();
|
return $varType->getValueType();
|
||||||
}
|
}
|
||||||
|
@ -897,14 +897,14 @@ class DefinitionResolver
|
||||||
// include, require, include_once, require_once
|
// include, require, include_once, require_once
|
||||||
if ($expr instanceof Node\Expression\ScriptInclusionExpression) {
|
if ($expr instanceof Node\Expression\ScriptInclusionExpression) {
|
||||||
// TODO: resolve path to PhpDocument and find return statement
|
// TODO: resolve path to PhpDocument and find return statement
|
||||||
return new Types\Mixed;
|
return new Types\Mixed_;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($expr instanceof Node\QualifiedName) {
|
if ($expr instanceof Node\QualifiedName) {
|
||||||
return $this->resolveClassNameToType($expr);
|
return $this->resolveClassNameToType($expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Types\Mixed;
|
return new Types\Mixed_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -918,7 +918,7 @@ class DefinitionResolver
|
||||||
public function resolveClassNameToType($class): Type
|
public function resolveClassNameToType($class): Type
|
||||||
{
|
{
|
||||||
if ($class instanceof Node\Expression) {
|
if ($class instanceof Node\Expression) {
|
||||||
return new Types\Mixed;
|
return new Types\Mixed_;
|
||||||
}
|
}
|
||||||
if ($class instanceof PhpParser\Token && $class->kind === PhpParser\TokenKind::ClassKeyword) {
|
if ($class instanceof PhpParser\Token && $class->kind === PhpParser\TokenKind::ClassKeyword) {
|
||||||
// Anonymous class
|
// Anonymous class
|
||||||
|
@ -958,7 +958,7 @@ class DefinitionResolver
|
||||||
* For classes and interfaces, this is the class type (object).
|
* For classes and interfaces, this is the class type (object).
|
||||||
* For variables / assignments, this is the documented type or type the assignment resolves to.
|
* For variables / assignments, this is the documented type or type the assignment resolves to.
|
||||||
* Can also be a compound type.
|
* Can also be a compound type.
|
||||||
* If it is unknown, will be Types\Mixed.
|
* If it is unknown, will be Types\Mixed_.
|
||||||
* Returns null if the node does not have a type.
|
* Returns null if the node does not have a type.
|
||||||
*
|
*
|
||||||
* @param Node $node
|
* @param Node $node
|
||||||
|
@ -1012,7 +1012,7 @@ class DefinitionResolver
|
||||||
}
|
}
|
||||||
$type = $defaultType;
|
$type = $defaultType;
|
||||||
}
|
}
|
||||||
return $type ?? new Types\Mixed;
|
return $type ?? new Types\Mixed_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTIONS AND METHODS
|
// FUNCTIONS AND METHODS
|
||||||
|
@ -1040,7 +1040,7 @@ class DefinitionResolver
|
||||||
return new Types\Object_(new Fqsen('\\' . (string)$node->returnType->getResolvedName()));
|
return new Types\Object_(new Fqsen('\\' . (string)$node->returnType->getResolvedName()));
|
||||||
}
|
}
|
||||||
// Unknown return type
|
// Unknown return type
|
||||||
return new Types\Mixed;
|
return new Types\Mixed_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PROPERTIES, CONSTS, CLASS CONSTS, ASSIGNMENT EXPRESSIONS
|
// PROPERTIES, CONSTS, CLASS CONSTS, ASSIGNMENT EXPRESSIONS
|
||||||
|
@ -1077,7 +1077,7 @@ class DefinitionResolver
|
||||||
// TODO: read @property tags of class
|
// TODO: read @property tags of class
|
||||||
// TODO: Try to infer the type from default value / constant value
|
// TODO: Try to infer the type from default value / constant value
|
||||||
// Unknown
|
// Unknown
|
||||||
return new Types\Mixed;
|
return new Types\Mixed_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The node does not have a type
|
// The node does not have a type
|
||||||
|
|
Loading…
Reference in New Issue