/**
  * @param Function_|ClassMethod $node
  */
 function importReturnValue($node)
 {
     $comment = $node->getDocComment();
     if ($comment) {
         $str = $comment->getText();
         try {
             $docBlock = $this->factory->create($str, $this->getDocBlockContext());
             $return = $docBlock->getTagsByName("return");
             if (count($return)) {
                 $returnType = $return[0]->getType();
                 $types = explode("|", $returnType);
                 if (count($types) > 1) {
                     $node->setAttribute("namespacedReturn", \Guardrail\Scope::MIXED_TYPE);
                 } else {
                     foreach ($types as $type) {
                         if ($type[0] == '\\') {
                             $type = substr($type, 1);
                         }
                         $node->setAttribute("namespacedReturn", strval($type));
                         return;
                     }
                 }
             }
         } catch (\InvalidArgumentException $e) {
             // Skip it.
         }
     }
 }
예제 #2
0
 protected function checkMethod(Class_ $class, ClassMethod $method, ClassInterface $parentClass, MethodInterface $parentMethod)
 {
     $visibility = $method->getAccessLevel();
     $oldVisibility = $parentMethod->getAccessLevel();
     $fileName = $this->symbolTable->getClassFile(strval($class->namespacedName));
     $this->incTests();
     // "public" and "protected" can be redefined," private can not.
     if ($oldVisibility != $visibility && $oldVisibility == "private") {
         $this->emitError($fileName, $class, self::TYPE_SIGNATURE_TYPE, "Access level mismatch in " . $method->getName() . "() " . $visibility . " vs " . $oldVisibility);
     }
     $params = $method->getParameters();
     $parentMethodParams = $parentMethod->getParameters();
     $count1 = count($params);
     $count2 = count($parentMethodParams);
     if ($count1 < $count2) {
         $this->emitError($fileName, $class, self::TYPE_SIGNATURE_COUNT, "Parameter count mismatch {$count1} vs {$count2} in method " . $class->namespacedName . "->" . $method->getName());
     } else {
         foreach ($params as $index => $param) {
             /** @var FunctionLikeParameter $param */
             // Only parameters specified by the parent need to match.  (Child can add more as long as they have a default.)
             if ($index < $count2) {
                 $parentParam = $parentMethodParams[$index];
                 $name1 = strval($param->getType());
                 $name2 = strval($parentParam->getType());
                 if (strcasecmp($name1, $name2) !== 0) {
                     $this->emitErrorOnLine($fileName, $method->getStartingLine(), self::TYPE_SIGNATURE_TYPE, "Parameter mismatch type mismatch " . $class->namespacedName . "::" . $method->getName() . " : {$name1} vs {$name2}");
                     break;
                 }
                 if ($param->isReference() != $parentParam->isReference()) {
                     $this->emitErrorOnLine($fileName, $method->getStartingLine(), self::TYPE_SIGNATURE_TYPE, "Child Method " . $class->name . "::" . $method->getName() . " add or removes & in \$" . $param->getName());
                     break;
                 }
                 if (!$param->isOptional() && $parentParam->isOptional()) {
                     $this->emitErrorOnLine($fileName, $method->getStartingLine(), self::TYPE_SIGNATURE_TYPE, "Child method " . $class->name . "::" . $method->getName() . " changes parameter \$" . $param->getName() . " to be required.");
                     break;
                 }
             } else {
                 if (!$param->isOptional()) {
                     $this->emitErrorOnLine($fileName, $method->getStartingLine(), self::TYPE_SIGNATURE_TYPE, "Child method " . $method->getName() . " adds parameter \$" . $param->getName() . " that doesn't have a default value");
                     break;
                 }
             }
         }
     }
 }