phpstan / phpstan Goto Github PK
View Code? Open in Web Editor NEWPHP Static Analysis Tool - discover bugs in your code without running it!
Home Page: https://phpstan.org/
License: MIT License
PHP Static Analysis Tool - discover bugs in your code without running it!
Home Page: https://phpstan.org/
License: MIT License
Message
30 Undefined variable: $minutes
30 Undefined variable: $seconds
31 Undefined variable: $minutes
31 Undefined variable: $minutes
Code
sscanf($time, '%d:%d:%d', $hours, $minutes, $seconds);
$seconds = isset($seconds) ? $hours * 3600 + $minutes * 60 + $seconds : $hours * 60 + $minutes;
Those values are created with references in method.
See sscanf doc
Among other things
226 Cannot call method hasChild() on false.
227 Cannot call method getChild() on false.
is returned for this piece of code:
public function getAdminByAdminCode($adminCode)
{
$codes = explode('|', $adminCode);
$admin = false;
foreach ($codes as $code) {
if ($admin == false) {
$admin = $this->getInstance($code);
} elseif ($admin->hasChild($code)) {
$admin = $admin->getChild($code);
}
}
return $admin;
}
The false
case is already handled.
This is my example code:
/**
* @param array $data
*
* @return static
*/
public static function fromArray(array $data)
{
foreach ($data as $key => $value) {
if (property_exists(self::class, $key)) {
${$key} = $value;
}
}
/** @var $location */
return new static($location);
}
I've got this error:
------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Line src/Example/Position.php
------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Internal error: Argument 1 passed to PHPStan\Analyser\Scope::assignVariable() must be of the type string, object given, called in /www-data/vendor/phpstan/phpstan/src/Analyser/NodeScopeResolver.php on
line 658
------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The following code results in error "Call to an undefined method Nette\Forms\Controls\BaseControl::setItems()". This is because setRequired
has annotation @return self
. Changing the annotation to @return static
does solve the problem. Ideally phpstan should notice return $this
and infer the correct return type regardless of annotation.
$form->addSelect('currency')
->setRequired()
->setItems($currencyList);
It seems phpstan currently doesn't recognize methods and properties provided through a trait. For e.g. if a class has usage $this->foo
and foo
property is provided through a trait, phpstan throws a Access to an undefined property..
error.
Function strtok invoked with 1 parameter, 2 required.
hHowever the first parameter is optional
This seems to be a regression in 0.5.2
My phpstan.neon
includes ...
parameters:
excludes_analyse:
# These should be removed once we've fixed each module
- lib/xxxxx/ZReads
Running vendor/bin/phpstan analyse --ansi --no-progress -c phpstan.neon -l 4 classes controllers lib
Outputs (clipped) ...
------ ---------------------------------------------------------------
Line lib/xxxxx/ZReads/EPOS/AuditTrail.php
------ ---------------------------------------------------------------
149 Call to an undefined method Assert\AssertionChain::integer().
150 Casting to int something that's already int.
207 Call to an undefined method Assert\AssertionChain::integer().
------ ---------------------------------------------------------------
------ ---------------------------------------------------------------
Line lib/xxxxx/ZReads/EPOS/AuditTrailCriteria.php
------ ---------------------------------------------------------------
48 Call to an undefined method Assert\AssertionChain::integer().
66 Call to an undefined method Assert\AssertionChain::integer().
------ ---------------------------------------------------------------
------ ---------------------------------------------------------
Line lib/xxxxx/ZReads/EPOS/AuditTrailRepository.php
------ ---------------------------------------------------------
45 Call to sprintf contains 0 placeholders, 1 value given.
------ ---------------------------------------------------------
------ ----------------------------------------------
Line lib/xxxxx/ZReads/ZReadRepository.php
------ ----------------------------------------------
99 Casting to int something that's already int.
99 Casting to int something that's already int.
102 Casting to int something that's already int.
------ ----------------------------------------------
Both public $myProperty;
and public $myProperty = NULL;
are equal in PHP. However phpstan treats those statements differently because it requires in the second case that NULL
is assignable to the property.
Ideally phpstan should check that all properties declared explicitly as not-null are assigned in constructor (to assignable not-null value).
------ --------------------------------------------------------------
Line src/Model/CloudFormationService.php
------ --------------------------------------------------------------
30 Call to an undefined method Aws\Sdk::createCloudFormation().
------ --------------------------------------------------------------
https://github.com/aws/aws-sdk-php/blob/3.18.32/src/Sdk.php#L17
I'm using Nette\Object: Events and I have class like this:
class FooControl extends Nette\Application\UI\Control
{
/** @var array */
public $onSuccess = [];
// some more code...
public function bar()
{
$this->onSuccess($this);
}
}
And I get this error from PhpStan:
10 Call to an undefined method FooControl::onSuccess().
It's mistake in my code? or is it false positive from PhpStan? Or I'm missing something important?
@return void
results in error " Return typehint of method ... has invalid type App\void".
Method Nette\Localization\ITranslator::translate() invoked with 3 parameters, 1-2 required.
On line: $this->translator->translate('string', null, $parameters);
Where
/** @var ITranslator */
protected $translator;
use Kdyby\Translation\ITranslator;
The ITranslator's class content:
<?php
namespace Kdyby\Translation;
use Kdyby;
use Nette;
/**
* @method translate($message, $count = NULL, $parameters = array(), $domain = NULL, $locale = NULL);
*/
interface ITranslator extends Nette\Localization\ITranslator
{
// function translate($message, $count = NULL, array $parameters = array(), $domain = NULL, $locale = NULL);
}
However it looks like @method
annotation doesn't overwrite Nette\Localization\ITranslator
translate()
declaration
<?php
namespace Nette\Localization;
/**
* Translator adapter.
*/
interface ITranslator
{
/**
* Translates the given string.
* @param string message
* @param int plural count
* @return string
*/
function translate($message, $count = NULL);
}
First of all, thanks for this amazing static analyzer.
Is it possible that DynamicMethodReturnTypeExtension
does not work for static method calls?
I am using mockery in my test code and this is the code for creating a mock: \Mockery::mock(SomeClass::class)
. The return value of this is a \Mockery\MockInterface
which I'd like to also "union" with the mocked type, in order to remove the errors PHPStan reports.
So, based on your example, I built this extension (NOTE: this does not yet provide the union type, but it should at least "convert" the mock type to the specific class type being mocked):
public static function getClass(): string
{
return \Mockery::class;
}
public function isMethodSupported(MethodReflection $methodReflection): bool
{
return $methodReflection->getName() === 'mock';
}
public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type
{
if (count($methodCall->args) === 0) {
return $methodReflection->getReturnType();
}
$arg = $methodCall->args[0]->value;
$type = $scope->getType($arg);
if ($type->getClass() !== null) {
return $type;
}
return $methodReflection->getReturnType();
}
and registered it. I then executed phpstan over a file with plenty of \Mockery::mock
calls and I noticed only getClass()
Β was being called. PHPStan never asked for isMethodSupported
from my extension, and the errors are still there. I suspect the extension system does not work with static method calls.
Is there anything I'm missing?
Let me know, if this report is ok. I've got more of these.
Error report:
Function includeIfExists not found.
Full code:
declare (strict_types = 1);
function includeIfExists(string $file)
{
if (file_exists($file)) {
return include $file;
}
}
if (
(!$classLoader = includeIfExists(__DIR__.'/../vendor/autoload.php')) &&
(!$classLoader = includeIfExists(__DIR__.'/../../../autoload.php'))
) {
echo 'You must set up the project dependencies, run the following commands:'.PHP_EOL.
'curl -sS https://getcomposer.org/installer | php'.PHP_EOL.
'php composer.phar install'.PHP_EOL;
exit(1);
}
<?php
declare(strict_types=1);
$headers = apache_request_headers();
Running phpstan analyse test.php -l 4
on PHP 7.0 give this error:
------ --------------------------------------------
Line test.php
------ --------------------------------------------
5 Function apache_request_headers not found.
------ --------------------------------------------
I guess it's because we are in a CLI context, not an apache context. Not sure if you must whitelist this or if users must handle it with ignoreErrors
.
PS: thanks for you're hard work, phpstan is a fantastic tool. π
With the following configuration:
parameters:
earlyTerminatingMethodCalls:
Nette\Application\UI\Presenter:
- redirect
- redirectUrl
- sendJson
- sendResponse
The following code works inside presenters but not inside controls because getPresenter()
may return NULL inside controls and not in presenters.
public function test()
{
if (rand() === 0) {
$foo = 13;
} else {
$this->getPresenter()->redirect('Homepage:default');
}
echo $foo;
}
For level greater than 0, "undefined variable" error is raised during destructuring in foreach.
Sample code:
<?php
foreach($rows as ['id' => $id])
yield new Foo($id);
Output:
------ ----------------------------------------------
69 Undefined variable: $id
70 Undefined variable: $id
------ ----------------------------------------------
I tried to analyse Carbon but I ran into the following error :
$ ./vendor/bin/phpstan analyse src/Carbon/Carbon.php
------ -------------------------------------------------------------------------
Line Carbon.php
------ -------------------------------------------------------------------------
Internal error: Argument 1 passed to
PHPStan\Analyser\Scope::assignVariable() must be of the type string,
object given, called in
Carbon\vendor\phpstan\phpstan\src\Analyser\NodeScopeResolver.php on line
701
------ -------------------------------------------------------------------------
[ERROR] Found 1 error
```
phpstan version : master (commit 319baa6)
PHPStan IMO should not depend on composer autoloader of the project. It is not a direct (dev) dependency and no code depends on it. That's the main difference to other dev tools such as PHPUnit, the code is directly dependent on PHPUnit.
Would be great to use it as "tool" in CI:
composer create-project phpstan/phpstan --no-dev
./phpstan/phpstan analyse ./myproject
PHPStan incorrectly reports βUndefined variable: $aβ
if (empty($a)) {
}
Hi!
In CircleCI I've got this:
./vendor/bin/phpstan analyse src
298/335 [ββββββββββββββββββββββββββββ] 88%
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes) in /home/ubuntu/shippeo.sf/vendor/phpstan/phpstan/src/Reflection/Php/PhpMethodReflection.php on line 158
./vendor/bin/phpstan analyse src returned exit code 255
So I must launch differently with:
php -d memory_limit=-1 ./vendor/bin/phpstan analyse src
335/335 [ββββββββββββββββββββββββββββ] 100%
[OK] No errors
! [NOTE] PHPStan is performing only the most basic checks. You can pass a
! higher rule level through the --level option (the default and current
! level is 0) to analyse code more thoroughly.
What do you think to increase/bypass memory limit?
Thanks
$: phpstan analyse includes admin
Fatal error: Class PHPStan\Command\ThrottledProgressBar may not inherit from final class (Symfony\Component\Console\Helper\ProgressBar) in /home/mte90/.composer/vendor/phpstan/phpstan/src/Command/ThrottledProgressBar.php on line 7
ErrorException: Class PHPStan\Command\ThrottledProgressBar may not inherit from final class (Symfony\Component\Console\Helper\ProgressBar) in /home/mte90/.composer/vendor/phpstan/phpstan/src/Command/ThrottledProgressBar.php:7
Stack trace:
#0 [internal function]: Tracy\Debugger::shutdownHandler()
#1 {main}
I got this error everytime i tried to use analyse, happen on php 7.0.14. I installed the software globally.
The following code reports 4 undefined variables, even though it should be fine in all cases.
<?php
if (isset($_[$a = 123]) && $a > 0) {}
Nette\Application\UI\Presenter::argsToParams('', '', $b);
echo $c = 'abc';
echo $c;
foreach ($d = [] as $_) {}
echo $d;
(float) (6 / 2)
should not result in βCasting to float something that's already float.β
Do you have any plans to support PHPDoc which states that a parameter or the return type would be an array consisting only of certain types?
Example:
/**
* @param int[] $ids
* @return User[]
*/
public function getUsersById(array $ids): array
{
return array_map(function($id) {
return User::find($id);
}, $ids);
}
I've seen this syntax for the first time in https://github.com/box/augmented_types and I think it was later supported in other static-code analysis tools (not sure, but I think Scrutinizer CI supports it).
Having that in code ${$param} = $value;
, phpstan throws an error
Internal error: Argument 1 passed to
PHPStan\Analyser\Scope::assignVariable() must be of the type string,
object given, called in
vendor/phpstan/phpstan/src/Ana
lyser/NodeScopeResolver.php on line 690
For example Mockery and Faker both use in one place Callable
instead of callable
.
The phpstan output is like bellow
1/1 [ββββββββββββββββββββββββββββ] 100%
------ ------------------------
Line src/Foo.php
------ ------------------------
9 Undefined variable: $a
------ ------------------------
[ERROR] Found 1 error
which is awesome for human but ugly for cli app reading from pipe. It's hard to use the phpstan's result for other app like vim-syntastic.
So, I promise to add an new option the make the result output like
src/Foo.php:9 Undefined variable: $a
src/Bar.php:9 Undefined variable: $a
Example code:
trait MyTrait
{
public function foo()
{
return $this->bar();
}
}
Call to an undefined method MyTrait::bar().
For example:
if (false === realpath('nope')){}
Results in Strict comparison using === between bool and string will always evaluate to false.
Whilst the statement about the comparison is true, realpath()
returns false
for a non existent file.
I suspect realpath(string $path): ?string
would solve this issue.
Which is PHP7.1. Not sure how many of the functions and methods in core/extensions have been updated to reflect this. Hopefully all of them!!
Hi guys,
I liked this tool a lot, I'm using on my tests and I received a possible false error on analysis. On my class, method use func_num_args()
and func_get_arg()
to manage parameters, but this script report error, as below:
------ ----------------------------------------------------------------------------------
Line vectordev/ajaxtable/examples/numbers.php
------ ----------------------------------------------------------------------------------
118 Class VectorDev\AjaxTable\Row constructor invoked with 6 parameters, 0 required.
------ ----------------------------------------------------------------------------------
https://github.com/vectornet/ajaxtable/blob/master/examples/numbers.php#L118
https://github.com/vectornet/ajaxtable/blob/master/src/Row.php#L29
I think that in this case why not a good idea to script check if have function handling functions ( func_get_*
) in method on validation.
What you think guys? Thanks
It would be great to have a switch for turning off the progress bar output (e.g. for CI). Like the one composer has for install command (composer install --no-progress
)
(I'm using dev-master
)
> phpstan analyse app bin src tests web --level 4
0/9 [ββββββββββββββββββββββββββββ] 0%
1/9 [ββββββββββββββββββββββββββββ] 11%
2/9 [ββββββββββββββββββββββββββββ] 22%
3/9 [ββββββββββββββββββββββββββββ] 33%
4/9 [ββββββββββββββββββββββββββββ] 44%
5/9 [ββββββββββββββββββββββββββββ] 55%
6/9 [ββββββββββββββββββββββββββββ] 66%
7/9 [ββββββββββββββββββββββββββββ] 77%
8/9 [ββββββββββββββββββββββββββββ] 88%
9/9 [ββββββββββββββββββββββββββββ] 100%
[OK] No errors
Should I send a PR or are you adamant analyse should be used? :)
american https://books.google.com/ngrams/graph?content=(analyze)+-+(analyse)&case_insensitive=on&year_start=1800&year_end=2000&corpus=17&smoothing=5&share=&direct_url=t1%3B%2C%28analyze%29%20-%20%28analyse%29%3B%2Cc0
british https://books.google.com/ngrams/graph?content=(analyze)+-+(analyse)&case_insensitive=on&year_start=1800&year_end=2000&corpus=18&smoothing=5&share=&direct_url=t1%3B%2C%28analyze%29%20-%20%28analyse%29%3B%2Cc0
I ran the analyzer against a code base that makes extensive use of traits. In almost all the cases these trait files return errors stating references to undefined properties/constants etc., as these are defined in classes which invoke the trait.
Is it possible to fix this so that when a trait is being analyzed, it is analyzed in context of the class that is using the trait? (so, if you have 1 trait re-used in 3 distinct classes, that would be 3 analysis for the trait - 1 for each class/trait pairing).
Currently PHPStan claims to be βPHP Static Analysis Toolβ but this is actually a lie, because phpstan executes the tested code which makes using the tool quite dangerous.
The correct solution is to use a library such as https://github.com/Roave/BetterReflection
I think the sign specifier throws off checking of the number of placeholders:
<?php
var_dump(sprintf('%+02d', 1));
Tested on 0.5.2
:
------ ---------------------------------------------------------
Line bootstrap.php
------ ---------------------------------------------------------
3 Call to sprintf contains 0 placeholders, 1 value given.
------ ---------------------------------------------------------
The sign specifier is part of the formatting options though, see the documentation:
An optional sign specifier that forces a sign (- or +) to be used on a number. By default, only the - sign is used on a number if it's negative. This specifier forces positive numbers to have the + sign attached as well.
The following code
https://github.com/nextras/migrations/blob/a3743b49386d3fdcbedb8b4a4db95abecf370e7d/src/Bridges/SymfonyConsole/CreateCommand.php results in incorrent βUndefined variableβ error. The variables are actually output variables of function call. Unfortunatelly, PHP does not differenciate between out-only and in-out variables.
------ ----------------------------------------------
Line src\Bridges\SymfonyConsole\CreateCommand.php
------ ----------------------------------------------
44 Undefined variable: $foundYear
45 Undefined variable: $foundYear
45 Undefined variable: $foundMonth
------ ----------------------------------------------
BTW: Have you consider using https://github.com/ircmaxell/php-cfg?
This piece of code :
/**
* Return the admin related to the given $class.
*
* @param string $class
*
* @return \Sonata\AdminBundle\Admin\AdminInterface|null
*/
public function getAdminByClass($class)
{
if (!$this->hasAdminByClass($class)) {
return;
}
if (!is_array($this->adminClasses[$class])) {
throw new \RuntimeException('Invalid format for the Pool::adminClass property');
}
if (count($this->adminClasses[$class]) > 1) {
throw new \RuntimeException(sprintf('Unable to find a valid admin for the class: %s, there are too many registered: %s', $class, implode(',', $this->adminClasses[$class])));
}
return $this->getInstance($this->adminClasses[$class][0]);
}
yields
187 Method Sonata\AdminBundle\Admin\Pool::getAdminByClass() should return
Sonata\AdminBundle\Admin\AdminInterface|null but empty return statement
found.
phpstan should be ok with that IMO.
Symfony Translator contains @return array[array] indexed by catalog
which is processed into
MessageSelector::__PHPSTAN_CLASS_REFLECTION_CONSTANT__;
ConfigCacheFactoryInterface::__PHPSTAN_CLASS_REFLECTION_CONSTANT__;
MessageSelector::__PHPSTAN_CLASS_REFLECTION_CONSTANT__;
ConfigCacheFactoryInterface::__PHPSTAN_CLASS_REFLECTION_CONSTANT__;
LoaderInterface::__PHPSTAN_CLASS_REFLECTION_CONSTANT__;
array[array]::__PHPSTAN_CLASS_REFLECTION_CONSTANT__; <--- this is line 30
ConfigCacheFactoryInterface::__PHPSTAN_CLASS_REFLECTION_CONSTANT__;
which php-parser fails to parse with error βSyntax error, unexpected '[', expecting '(' on line 30β
Another PHP Reflection issue (See https://bugs.php.net/bug.php?id=73803)
The public properties of the ZipArchive class (as documented in http://uk1.php.net/manual/en/class.ziparchive.php) are not exposed via ReflectionClass (as seen if you run php --rc ZipArchive | grep Properties
).
As a consequence, you get Access to an undefined property ZipArchive::$numFiles.
, etc.
If you have a mechanism to support missing/broken reflections for PHPStan, I'll happily make a pull request. Just need a pointer as to where to start.
please add phpstan.phar download. thanks.
class Base { protected function foo() {} }
class Other extends Base { protected function foo() {} }
class Child extends Base { public function bar() { $otherBase = new Other(); $otherBase->foo(); } }
$child = new Child();
$child->bar();
This code produce Cannot call method Other::foo() from current scope.
which is not true - https://3v4l.org/8DNBa
There is no error when method is not overriden:
class Base { protected function foo() {} }
class Other extends Base { }
class Child extends Base { public function bar() { $otherBase = new Other(); $otherBase->foo(); } }
$child = new Child();
$child->bar();
sscanf
has an "additional" way of specifying strings using regex-like character classes. It's handy when parsing strings with non-space separators. These character classes are not correctly detected by PHPStan.
sscanf
call like the following one throws Call to sscanf contains 1 placeholder, 3 values given.
sscanf('foo,bar,2600', '%20[^,],%20[^,],%d', $foo, $bar, $baz);
but it's actually a correct sscanf
call, see https://3v4l.org/PNEok (also explains the character classes thing)
Error:
Access to an undefined property Some\Class\With\CallbackStackProcessing::$counter
Sample abstract code:
/**
* Storage.php
*/
class Storage
{
private $data;
public function __get($key)
{
return $this->data[$key] ?? null;
}
public function __set($key, $value)
{
$this->data[$key] = $value;
}
}
/**
* Inside Some\Class\With\CallbackStackProcessing::process()
*/
$storage = new Storage;
$result = $this->data;
foreach ($this->processors as $processor)
{
$result = Closure::bind($processor, $storage)($result);
}
return $result;
/**
* Callbacks in Some\Class\With\CallbackStackProcessing::$processors
*/
[
function ($data) {
$this->counter = count($data);
return $data;
},
function ($data) {
return array_map($data, function ($item) {
return (int) $data;
});
},
function ($data) {
if ($data[0] < 100) return false;
return $data;
},
function ($data) {
return [
'before' => $this->counter,
'items' => $data,
'after' => count($data),
];
},
]
Is there any way to tell analyzer to skip this particular error or typehint via annotations?
This is a bit weird, but is valid : https://3v4l.org/kcqmL
But phpstan complains :
Call to sprintf contains 1 placeholder, 2 values given.
foreach ($variableAssignedInForeach = [] as $v) {
var_dump($variableAssignedInForeach);
}
$a = ($b = 123) && $b;
unset($c);
function () use (& $d) { };
echo $d;
PHPStan says Undefined variable: $value
foreach ($params as $key => &$value) {
if (is_array($value)) {
$value = implode(',', $value);
}
}
unset($value);
I cannot come up with a solution how to fix this warning. Does it mean I shouldn't use &
?
In is quite surprising but the following code is valid in PHP
class ParentClass
{
public function test()
{
$a = new ChildClass();
$a->onChild();
}
}
class ChildClass extends ParentClass
{
protected function onChild()
{
}
}
(new ParentClass)->test();
I get many errors during a scan of a WordPress plugin (I analyse the folder of a plugin) so I think that I need to prepare a file with a list of all the functions and classes because I get many errors because they not exist.
I get also many errors about the autoloading but in WordPress you can also chose to not use composer (direct file to include) so there are many errors about it.
Anyone have suggestions for these problems?
I think traits with aliased methods are not supported.
I have something similar to this:
class Foo
{
use BarTrait;
}
trait BarTrait
{
use BazTrait {
fooMethod as parentFooMethod;
}
public function fooMethod()
{
// some code ...
$this->parentFooMethod();
}
}
trait BazTrait
{
public function fooMethod()
{
// some code ...
}
}
During the analyse
command progress I get the following output:
PHP Notice: Undefined index: parentfoomethod in /vagrant/vendor/phpstan/phpstan/src/Reflection/Php/PhpClassReflectionExtension.php on line 127
In the end I get the following error:
------ ------------------------------------------------------------------------------------------------------
Line src/Foo.php
------ ------------------------------------------------------------------------------------------------------
Internal error: Return value of PHPStan\Reflection\Php\PhpClassReflectionExtension::getMethod() must
implement interface PHPStan\Reflection\MethodReflection, null returned
------ ------------------------------------------------------------------------------------------------------
Let me know if I could be of any further assistance with pinpointing the issue. Thank you!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.