Inferring during transpilation
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 25/100
Línea de trabajo
Start with the provided main.php reproducer and run the shown kphp compilation command. Investigate constant-condition handling and type inference for the ternary involving KPHP_VERSION, then verify that the single-line assignment compiles while preserving the KPHP branch and PHP branch behavior.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
If I do someting like:
EmulatedEnumInt.php:
<?php
class EmulatedEnumInt {
protected int $value;
protected function __construct(int $value) {
$this->value = $value;
}
public function __toString() : string {
return (string) $this->value;
}
}
CfgType.php:
<?php
#ifndef KPHP
enum CfgType : int {
case STRING = 1;
case INT = 2;
case BOOL = 3;
case ARRAY = 4;
}
if (false) {
#endif
final class CfgType extends EmulatedEnumInt
{
const STRING = 1;
const INT = 2;
const BOOL = 3;
const ARRAY = 4;
// GENERATED
public static function STRING() : static {
return new static(1);
}
public static function INT() : static {
return new static(2);
}
public static function BOOL() : static {
return new static(3);
}
public static function ARRAY() : static {
return new static(4);
}
private static $fromMap = [
1 => 'STRING',
2 => 'INT',
3 => 'BOOL',
4 => 'ARRAY',
];
public static function tryFrom(string|int $value) : static {
if (isset(self::$fromMap[$value])) return new static(self::$fromMap[$value]);
throw new \Exception("No such enum value:".$value);
}
}
#ifndef KPHP
}
#endif
code.php:
<?php
include_once('CfgType.php');
#ifndef KPHP
/**
* Get a configuration value (PHP VERSION)
*
* (Assumes Config object is already stored in Memcache (in KEY: '___PROJECT_SHORT____CONFIG') )
*
* @param string $settingName
* @param CfgType $type
* @param int $ttl
*
* @return ?int|?string|boolean|array
*/
function cfg(string $settingName, CfgType $type = CfgType::STRING, int $ttl = 86400) {
switch($type) {
case CfgType::STRING:
$value = (time() % 2 === 0) ? NULL : (string)$settingName;
return $value;
case CfgType::INT:
$value = (time() % 2 === 0) ? NULL : (int)80;
return $value;
case CfgType::BOOL:
$value = (time() % 2 === 0) ? NULL : (bool) $settingName;
return $value;
case CfgType::ARRAY:
$value = (time() % 2 === 0) ? NULL : ['foo', 'bar'];
return $value;
}
}
if (false) {
#endif
/**
* Get a configuration value (KPHP VERSION)
*
* (Assumes Config object is already stored in Memcache (in KEY: '___PROJECT_SHORT____CONFIG') )
*
* @param string $settingName
* @param CfgType $type
* @param int $ttl
*
* @return ?int|?string|boolean|array
*/
function cfg(string $settingName, CfgType $type, int $ttl = 86400) {
$value = (string) $type;
switch($value) {
case (string)CfgType::STRING():
$value = (time() % 2 === 0) ? NULL : (string)$settingName;
return $value;
case (string)CfgType::INT():
$value = (time() % 2 === 0) ? NULL : (int)80;
return $value;
case (string)CfgType::BOOL():
$value = (time() % 2 === 0) ? NULL : (bool)$settingName;
return (bool) $settingName;
case (string)CfgType::ARRAY():
$value = (time() % 2 === 0) ? NULL : (array) ['foo', 'bar'];
return $value;
default:
return (string) $settingName.'_default';
}
}
#ifndef KPHP
}
#endif
main.php:
<?php
#ifndef KPHP // PHP
define('KPHP_VERSION', 0);
if (false)
#endif // KPHP
define('KPHP_VERSION', 1);
include('EmulatedEnumInt.php');
include('CfgType.php');
include('code.php');
$user = (KPHP_VERSION) ? cfg('USER', CfgType::STRING()) : cfg('USER', CfgType::STRING);
echo "User=".$user.PHP_EOL;
to cater for the fact that enums are not supported in KPHP (the code base I am trying to convert uses many enums), I would expect the transpiler to be able to deduce that the above statement can be re-written as:
$user = cfg('USER', CfgType::STRING());
since KPHP_VERSION is defined to be 1 when compiling with KPHP (and the else part of the ternary will only be taken when running in a PHP context)
However, if I compile like this:
# kphp main.php --mode server --include-dir $(pwd) -o ./server
I get this error:
Compilation error at stage: Calc actual calls, gen by type-inferer.cpp:53
main.php:14 in global scope
$user = (KPHP_VERSION) ? cfg('USER', CfgType::STRING()) : cfg('USER', CfgType::STRING);
pass int to argument $type of cfg
but it's declared as @param CfgType
main.php:14 in global scope
$user = (KPHP_VERSION) ? cfg('USER', CfgType::STRING()) : cfg('USER', CfgType::STRING);
1 is int
apparently because it takes the else part into account ?
I would like to be able to do assignments like ($user = ) on a single line.
However, I am aware that the $user = ... line can be replaced by:
#ifndef KPHP // PHP
$user = cfg('USER', CfgType::STRING);
if (FALSE) { // KPHP
#endif
$user = cfg('USER', CfgType::STRING());
#ifndef KPHP // PHP
}
#endif
but that syntax is rather cumbersome ...
So can't the transpiler be improved in this regard ?
- Lenguaje dominante
- C++
- Estrellas
- 1.5k
- Forks
- 116
- Merge medio
- 5 d 17 h
- PR fusionados (30 d)
- 11
Guía de contribución
No hay ninguna guía de contribución indexada para este repositorio
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de VKCOM/kphp
-
PK85MSHQ0000089200087465 Abierto
Dificultad 5/5 Más de una semana Aptitud para principiantes 10/100
-
Khan Abierto
Dificultad 5/5 Más de una semana Aptitud para principiantes 10/100
-
.github/CODEOWNERS Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 25/100
-
Dificultad 4/5 3-5 días Aptitud para principiantes 32/100
-
Dificultad 4/5 3-5 días Aptitud para principiantes 25/100
Todos los issues de VKCOM/kphp
Issues similares
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 90/100
AXERA-TECH/ax-llm#77 ·
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 90/100
games-on-whales/wolf#509 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
-
bug-unconfirmed
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100