Exemplo n.º 1
0
 /**
  * Check method parameters to make sure they're valid
  *
  * @return null
  */
 public static function analyzeParameterTypes(CodeBase $code_base, FunctionInterface $method)
 {
     // Look at each parameter to make sure their types
     // are valid
     foreach ($method->getParameterList() as $parameter) {
         $union_type = $parameter->getUnionType();
         // Look at each type in the parameter's Union Type
         foreach ($union_type->getTypeSet() as $type) {
             // If its a native type or a reference to
             // self, its OK
             if ($type->isNativeType() || $type->isSelfType()) {
                 continue;
             }
             if ($type instanceof TemplateType) {
                 if ($method instanceof Method) {
                     if ($method->isStatic()) {
                         Issue::maybeEmit($code_base, $method->getContext(), Issue::TemplateTypeStaticMethod, $method->getFileRef()->getLineNumberStart(), (string) $method->getFQSEN());
                     }
                 }
             } else {
                 // Make sure the class exists
                 $type_fqsen = $type->asFQSEN();
                 if (!$code_base->hasClassWithFQSEN($type_fqsen)) {
                     Issue::maybeEmit($code_base, $method->getContext(), Issue::UndeclaredTypeParameter, $method->getFileRef()->getLineNumberStart(), (string) $type_fqsen);
                 }
             }
         }
     }
     if ($method instanceof Method) {
         self::analyzeOverrideSignature($code_base, $method);
     }
 }
Exemplo n.º 2
0
 /**
  * Check to see if the given Clazz is a duplicate
  *
  * @return null
  */
 public static function analyzeDuplicateFunction(CodeBase $code_base, FunctionInterface $method)
 {
     $fqsen = $method->getFQSEN();
     if (!$fqsen->isAlternate()) {
         return;
     }
     $original_fqsen = $fqsen->getCanonicalFQSEN();
     if ($original_fqsen instanceof FullyQualifiedFunctionName) {
         if (!$code_base->hasFunctionWithFQSEN($original_fqsen)) {
             return;
         }
         $original_method = $code_base->getFunctionByFQSEN($original_fqsen);
     } else {
         if (!$code_base->hasMethodWithFQSEN($original_fqsen)) {
             return;
         }
         $original_method = $code_base->getMethodByFQSEN($original_fqsen);
     }
     $method_name = $method->getName();
     if (!$method->hasSuppressIssue(Issue::RedefineFunction)) {
         if ($original_method->isInternal()) {
             Issue::maybeEmit($code_base, $method->getContext(), Issue::RedefineFunctionInternal, $method->getFileRef()->getLineNumberStart(), $method_name, $method->getFileRef()->getFile(), $method->getFileRef()->getLineNumberStart());
         } else {
             Issue::maybeEmit($code_base, $method->getContext(), Issue::RedefineFunction, $method->getFileRef()->getLineNumberStart(), $method_name, $method->getFileRef()->getFile(), $method->getFileRef()->getLineNumberStart(), $original_method->getFileRef()->getFile(), $original_method->getFileRef()->getLineNumberStart());
         }
     }
 }
Exemplo n.º 3
0
 /**
  * @param FunctionInterface $function
  * Get a list of methods hydrated with type information
  * for the given partial method
  *
  * @param CodeBase $code_base
  * The global code base holding all state
  *
  * @return Method[]
  * A list of typed methods based on the given method
  */
 private static function functionListFromFunction(FunctionInterface $function, CodeBase $code_base) : array
 {
     // See if we have any type information for this
     // internal function
     $map_list = UnionType::internalFunctionSignatureMapForFQSEN($function->getFQSEN());
     if (!$map_list) {
         return [$function];
     }
     $alternate_id = 0;
     return array_map(function ($map) use($function, &$alternate_id) : FunctionInterface {
         $alternate_function = clone $function;
         $alternate_function->setFQSEN($alternate_function->getFQSEN()->withAlternateId($alternate_id++));
         // Set the return type if one is defined
         if (!empty($map['return_type'])) {
             $alternate_function->setUnionType($map['return_type']);
         }
         // Load properties if defined
         foreach ($map['property_name_type_map'] ?? [] as $parameter_name => $parameter_type) {
             $flags = 0;
             $is_optional = false;
             // Check to see if its a pass-by-reference parameter
             if (strpos($parameter_name, '&') === 0) {
                 $flags |= \ast\flags\PARAM_REF;
                 $parameter_name = substr($parameter_name, 1);
             }
             // Check to see if its variadic
             if (strpos($parameter_name, '...') !== false) {
                 $flags |= \ast\flags\PARAM_VARIADIC;
                 $parameter_name = str_replace('...', '', $parameter_name);
             }
             // Check to see if its an optional parameter
             if (strpos($parameter_name, '=') !== false) {
                 $is_optional = true;
                 $parameter_name = str_replace('=', '', $parameter_name);
             }
             $parameter = new Parameter($function->getContext(), $parameter_name, $parameter_type, $flags);
             if ($is_optional) {
                 $parameter->setDefaultValueType(NullType::instance()->asUnionType());
             }
             // Add the parameter
             $alternate_function->appendParameter($parameter);
         }
         $alternate_function->setNumberOfRequiredParameters(array_reduce($alternate_function->getParameterList(), function (int $carry, Parameter $parameter) : int {
             return $carry + ($parameter->isOptional() ? 0 : 1);
         }, 0));
         $alternate_function->setNumberOfOptionalParameters(count($alternate_function->getParameterList()) - $alternate_function->getNumberOfRequiredParameters());
         return $alternate_function;
     }, $map_list);
 }
Exemplo n.º 4
0
 /**
  * @return array
  * Get a map from column name to row values for
  * this instance
  */
 public function toRow() : array
 {
     return ['scope_name' => $this->primaryKeyValue(), 'fqsen' => (string) $this->method->getFQSEN(), 'name' => (string) $this->method->getName(), 'type' => (string) $this->method->getUnionType(), 'flags' => $this->method->getFlags(), 'context' => base64_encode(serialize($this->method->getContext())), 'is_deprecated' => $this->method->isDeprecated(), 'number_of_required_parameters' => $this->method->getNumberOfRequiredParameters(), 'number_of_optional_parameters' => $this->method->getNumberOfOptionalParameters()];
 }