/** * * @param blaze\lang\Integer|int $value * @return blaze\lang\ClassWrapper */ public static function getNumberClass($value) { if (self::$numberClasses == null) { self::lazyInit(); } if (Byte::isType($value)) { return self::$numberClasses[0]; } else { if (Short::isType($value)) { return self::$numberClasses[1]; } else { if (Integer::isType($value)) { return self::$numberClasses[4]; } else { if (Long::isType($value)) { return self::$numberClasses[5]; } else { if (Float::isType($value)) { return self::$numberClasses[3]; } else { if (Double::isType($value)) { return self::$numberClasses[2]; } else { if (BigInteger::isType($value)) { return self::$numberClasses[6]; } else { if (BigDecimal::isType($value)) { return self::$numberClasses[7]; } } } } } } } } return null; }
/** * This method handles every error from PHP and decides * wether this is a real error or not. The type hinting of * native types, widening and auto boxing is supported through this method. * * @access private * @param int $errorLevel * @param string $errorMessage * @return boolean False if an error occured, otherwise true */ public static function systemErrorHandler($errorLevel, $errorMessage, $errorFile, $errorLine, &$errorContext) { switch ($errorLevel) { case E_USER_ERROR: // User error // User error case E_WARNING: // Runtime warnings // Runtime warnings case E_USER_WARNING: // User warning // User warning case E_NOTICE: // This could be used for operator overloading but the errorContext does not provide references to the objects // var_dump($errorContext); // $keys = array_keys($errorContext); // $errorContext[$keys[count($keys) - 1]] = $errorContext[$keys[count($keys) - 1]]->toNative(); // var_dump($errorContext); // return true; // Runtime notices // This could be used for operator overloading but the errorContext does not provide references to the objects // var_dump($errorContext); // $keys = array_keys($errorContext); // $errorContext[$keys[count($keys) - 1]] = $errorContext[$keys[count($keys) - 1]]->toNative(); // var_dump($errorContext); // return true; // Runtime notices case E_USER_NOTICE: // User notice // User notice case E_DEPRECATED: case E_USER_DEPRECATED: case E_STRICT: break; // return false; // return false; case E_RECOVERABLE_ERROR: $ok = false; $matches = null; if (array_key_exists($errorMessage, self::$cachedHints)) { $matches = self::$cachedHints[$errorMessage]; } else { preg_match('/^Argument (?<argNumber>\\d+) passed to (?<namespace>(([a-zA-Z_]{1}[a-zA-Z0-9_]+)\\\\)+)?[:a-zA-Z0-9_]+\\(\\) must (be an instance of|be an|implement interface) (?<hintName>[a-zA-Z0-9_\\\\]+), (instance of )?(?<typeName>[a-zA-Z0-9_\\\\]+) given/AUD', $errorMessage, $matches); } if ($matches !== null) { if ($matches['typeName'] === 'null') { throw new NullPointerException(); } $argNumber = (int) $matches['argNumber'] - 1; $args = self::getArgsOfErrorCall(); switch ($matches['hintName']) { case 'boolean': if ($matches['typeName'] === 'blaze\\lang\\Boolean') { var_dump('Unboxing does not work yet!'); $args[$argNumber] = $args[$argNumber]->toNative(); $ok = true; } else { $ok = $matches['typeName'] === 'boolean'; } break; case 'blaze\\lang\\Boolean': if ($matches['typeName'] === 'boolean') { $args[$argNumber] = new Boolean($args[$argNumber]); $ok = true; } break; case 'byte': switch ($matches['typeName']) { case 'blaze\\lang\\Byte': var_dump('Unboxing does not work yet!'); $args[$argNumber] = $args[$argNumber]->toNative(); $ok = true; break; case 'integer': case 'double': $ok = Byte::isNativeType($args[$argNumber]); if ($ok) { $args[$argNumber] = (int) $args[$argNumber]; } } break; case 'blaze\\lang\\Byte': if ($matches['typeName'] === 'integer' || $matches['typeName'] === 'double') { $ok = Byte::isNativeType($args[$argNumber]); if ($ok) { $args[$argNumber] = new Byte($args[$argNumber]); } } break; case 'short': switch ($matches['typeName']) { case 'blaze\\lang\\Byte': case 'blaze\\lang\\Short': var_dump('Unboxing does not work yet!'); $args[$argNumber] = $args[$argNumber]->toNative(); $ok = true; break; case 'integer': case 'double': $ok = Short::isNativeType($args[$argNumber]); if ($ok) { $args[$argNumber] = (int) $args[$argNumber]; } } break; case 'blaze\\lang\\Short': switch ($matches['typeName']) { case 'blaze\\lang\\Byte': $args[$argNumber] = new Short($args[$argNumber]->toNative()); $ok = true; break; case 'integer': case 'double': $ok = Short::isNativeType($args[$argNumber]); if ($ok) { $args[$argNumber] = new Short($args[$argNumber]); } } break; case 'int': switch ($matches['typeName']) { case 'integer': $ok = true; break; case 'blaze\\lang\\Byte': case 'blaze\\lang\\Short': case 'blaze\\lang\\Integer': var_dump('Unboxing does not work yet!'); $args[$argNumber] = $args[$argNumber]->toNative(); $ok = true; break; case 'double': $ok = Integer::isNativeType($args[$argNumber]); if ($ok) { $args[$argNumber] = (int) $args[$argNumber]; } } break; case 'blaze\\lang\\Integer': switch ($matches['typeName']) { case 'blaze\\lang\\Byte': case 'blaze\\lang\\Short': $args[$argNumber] = new Integer($args[$argNumber]->toNative()); $ok = true; break; case 'integer': case 'double': $ok = Integer::isNativeType($args[$argNumber]); if ($ok) { $args[$argNumber] = new Integer($args[$argNumber]); } } break; case 'long': switch ($matches['typeName']) { case 'integer': $ok = true; break; case 'blaze\\lang\\Byte': case 'blaze\\lang\\Short': case 'blaze\\lang\\Integer': case 'blaze\\lang\\Long': var_dump('Unboxing does not work yet!'); $args[$argNumber] = $args[$argNumber]->toNative(); $ok = true; break; case 'double': $ok = Long::isNativeType($args[$argNumber]); if ($ok) { $args[$argNumber] = (double) $args[$argNumber]; } } break; case 'blaze\\lang\\Long': switch ($matches['typeName']) { case 'blaze\\lang\\Byte': case 'blaze\\lang\\Short': case 'blaze\\lang\\Integer': $args[$argNumber] = new Long($args[$argNumber]->toNative()); $ok = true; break; case 'integer': case 'double': $ok = Long::isNativeType($args[$argNumber]); if ($ok) { $args[$argNumber] = new Long($args[$argNumber]); } } break; case 'float': switch ($matches['typeName']) { case 'integer': $ok = true; break; case 'blaze\\lang\\Byte': case 'blaze\\lang\\Short': case 'blaze\\lang\\Integer': case 'blaze\\lang\\Long': case 'blaze\\lang\\Float': var_dump('Unboxing does not work yet!'); $args[$argNumber] = $args[$argNumber]->toNative(); $ok = true; break; case 'double': $ok = Float::isNativeType($args[$argNumber]); if ($ok) { $args[$argNumber] = (double) $args[$argNumber]; } } break; case 'blaze\\lang\\Float': switch ($matches['typeName']) { case 'blaze\\lang\\Byte': case 'blaze\\lang\\Short': case 'blaze\\lang\\Integer': case 'blaze\\lang\\Long': $args[$argNumber] = new Float($args[$argNumber]->toNative()); $ok = true; break; case 'integer': case 'double': $ok = Float::isNativeType($args[$argNumber]); if ($ok) { $args[$argNumber] = new Float($args[$argNumber]); } } break; case 'double': switch ($matches['typeName']) { case 'integer': $ok = true; break; case 'blaze\\lang\\Byte': case 'blaze\\lang\\Short': case 'blaze\\lang\\Integer': case 'blaze\\lang\\Long': case 'blaze\\lang\\Float': case 'blaze\\lang\\Double': var_dump('Unboxing does not work yet!'); $args[$argNumber] = $args[$argNumber]->toNative(); $ok = true; break; case 'double': $ok = Double::isNativeType($args[$argNumber]); if ($ok) { $args[$argNumber] = (double) $args[$argNumber]; } } break; case 'blaze\\lang\\Double': switch ($matches['typeName']) { case 'blaze\\lang\\Byte': case 'blaze\\lang\\Short': case 'blaze\\lang\\Integer': case 'blaze\\lang\\Long': case 'blaze\\lang\\Float': $args[$argNumber] = new Double($args[$argNumber]->toNative()); $ok = true; break; case 'integer': case 'double': $ok = Double::isNativeType($args[$argNumber]); if ($ok) { $args[$argNumber] = new Double($args[$argNumber]); } break; } break; case 'char': switch ($matches['typeName']) { case 'string': $ok = Character::isNativeType($args[$argNumber]); break; case 'blaze\\lang\\Character': var_dump('Unboxing does not work yet!'); $args[$argNumber] = $args[$argNumber]->toNative(); $ok = true; break; } break; case 'blaze\\lang\\Character': if ($matches['typeName'] === 'string') { $ok = Character::isNativeType($args[$argNumber]); if ($ok) { $args[$argNumber] = new Character($args[$argNumber]); } } break; case 'string': switch ($matches['typeName']) { case 'integer': case 'double': $args[$argNumber] = (string) $args[$argNumber]; $ok = true; break; case 'blaze\\lang\\String': var_dump('Unboxing does not work yet!'); $args[$argNumber] = $args[$argNumber]->toNative(); $ok = true; break; } break; case 'blaze\\lang\\String': if ($matches['typeName'] === 'string') { $args[$argNumber] = new String($args[$argNumber]); $ok = true; } break; case 'array': switch ($matches['typeName']) { case 'object': if (!$args[$argNumber] instanceof \blaze\collections\ArrayI) { break; } case 'blaze\\collections\\arrays\\ArrayObject': var_dump('Unboxing does not work yet!'); $args[$argNumber] = $args[$argNumber]->toNative(); $ok = true; break; } break; case 'blaze\\collections\\ArrayI': case 'blaze\\collections\\arrays\\ArrayObject': if ($matches['typeName'] === 'array') { $ok = \blaze\collections\arrays\ArrayObject::isNativeType($args[$argNumber]); if ($ok) { $args[$argNumber] = new \blaze\collections\arrays\ArrayObject($args[$argNumber]); } } break; case 'blaze\\math\\BigInteger': switch ($matches['typeName']) { case 'blaze\\lang\\Byte': case 'blaze\\lang\\Short': case 'blaze\\lang\\Integer': case 'blaze\\lang\\Long': var_dump('Unboxing does not work yet!'); $args[$argNumber] = new \blaze\math\BigInteger($args[$argNumber]->toNative()); $ok = true; break; case 'integer': case 'double': case 'string': $ok = \blaze\math\BigInteger::isNativeType($args[$argNumber]); if ($ok) { $args[$argNumber] = new \blaze\math\BigInteger($args[$argNumber]); } } break; case 'blaze\\math\\BigDecimal': switch ($matches['typeName']) { case 'blaze\\lang\\Byte': case 'blaze\\lang\\Short': case 'blaze\\lang\\Integer': case 'blaze\\lang\\Long': case 'blaze\\lang\\Float': case 'blaze\\lang\\Double': case 'blaze\\math\\BigInteger': var_dump('Unboxing does not work yet!'); $args[$argNumber] = new \blaze\math\BigDecimal($args[$argNumber]->toNative()); $ok = true; break; case 'integer': case 'double': case 'string': $ok = \blaze\math\BigDecimal::isNativeType($args[$argNumber]); if ($ok) { $args[$argNumber] = new \blaze\math\BigDecimal($args[$argNumber]); } } break; case 'blaze\\lang\\Reflectable': case 'blaze\\lang\\Object': switch ($matches['typeName']) { case 'boolean': $args[$argNumber] = new Boolean($args[$argNumber]); $ok = true; break; case 'integer': case 'double': if (($class = Number::getNumberClass($args[$argNumber])) != null) { if (Integer::isNativeType($args[$argNumber])) { $className = 'blaze\\lang\\Integer'; } else { if (Double::isNativeType($args[$argNumber])) { $className = 'blaze\\lang\\Double'; } else { $className = $class->getName()->toNative(); } } $args[$argNumber] = $className::asWrapper($args[$argNumber]); $ok = true; } break; case 'string': if (\blaze\math\BigInteger::isNativeType($args[$argNumber])) { $args[$argNumber] = new \blaze\math\BigInteger($args[$argNumber]); } else { if (\blaze\math\BigDecimal::isNativeType($args[$argNumber])) { $args[$argNumber] = new \blaze\math\BigDecimal($args[$argNumber]); } else { $args[$argNumber] = new String($args[$argNumber]); } } $ok = true; break; case 'array': $args[$argNumber] = new \blaze\collections\arrays\ArrayObject($args[$argNumber]); $ok = true; break; } break; default: $ok = false; } if ($ok) { self::$cachedHints[$errorMessage] = $matches; return true; } return false; } } return false; }