/**
  * Create from a Class Node.
  *
  * @param Reflector          $reflector
  * @param ClassLikeNode      $node
  * @param LocatedSource      $locatedSource
  * @param NamespaceNode|null $namespace optional - if omitted, we assume it is global namespaced class
  *
  * @return ReflectionClass
  */
 public static function createFromNode(Reflector $reflector, ClassLikeNode $node, LocatedSource $locatedSource, NamespaceNode $namespace = null)
 {
     $class = new self();
     $class->reflector = $reflector;
     $class->node = $node;
     $class->locatedSource = $locatedSource;
     $class->name = $node->name;
     if (null !== $namespace) {
         $class->declaringNamespace = $namespace;
     }
     if ($node instanceof ClassNode && null !== $node->extends) {
         $objectType = (new FindTypeFromAst())->__invoke($node->extends, $locatedSource, $class->getNamespaceName());
         if (null !== $objectType && $objectType instanceof Object_) {
             $class->extendsClassType = $objectType->getFqsen();
         }
     }
     $methodNodes = $node->getMethods();
     foreach ($methodNodes as $methodNode) {
         $class->methods[] = ReflectionMethod::createFromNode($methodNode, $class);
     }
     foreach ($node->stmts as $stmt) {
         if ($stmt instanceof ConstNode) {
             $constName = $stmt->consts[0]->name;
             $constValue = (new CompileNodeToValue())->__invoke($stmt->consts[0]->value);
             $class->constants[$constName] = $constValue;
         }
         if ($stmt instanceof PropertyNode) {
             $prop = ReflectionProperty::createFromNode($stmt, $class);
             $class->properties[$prop->getName()] = $prop;
         }
     }
     return $class;
 }