public function analyze()
{
$magicMethods = $this->loadIni('php_magic_methods.ini', 'magicMethod');
// Normal Methodcall
$methods = $this->query('g.V().hasLabel("Methodcall").out("METHOD").has("token", "T_STRING").map{ it.get().value("code").toLowerCase(); }.unique()');
$this->atomIs('Class')->outIs('BLOCK')->outIs('ELEMENT')->atomIs('Function')->_as('used')->outIs('NAME')->codeIsNot($magicMethods)->codeIs($methods)->back('used');
$this->prepareQuery();
// Staticmethodcall
$staticmethods = $this->query('g.V().hasLabel("Staticmethodcall").out("METHOD").has("token", "T_STRING").map{ it.get().value("code").toLowerCase(); }.unique()');
$this->atomIs('Class')->outIs('BLOCK')->outIs('ELEMENT')->atomIs('Function')->_as('used')->outIs('NAME')->codeIsNot($magicMethods)->codeIs($staticmethods)->back('used');
$this->prepareQuery();
$callables = $this->query(<<<GREMLIN
g.V().hasLabel("Analysis").has("analyzer", "Functions/MarkCallable").out("ANALYZED")
.not( hasLabel("Function") )
.map{
// Strings
if (it.get().label() == 'String') {
if (it.get().value("noDelimiter") =~ /::/) {
s = it.get().value("noDelimiter").split('::');
s[1].toLowerCase();
} else {
it.get().value("noDelimiter").toLowerCase();
}
} else if (it.get().label() == 'Arguments') {
it.get().vertices(OUT, "ARGUMENT").each{
if (it.value("rank") == 1) {
s = it.value("noDelimiter").toLowerCase();
}
}
s;
} else {
it.get().value("noDelimiter").toLowerCase();
}
}
GREMLIN
);
// method used statically in a callback with an array
$this->atomIs('Class')->savePropertyAs('fullnspath', 'fullnspath')->outIs('BLOCK')->outIs('ELEMENT')->atomIs('Function')->_as('used')->outIs('NAME')->codeIsNot($magicMethods)->codeIs($callables)->back('used');
$this->prepareQuery();
// Private constructors
$this->atomIs('Class')->savePropertyAs('fullnspath', 'fullnspath')->outIs('BLOCK')->outIs('ELEMENT')->atomIs('Function')->hasOut('PRIVATE')->_as('used')->outIs('NAME')->codeIs('__construct')->inIs('NAME')->inIs('ELEMENT')->atomInside('New')->outIs('NEW')->tokenIs(array('T_STRING', 'T_NS_SEPARATOR'))->samePropertyAs('fullnspath', 'fullnspath')->back('used');
$this->prepareQuery();
// Normal Constructors
$this->atomIs('Class')->savePropertyAs('fullnspath', 'fullnspath')->outIs('BLOCK')->outIs('ELEMENT')->atomIs('Function')->hasNoOut('PRIVATE')->_as('used')->outIs('NAME')->codeIs('__construct')->goToClass()->outIs('DEFINITION')->hasIn('NEW')->back('used');
$this->prepareQuery();
// the special methods must be processed independantly
// __destruct is always used, no need to spot
}