Adding more strict resolving of symbols
This commit is contained in:
parent
4939f05cfc
commit
a73126b3e0
|
@ -10,10 +10,10 @@ class mtgTypeRef implements mtgType
|
|||
private $name;
|
||||
private $file;
|
||||
private $line;
|
||||
private $meta;
|
||||
private $module;
|
||||
private $resolved;
|
||||
|
||||
function __construct($name_or_resolved, mtgMetaInfo $meta = null, $file = '', $line= 0)
|
||||
function __construct($name_or_resolved, mtgMetaParsedModule $module = null, $file = '', $line= 0)
|
||||
{
|
||||
if(is_object($name_or_resolved))
|
||||
{
|
||||
|
@ -22,9 +22,13 @@ class mtgTypeRef implements mtgType
|
|||
$this->resolved = $name_or_resolved;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->name = $name_or_resolved;
|
||||
if(!$module)
|
||||
throw new Exception("Module is not set");
|
||||
}
|
||||
|
||||
$this->meta = $meta;
|
||||
$this->module = $module;
|
||||
$this->file = $file;
|
||||
$this->line = $line;
|
||||
|
||||
|
@ -42,17 +46,23 @@ class mtgTypeRef implements mtgType
|
|||
if($this->resolved)
|
||||
return $this->resolved;
|
||||
|
||||
$u = $this->meta->findUnit($this->name, false/*non strict*/);
|
||||
$u = $this->module->findUnit($this->name);
|
||||
if($u)
|
||||
{
|
||||
$this->resolved = $u->object;
|
||||
return $this->resolved;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("{$this->file}@{$this->line} : Symbol '{$this->name}' not found");
|
||||
}
|
||||
}
|
||||
|
||||
function __toString()
|
||||
{
|
||||
if($this->resolved)
|
||||
return ''.$this->resolved;
|
||||
else
|
||||
return $this->name;
|
||||
}
|
||||
}
|
||||
|
||||
class mtgMetaInfoUnit
|
||||
|
@ -89,12 +99,18 @@ class mtgMetaInfo
|
|||
return $this->units;
|
||||
}
|
||||
|
||||
function findUnit($id, $strict = true)
|
||||
function findUnit($id)
|
||||
{
|
||||
if(isset($this->units[$id]))
|
||||
return $this->units[$id];
|
||||
else if($strict)
|
||||
throw new Exception("Unit '$id' not found");
|
||||
return null;
|
||||
}
|
||||
|
||||
function getUnit($id)
|
||||
{
|
||||
if(isset($this->units[$id]))
|
||||
return $this->units[$id];
|
||||
throw new Exception("Unit '$id' not found");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ class mtgMetaInfoParser
|
|||
private $current_meta;
|
||||
private $parsed_files = array();
|
||||
private $file_stack = array();
|
||||
private $module = null;
|
||||
private $file = "";
|
||||
private $source = "";
|
||||
private $cursor = 0;
|
||||
|
@ -111,7 +112,8 @@ class mtgMetaInfoParser
|
|||
{
|
||||
if(isset($this->parsed_files[$file]))
|
||||
return;
|
||||
$this->parsed_files[$file] = true;
|
||||
$module = new mtgMetaParsedModule($file);
|
||||
$this->parsed_files[$file] = $module;
|
||||
$this->file_stack[] = $file;
|
||||
$source = file_get_contents($file);
|
||||
$is_php = false;
|
||||
|
@ -128,9 +130,7 @@ class mtgMetaInfoParser
|
|||
$is_php = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
self::resolveIncludes($source, $this->config['include_path'], array($this, '_parse'));
|
||||
}
|
||||
$this->_resolveIncludes($module, $source);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
|
@ -142,6 +142,7 @@ class mtgMetaInfoParser
|
|||
if($is_php)
|
||||
return;
|
||||
|
||||
$this->module = $module;
|
||||
$this->file = $file;
|
||||
$this->source = $source;
|
||||
$this->cursor = 0;
|
||||
|
@ -177,6 +178,13 @@ class mtgMetaInfoParser
|
|||
}
|
||||
}
|
||||
|
||||
private function _parseInclude(mtgMetaParsedModule $module, $file)
|
||||
{
|
||||
$this->_parse($file);
|
||||
|
||||
$module->addInclude($this->parsed_files[$file]);
|
||||
}
|
||||
|
||||
private function _parseSharedTokens(array $tokens)
|
||||
{
|
||||
if(!isset($tokens['shared_tokens']))
|
||||
|
@ -198,17 +206,17 @@ class mtgMetaInfoParser
|
|||
if($this->token == self::T_Func)
|
||||
{
|
||||
$func_type = $this->_parseFuncType();
|
||||
$type = new mtgTypeRef($func_type);
|
||||
$type = new mtgTypeRef($func_type, $this->module, $this->file, $this->line);
|
||||
}
|
||||
else if($this->token == self::T_Identifier)
|
||||
{
|
||||
$type_name = $this->_parseDotName();
|
||||
$type = new mtgTypeRef($type_name, $this->current_meta, $this->file, $this->line);
|
||||
$type = new mtgTypeRef($type_name, $this->module, $this->file, $this->line);
|
||||
}
|
||||
else
|
||||
{
|
||||
$type_name = $this->attribute;
|
||||
$type = new mtgTypeRef(new mtgBuiltinType($type_name));
|
||||
$type = new mtgTypeRef(new mtgBuiltinType($type_name), $this->module, $this->file, $this->line);
|
||||
$this->_next();
|
||||
}
|
||||
|
||||
|
@ -216,7 +224,7 @@ class mtgMetaInfoParser
|
|||
{
|
||||
$this->_next();
|
||||
$this->_checkThenNext(']');
|
||||
$type = new mtgTypeRef(new mtgArrType($type));
|
||||
$type = new mtgTypeRef(new mtgArrType($type), $this->module, $this->file, $this->line);
|
||||
}
|
||||
$types[] = $type;
|
||||
|
||||
|
@ -229,7 +237,7 @@ class mtgMetaInfoParser
|
|||
}
|
||||
|
||||
if(sizeof($types) > 1)
|
||||
return new mtgTypeRef(new mtgMultiType($types));
|
||||
return new mtgTypeRef(new mtgMultiType($types), $this->module, $this->file, $this->line);
|
||||
else
|
||||
return $types[0];
|
||||
}
|
||||
|
@ -270,15 +278,17 @@ class mtgMetaInfoParser
|
|||
return $ftype;
|
||||
}
|
||||
|
||||
static function resolveIncludes(&$text, array $include_paths, $callback)
|
||||
{
|
||||
private function _resolveIncludes(mtgMetaParsedModule $module, &$text)
|
||||
{
|
||||
$include_paths = $this->config['include_path'];
|
||||
|
||||
$result = array();
|
||||
$lines = explode("\n", $text);
|
||||
foreach($lines as $line)
|
||||
{
|
||||
if(preg_match('~^#include\s+(\S+)~', $line, $m))
|
||||
{
|
||||
self::processInclude($m[1], $include_paths, $callback);
|
||||
$this->_processInclude($module, $m[1], $include_paths);
|
||||
$result[] = "";
|
||||
}
|
||||
else
|
||||
|
@ -287,7 +297,7 @@ class mtgMetaInfoParser
|
|||
$text = implode("\n", $result);
|
||||
}
|
||||
|
||||
static function processInclude($include, array $include_paths, $callback)
|
||||
private function _processInclude(mtgMetaParsedModule $module, $include, array $include_paths)
|
||||
{
|
||||
$file = false;
|
||||
foreach($include_paths as $include_path)
|
||||
|
@ -300,7 +310,7 @@ class mtgMetaInfoParser
|
|||
if($file === false)
|
||||
throw new Exception("#include {$include} can't be resolved(include path is '". implode(':', $include_paths) . "')");
|
||||
|
||||
call_user_func_array($callback, array($file));
|
||||
$this->_parseInclude($module, $file);
|
||||
}
|
||||
|
||||
private function _parseEnumOrValues()
|
||||
|
@ -368,7 +378,7 @@ class mtgMetaInfoParser
|
|||
$existing->object->override($enum);
|
||||
}
|
||||
else
|
||||
$this->current_meta->addUnit(new mtgMetaInfoUnit($this->file, $enum));
|
||||
$this->_addUnit(new mtgMetaInfoUnit($this->file, $enum));
|
||||
}
|
||||
|
||||
private function _parseFields($next_doer)
|
||||
|
@ -483,12 +493,18 @@ class mtgMetaInfoParser
|
|||
return $fn;
|
||||
}
|
||||
|
||||
private function _addUnit(mtgMetaInfoUnit $unit)
|
||||
{
|
||||
$this->current_meta->addUnit($unit);
|
||||
$this->module->addUnit($unit);
|
||||
}
|
||||
|
||||
private function _parseFreeFunc()
|
||||
{
|
||||
$this->_next();
|
||||
$fn = $this->_parseFunc();
|
||||
$fn->setTokens(array_merge($this->shared_tokens, $fn->getTokens()));
|
||||
$this->current_meta->addUnit(new mtgMetaInfoUnit($this->file, $fn));
|
||||
$this->_addUnit(new mtgMetaInfoUnit($this->file, $fn));
|
||||
}
|
||||
|
||||
private function _parseStruct()
|
||||
|
@ -501,7 +517,7 @@ class mtgMetaInfoParser
|
|||
{
|
||||
$this->_next();
|
||||
$parent_name = $this->_checkThenNext(self::T_Identifier);
|
||||
$parent = new mtgTypeRef($parent_name, $this->current_meta, $this->file, $this->line);
|
||||
$parent = new mtgTypeRef($parent_name, $this->module, $this->file, $this->line);
|
||||
}
|
||||
|
||||
$implements = array();
|
||||
|
@ -511,12 +527,12 @@ class mtgMetaInfoParser
|
|||
{
|
||||
$this->_next();
|
||||
$if_name = $this->_checkThenNext(self::T_Identifier);
|
||||
$implements[] = new mtgTypeRef($if_name, $this->current_meta, $this->file, $this->line);
|
||||
$implements[] = new mtgTypeRef($if_name, $this->module, $this->file, $this->line);
|
||||
} while($this->token == ord(','));
|
||||
}
|
||||
|
||||
$s = new mtgMetaStruct($name, array(), $parent, array(), $implements);
|
||||
$this->current_meta->addUnit(new mtgMetaInfoUnit($this->file, $s));
|
||||
$this->_addUnit(new mtgMetaInfoUnit($this->file, $s));
|
||||
|
||||
$tokens = $this->shared_tokens;
|
||||
if($this->token == self::T_Prop)
|
||||
|
@ -553,7 +569,7 @@ class mtgMetaInfoParser
|
|||
$name = $this->_parseDotName();
|
||||
|
||||
$s = new mtgMetaInterface($name);
|
||||
$this->current_meta->addUnit(new mtgMetaInfoUnit($this->file, $s));
|
||||
$this->_addUnit(new mtgMetaInfoUnit($this->file, $s));
|
||||
|
||||
$tokens = $this->shared_tokens;
|
||||
if($this->token == self::T_Prop)
|
||||
|
@ -590,7 +606,7 @@ class mtgMetaInfoParser
|
|||
$rsp->setFields($rsp_fields);
|
||||
|
||||
$rpc = new mtgMetaRPC("RPC_$name", $code, $req, $rsp, $tokens);
|
||||
$this->current_meta->addUnit(new mtgMetaInfoUnit($this->file, $rpc));
|
||||
$this->_addUnit(new mtgMetaInfoUnit($this->file, $rpc));
|
||||
}
|
||||
|
||||
private function _parsePropTokens()
|
||||
|
@ -861,6 +877,42 @@ class mtgMetaInfoParser
|
|||
}
|
||||
}
|
||||
|
||||
class mtgMetaParsedModule
|
||||
{
|
||||
public $file;
|
||||
public $units = array();
|
||||
public $includes = array();
|
||||
|
||||
function __construct($file)
|
||||
{
|
||||
$this->file = $file;
|
||||
}
|
||||
|
||||
function addUnit(mtgMetaInfoUnit $unit)
|
||||
{
|
||||
$this->units[$unit->object->getId()] = $unit;
|
||||
}
|
||||
|
||||
function findUnit($id)
|
||||
{
|
||||
if(isset($this->units[$id]))
|
||||
return $this->units[$id];
|
||||
|
||||
foreach($this->includes as $include)
|
||||
{
|
||||
if(isset($include->units[$id]))
|
||||
return $include->units[$id];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function addInclude(mtgMetaParsedModule $include)
|
||||
{
|
||||
$this->includes[] = $include;
|
||||
}
|
||||
}
|
||||
|
||||
function mtg_parse_meta(array $meta_srcs, $valid_tokens = null, $inc_path = null)
|
||||
{
|
||||
if($inc_path === null)
|
||||
|
|
Loading…
Reference in New Issue