Adding initial support for partial services via @service_partial, also support for service local structs; Restoring tests
Publish PHP Package / docker (push) Successful in 7s
Details
Publish PHP Package / docker (push) Successful in 7s
Details
This commit is contained in:
parent
497c6b6b0b
commit
3bcf6c8ad2
|
@ -7,7 +7,28 @@ interface mtgType
|
|||
|
||||
interface mtgScope
|
||||
{
|
||||
function findSymbol($name);
|
||||
function findSymbol(string $name) : ?mtgMetaUnit;
|
||||
}
|
||||
|
||||
class mtgMultiScope implements mtgScope
|
||||
{
|
||||
private array $scopes = array();
|
||||
|
||||
function addScope(mtgScope $scope)
|
||||
{
|
||||
$this->scopes[] = $scope;
|
||||
}
|
||||
|
||||
function findSymbol(string $name) : ?mtgMetaUnit
|
||||
{
|
||||
foreach($this->scopes as $scope)
|
||||
{
|
||||
$unit = $scope->findSymbol($name);
|
||||
if($unit)
|
||||
return $unit;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class mtgTypeRef implements mtgType
|
||||
|
@ -583,22 +604,35 @@ class mtgMetaRPC extends mtgMetaUnit
|
|||
|
||||
class mtgMetaService extends mtgMetaUnit implements mtgScope
|
||||
{
|
||||
private $name;
|
||||
private $parent_scope;
|
||||
private string $name;
|
||||
//for partial services
|
||||
private mtgMultiScope $parent_scope;
|
||||
private $rpcs = array();
|
||||
private $events = array();
|
||||
private $user_types = array();
|
||||
|
||||
function __construct($name, mtgScope $parent_scope, array $tokens = array())
|
||||
function __construct(string $name, mtgScope $parent_scope, array $tokens = array())
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->parent_scope = $parent_scope;
|
||||
$this->parent_scope = new mtgMultiScope();
|
||||
$this->parent_scope->addScope($parent_scope);
|
||||
$this->tokens = $tokens;
|
||||
}
|
||||
|
||||
function getParentScope() : mtgScope
|
||||
{
|
||||
return $this->parent_scope;
|
||||
}
|
||||
|
||||
function validate(mtgMetaInfo $meta) {}
|
||||
|
||||
function getName()
|
||||
function addPartial(mtgMetaService $service)
|
||||
{
|
||||
$this->setTokens(array_merge($this->getTokens(), $service->getTokens()));
|
||||
$this->parent_scope->addScope($service->getParentScope());
|
||||
}
|
||||
|
||||
function getName() : string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
@ -608,7 +642,7 @@ class mtgMetaService extends mtgMetaUnit implements mtgScope
|
|||
return $this->name;
|
||||
}
|
||||
|
||||
function findSymbol($name)
|
||||
function findSymbol(string $name) : ?mtgMetaUnit
|
||||
{
|
||||
if(isset($this->user_types[$name]))
|
||||
return $this->user_types[$name];
|
||||
|
@ -635,12 +669,12 @@ class mtgMetaService extends mtgMetaUnit implements mtgScope
|
|||
$this->rpcs[$rpc->getName()] = $rpc;
|
||||
}
|
||||
|
||||
function hasRPC($name)
|
||||
function hasRPC(string $name) : bool
|
||||
{
|
||||
return isset($this->rpcs[$name]);
|
||||
}
|
||||
|
||||
function getRPC($name)
|
||||
function getRPC(string $name) : mtgMetaRPC
|
||||
{
|
||||
if(!isset($this->rpcs[$name]))
|
||||
throw new Exception("No such RPC '$name'");
|
||||
|
@ -660,12 +694,12 @@ class mtgMetaService extends mtgMetaUnit implements mtgScope
|
|||
$this->user_types[$utype->getName()] = $utype;
|
||||
}
|
||||
|
||||
function hasUserType($name)
|
||||
function hasUserType(string $name) : bool
|
||||
{
|
||||
return isset($this->user_types[$name]);
|
||||
}
|
||||
|
||||
function getUserType($name)
|
||||
function getUserType(bool $name) : mtgUserType
|
||||
{
|
||||
if(!isset($this->user_types[$name]))
|
||||
throw new Exception("No such user type '$name'");
|
||||
|
@ -683,7 +717,7 @@ class mtgMetaService extends mtgMetaUnit implements mtgScope
|
|||
return $this->events;
|
||||
}
|
||||
|
||||
function getClassId()
|
||||
function getClassId() : int
|
||||
{
|
||||
if($this->hasToken('class_id'))
|
||||
return $this->getToken('class_id');
|
||||
|
|
|
@ -26,7 +26,7 @@ class mtgMetaParsedModule implements mtgScope
|
|||
$this->units[$unit->object->getMetaId()] = $unit;
|
||||
}
|
||||
|
||||
function findSymbol($name)
|
||||
function findSymbol(string $name) : ?mtgMetaUnit
|
||||
{
|
||||
$unit = $this->findUnit($name);
|
||||
if(!$unit)
|
||||
|
|
|
@ -127,6 +127,7 @@ class mtgMetaInfoParser implements mtgIMetaInfoParser
|
|||
$config['valid_tokens'][] = 'shared_tokens';
|
||||
$config['valid_tokens'][] = 'enum_override';
|
||||
$config['valid_tokens'][] = 'enum_replace';
|
||||
$config['valid_tokens'][] = 'service_partial';
|
||||
}
|
||||
|
||||
function parse(mtgMetaInfo $meta, string $raw_file)
|
||||
|
@ -358,7 +359,7 @@ class mtgMetaInfoParser implements mtgIMetaInfoParser
|
|||
return $values;
|
||||
}
|
||||
|
||||
private function _parseEnum($is_global = true)
|
||||
private function _parseEnum($is_global = true) : mtgMetaEnum
|
||||
{
|
||||
$this->_nextT();
|
||||
$name = $this->_parseDotName();
|
||||
|
@ -399,11 +400,11 @@ class mtgMetaInfoParser implements mtgIMetaInfoParser
|
|||
|
||||
$existing = $this->current_meta->findUnit($enum->getMetaId());
|
||||
if(!$existing)
|
||||
throw new Exception("Not found '{$name}' enum to override values");
|
||||
$this->_error("Not found '{$name}' enum to override values");
|
||||
if(!($existing->object instanceof mtgMetaEnum))
|
||||
throw new Exception("Not an enum struct '{$name}'");
|
||||
|
||||
$existing->object->override($enum);
|
||||
$this->_error("Not an enum struct '{$name}'");
|
||||
else
|
||||
$existing->object->override($enum);
|
||||
}
|
||||
//NOTE: special case for enums when we allow to 'replace' the original one,
|
||||
// with additional values
|
||||
|
@ -414,11 +415,11 @@ class mtgMetaInfoParser implements mtgIMetaInfoParser
|
|||
|
||||
$existing = $this->current_meta->findUnit($enum->getMetaId());
|
||||
if(!$existing)
|
||||
throw new Exception("Not found '{$name}' enum to replace values");
|
||||
$this->_error("Not found '{$name}' enum to replace values");
|
||||
if(!($existing->object instanceof mtgMetaEnum))
|
||||
throw new Exception("Not an enum struct '{$name}'");
|
||||
|
||||
$existing->object->replace($enum);
|
||||
$this->_error("Not an enum struct '{$name}'");
|
||||
else
|
||||
$existing->object->replace($enum);
|
||||
}
|
||||
else if($is_global)
|
||||
$this->_addUnit(new mtgMetaInfoUnit($this->module, $enum));
|
||||
|
@ -575,7 +576,7 @@ class mtgMetaInfoParser implements mtgIMetaInfoParser
|
|||
$this->_addUnit(new mtgMetaInfoUnit($this->module, $fn));
|
||||
}
|
||||
|
||||
private function _parseStruct()
|
||||
private function _parseStruct($is_global = true) : mtgMetaStruct
|
||||
{
|
||||
$this->_nextT();
|
||||
$struct_origin = new mtgOrigin($this->file, $this->line);
|
||||
|
@ -604,7 +605,9 @@ class mtgMetaInfoParser implements mtgIMetaInfoParser
|
|||
|
||||
$s = new mtgMetaStruct($name, array(), $parent, array(), $implements);
|
||||
$s->setOrigin($struct_origin);
|
||||
$this->_addUnit(new mtgMetaInfoUnit($this->module, $s));
|
||||
|
||||
if($is_global)
|
||||
$this->_addUnit(new mtgMetaInfoUnit($this->module, $s));
|
||||
|
||||
$tokens = $this->shared_tokens;
|
||||
if($this->T == self::T_Prop)
|
||||
|
@ -633,6 +636,8 @@ class mtgMetaInfoParser implements mtgIMetaInfoParser
|
|||
foreach($funcs as $fn)
|
||||
$s->addFunc($fn);
|
||||
}
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
private function _parseInterface()
|
||||
|
@ -659,7 +664,7 @@ class mtgMetaInfoParser implements mtgIMetaInfoParser
|
|||
$this->_nextT();
|
||||
}
|
||||
|
||||
private function _parseRPC($is_global = true)
|
||||
private function _parseRPC($is_global = true) : mtgMetaRPC
|
||||
{
|
||||
$this->_nextT();
|
||||
$code = $this->T_value;
|
||||
|
@ -704,6 +709,25 @@ class mtgMetaInfoParser implements mtgIMetaInfoParser
|
|||
$tokens = array_merge($tokens, $this->_parsePropTokens());
|
||||
$service->setTokens($tokens);
|
||||
|
||||
$existing = null;
|
||||
if($service->hasToken('service_partial'))
|
||||
{
|
||||
$existing = $this->current_meta->findUnit($service->getMetaId());
|
||||
if($existing)
|
||||
{
|
||||
if(!($existing->object instanceof mtgMetaService))
|
||||
$this->_error("Not a service instance '{$name}'");
|
||||
else
|
||||
{
|
||||
$existing->object->addPartial($service);
|
||||
//let's replace service with the existing one
|
||||
$service = $existing->object;
|
||||
$this->_popScope();
|
||||
$this->_pushScope($service);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while(true)
|
||||
{
|
||||
if($this->_nextIf(self::T_End))
|
||||
|
@ -713,13 +737,16 @@ class mtgMetaInfoParser implements mtgIMetaInfoParser
|
|||
$service->addRPC($this->_parseRPC(false));
|
||||
else if($this->T == self::T_Enum)
|
||||
$service->addUserType($this->_parseEnum(false));
|
||||
else if($this->T == self::T_Struct)
|
||||
$service->addUserType($this->_parseStruct(false));
|
||||
else
|
||||
$this->_error("Unsupported type");
|
||||
}
|
||||
|
||||
$this->_popScope();
|
||||
|
||||
$this->_addUnit(new mtgMetaInfoUnit($this->module, $service));
|
||||
if(!$existing)
|
||||
$this->_addUnit(new mtgMetaInfoUnit($this->module, $service));
|
||||
}
|
||||
|
||||
private function _parsePropTokens() : array
|
||||
|
|
|
@ -127,6 +127,7 @@ class mtgMetaInfoParser2 implements mtgIMetaInfoParser
|
|||
$config['valid_tokens'][] = 'shared_tokens';
|
||||
$config['valid_tokens'][] = 'enum_override';
|
||||
$config['valid_tokens'][] = 'enum_replace';
|
||||
$config['valid_tokens'][] = 'service_partial';
|
||||
}
|
||||
|
||||
function parse(mtgMetaInfo $meta, string $raw_file)
|
||||
|
@ -401,11 +402,11 @@ class mtgMetaInfoParser2 implements mtgIMetaInfoParser
|
|||
|
||||
$existing = $this->current_meta->findUnit($enum->getMetaId());
|
||||
if(!$existing)
|
||||
throw new Exception("Not found '{$name}' enum to override values");
|
||||
$this->_error("Not found '{$name}' enum to override values");
|
||||
if(!($existing->object instanceof mtgMetaEnum))
|
||||
throw new Exception("Not an enum struct '{$name}'");
|
||||
|
||||
$existing->object->override($enum);
|
||||
$this->_error("Not an enum struct '{$name}'");
|
||||
else
|
||||
$existing->object->override($enum);
|
||||
}
|
||||
//NOTE: special case for enums when we allow to 'replace' the original one,
|
||||
// with additional values
|
||||
|
@ -416,11 +417,11 @@ class mtgMetaInfoParser2 implements mtgIMetaInfoParser
|
|||
|
||||
$existing = $this->current_meta->findUnit($enum->getMetaId());
|
||||
if(!$existing)
|
||||
throw new Exception("Not found '{$name}' enum to replace values");
|
||||
$this->_error("Not found '{$name}' enum to replace values");
|
||||
if(!($existing->object instanceof mtgMetaEnum))
|
||||
throw new Exception("Not an enum struct '{$name}'");
|
||||
|
||||
$existing->object->replace($enum);
|
||||
$this->_error("Not an enum struct '{$name}'");
|
||||
else
|
||||
$existing->object->replace($enum);
|
||||
}
|
||||
else if($is_global)
|
||||
$this->_addUnit(new mtgMetaInfoUnit($this->module, $enum));
|
||||
|
@ -744,6 +745,25 @@ class mtgMetaInfoParser2 implements mtgIMetaInfoParser
|
|||
$tokens = array_merge($tokens, $this->_parsePropTokens());
|
||||
$service->setTokens($tokens);
|
||||
|
||||
$existing = null;
|
||||
if($service->hasToken('service_partial'))
|
||||
{
|
||||
$existing = $this->current_meta->findUnit($service->getMetaId());
|
||||
if($existing)
|
||||
{
|
||||
if(!($existing->object instanceof mtgMetaService))
|
||||
$this->_error("Not a service instance '{$name}'");
|
||||
else
|
||||
{
|
||||
$existing->object->addPartial($service);
|
||||
//let's replace service with the existing one
|
||||
$service = $existing->object;
|
||||
$this->_popScope();
|
||||
$this->_pushScope($service);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while(true)
|
||||
{
|
||||
if($this->_nextIf(ord('}')))
|
||||
|
@ -761,7 +781,8 @@ class mtgMetaInfoParser2 implements mtgIMetaInfoParser
|
|||
|
||||
$this->_popScope();
|
||||
|
||||
$this->_addUnit(new mtgMetaInfoUnit($this->module, $service));
|
||||
if(!$existing)
|
||||
$this->_addUnit(new mtgMetaInfoUnit($this->module, $service));
|
||||
}
|
||||
|
||||
private function _parsePropTokens() : array
|
||||
|
|
|
@ -60,3 +60,21 @@ end
|
|||
struct ConfStock
|
||||
id : EnumStock
|
||||
end
|
||||
|
||||
service GameService
|
||||
enum ErrorCode
|
||||
OK = 0
|
||||
Err = 1
|
||||
end
|
||||
|
||||
struct DataPing
|
||||
value : int32
|
||||
end
|
||||
|
||||
RPC 10 PING(
|
||||
value : DataPing
|
||||
)
|
||||
error : ErrorCode
|
||||
value : int32
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,12 +4,15 @@
|
|||
require_once(__DIR__ . '/../metagen.inc.php');
|
||||
require_once(__DIR__ . '/../parser.inc.php');
|
||||
|
||||
assert_options(ASSERT_ACTIVE, true);
|
||||
assert_options(ASSERT_BAIL, true);
|
||||
assert_options(ASSERT_WARNING, true);
|
||||
ini_set('zend.assertions', 1);
|
||||
|
||||
touch(__DIR__ . '/meta/DataAll.meta');
|
||||
$meta = mtg_parse_meta(array(__DIR__ . '/meta/'));
|
||||
//we don't need that right now
|
||||
//touch(__DIR__ . '/meta/DataAll.meta');
|
||||
$meta = mtg_parse_meta(
|
||||
[__DIR__ . '/meta/'],
|
||||
['POD', 'table', 'pkey', 'bhl_ret_type', 'bhl_args',
|
||||
'strmax', 'default', 'virtual'],
|
||||
);
|
||||
|
||||
$u = $meta->findUnit("DataPlayer");
|
||||
assert($u->object instanceof mtgMetaStruct);
|
||||
|
@ -83,3 +86,10 @@ $u = $meta->findUnit("ConfStock");
|
|||
assert($u->object instanceof mtgMetaStruct);
|
||||
assert(sizeof($u->object->getFields()) == 1);
|
||||
assert($u->object->getFields()["id"]->getType() == "EnumStock");
|
||||
|
||||
$u = $meta->findUnit("GameService");
|
||||
assert($u->object instanceof mtgMetaService);
|
||||
|
||||
assert($u->object->getRPC("PING") instanceof mtgMetaRPC);
|
||||
assert($u->object->findSymbol("DataPing") instanceof mtgMetaStruct);
|
||||
assert($u->object->findSymbol("ErrorCode") instanceof mtgMetaEnum);
|
||||
|
|
Loading…
Reference in New Issue