{"action":"created","comment":{"url":"https://api.github.com/repos/intellij-rust/intellij-rust/pulls/comments/61308871","id":61308871,"diff_hunk":"@@ -1,10 +1,19 @@\n package org.rust.lang.core.psi.visitors\n \n+import com.intellij.psi.PsiFile\n import org.rust.lang.core.psi.RustLiteral\n import org.rust.lang.core.psi.RustVisitor\n+import org.rust.lang.core.psi.impl.RustFile\n \n open class RustVisitorEx : RustVisitor() {\n     open fun visitLiteral(literal: RustLiteral) = visitElement(literal)\n     open fun visitNumericLiteral(literal: RustLiteral.Number) = visitLiteral(literal)\n     open fun visitTextLiteral(literal: RustLiteral.Text) = visitLiteral(literal)\n+    open fun visitRustFile(file: RustFile) {\n+        super.visitFile(file)\n+    }\n+\n+    override fun visitFile(file: PsiFile) {\n+        if (file is RustFile) visitRustFile(file) else super.visitFile(file)\n+    }","path":"src/main/kotlin/org/rust/lang/core/psi/visitors/RustVisitorEx.kt","position":18,"original_position":18,"commit_id":"94427f82c497ad5489bb0709757576703fe5f168","original_commit_id":"94427f82c497ad5489bb0709757576703fe5f168","user":{"login":"jajakobyly","id":3450050,"avatar_url":"https://avatars.githubusercontent.com/u/3450050?v=3","gravatar_id":"","url":"https://api.github.com/users/jajakobyly","html_url":"https://github.com/jajakobyly","followers_url":"https://api.github.com/users/jajakobyly/followers","following_url":"https://api.github.com/users/jajakobyly/following{/other_user}","gists_url":"https://api.github.com/users/jajakobyly/gists{/gist_id}","starred_url":"https://api.github.com/users/jajakobyly/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jajakobyly/subscriptions","organizations_url":"https://api.github.com/users/jajakobyly/orgs","repos_url":"https://api.github.com/users/jajakobyly/repos","events_url":"https://api.github.com/users/jajakobyly/events{/privacy}","received_events_url":"https://api.github.com/users/jajakobyly/received_events","type":"User","site_admin":false},"body":"`visitRustFile` looks to be just a convenience method. It could be easily removed and that `if (file is RustFile) ...` pattern could be used instead. I don't see any disadvantages of this other than you have to be careful when override `visitFile`, which probably will never happen having in mind that this is `RustVisitorEx`","created_at":"2016-04-27T18:14:35Z","updated_at":"2016-04-27T18:14:35Z","html_url":"https://github.com/intellij-rust/intellij-rust/pull/359#discussion_r61308871","pull_request_url":"https://api.github.com/repos/intellij-rust/intellij-rust/pulls/359","_links":{"self":{"href":"https://api.github.com/repos/intellij-rust/intellij-rust/pulls/comments/61308871"},"html":{"href":"https://github.com/intellij-rust/intellij-rust/pull/359#discussion_r61308871"},"pull_request":{"href":"https://api.github.com/repos/intellij-rust/intellij-rust/pulls/359"}}},"pull_request":{"url":"https://api.github.com/repos/intellij-rust/intellij-rust/pulls/359","id":68095358,"html_url":"https://github.com/intellij-rust/intellij-rust/pull/359","diff_url":"https://github.com/intellij-rust/intellij-rust/pull/359.diff","patch_url":"https://github.com/intellij-rust/intellij-rust/pull/359.patch","issue_url":"https://api.github.com/repos/intellij-rust/intellij-rust/issues/359","number":359,"state":"open","locked":false,"title":"Rust mod","user":{"login":"matklad","id":1711539,"avatar_url":"https://avatars.githubusercontent.com/u/1711539?v=3","gravatar_id":"","url":"https://api.github.com/users/matklad","html_url":"https://github.com/matklad","followers_url":"https://api.github.com/users/matklad/followers","following_url":"https://api.github.com/users/matklad/following{/other_user}","gists_url":"https://api.github.com/users/matklad/gists{/gist_id}","starred_url":"https://api.github.com/users/matklad/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matklad/subscriptions","organizations_url":"https://api.github.com/users/matklad/orgs","repos_url":"https://api.github.com/users/matklad/repos","events_url":"https://api.github.com/users/matklad/events{/privacy}","received_events_url":"https://api.github.com/users/matklad/received_events","type":"User","site_admin":false},"body":"This PR refactors the way we handle top-level module in file. Why do we need this?\r\n\r\nWell, currently we have `mod_item` and `file_mod_item { extends = mod_item }`. This has several drawbacks: \r\n\r\n* this is one of the [fragile points](https://github.com/intellij-rust/intellij-rust/blob/master/src/main/kotlin/org/rust/lang/core/grammar/rust.bnf#L300-L301) of our parser.\r\n* we have a semi invariant that Rust file has exactly one child node, and it's type is `RustFileModItem`. This is *semi* because it does not work for comments and docs (#354). It's interesting that if I try to fix this particular issue with the help of `TokenBinders`, I get `NoClassDefFound` error during `generate` phase (this reinforces the \"fragile point\" point)\r\n* the invariant looks kind of strange: if file node has exactly one child, can we just remove it and attach all elements to the file instead?\r\n\r\nMoreover the inheritance itself seems backwards. `mod_item` has more stuff in it then `file_mod_item`, so looks like `mod_item` should extend `file_mod_item`. Alas, `mod_item` already extends `item`, `file_mod_item` is definitely not an item, and we can't extend two parents simultaneously. \r\n\r\nOk, if `A` can't extend `B` and `B` can't extend `C` then why can't we simply introduce an interface `I` and implement it for `A` and `B`? Well, this is exactly what happens here :) \r\n\r\nHere is [the interface](https://github.com/intellij-rust/intellij-rust/blob/rust-mod/src/main/kotlin/org/rust/lang/core/psi/RustMod.kt). It is implemented for `RustFile` and for `RustModItem`. That is, `RustFileModItem` is gone and `RustFile` is used directly (PSI becomes one level more shallow (this is the reason why **every** parsing test result is changed :( ) ) \r\n\r\nI am pretty sure that this implementation is much better then the previous one, but I am not absolutely happy with it either. Particularly, I don't like the amount of changes here, and the introduction of `visitRustFile` visitor method. \r\n\r\n@jajakobyly @alexeykudinkin what do you think about this? ","created_at":"2016-04-27T17:48:23Z","updated_at":"2016-04-27T18:14:35Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5eda2ceab5fdfb37f8262a432ece9d4354961d23","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/intellij-rust/intellij-rust/pulls/359/commits","review_comments_url":"https://api.github.com/repos/intellij-rust/intellij-rust/pulls/359/comments","review_comment_url":"https://api.github.com/repos/intellij-rust/intellij-rust/pulls/comments{/number}","comments_url":"https://api.github.com/repos/intellij-rust/intellij-rust/issues/359/comments","statuses_url":"https://api.github.com/repos/intellij-rust/intellij-rust/statuses/94427f82c497ad5489bb0709757576703fe5f168","head":{"label":"intellij-rust:rust-mod","ref":"rust-mod","sha":"94427f82c497ad5489bb0709757576703fe5f168","user":{"login":"intellij-rust","id":16057867,"avatar_url":"https://avatars.githubusercontent.com/u/16057867?v=3","gravatar_id":"","url":"https://api.github.com/users/intellij-rust","html_url":"https://github.com/intellij-rust","followers_url":"https://api.github.com/users/intellij-rust/followers","following_url":"https://api.github.com/users/intellij-rust/following{/other_user}","gists_url":"https://api.github.com/users/intellij-rust/gists{/gist_id}","starred_url":"https://api.github.com/users/intellij-rust/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/intellij-rust/subscriptions","organizations_url":"https://api.github.com/users/intellij-rust/orgs","repos_url":"https://api.github.com/users/intellij-rust/repos","events_url":"https://api.github.com/users/intellij-rust/events{/privacy}","received_events_url":"https://api.github.com/users/intellij-rust/received_events","type":"Organization","site_admin":false},"repo":{"id":42619487,"name":"intellij-rust","full_name":"intellij-rust/intellij-rust","owner":{"login":"intellij-rust","id":16057867,"avatar_url":"https://avatars.githubusercontent.com/u/16057867?v=3","gravatar_id":"","url":"https://api.github.com/users/intellij-rust","html_url":"https://github.com/intellij-rust","followers_url":"https://api.github.com/users/intellij-rust/followers","following_url":"https://api.github.com/users/intellij-rust/following{/other_user}","gists_url":"https://api.github.com/users/intellij-rust/gists{/gist_id}","starred_url":"https://api.github.com/users/intellij-rust/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/intellij-rust/subscriptions","organizations_url":"https://api.github.com/users/intellij-rust/orgs","repos_url":"https://api.github.com/users/intellij-rust/repos","events_url":"https://api.github.com/users/intellij-rust/events{/privacy}","received_events_url":"https://api.github.com/users/intellij-rust/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/intellij-rust/intellij-rust","description":"Rust IDE built using the IntelliJ Platform","fork":false,"url":"https://api.github.com/repos/intellij-rust/intellij-rust","forks_url":"https://api.github.com/repos/intellij-rust/intellij-rust/forks","keys_url":"https://api.github.com/repos/intellij-rust/intellij-rust/keys{/key_id}","collaborators_url":"https://api.github.com/repos/intellij-rust/intellij-rust/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/intellij-rust/intellij-rust/teams","hooks_url":"https://api.github.com/repos/intellij-rust/intellij-rust/hooks","issue_events_url":"https://api.github.com/repos/intellij-rust/intellij-rust/issues/events{/number}","events_url":"https://api.github.com/repos/intellij-rust/intellij-rust/events","assignees_url":"https://api.github.com/repos/intellij-rust/intellij-rust/assignees{/user}","branches_url":"https://api.github.com/repos/intellij-rust/intellij-rust/branches{/branch}","tags_url":"https://api.github.com/repos/intellij-rust/intellij-rust/tags","blobs_url":"https://api.github.com/repos/intellij-rust/intellij-rust/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/intellij-rust/intellij-rust/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/intellij-rust/intellij-rust/git/refs{/sha}","trees_url":"https://api.github.com/repos/intellij-rust/intellij-rust/git/trees{/sha}","statuses_url":"https://api.github.com/repos/intellij-rust/intellij-rust/statuses/{sha}","languages_url":"https://api.github.com/repos/intellij-rust/intellij-rust/languages","stargazers_url":"https://api.github.com/repos/intellij-rust/intellij-rust/stargazers","contributors_url":"https://api.github.com/repos/intellij-rust/intellij-rust/contributors","subscribers_url":"https://api.github.com/repos/intellij-rust/intellij-rust/subscribers","subscription_url":"https://api.github.com/repos/intellij-rust/intellij-rust/subscription","commits_url":"https://api.github.com/repos/intellij-rust/intellij-rust/commits{/sha}","git_commits_url":"https://api.github.com/repos/intellij-rust/intellij-rust/git/commits{/sha}","comments_url":"https://api.github.com/repos/intellij-rust/intellij-rust/comments{/number}","issue_comment_url":"https://api.github.com/repos/intellij-rust/intellij-rust/issues/comments{/number}","contents_url":"https://api.github.com/repos/intellij-rust/intellij-rust/contents/{+path}","compare_url":"https://api.github.com/repos/intellij-rust/intellij-rust/compare/{base}...{head}","merges_url":"https://api.github.com/repos/intellij-rust/intellij-rust/merges","archive_url":"https://api.github.com/repos/intellij-rust/intellij-rust/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/intellij-rust/intellij-rust/downloads","issues_url":"https://api.github.com/repos/intellij-rust/intellij-rust/issues{/number}","pulls_url":"https://api.github.com/repos/intellij-rust/intellij-rust/pulls{/number}","milestones_url":"https://api.github.com/repos/intellij-rust/intellij-rust/milestones{/number}","notifications_url":"https://api.github.com/repos/intellij-rust/intellij-rust/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/intellij-rust/intellij-rust/labels{/name}","releases_url":"https://api.github.com/repos/intellij-rust/intellij-rust/releases{/id}","deployments_url":"https://api.github.com/repos/intellij-rust/intellij-rust/deployments","created_at":"2015-09-16T23:44:57Z","updated_at":"2016-04-27T12:13:37Z","pushed_at":"2016-04-27T17:48:23Z","git_url":"git://github.com/intellij-rust/intellij-rust.git","ssh_url":"git@github.com:intellij-rust/intellij-rust.git","clone_url":"https://github.com/intellij-rust/intellij-rust.git","svn_url":"https://github.com/intellij-rust/intellij-rust","homepage":null,"size":6857,"stargazers_count":561,"watchers_count":561,"language":"Kotlin","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":41,"mirror_url":null,"open_issues_count":26,"forks":41,"open_issues":26,"watchers":561,"default_branch":"master"}},"base":{"label":"intellij-rust:master","ref":"master","sha":"c63d422ef7aa65dfb61bd2bff144359e8e3533a7","user":{"login":"intellij-rust","id":16057867,"avatar_url":"https://avatars.githubusercontent.com/u/16057867?v=3","gravatar_id":"","url":"https://api.github.com/users/intellij-rust","html_url":"https://github.com/intellij-rust","followers_url":"https://api.github.com/users/intellij-rust/followers","following_url":"https://api.github.com/users/intellij-rust/following{/other_user}","gists_url":"https://api.github.com/users/intellij-rust/gists{/gist_id}","starred_url":"https://api.github.com/users/intellij-rust/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/intellij-rust/subscriptions","organizations_url":"https://api.github.com/users/intellij-rust/orgs","repos_url":"https://api.github.com/users/intellij-rust/repos","events_url":"https://api.github.com/users/intellij-rust/events{/privacy}","received_events_url":"https://api.github.com/users/intellij-rust/received_events","type":"Organization","site_admin":false},"repo":{"id":42619487,"name":"intellij-rust","full_name":"intellij-rust/intellij-rust","owner":{"login":"intellij-rust","id":16057867,"avatar_url":"https://avatars.githubusercontent.com/u/16057867?v=3","gravatar_id":"","url":"https://api.github.com/users/intellij-rust","html_url":"https://github.com/intellij-rust","followers_url":"https://api.github.com/users/intellij-rust/followers","following_url":"https://api.github.com/users/intellij-rust/following{/other_user}","gists_url":"https://api.github.com/users/intellij-rust/gists{/gist_id}","starred_url":"https://api.github.com/users/intellij-rust/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/intellij-rust/subscriptions","organizations_url":"https://api.github.com/users/intellij-rust/orgs","repos_url":"https://api.github.com/users/intellij-rust/repos","events_url":"https://api.github.com/users/intellij-rust/events{/privacy}","received_events_url":"https://api.github.com/users/intellij-rust/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/intellij-rust/intellij-rust","description":"Rust IDE built using the IntelliJ Platform","fork":false,"url":"https://api.github.com/repos/intellij-rust/intellij-rust","forks_url":"https://api.github.com/repos/intellij-rust/intellij-rust/forks","keys_url":"https://api.github.com/repos/intellij-rust/intellij-rust/keys{/key_id}","collaborators_url":"https://api.github.com/repos/intellij-rust/intellij-rust/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/intellij-rust/intellij-rust/teams","hooks_url":"https://api.github.com/repos/intellij-rust/intellij-rust/hooks","issue_events_url":"https://api.github.com/repos/intellij-rust/intellij-rust/issues/events{/number}","events_url":"https://api.github.com/repos/intellij-rust/intellij-rust/events","assignees_url":"https://api.github.com/repos/intellij-rust/intellij-rust/assignees{/user}","branches_url":"https://api.github.com/repos/intellij-rust/intellij-rust/branches{/branch}","tags_url":"https://api.github.com/repos/intellij-rust/intellij-rust/tags","blobs_url":"https://api.github.com/repos/intellij-rust/intellij-rust/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/intellij-rust/intellij-rust/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/intellij-rust/intellij-rust/git/refs{/sha}","trees_url":"https://api.github.com/repos/intellij-rust/intellij-rust/git/trees{/sha}","statuses_url":"https://api.github.com/repos/intellij-rust/intellij-rust/statuses/{sha}","languages_url":"https://api.github.com/repos/intellij-rust/intellij-rust/languages","stargazers_url":"https://api.github.com/repos/intellij-rust/intellij-rust/stargazers","contributors_url":"https://api.github.com/repos/intellij-rust/intellij-rust/contributors","subscribers_url":"https://api.github.com/repos/intellij-rust/intellij-rust/subscribers","subscription_url":"https://api.github.com/repos/intellij-rust/intellij-rust/subscription","commits_url":"https://api.github.com/repos/intellij-rust/intellij-rust/commits{/sha}","git_commits_url":"https://api.github.com/repos/intellij-rust/intellij-rust/git/commits{/sha}","comments_url":"https://api.github.com/repos/intellij-rust/intellij-rust/comments{/number}","issue_comment_url":"https://api.github.com/repos/intellij-rust/intellij-rust/issues/comments{/number}","contents_url":"https://api.github.com/repos/intellij-rust/intellij-rust/contents/{+path}","compare_url":"https://api.github.com/repos/intellij-rust/intellij-rust/compare/{base}...{head}","merges_url":"https://api.github.com/repos/intellij-rust/intellij-rust/merges","archive_url":"https://api.github.com/repos/intellij-rust/intellij-rust/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/intellij-rust/intellij-rust/downloads","issues_url":"https://api.github.com/repos/intellij-rust/intellij-rust/issues{/number}","pulls_url":"https://api.github.com/repos/intellij-rust/intellij-rust/pulls{/number}","milestones_url":"https://api.github.com/repos/intellij-rust/intellij-rust/milestones{/number}","notifications_url":"https://api.github.com/repos/intellij-rust/intellij-rust/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/intellij-rust/intellij-rust/labels{/name}","releases_url":"https://api.github.com/repos/intellij-rust/intellij-rust/releases{/id}","deployments_url":"https://api.github.com/repos/intellij-rust/intellij-rust/deployments","created_at":"2015-09-16T23:44:57Z","updated_at":"2016-04-27T12:13:37Z","pushed_at":"2016-04-27T17:48:23Z","git_url":"git://github.com/intellij-rust/intellij-rust.git","ssh_url":"git@github.com:intellij-rust/intellij-rust.git","clone_url":"https://github.com/intellij-rust/intellij-rust.git","svn_url":"https://github.com/intellij-rust/intellij-rust","homepage":null,"size":6857,"stargazers_count":561,"watchers_count":561,"language":"Kotlin","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":41,"mirror_url":null,"open_issues_count":26,"forks":41,"open_issues":26,"watchers":561,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/intellij-rust/intellij-rust/pulls/359"},"html":{"href":"https://github.com/intellij-rust/intellij-rust/pull/359"},"issue":{"href":"https://api.github.com/repos/intellij-rust/intellij-rust/issues/359"},"comments":{"href":"https://api.github.com/repos/intellij-rust/intellij-rust/issues/359/comments"},"review_comments":{"href":"https://api.github.com/repos/intellij-rust/intellij-rust/pulls/359/comments"},"review_comment":{"href":"https://api.github.com/repos/intellij-rust/intellij-rust/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/intellij-rust/intellij-rust/pulls/359/commits"},"statuses":{"href":"https://api.github.com/repos/intellij-rust/intellij-rust/statuses/94427f82c497ad5489bb0709757576703fe5f168"}}}}