{"action":"created","issue":{"url":"https://api.github.com/repos/Roave/BetterReflection/issues/64","labels_url":"https://api.github.com/repos/Roave/BetterReflection/issues/64/labels{/name}","comments_url":"https://api.github.com/repos/Roave/BetterReflection/issues/64/comments","events_url":"https://api.github.com/repos/Roave/BetterReflection/issues/64/events","html_url":"https://github.com/Roave/BetterReflection/issues/64","id":95131862,"number":64,"title":"CompileNodeToValue: compile complex expressions","user":{"login":"asgrim","id":496145,"avatar_url":"https://avatars.githubusercontent.com/u/496145?v=3","gravatar_id":"","url":"https://api.github.com/users/asgrim","html_url":"https://github.com/asgrim","followers_url":"https://api.github.com/users/asgrim/followers","following_url":"https://api.github.com/users/asgrim/following{/other_user}","gists_url":"https://api.github.com/users/asgrim/gists{/gist_id}","starred_url":"https://api.github.com/users/asgrim/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/asgrim/subscriptions","organizations_url":"https://api.github.com/users/asgrim/orgs","repos_url":"https://api.github.com/users/asgrim/repos","events_url":"https://api.github.com/users/asgrim/events{/privacy}","received_events_url":"https://api.github.com/users/asgrim/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/Roave/BetterReflection/labels/bug","name":"bug","color":"fc2929"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/Roave/BetterReflection/milestones/1","html_url":"https://github.com/Roave/BetterReflection/milestones/1.0.0","labels_url":"https://api.github.com/repos/Roave/BetterReflection/milestones/1/labels","id":1187129,"number":1,"title":"1.0.0","description":"","creator":{"login":"asgrim","id":496145,"avatar_url":"https://avatars.githubusercontent.com/u/496145?v=3","gravatar_id":"","url":"https://api.github.com/users/asgrim","html_url":"https://github.com/asgrim","followers_url":"https://api.github.com/users/asgrim/followers","following_url":"https://api.github.com/users/asgrim/following{/other_user}","gists_url":"https://api.github.com/users/asgrim/gists{/gist_id}","starred_url":"https://api.github.com/users/asgrim/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/asgrim/subscriptions","organizations_url":"https://api.github.com/users/asgrim/orgs","repos_url":"https://api.github.com/users/asgrim/repos","events_url":"https://api.github.com/users/asgrim/events{/privacy}","received_events_url":"https://api.github.com/users/asgrim/received_events","type":"User","site_admin":false},"open_issues":11,"closed_issues":55,"state":"open","created_at":"2015-06-30T13:57:38Z","updated_at":"2015-07-26T19:49:31Z","due_on":null,"closed_at":null},"comments":2,"created_at":"2015-07-15T08:12:46Z","updated_at":"2015-07-26T20:03:49Z","closed_at":null,"body":"e.g. stuff like `[\"foo\".\"bar\" => 2 * 3]`\r\n\r\nThey are constant expressions, but currently not supported."},"comment":{"url":"https://api.github.com/repos/Roave/BetterReflection/issues/comments/125033934","html_url":"https://github.com/Roave/BetterReflection/issues/64#issuecomment-125033934","issue_url":"https://api.github.com/repos/Roave/BetterReflection/issues/64","id":125033934,"user":{"login":"asgrim","id":496145,"avatar_url":"https://avatars.githubusercontent.com/u/496145?v=3","gravatar_id":"","url":"https://api.github.com/users/asgrim","html_url":"https://github.com/asgrim","followers_url":"https://api.github.com/users/asgrim/followers","following_url":"https://api.github.com/users/asgrim/following{/other_user}","gists_url":"https://api.github.com/users/asgrim/gists{/gist_id}","starred_url":"https://api.github.com/users/asgrim/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/asgrim/subscriptions","organizations_url":"https://api.github.com/users/asgrim/orgs","repos_url":"https://api.github.com/users/asgrim/repos","events_url":"https://api.github.com/users/asgrim/events{/privacy}","received_events_url":"https://api.github.com/users/asgrim/received_events","type":"User","site_admin":false},"created_at":"2015-07-26T20:03:49Z","updated_at":"2015-07-26T20:03:49Z","body":"@ircmaxell I'd love it if you had any feedback on what the best way to implement this may be.\r\n\r\nTo summarise, given that we have an AST node (that represents a value):\r\n\r\n```php\r\npublic function foo($x = null) {\r\n```\r\n\r\nCurrently we have this [current CompileNodeToValue.php](https://github.com/Roave/BetterReflection/blob/336d9aa95e703907dd8e2f17ea8d3947796ed1f6/src/NodeCompiler/CompileNodeToValue.php)\r\n\r\nWhich takes the AST node (representing `null` in the example above), and evaluating `null` is pretty simple (it is a `ConstNode` so we can just return the value `null`).\r\n\r\nHowever, it starts to get a little more complicated if you have an expression, e.g.:\r\n\r\n```php\r\n5 + (self::FOO * 3)\r\n```\r\n\r\nThe AST tree needs to essentially be \"compiled\" now (beyond the rudimentary switch we have currently). The current proposal we have is in [proposed CompileNodeToValue.php](https://github.com/Roave/BetterReflection/blob/a79162c1dd1079e6ac468d0a25e601c47e65aa68/src/NodeCompiler/CompileNodeToValue.php) (part of PR #67), but basically uses the `PhpParser` printer to render PHP code (for whitelisted nodes) and then `eval()`'s the statement...\r\n\r\nThe main issues at the moment with this approach is:\r\n\r\n* `ClassConstFetch` and `ConstFetch` (that isn't `true|false|null`) are difficult to evaluate - contextual information is required to do this. We've discussed this in issue #19 and feel that the best solution at the moment is to only resolve `ClassConstFetch`, otherwise there's a big rabbit hole. Bear in mind we could potentially be very limited to the scope we are able to look for defined constants for example (e.g. if we only have the source code of a single file, but the constant defined in a different file to that which we are reflecting from, then we would not be able to evaluate the constant).\r\n* This code in #67 uses `eval()`... despite using a white list, I still feel uncomfortable using `eval()` to do this, although I'm not sure if there are any other approaches...\r\n\r\nIf you have any moments spare, I'd love it if we could pick your brains on this one! Thanks so much :)"}}