Merge: Minor graphics related fixes and features
authorJean Privat <jean@pryen.org>
Tue, 20 Jan 2015 04:18:57 +0000 (11:18 +0700)
committerJean Privat <jean@pryen.org>
Tue, 20 Jan 2015 04:18:57 +0000 (11:18 +0700)
Pull-Request: #1113
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>

20 files changed:
contrib/nitiwiki/src/wiki_html.nit
contrib/nitiwiki/tests/res/nitiwiki_render.res
contrib/nitiwiki/tests/res/nitiwiki_status.res
lib/cocoa/examples/cocoa_message_box.nit
lib/cocoa/examples/hello_cocoa.nit
lib/github/api.nit
lib/github/events.nit [new file with mode: 0644]
lib/glesv2/examples/opengles2_hello_triangle.nit
src/compiler/compiler.nit
src/compiler/separate_compiler.nit
src/compiler/separate_erasure_compiler.nit
src/doc/doc_down.nit
src/ffi/header_dependency.nit
src/ffi/objc.nit
src/platform/android.nit [moved from src/compiler/android_platform.nit with 99% similarity]
src/platform/android_annotations.nit [moved from src/compiler/android_annotations.nit with 100% similarity]
src/platform/emscripten.nit [moved from src/compiler/emscripten_platform.nit with 97% similarity]
src/platform/platform.nit [moved from src/platform.nit with 100% similarity]
src/platform/pnacl.nit [moved from src/compiler/pnacl_platform.nit with 99% similarity]
tests/sav/opengles2_hello_triangle.res [deleted file]

index 7f213b7..89546ce 100644 (file)
@@ -81,6 +81,7 @@ redef class WikiSection
                end
                var index = self.index
                if index isa WikiSectionIndex then
+                       wiki.message("Render auto-index for section {out_path}", 1)
                        index.is_dirty = true
                        add_child index
                end
@@ -322,6 +323,10 @@ class WikiSectionIndex
        # The section described by `self`.
        var section: WikiSection
 
+       redef fun title do return section.title
+
+       redef fun url do return section.url
+
        redef var is_dirty = false
 
        redef fun tpl_article do
index adf25a7..25f17ab 100644 (file)
@@ -1 +1,6 @@
 Render section out
+Render section out/sec1
+Render section out/sec2
+Render auto-index for section out/sec2
+Render section out/sec2/sub-sec21
+Render section out/sec2/sub-sec22
index 936a764..9eb2262 100644 (file)
@@ -6,5 +6,12 @@ url: http://localhost/
 There is modified files:
  + pages
  + /pages/index.md
+ + pages/sec1
+ + /pages/sec1/index.md
+ + pages/sec2
+ + pages/sec2/sub-sec21
+ + /pages/sec2/sub-sec21/index.md
+ + pages/sec2/sub-sec22
+ + /pages/sec2/sub-sec22/index.md
 
 Use nitiwiki --render to render modified files
index 72e35d7..224c7ab 100644 (file)
@@ -19,10 +19,6 @@ module cocoa_message_box
 
 import cocoa
 
-in "ObjC" `{
-       #import <Cocoa/Cocoa.h>
-`}
-
 fun dialog in "ObjC" `{
        NSAlert *alert = [[[NSAlert alloc] init] autorelease];
        [alert setMessageText:@"Hello world!"];
index 3a2b168..960b001 100644 (file)
@@ -19,10 +19,6 @@ module hello_cocoa
 
 import cocoa::foundation
 
-in "ObjC" `{
-       #import <Foundation/Foundation.h>
-`}
-
 # Print `"Hello world!"` to the log
 fun hello_world in "ObjC" `{
        @autoreleasepool {
index 3e06f52..b979b5d 100644 (file)
@@ -252,6 +252,25 @@ class GithubAPI
                return milestone.load_from_github
        end
 
+       # Get the Github issue event with `id`.
+       #
+       # Returns `null` if the event cannot be found.
+       #
+       #     var api = new GithubAPI(get_github_oauth)
+       #     var repo = api.load_repo("privat/nit")
+       #     assert repo isa Repo
+       #     var event = api.load_issue_event(repo, 199674194)
+       #     assert event.actor.login == "privat"
+       #     assert event.event == "labeled"
+       #     assert event.labl.name == "need_review"
+       #     assert event.issue.number == 945
+       fun load_issue_event(repo: Repo, id: Int): nullable IssueEvent do
+               var event = new IssueEvent(self, repo, id)
+               event.load_from_github
+               if was_error then return null
+               return event
+       end
+
        # Get the Github commit comment with `id`.
        #
        # Returns `null` if the comment cannot be found.
@@ -475,6 +494,19 @@ class Repo
                return res
        end
 
+       # List of contributor related statistics.
+       fun contrib_stats: Array[ContributorStats] do
+               api.message(1, "Get contributor stats for {full_name}")
+               var res = new Array[ContributorStats]
+               var array = api.get("{key}/stats/contributors")
+               if array isa JsonArray then
+                       for obj in array do
+                               res.add new ContributorStats.from_json(api, obj.as(JsonObject))
+                       end
+               end
+               return res
+       end
+
        # Repo default branch.
        fun default_branch: Branch do
                var name = json["default_branch"].to_s
@@ -604,6 +636,17 @@ class Commit
                return new ISODate.from_string(author["date"].to_s)
        end
 
+       # List files staged in this commit.
+       fun files: Array[GithubFile] do
+               var res = new Array[GithubFile]
+               var files = json["files"]
+               if not files isa JsonArray then return res
+               for obj in files do
+                       res.add(new GithubFile(obj.as(JsonObject)))
+               end
+               return res
+       end
+
        # Commit message.
        fun message: String do return json["commit"].as(JsonObject)["message"].to_s
 end
@@ -713,6 +756,22 @@ class Issue
        # Full description of the issue.
        fun body: String  do return json["body"].to_s
 
+       # List of events on this issue.
+       fun events: Array[IssueEvent] do
+               var res = new Array[IssueEvent]
+               var page = 1
+               var array = api.get("{key}/events?page={page}").as(JsonArray)
+               while not array.is_empty do
+                       for obj in array do
+                               if not obj isa JsonObject then continue
+                               res.add new IssueEvent.from_json(api, repo, obj)
+                       end
+                       page += 1
+                       array = api.get("{key}/events?page={page}").as(JsonArray)
+               end
+               return res
+       end
+
        # User that closed this issue (if any).
        fun closed_by: nullable User do
                var closer = json["closed_by"]
@@ -1030,3 +1089,137 @@ class ReviewComment
        # Original commit id.
        fun original_commit_id: String do return json["original_commit_id"].to_s
 end
+
+# An event that occurs on a Github `Issue`.
+#
+# Should be accessed from `GithubAPI::load_issue_event`.
+#
+# See <https://developer.github.com/v3/issues/events/>.
+class IssueEvent
+       super RepoEntity
+
+       redef var key is lazy do return "{repo.key}/issues/events/{id}"
+
+       # Event id on Github.
+       var id: Int
+
+       redef init from_json(api, repo, json) do
+               self.id = json["id"].as(Int)
+               super
+       end
+
+       # Issue that contains `self`.
+       fun issue: Issue do
+               return new Issue.from_json(api, repo, json["issue"].as(JsonObject))
+       end
+
+       # User that initiated the event.
+       fun actor: User do
+               return new User.from_json(api, json["actor"].as(JsonObject))
+       end
+
+       # Creation time in ISODate format.
+       fun created_at: ISODate do
+               return new ISODate.from_string(json["created_at"].to_s)
+       end
+
+       # Event descriptor.
+       fun event: String do return json["event"].to_s
+
+       # Commit linked to this event (if any).
+       fun commit_id: nullable String do
+               var res = json["commit_id"]
+               if res == null then return null
+               return res.to_s
+       end
+
+       # Label linked to this event (if any).
+       fun labl: nullable Label do
+               var res = json["label"]
+               if not res isa JsonObject then return null
+               return new Label.from_json(api, repo, res)
+       end
+
+       # User linked to this event (if any).
+       fun assignee: nullable User do
+               var res = json["assignee"]
+               if not res isa JsonObject then return null
+               return new User.from_json(api, res)
+       end
+
+       # Milestone linked to this event (if any).
+       fun milestone: nullable Milestone do
+               var res = json["milestone"]
+               if not res isa JsonObject then return null
+               return new Milestone.from_json(api, repo, res)
+       end
+
+       # Rename linked to this event (if any).
+       fun rename: nullable RenameAction do
+               var res = json["rename"]
+               if res == null then return null
+               return new RenameAction(res.as(JsonObject))
+       end
+end
+
+# A rename action maintains the name before and after a renaming action.
+class RenameAction
+
+       # JSON content.
+       var json: JsonObject
+
+       # Name before renaming.
+       fun from: String do return json["from"].to_s
+
+       # Name after renaming.
+       fun to: String do return json["to"].to_s
+end
+
+# Contributors list with additions, deletions, and commit counts.
+#
+# Should be accessed from `Repo::contrib_stats`.
+#
+# See <https://developer.github.com/v3/repos/statistics/>.
+class ContributorStats
+       super Comparable
+
+       redef type OTHER: ContributorStats
+
+       # Github API client.
+       var api: GithubAPI
+
+       # Json content.
+       var json: JsonObject
+
+       # Init `self` from a `json` object.
+       init from_json(api: GithubAPI, json: JsonObject) do
+               self.api = api
+               self.json = json
+       end
+
+       # User these statistics are about.
+       fun author: User do
+               return new User.from_json(api, json["author"].as(JsonObject))
+       end
+
+       # Total number of commit.
+       fun total: Int do return json["total"].to_s.to_i
+
+       # Are of weeks of activity with detailed statistics.
+       fun weeks: JsonArray do return json["weeks"].as(JsonArray)
+
+       # ContributorStats can be compared on the total amount of commits.
+       redef fun <(o) do return total < o.total
+end
+
+# A Github file representation.
+#
+# Mostly a wrapper around a json object.
+class GithubFile
+
+       # Json content.
+       var json: JsonObject
+
+       # File name.
+       fun filename: String do return json["filename"].to_s
+end
diff --git a/lib/github/events.nit b/lib/github/events.nit
new file mode 100644 (file)
index 0000000..b6e5af3
--- /dev/null
@@ -0,0 +1,302 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Events are emitted by Github Hooks.
+#
+# See <https://developer.github.com/v3/activity/events/types/>
+module events
+
+import api
+
+# Github event stub.
+class GithubEvent
+
+       # Github API client.
+       var api: GithubAPI
+
+       # Json representation of `self`.
+       var json: JsonObject is noinit
+
+       init do
+               json = new JsonObject
+       end
+
+       # Init `self` from a `json` object.
+       init from_json(api: GithubAPI, json: JsonObject) do
+               self.api = api
+               self.json = json
+       end
+
+       # Action performed by the event.
+       fun action: String do return json["action"].to_s
+
+       # Repo where this event occured.
+       fun repo: Repo do
+               return new Repo.from_json(api, json["repository"].as(JsonObject))
+       end
+end
+
+# Triggered when a commit comment is created.
+class CommitCommentEvent
+       super GithubEvent
+
+       # The `Comment` itself.
+       fun comment: CommitComment do
+               return new CommitComment.from_json(api, repo, json["comment"].as(JsonObject))
+       end
+end
+
+# Triggered when a repository, branch, or tag is created.
+class CreateEvent
+       super GithubEvent
+
+       # Oject type that was created.
+       #
+       # Can be one of `repository`, `branch`, or `tag`.
+       fun ref_type: String do return json["ref_type"].to_s
+
+       # Git ref (or null if only a repository was created).
+       fun ref: String do return json["ref"].to_s
+
+       # Name of the repo's default branch (usually master).
+       fun master_branch: String do return json["master_branch"].to_s
+
+       # Repo's current description.
+       fun description: String do return json["description"].to_s
+end
+
+# Triggered when a branch or a tag is deleted.
+class DeleteEvent
+       super GithubEvent
+
+       # Object type that was deleted.
+       #
+       # Can be one of `repository`, `branch`, or `tag`.
+       fun ref_type: String do return json["ref_type"].to_s
+
+       # Git ref (or null if only a repository was deleted).
+       fun ref: String do return json["ref"].to_s
+end
+
+# Triggered when a new snapshot is deployed.
+#
+# Deployement are mainly used with integration testing servers.
+class DeploymentEvent
+       super GithubEvent
+
+       # Commit SHA for which this deployment was created.
+       fun sha: String do return json["sha"].to_s
+
+       # Name of repository for this deployment, formatted as :owner/:repo.
+       fun name: String do return json["name"].to_s
+
+       # Optional extra information for this deployment.
+       fun payload: nullable String do
+               if not json.has_key("payload") then return null
+               return json["payload"].to_s
+       end
+
+       # Optional environment to deploy to.
+       # Default: "production"
+       fun environment: nullable String do
+               if not json.has_key("environment") then return null
+               return json["environment"].to_s
+       end
+
+       # Optional human-readable description added to the deployment.
+       fun description: nullable String do
+               if not json.has_key("description") then return null
+               return json["description"].to_s
+       end
+end
+
+# Triggered when a deployement's status changes.
+class DeploymentStatusEvent
+       super GithubEvent
+
+       # New deployment state.
+       #
+       # Can be `pending`, `success`, `failure`, or `error`.
+       fun state: String do return json["state"].to_s
+
+       # Optional link added to the status.
+       fun target_url: nullable String do
+               if not json.has_key("target_url") then return null
+               return json["target_url"].to_s
+       end
+
+       # Deployment hash that this status is associated with.
+       fun deployment: String do return json["deployment"].to_s
+
+       # Optional human-readable description added to the status.
+       fun description: nullable String do
+               if not json.has_key("description") then return null
+               return json["description"].to_s
+       end
+end
+
+# Triggered when a user forks a repository.
+class ForkEvent
+       super GithubEvent
+
+       # Created repository.
+       fun forkee: Repo do return new Repo.from_json(api, json["forkee"].as(JsonObject))
+end
+
+# Triggered when an issue comment is created.
+class IssueCommentEvent
+       super GithubEvent
+
+       # `Issue` the comment belongs to.
+       fun issue: Issue do
+               return new Issue.from_json(api, repo, json["issue"].as(JsonObject))
+       end
+
+       # The `Comment` itself.
+       fun comment: IssueComment do
+               return new IssueComment.from_json(api, repo, json["comment"].as(JsonObject))
+       end
+end
+
+# Triggered when an event occurs on an issue.
+#
+# Triggered when an issue is assigned, unassigned, labeled, unlabeled,
+# opened, closed or reopened.
+class IssuesEvent
+       super GithubEvent
+
+       # The `Issue` itself.
+       fun issue: Issue do return new Issue.from_json(api, repo, json["issue"].as(JsonObject))
+
+       # Optional `Label` that was added or removed from the issue.
+       fun lbl: nullable Label do
+               if not json.has_key("label") then return null
+               return new Label.from_json(api, repo, json["label"].as(JsonObject))
+       end
+
+       # Optional `User` that was assigned or unassigned from the issue.
+       fun assignee: nullable User do
+               if not json.has_key("assignee") then return null
+               return new User.from_json(api, json["assignee"].as(JsonObject))
+       end
+end
+
+# Triggered when a user is added as a collaborator to a repository.
+class MemberEvent
+       super GithubEvent
+
+       # `User` that was added.
+       fun member: User do return new User.from_json(api, json["member"].as(JsonObject))
+end
+
+# Triggered when an event occurs on a pull request.
+#
+# Triggered when a pull request is assigned, unassigned,
+# labeled, unlabeled, opened, closed, reopened, or synchronized.
+class PullRequestEvent
+       super GithubEvent
+
+       # The pull request number.
+       fun number: Int do return json["number"].as(Int)
+
+       # The `PullRequest` itself.
+       fun pull: PullRequest do
+               return new PullRequest.from_json(api, repo, json["pull_request"].as(JsonObject))
+       end
+end
+
+# Triggered when a comment is created on a pull request diff.
+class PullRequestReviewCommentEvent
+       super GithubEvent
+
+       # The `Comment` itself.
+       fun comment: ReviewComment do
+               return new ReviewComment.from_json(api, repo, json["comment"].as(JsonObject))
+       end
+
+       # `PullRequest` the `comment` belongs to.
+       fun pull: PullRequest do
+               return new PullRequest.from_json(api, repo, json["pull_request"].as(JsonObject))
+       end
+end
+
+# Triggered when a repository branch is pushed to.
+class PushEvent
+       super GithubEvent
+
+       # SHA of the HEAD commit on the repository.
+       fun head: String do return json["head"].to_s
+
+       # Full Git ref that was pushed.
+       #
+       # Example: “refs/heads/master”
+       fun ref: String do return json["ref"].to_s
+
+       # Number of commits in the push.
+       fun size: Int do return json["size"].as(Int)
+
+       # Array of pushed commits.
+       fun commits: Array[Commit] do
+               var res = new Array[Commit]
+               var arr = json["commits"].as(JsonArray)
+               for obj in arr do
+                       if not obj isa JsonObject then continue
+                       res.add api.load_commit(repo, obj["sha"].to_s).as(not null)
+               end
+               return res
+       end
+end
+
+# Triggered when the status of a Git commit changes.
+class StatusEvent
+       super GithubEvent
+
+       # The `Commit` itself.
+       fun commit: Commit do
+               return api.load_commit(repo, json["sha"].to_s).as(not null)
+       end
+
+       # New state.
+       #
+       # Can be `pending`, `success`, `failure`, or `error`.
+       fun state: String do return json["state"].to_s
+
+       # Optional human-readable description added to the status.
+       fun description: nullable String do
+               if not json.has_key("description") then return null
+               return json["description"].to_s
+       end
+
+       # Optional link added to the status.
+       fun target_url: nullable String do
+               if not json.has_key("target_url") then return null
+               return json["target_url"].to_s
+       end
+
+       # Array of branches containing the status' SHA.
+       #
+       # Each branch contains the given SHA,
+       # but the SHA may or may not be the head of the branch.
+       #
+       # The array includes a maximum of 10 branches.
+       fun branches: Array[Branch] do
+               var res = new Array[Branch]
+               var arr = json["branches"].as(JsonArray)
+               for obj in arr do
+                       if not obj isa JsonObject then continue
+                       res.add api.load_branch(repo, obj["name"].to_s).as(not null)
+               end
+               return res
+       end
+end
index cfab7ae..cbf851f 100644 (file)
@@ -22,7 +22,7 @@ module opengles2_hello_triangle
 
 import glesv2
 import egl
-import mnit_linux # for sdl
+import mnit_linux::sdl
 import x11
 
 if "NIT_TESTING".environ == "true" then exit(0)
index 902a656..ea60c0a 100644 (file)
@@ -19,6 +19,6 @@ import separate_erasure_compiler
 import global_compiler
 import compiler_ffi
 
-import android_platform
-import pnacl_platform
-import emscripten_platform
+import platform::android
+import platform::pnacl
+import platform::emscripten
index 68438c7..9c03910 100644 (file)
@@ -560,7 +560,7 @@ class SeparateCompiler
                                var r = pd.separate_runtime_function
                                r.compile_to_c(self)
                                var r2 = pd.virtual_runtime_function
-                               r2.compile_to_c(self)
+                               if r2 != r then r2.compile_to_c(self)
                        end
                end
                self.mainmodule = old_module
@@ -1180,8 +1180,10 @@ class SeparateCompilerVisitor
 
                var res0 = before_send(mmethod, arguments)
 
+               var runtime_function = mmethod.intro.virtual_runtime_function
+               var msignature = runtime_function.called_signature
+
                var res: nullable RuntimeVariable
-               var msignature = mmethod.intro.msignature.resolve_for(mmethod.intro.mclassdef.bound_mtype, mmethod.intro.mclassdef.bound_mtype, mmethod.intro.mclassdef.mmodule, true)
                var ret = msignature.return_mtype
                if ret == null then
                        res = null
@@ -1189,10 +1191,8 @@ class SeparateCompilerVisitor
                        res = self.new_var(ret)
                end
 
-               var s = new FlatBuffer
                var ss = new FlatBuffer
 
-               s.append("val*")
                ss.append("{recv}")
                for i in [0..msignature.arity[ do
                        var a = arguments[i+1]
@@ -1200,16 +1200,12 @@ class SeparateCompilerVisitor
                        if i == msignature.vararg_rank then
                                t = arguments[i+1].mcasttype
                        end
-                       s.append(", {t.ctype}")
                        a = self.autobox(a, t)
                        ss.append(", {a}")
                end
 
-
-               var r
-               if ret == null then r = "void" else r = ret.ctype
                self.require_declaration(const_color)
-               var call = "(({r} (*)({s}))({arguments.first}->class->vft[{const_color}]))({ss}) /* {mmethod} on {arguments.first.inspect}*/"
+               var call = "(({runtime_function.c_ret} (*){runtime_function.c_sig})({arguments.first}->class->vft[{const_color}]))({ss}) /* {mmethod} on {arguments.first.inspect}*/"
 
                if res != null then
                        self.add("{res} = {call};")
@@ -1778,108 +1774,112 @@ class SeparateCompilerVisitor
 end
 
 redef class MMethodDef
-       fun separate_runtime_function: AbstractRuntimeFunction
+       # The C function associated to a mmethoddef
+       fun separate_runtime_function: SeparateRuntimeFunction
        do
                var res = self.separate_runtime_function_cache
                if res == null then
-                       res = new SeparateRuntimeFunction(self)
+                       var recv = mclassdef.bound_mtype
+                       var msignature = msignature.resolve_for(recv, recv, mclassdef.mmodule, true)
+                       res = new SeparateRuntimeFunction(self, recv, msignature, c_name)
                        self.separate_runtime_function_cache = res
                end
                return res
        end
        private var separate_runtime_function_cache: nullable SeparateRuntimeFunction
 
-       fun virtual_runtime_function: AbstractRuntimeFunction
+       # The C function associated to a mmethoddef, that can be stored into a VFT of a class
+       # The first parameter (the reciever) is always typed by val* in order to accept an object value
+       # The C-signature is always compatible with the intro
+       fun virtual_runtime_function: SeparateRuntimeFunction
        do
                var res = self.virtual_runtime_function_cache
                if res == null then
-                       res = new VirtualRuntimeFunction(self)
+                       # Because the function is virtual, the signature must match the one of the original class
+                       var intromclassdef = mproperty.intro.mclassdef
+                       var recv = intromclassdef.bound_mtype
+
+                       res = separate_runtime_function
+                       if res.called_recv == recv then
+                               self.virtual_runtime_function_cache = res
+                               return res
+                       end
+
+                       var msignature = mproperty.intro.msignature.resolve_for(recv, recv, intromclassdef.mmodule, true)
+
+                       if recv.ctype == res.called_recv.ctype and msignature.c_equiv(res.called_signature) then
+                               self.virtual_runtime_function_cache = res
+                               return res
+                       end
+
+                       res = new SeparateRuntimeFunction(self, recv, msignature, "VIRTUAL_{c_name}")
                        self.virtual_runtime_function_cache = res
+                       res.is_thunk = true
                end
                return res
        end
-       private var virtual_runtime_function_cache: nullable VirtualRuntimeFunction
+       private var virtual_runtime_function_cache: nullable SeparateRuntimeFunction
+end
+
+redef class MSignature
+       # Does the C-version of `self` the same than the C-version of `other`?
+       fun c_equiv(other: MSignature): Bool
+       do
+               if self == other then return true
+               if arity != other.arity then return false
+               for i in [0..arity[ do
+                       if mparameters[i].mtype.ctype != other.mparameters[i].mtype.ctype then return false
+               end
+               if return_mtype != other.return_mtype then
+                       if return_mtype == null or other.return_mtype == null then return false
+                       if return_mtype.ctype != other.return_mtype.ctype then return false
+               end
+               return true
+       end
 end
 
 # The C function associated to a methoddef separately compiled
 class SeparateRuntimeFunction
        super AbstractRuntimeFunction
 
-       redef fun build_c_name: String do return "{mmethoddef.c_name}"
+       # The call-side static receiver
+       var called_recv: MType
 
-       redef fun to_s do return self.mmethoddef.to_s
+       # The call-side static signature
+       var called_signature: MSignature
 
-       redef fun compile_to_c(compiler)
-       do
-               var mmethoddef = self.mmethoddef
+       # The name on the compiled method
+       redef var build_c_name: String
 
-               var recv = self.mmethoddef.mclassdef.bound_mtype
-               var v = compiler.new_visitor
-               var selfvar = new RuntimeVariable("self", recv, recv)
-               var arguments = new Array[RuntimeVariable]
-               var frame = new StaticFrame(v, mmethoddef, recv, arguments)
-               v.frame = frame
+       # Statically call the original body instead
+       var is_thunk = false
 
-               var msignature = mmethoddef.msignature.resolve_for(mmethoddef.mclassdef.bound_mtype, mmethoddef.mclassdef.bound_mtype, mmethoddef.mclassdef.mmodule, true)
+       redef fun to_s do return self.mmethoddef.to_s
 
-               var sig = new FlatBuffer
-               var comment = new FlatBuffer
-               var ret = msignature.return_mtype
+       # The C return type (something or `void`)
+       var c_ret: String is lazy do
+               var ret = called_signature.return_mtype
                if ret != null then
-                       sig.append("{ret.ctype} ")
+                       return ret.ctype
                else
-                       sig.append("void ")
+                       return "void"
                end
-               sig.append(self.c_name)
-               sig.append("({selfvar.mtype.ctype} {selfvar}")
-               comment.append("({selfvar}: {selfvar.mtype}")
-               arguments.add(selfvar)
-               for i in [0..msignature.arity[ do
-                       var mtype = msignature.mparameters[i].mtype
-                       if i == msignature.vararg_rank then
-                               mtype = v.get_class("Array").get_mtype([mtype])
+       end
+
+       # The C signature (only the parmeter part)
+       var c_sig: String is lazy do
+               var sig = new FlatBuffer
+               sig.append("({called_recv.ctype} self")
+               for i in [0..called_signature.arity[ do
+                       var mtype = called_signature.mparameters[i].mtype
+                       if i == called_signature.vararg_rank then
+                               mtype = mmethoddef.mclassdef.mmodule.get_primitive_class("Array").get_mtype([mtype])
                        end
-                       comment.append(", {mtype}")
                        sig.append(", {mtype.ctype} p{i}")
-                       var argvar = new RuntimeVariable("p{i}", mtype, mtype)
-                       arguments.add(argvar)
                end
                sig.append(")")
-               comment.append(")")
-               if ret != null then
-                       comment.append(": {ret}")
-               end
-               compiler.provide_declaration(self.c_name, "{sig};")
-
-               v.add_decl("/* method {self} for {comment} */")
-               v.add_decl("{sig} \{")
-               if ret != null then
-                       frame.returnvar = v.new_var(ret)
-               end
-               frame.returnlabel = v.get_name("RET_LABEL")
-
-               if recv != arguments.first.mtype then
-                       #print "{self} {recv} {arguments.first}"
-               end
-               mmethoddef.compile_inside_to_c(v, arguments)
-
-               v.add("{frame.returnlabel.as(not null)}:;")
-               if ret != null then
-                       v.add("return {frame.returnvar.as(not null)};")
-               end
-               v.add("\}")
-               if not self.c_name.has_substring("VIRTUAL", 0) then compiler.names[self.c_name] = "{mmethoddef.mclassdef.mmodule.name}::{mmethoddef.mclassdef.mclass.name}::{mmethoddef.mproperty.name} ({mmethoddef.location.file.filename}:{mmethoddef.location.line_start})"
+               return sig.to_s
        end
-end
-
-# The C function associated to a methoddef on a primitive type, stored into a VFT of a class
-# The first parameter (the reciever) is always typed by val* in order to accept an object value
-class VirtualRuntimeFunction
-       super AbstractRuntimeFunction
-
-       redef fun build_c_name: String do return "VIRTUAL_{mmethoddef.c_name}"
-
-       redef fun to_s do return self.mmethoddef.to_s
 
        redef fun compile_to_c(compiler)
        do
@@ -1887,25 +1887,20 @@ class VirtualRuntimeFunction
 
                var recv = self.mmethoddef.mclassdef.bound_mtype
                var v = compiler.new_visitor
-               var selfvar = new RuntimeVariable("self", v.object_type, recv)
+               var selfvar = new RuntimeVariable("self", called_recv, recv)
                var arguments = new Array[RuntimeVariable]
                var frame = new StaticFrame(v, mmethoddef, recv, arguments)
                v.frame = frame
 
+               var msignature = called_signature
+               var ret = called_signature.return_mtype
+
                var sig = new FlatBuffer
                var comment = new FlatBuffer
-
-               # Because the function is virtual, the signature must match the one of the original class
-               var intromclassdef = self.mmethoddef.mproperty.intro.mclassdef
-               var msignature = mmethoddef.mproperty.intro.msignature.resolve_for(intromclassdef.bound_mtype, intromclassdef.bound_mtype, intromclassdef.mmodule, true)
-               var ret = msignature.return_mtype
-               if ret != null then
-                       sig.append("{ret.ctype} ")
-               else
-                       sig.append("void ")
-               end
+               sig.append(c_ret)
+               sig.append(" ")
                sig.append(self.c_name)
-               sig.append("({selfvar.mtype.ctype} {selfvar}")
+               sig.append(c_sig)
                comment.append("({selfvar}: {selfvar.mtype}")
                arguments.add(selfvar)
                for i in [0..msignature.arity[ do
@@ -1914,11 +1909,9 @@ class VirtualRuntimeFunction
                                mtype = v.get_class("Array").get_mtype([mtype])
                        end
                        comment.append(", {mtype}")
-                       sig.append(", {mtype.ctype} p{i}")
                        var argvar = new RuntimeVariable("p{i}", mtype, mtype)
                        arguments.add(argvar)
                end
-               sig.append(")")
                comment.append(")")
                if ret != null then
                        comment.append(": {ret}")
@@ -1932,10 +1925,14 @@ class VirtualRuntimeFunction
                end
                frame.returnlabel = v.get_name("RET_LABEL")
 
-               var subret = v.call(mmethoddef, recv, arguments)
-               if ret != null then
-                       assert subret != null
-                       v.assign(frame.returnvar.as(not null), subret)
+               if is_thunk then
+                       var subret = v.call(mmethoddef, recv, arguments)
+                       if ret != null then
+                               assert subret != null
+                               v.assign(frame.returnvar.as(not null), subret)
+                       end
+               else
+                       mmethoddef.compile_inside_to_c(v, arguments)
                end
 
                v.add("{frame.returnlabel.as(not null)}:;")
@@ -1943,11 +1940,8 @@ class VirtualRuntimeFunction
                        v.add("return {frame.returnvar.as(not null)};")
                end
                v.add("\}")
-               if not self.c_name.has_substring("VIRTUAL", 0) then compiler.names[self.c_name] = "{mmethoddef.mclassdef.mmodule.name}::{mmethoddef.mclassdef.mclass.name}::{mmethoddef.mproperty.name} ({mmethoddef.location.file.filename}--{mmethoddef.location.line_start})"
+               compiler.names[self.c_name] = "{mmethoddef.full_name} ({mmethoddef.location.file.filename}:{mmethoddef.location.line_start})"
        end
-
-       # TODO ?
-       redef fun call(v, arguments) do abort
 end
 
 redef class MEntity
index 8a33265..2c90e65 100644 (file)
@@ -235,13 +235,9 @@ class SeparateErasureCompiler
                                                v.add_decl("NULL, /* DEAD {mclass.intro_mmodule}:{mclass}:{mpropdef} */")
                                                continue
                                        end
-                                       if true or mpropdef.mclassdef.bound_mtype.ctype != "val*" then
-                                               v.require_declaration("VIRTUAL_{mpropdef.c_name}")
-                                               v.add_decl("(nitmethod_t)VIRTUAL_{mpropdef.c_name}, /* pointer to {mclass.intro_mmodule}:{mclass}:{mpropdef} */")
-                                       else
-                                               v.require_declaration("{mpropdef.c_name}")
-                                               v.add_decl("(nitmethod_t){mpropdef.c_name}, /* pointer to {mclass.intro_mmodule}:{mclass}:{mpropdef} */")
-                                       end
+                                       var rf = mpropdef.virtual_runtime_function
+                                       v.require_declaration(rf.c_name)
+                                       v.add_decl("(nitmethod_t){rf.c_name}, /* pointer to {mpropdef.full_name} */")
                                end
                        end
                        v.add_decl("\}")
index 1c77939..1cdc51a 100644 (file)
@@ -143,6 +143,10 @@ private class NitdocDecorator
        end
 end
 
+# Decorator for span elements.
+#
+# Because inline comments can appear as span elements,
+# InlineDecorator do not decorate things like paragraphs or headers.
 private class InlineDecorator
        super NitdocDecorator
 
@@ -150,6 +154,10 @@ private class InlineDecorator
                v.emit_in block
        end
 
+       redef fun add_headline(v, block) do
+               v.emit_in block
+       end
+
        redef fun add_code(v, block) do
                # Try to parse code
                var ast = toolcontext.parse_something(block.block.text.to_s)
index 10c1db3..84bbb29 100644 (file)
@@ -33,36 +33,32 @@ redef class AModule
 end
 
 redef class MModule
-       private var header_dependencies_cache: nullable Array[MModule] = null
-       fun header_dependencies: Array[MModule]
-       do
-               var cache = header_dependencies_cache
-               assert cache != null
-               return cache
-       end
+       # Modules with public foreign code blocks (C header)
+       var header_dependencies: nullable HashSet[MModule] = null
 
        private fun compute_header_dependencies(v: HeaderDependancyPhase)
        do
-               if header_dependencies_cache != null then return
+               if header_dependencies != null then return
 
-               var header_dependencies = new Array[MModule]
+               var header_dependencies = new HashSet[MModule]
 
                # gather from importation
                for m in in_importation.direct_greaters do
-                       m.compute_header_dependencies(v)
+                       m.compute_header_dependencies v
 
-                       # does the super module has inherited dependancies?
+                       # does the super module has inherited dependencies?
                        var hd = m.header_dependencies
+                       assert hd != null
                        if not hd.is_empty then
-                               header_dependencies.add_all(hd)
+                               header_dependencies.add_all hd
                        end
 
-                       # does the super module itself has extern dependancies?
+                       # does the super module itself has extern dependencies?
                        var amodule = v.toolcontext.modelbuilder.mmodule2node(m)
                        if amodule != null and amodule.has_public_c_header then header_dependencies.add(m)
                end
 
-               header_dependencies_cache = header_dependencies
+               self.header_dependencies = header_dependencies
        end
 end
 
index 5c7eeeb..f031289 100644 (file)
@@ -32,6 +32,27 @@ end
 
 redef class MModule
        private var objc_file: nullable ObjCCompilationUnit = null
+
+       private var has_public_objc_header = false
+
+       # Imported modules with public Objective-C code blocks
+       var objc_imported_headers: HashSet[MModule] is lazy do
+               var dep = new HashSet[MModule]
+
+               # gather from importation
+               for m in in_importation.direct_greaters do
+                       # does the super module has inherited dependencies?
+                       var import_dep = m.objc_imported_headers
+                       if not import_dep.is_empty then
+                               dep.add_all import_dep
+                       end
+
+                       # does the super module itself has a public header?
+                       if m.has_public_objc_header then dep.add(m)
+               end
+
+               return dep
+       end
 end
 
 # The Objective-C langugage visitor
@@ -47,6 +68,8 @@ class ObjCLanguage
                if block.is_objc_header then
                        mmodule.objc_file.header_custom.add block.location.as_line_pragma
                        mmodule.objc_file.header_custom.add block.code
+
+                       mmodule.has_public_objc_header = true
                else if block.is_objc_body then
                        mmodule.objc_file.body_custom.add block.location.as_line_pragma
                        mmodule.objc_file.body_custom.add block.code
@@ -77,6 +100,12 @@ class ObjCLanguage
                var objc_file = mmodule.objc_file
                assert objc_file != null
 
+               # Import public Objective-C header of imported modules
+               var dep = mmodule.objc_imported_headers
+               for mod in dep do
+                       objc_file.header_custom.add "#include \"{mod.c_name}._ffi_m.h\"\n"
+               end
+
                # write .m and _m.h file
                mmodule.objc_file.header_c_types.add """
        #include "{{{mmodule.c_name}}}._ffi.h"
@@ -211,6 +240,13 @@ end
 private class FromObjCCallContext
        super ObjCCallContext
 
+       redef fun cast_to(mtype, name)
+       do
+               if mtype isa MClassType and mtype.mclass.ftype isa ForeignObjCType then
+                       return "(__bridge void*)({name})"
+               else return name
+       end
+
        redef fun cast_from(mtype, name)
        do
                if mtype isa MClassType and mtype.mclass.ftype isa ForeignObjCType then
similarity index 99%
rename from src/compiler/android_platform.nit
rename to src/platform/android.nit
index b7069e3..6ba5502 100644 (file)
 # limitations under the License.
 
 # Compile program for the Android platform
-module android_platform
+module android
 
 import platform
-import abstract_compiler
+import compiler::abstract_compiler
 import ffi
 intrude import ffi::extra_java_files
 import android_annotations
similarity index 97%
rename from src/compiler/emscripten_platform.nit
rename to src/platform/emscripten.nit
index 6332098..dc2662f 100644 (file)
 # limitations under the License.
 
 # Compile to JavaScript using the Emscripten SDK
-module emscripten_platform
+module emscripten
 
 import platform
-import abstract_compiler
+import compiler::abstract_compiler
 
 redef class ToolContext
        redef fun platform_from_name(name)
similarity index 100%
rename from src/platform.nit
rename to src/platform/platform.nit
similarity index 99%
rename from src/compiler/pnacl_platform.nit
rename to src/platform/pnacl.nit
index 3f96318..9fceaad 100644 (file)
 # limitations under the License.
 
 # Compile program for the PNaCl platform
-module pnacl_platform
+module pnacl
 
 import platform
-import abstract_compiler
+import compiler::abstract_compiler
 
 redef class ToolContext
        redef fun platform_from_name(name)
diff --git a/tests/sav/opengles2_hello_triangle.res b/tests/sav/opengles2_hello_triangle.res
deleted file mode 100644 (file)
index c1dad34..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-../lib/mnit_linux/linux_app.nit:29,16--31: Redef Error: a virtual type cannot be refined.
-../lib/mnit_linux/linux_app.nit:30,16--29: Redef Error: a virtual type cannot be refined.