/**
  * @expectedException \DomainException
  * @expectedExceptionMessage In "requiredMember" member of Dictionary, expected DOMString, got none
  */
 public function testInvalidDictionary3()
 {
     DictionaryType::toDictionary(['stringMember' => 'string'], 'Dictionary', ['Dictionary' => ['stringMember' => ['type' => 'DOMString'], 'requiredMember' => ['type' => 'DOMString', 'required' => true]]]);
 }
Beispiel #2
0
 /**
  * 与えられた値を、指定された型に変換して返します。
  * @link https://heycam.github.io/webidl/#idl-types Web IDL (Second Edition)
  * @link https://www.w3.org/TR/WebIDL/#idl-types Web IDL
  * @param string $type
  * @param mixed $value
  * @param array $pseudoTypes callback interface 型、列挙型、callback 関数型、または dictionary 型の識別子をキーとした型情報の配列。
  * @return mixed
  */
 public static function to($type, $value, $pseudoTypes = null)
 {
     switch ($type) {
         case 'any':
             $returnValue = $value;
             break;
         case 'boolean':
             $returnValue = BooleanType::toBoolean($value);
             break;
         case '[EnforceRange] byte':
             $returnValue = IntegerType::toByte($value, '[EnforceRange]');
             break;
         case '[Clamp] byte':
             $returnValue = IntegerType::toByte($value, '[Clamp]');
             break;
         case 'byte':
             $returnValue = IntegerType::toByte($value);
             break;
         case '[EnforceRange] octet':
             $returnValue = IntegerType::toOctet($value, '[EnforceRange]');
             break;
         case '[Clamp] octet':
             $returnValue = IntegerType::toOctet($value, '[Clamp]');
             break;
         case 'octet':
             $returnValue = IntegerType::toOctet($value);
             break;
         case '[EnforceRange] short':
             $returnValue = IntegerType::toShort($value, '[EnforceRange]');
             break;
         case '[Clamp] short':
             $returnValue = IntegerType::toShort($value, '[Clamp]');
             break;
         case 'short':
             $returnValue = IntegerType::toShort($value);
             break;
         case '[EnforceRange] unsigned short':
             $returnValue = IntegerType::toUnsignedShort($value, '[EnforceRange]');
             break;
         case '[Clamp] unsigned short':
             $returnValue = IntegerType::toUnsignedShort($value, '[Clamp]');
             break;
         case 'unsigned short':
             $returnValue = IntegerType::toUnsignedShort($value);
             break;
         case '[EnforceRange] long':
             $returnValue = IntegerType::toLong($value, '[EnforceRange]');
             break;
         case '[Clamp] long':
             $returnValue = IntegerType::toLong($value, '[Clamp]');
             break;
         case 'long':
             $returnValue = IntegerType::toLong($value);
             break;
         case '[EnforceRange] unsigned long':
             $returnValue = IntegerType::toUnsignedLong($value, '[EnforceRange]');
             break;
         case '[Clamp] unsigned long':
             $returnValue = IntegerType::toUnsignedLong($value, '[Clamp]');
             break;
         case 'unsigned long':
             $returnValue = IntegerType::toUnsignedLong($value);
             break;
         case '[EnforceRange] long long':
             $returnValue = IntegerType::toLongLong($value, '[EnforceRange]');
             break;
         case '[Clamp] long long':
             $returnValue = IntegerType::toLongLong($value, '[Clamp]');
             break;
         case 'long long':
             $returnValue = IntegerType::toLongLong($value);
             break;
         case '[EnforceRange] unsigned long long':
             $returnValue = IntegerType::toUnsignedLongLong($value, '[EnforceRange]');
             break;
         case '[Clamp] unsigned long long':
             $returnValue = IntegerType::toUnsignedLongLong($value, '[Clamp]');
             break;
         case 'unsigned long long':
             $returnValue = IntegerType::toUnsignedLongLong($value);
             break;
         case 'float':
             $returnValue = FloatType::toFloat($value);
             break;
         case 'unrestricted float':
             $returnValue = FloatType::toUnrestrictedFloat($value);
             break;
         case 'double':
             $returnValue = FloatType::toDouble($value);
             break;
         case 'unrestricted double':
             $returnValue = FloatType::toUnrestrictedDouble($value);
             break;
         case 'DOMString':
             $returnValue = StringType::toDOMString($value);
             break;
         case 'ByteString':
             $returnValue = StringType::toByteString($value);
             break;
         case 'USVString':
             $returnValue = StringType::toUSVString($value);
             break;
         case 'object':
             $returnValue = ObjectType::toObject($value);
             break;
         case 'Date':
             $returnValue = ObjectType::toInterface($value, 'DateTimeInterface');
             break;
         case 'RegExp':
             $returnValue = RegExpType::toRegExp($value);
             break;
         case 'Error':
             $returnValue = self::to('(esperecyan\\webidl\\Error or DOMException)', $value, $pseudoTypes);
             break;
         case 'DOMException':
             $returnValue = ObjectType::toInterface($value, 'DOMException');
             break;
         default:
             $pattern = '/^(?:(?<nullable>.+)\\?|sequence<(?<sequence>.+)>|(?<array>.+)\\[]|(?<union>\\(.+\\))|FrozenArray<(?<FrozenArray>.+)>)$/u';
             if (preg_match($pattern, $type, $matches) === 1) {
                 if (!empty($matches['nullable'])) {
                     $returnValue = NullableType::toNullable($value, $matches['nullable'], $pseudoTypes);
                 } elseif (!empty($matches['sequence'])) {
                     $returnValue = SequenceType::toSequence($value, $matches['sequence'], $pseudoTypes);
                 } elseif (!empty($matches['array'])) {
                     $returnValue = SequenceType::toArray($value, $matches['array'], $pseudoTypes);
                 } elseif (!empty($matches['union'])) {
                     $returnValue = UnionType::toUnion($value, $matches['union'], $pseudoTypes);
                 } elseif (!empty($matches['FrozenArray'])) {
                     $returnValue = SequenceType::toFrozenArray($value, $matches['FrozenArray'], $pseudoTypes);
                 }
             } elseif (isset($pseudoTypes[$type])) {
                 $pseudoType = $pseudoTypes[$type];
                 switch ($pseudoType) {
                     case 'callback interface':
                     case 'single operation callback interface':
                         $returnValue = ObjectType::toCallbackInterface($value, $pseudoType === 'single operation callback interface');
                         break;
                     case 'callback function':
                         $returnValue = ObjectType::toCallbackFunction($value);
                         break;
                     default:
                         if (is_string($pseudoType) || isset($pseudoType[0])) {
                             $returnValue = StringType::toEnumerationValue($value, $type, $pseudoType);
                         } else {
                             $returnValue = DictionaryType::toDictionary($value, $type, $pseudoTypes);
                         }
                 }
             } else {
                 $returnValue = ObjectType::toInterface($value, $type);
             }
     }
     return $returnValue;
 }
Beispiel #3
0
 /**
  * 与えられた値を、指定された型のいずれか一つに変換して返します。
  * @link https://heycam.github.io/webidl/#idl-union Web IDL (Second Edition)
  * @link http://www.w3.org/TR/WebIDL/#idl-union Web IDL
  * @link https://heycam.github.io/webidl/#es-union Web IDL (Second Edition)
  * @param mixed $value
  * @param string $unitTypeString 共用体型。先頭、末尾の丸括弧も含む文字列。
  * @param array $pseudoTypes callback interface 型、列挙型、callback 関数型、または dictionary 型の識別子をキーとした型情報の配列。
  * @throws \InvalidArgumentException 指定された型のいずれにも一致しない値が与えられた場合。
  * @throws \DomainException 指定された型のいずれにも一致しない値が与えられた場合。
  * @return mixed
  */
 public static function toUnion($value, $unitTypeString, $pseudoTypes = [])
 {
     $flattenedTypesAndNullableNums = self::getFlattenedTypesAndNullableNums($unitTypeString);
     if ($flattenedTypesAndNullableNums['numberOfNullableMemberTypes'] === 1 && is_null($value)) {
         return null;
     }
     foreach ($flattenedTypesAndNullableNums['flattenedMemberTypes'] as $type) {
         $genericTypes[$type] = self::getGenericType($type, $pseudoTypes);
     }
     if (is_object($value) || $value instanceof \__PHP_Incomplete_Class) {
         foreach (array_keys($genericTypes, 'interface') as $interfaceType) {
             try {
                 return Type::to($interfaceType, $value, $pseudoTypes);
             } catch (\LogicException $exception) {
                 if ($exception instanceof \InvalidArgumentException) {
                     $lastInvalidArgumentException = $exception;
                 } elseif ($exception instanceof \DomainException) {
                     $lastDomainException = $exception;
                 } else {
                     throw $exception;
                 }
             }
         }
         if (isset($genericTypes['object'])) {
             return $value;
         }
     }
     if (RegExpType::isRegExpCastable($value) && isset($genericTypes['RegExp'])) {
         try {
             return RegExpType::toRegExp($value);
         } catch (\LogicException $exception) {
             if ($exception instanceof \DomainException) {
                 $lastDomainException = $exception;
             } else {
                 throw $exception;
             }
         }
     }
     if (is_callable($value) && array_search('callback function', $genericTypes)) {
         return $value;
     }
     try {
         if ((is_array($value) || is_object($value) || $value instanceof \__PHP_Incomplete_Class || is_null($value)) && ($identifier = array_search('dictionary', $genericTypes)) !== false) {
             return DictionaryType::toDictionary($value, $identifier, $pseudoTypes);
         }
         if (is_array($value) || is_object($value) || $value instanceof \__PHP_Incomplete_Class || is_null($value)) {
             $type = array_search('array', $genericTypes) ?: array_search('sequence', $genericTypes) ?: array_search('FrozenArray', $genericTypes);
             if ($type) {
                 return Type::to($type, $value, $pseudoTypes);
             }
             foreach (array_keys($genericTypes, 'interface') as $interfaceType) {
                 if (isset($pseudoTypes[$interfaceType]) && ($pseudoTypes[$interfaceType] === 'callback interface' || $pseudoTypes[$interfaceType] === 'single operation callback interface')) {
                     return Type::to($interfaceType, $value, $pseudoTypes);
                 }
             }
         }
         if (is_bool($value) && isset($genericTypes['boolean'])) {
             return $value;
         }
         if ((is_int($value) || is_float($value)) && ($type = array_search('numeric', $genericTypes))) {
             return Type::to($type, $value);
         }
         if ($type = array_search('string', $genericTypes) ?: array_search('numeric', $genericTypes)) {
             return Type::to($type, $value, $pseudoTypes);
         }
         if (isset($genericTypes['boolean'])) {
             return BooleanType::toBoolean($value);
         }
     } catch (\LogicException $exception) {
         if ($exception instanceof \InvalidArgumentException) {
             $lastInvalidArgumentException = $exception;
         } elseif ($exception instanceof \DomainException) {
             $lastDomainException = $exception;
         } else {
             throw $exception;
         }
     }
     $errorMessage = ErrorMessageCreator::create($value, $unitTypeString);
     if (isset($lastDomainException)) {
         throw new \DomainException($errorMessage, 0, $lastDomainException);
     } elseif (isset($lastInvalidArgumentException)) {
         throw new \InvalidArgumentException($errorMessage, 0, $lastInvalidArgumentException);
     } else {
         throw new \InvalidArgumentException($errorMessage);
     }
 }