| 227 | |
| 228 | |
| 229 | class PHP(BaseLanguage): |
| 230 | @staticmethod |
| 231 | def assert_dependencies(): |
| 232 | """Assert that php and php-parser are installed""" |
| 233 | assert is_installed('php'), "No php installation could be found" |
| 234 | self_ref = os.path.join(os.path.dirname(os.path.realpath(__file__)), |
| 235 | "get_ast.php") |
| 236 | outp, returncode = run_ast_parser(self_ref) |
| 237 | path = os.path.dirname(os.path.realpath(__file__)) |
| 238 | assert_msg = 'Error running the PHP parser. From the `%s` directory, run ' \ |
| 239 | '`composer require nikic/php-parser "^4.10"`.' % path |
| 240 | assert not returncode, assert_msg |
| 241 | return outp |
| 242 | |
| 243 | @staticmethod |
| 244 | def get_tree(filename, lang_params): |
| 245 | """ |
| 246 | Get the entire AST for this file |
| 247 | |
| 248 | :param filename str: |
| 249 | :param lang_params LanguageParams: |
| 250 | :rtype: ast |
| 251 | """ |
| 252 | |
| 253 | outp, returncode = run_ast_parser(filename) |
| 254 | if returncode: |
| 255 | raise AssertionError( |
| 256 | "Could not parse file %r. You may have a syntax error. " |
| 257 | "For more detail, try running with `php %s`. " % |
| 258 | (filename, filename)) |
| 259 | |
| 260 | tree = json.loads(outp) |
| 261 | assert isinstance(tree, list) |
| 262 | if len(tree) == 1 and tree[0]['nodeType'] == 'Stmt_InlineHTML': |
| 263 | raise AssertionError("Tried to parse a file that is not likely PHP") |
| 264 | return tree |
| 265 | |
| 266 | @staticmethod |
| 267 | def separate_namespaces(tree): |
| 268 | """ |
| 269 | Given a tree element, recursively separate that AST into lists of ASTs for the |
| 270 | subgroups, nodes, and body. This is an intermediate step to allow for |
| 271 | cleaner processing downstream |
| 272 | |
| 273 | :param tree ast: |
| 274 | :returns: tuple of group, node, and body trees. These are processed |
| 275 | downstream into real Groups and Nodes. |
| 276 | :rtype: (list[ast], list[ast], list[ast]) |
| 277 | """ |
| 278 | tree = tree or [] # if its abstract, it comes in with no body |
| 279 | |
| 280 | groups = [] |
| 281 | nodes = [] |
| 282 | body = [] |
| 283 | for el in tree: |
| 284 | if el['nodeType'] in ('Stmt_Function', 'Stmt_ClassMethod', 'Expr_Closure'): |
| 285 | nodes.append(el) |
| 286 | elif el['nodeType'] in ('Stmt_Class', 'Stmt_Namespace', 'Stmt_Trait'): |
nothing calls this directly
no outgoing calls
no test coverage detected