public function visit(NodeTraversal $t, \PHPParser_Node $node, \PHPParser_Node $parent = null)
 {
     // Consider only non-dynamic variables in this pass.
     if (!$node instanceof \PHPParser_Node_Expr_Variable || !is_string($node->name)) {
         return;
     }
     // We ignore PHP globals.
     if (NodeUtil::isSuperGlobal($node)) {
         return;
     }
     // Ignore variables which are defined here.
     if ($parent instanceof \PHPParser_Node_Expr_Assign && $parent->var === $node) {
         return;
     }
     if (!$t->getScope()->isDeclared($node->name)) {
         if ($bestName = CheckForTyposPass::getMostSimilarName($node->name, $t->getScope()->getVarNames())) {
             $this->phpFile->addComment($node->getLine(), Comment::error('typos.mispelled_variable_name', 'The variable ``%offending_variable_name%`` does not exist. Did you mean ``%closest_variable_name%``?', array('offending_variable_name' => '$' . $node->name, 'closest_variable_name' => '$' . $bestName)));
         } else {
             $this->phpFile->addComment($node->getLine(), Comment::warning('usage.undeclared_variable', 'The variable ``%variable_name%`` does not exist. Did you forget to declare it?', array('variable_name' => '$' . $node->name)));
         }
         return;
     }
     if ($parent instanceof \PHPParser_Node_Expr_ArrayDimFetch && $node->getAttribute('array_initializing_variable') && $parent->var === $node) {
         $this->phpFile->addComment($node->getLine(), Comment::warning('usage.non_initialized_array', '``%array_fetch_expr%`` was never initialized. Although not strictly required by PHP, it is generally a good practice to add ``%array_fetch_expr% = array();`` before regardless.', array('array_fetch_expr' => self::$prettyPrinter->prettyPrintExpr($node))));
     }
 }
 public function visit(NodeTraversal $t, \PHPParser_Node $node, \PHPParser_Node $parent = null)
 {
     switch (true) {
         case $node instanceof \PHPParser_Node_Expr_Variable:
             if (NodeUtil::isSuperGlobal($node)) {
                 return;
             }
             if (is_string($node->name)) {
                 $this->checkNaming($node->getLine(), '$' . $node->name, $node->name, 'local_variable');
             }
             break;
         case $node instanceof \PHPParser_Node_Stmt_PropertyProperty:
             $this->checkNaming($node->getLine(), '$' . $node->name, $node->name, 'property_name');
             break;
         case $node instanceof \PHPParser_Node_Stmt_Function:
         case $node instanceof \PHPParser_Node_Stmt_ClassMethod:
             $function = $this->typeRegistry->getFunctionByNode($node);
             // If a class method is constrained by a contract of an interface, or an abstract
             // class, then there is no point in adding warnings for them.
             if ($function instanceof ClassMethod && $function->isConstrainedByContract()) {
                 break;
             }
             $this->checkNaming($node->getLine(), 'function ' . $node->name . '()', $node->name, 'method_name');
             if (null !== $function && null !== ($returnType = $function->getReturnType()) && $returnType->isBooleanType()) {
                 $this->checkNaming($node->getLine(), 'function ' . $node->name . '()', $node->name, 'isser_method_name');
             }
             $this->checkParameters($node->params);
             break;
         case $node instanceof \PHPParser_Node_Expr_Closure:
             $this->checkParameters($node->params);
             break;
         case NodeUtil::isMethodContainer($node):
             $class = $this->typeRegistry->getClassByNode($node)->toMaybeObjectType();
             if ($class) {
                 $this->checkNaming($node->getLine(), $class->getShortName(), $class->getShortName(), 'type_name');
                 if ($class->isInterface()) {
                     $this->checkNaming($node->getLine(), $class->getShortName(), $class->getShortName(), 'interface_name');
                 } elseif ($class instanceof Clazz) {
                     if ($class->isUtilityClass()) {
                         $this->checkNaming($node->getLine(), $class->getShortName(), $class->getShortName(), 'utility_class_name');
                     } elseif ($class->isAbstract()) {
                         $this->checkNaming($node->getLine(), $class->getShortName(), $class->getShortName(), 'abstract_class_name');
                     }
                     // No Else-If here as there might be an abstract exception.
                     // TODO: isSubtype needs to return a TernaryValue so that we
                     //       can decide here what to do in the unknown case.
                     //                        if ($class->isSubTypeOf($this->typeRegistry->getClassOrCreate('Exception'))) {
                     //                            $this->checkNaming($node->getLine(), $class->getShortName(), $class->getShortName(), 'exception_name');
                     //                        }
                 }
                 // The original check only allows final classes to have a private
                 // constructor. We also allow the constructor to be private if it
                 // is declared final, and the class is declared abstract. This is
                 // for example a common practice for utility classes.
                 $method = $class->getMethod('__construct');
                 if (null !== $method && $method->isPrivate() && !$class->isFinal() && (!$method->isFinal() || !$class->isAbstract())) {
                     if (($method = $class->getMethod('__construct')) && $method->isPrivate() && !$class->isFinal() && (!$method->isFinal() || !$class->isAbstract())) {
                         if ($method->isFinal()) {
                             if ($class->isUtilityClass()) {
                                 $this->phpFile->addComment($node->getLine(), Comment::warning('coding_style.non_abstract_util_class', 'Since you have declared the constructor as final, and this seems like a utility class, maybe you should also declare the class as abstract.'));
                             } else {
                                 if (null === $method->getAstNode()) {
                                     break;
                                 }
                                 $this->phpFile->addComment($method->getAstNode()->getLine(), Comment::warning('coding_style.non_util_class_with_final_private_constructor', 'Instead of declaring the constructor as final, maybe you should declare the entire class as final.'));
                             }
                         } elseif ($class->isAbstract()) {
                             if ($class->isUtilityClass()) {
                                 $this->phpFile->addComment($method->getAstNode()->getLine(), Comment::warning('coding_style.util_class_with_non_final_constructor', 'Since you have declared this class abstract, and the constructor is private, maybe you should also declare the constructor as final.'));
                             } else {
                                 $this->phpFile->addComment($method->getAstNode()->getLine(), Comment::warning('coding_style.abstract_non_util_class_with_private_constructor', 'Something seems to be off here. Are you sure you want to declare the constructor as private, and the class as abstract?'));
                             }
                         } else {
                             $this->phpFile->addComment($node->getLine(), Comment::warning('coding_style.non_final_class_with_private_constructor', 'Since you have declared the constructor as private, maybe you should also declare the class as final.'));
                         }
                     }
                 }
             }
             break;
     }
 }