PHP namespace removal / mapping and rewriting identifiers

心不动则不痛 提交于 2019-11-29 23:52:31
NikiC

In an existing question on migration of namespaces to pseudo namespaced code I already introduced a conversion tool I have written as part of a larger project. I haven't maintained this project anymore since that point, but as far as I remember the namespace replacements did work. (I may reimplement this project using a proper parser at some point. Working with plain tokens has proven to be quite a tedious task.)

You will find my implementation of namespace -> pseudo-namespace resolution in the namespace.php. I based the implementation on the namespace resolution rules, which will probably be of help for you, too.

To make this a less blatant readmycodez answer, here the basic steps the code does:

  1. Get the identifier to be resolved and ensure that it is not a class, interface, function or constant declaration (these are resolved in registerClass and registerOther by simply prepending the current namespace with ns separators replaced by underscores).
  2. Determine what type of identifier it is: A class, a function or a constant. (As these need different resolution.)
  3. Make sure we do not resolve the self and parent classes, nor the true, false and null constants.
  4. Resolve aliases (use list):
    1. If the identifier is qualified get the part before the first namespace separator and check whether there exists an alias with that name. If it does, replace the first part with the aliased namespace (now the identifier will be fully qualified). Otherwise prepend the current namespace.
    2. If identifier is unqualified and the identifier type is class, check whether the identifier is an alias and if it is, replace it with the aliased class.
  5. If the identifier is fully qualified now drop the leading namespace separator and replace all other namespace separators with underscores and end this algorithm.
  6. Otherwise:
    1. If we are in the global namespace no further resolution required, thus end this algorithm.
    2. If the identifier type is class prepend the current namespace, replace all NS separators with underscores and end this algorithm.
    3. Otherwise:
      1. If the function / constant is defined globally leave the identifier as is and end this algorithm. (This assumes that no global functions are redefined in a namespace! In my code I don't make this assumption, thus I insert dynamic resolution code.)
      2. Otherwise prepend the current namespace and replace all namespace separators with underscores. (Seems like I got a fault in my code here: I don't do this even if the assumeGlobal flag is set. Instead I always insert the dynamic dispatch code.)

Additional note: Don't forget that one can also write namespace\some\ns. I resolve these constructs in the NS function (which is also responsible for finding namespace declarations).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!