From: Jean Privat Date: Thu, 22 Jan 2015 06:27:35 +0000 (+0700) Subject: Merge: Audio management for android + audio Abstraction API X-Git-Tag: v0.7.1~18 X-Git-Url: http://nitlanguage.org?hp=9400647f74f5a9c90c5463ccb4e196c050c7c925 Merge: Audio management for android + audio Abstraction API Fixes some problems with the audio management for the android platform. The audio API for android still needs some work but is fine to use now ! The Abstraction API for sound management is very simple for now Pull-Request: #1101 Reviewed-by: Alexis Laferrière Reviewed-by: Alexandre Terrasa Reviewed-by: Jean Privat Reviewed-by: Lucas Bajolet --- diff --git a/contrib/nitiwiki/src/wiki_html.nit b/contrib/nitiwiki/src/wiki_html.nit index 7f213b7..89546ce 100644 --- a/contrib/nitiwiki/src/wiki_html.nit +++ b/contrib/nitiwiki/src/wiki_html.nit @@ -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 diff --git a/contrib/nitiwiki/tests/res/nitiwiki_render.res b/contrib/nitiwiki/tests/res/nitiwiki_render.res index adf25a7..25f17ab 100644 --- a/contrib/nitiwiki/tests/res/nitiwiki_render.res +++ b/contrib/nitiwiki/tests/res/nitiwiki_render.res @@ -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 diff --git a/contrib/nitiwiki/tests/res/nitiwiki_status.res b/contrib/nitiwiki/tests/res/nitiwiki_status.res index 936a764..9eb2262 100644 --- a/contrib/nitiwiki/tests/res/nitiwiki_status.res +++ b/contrib/nitiwiki/tests/res/nitiwiki_status.res @@ -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 diff --git a/lib/c.nit b/lib/c.nit index d94ae8e..ae1b875 100644 --- a/lib/c.nit +++ b/lib/c.nit @@ -70,10 +70,10 @@ extern class NativeCArray `{ void * `} type E: nullable Object # Get element at `index`. - fun [](index: E): E is abstract + fun [](index: Int): E is abstract # Set `val` at `index`. - fun []=(index: E, val: E) is abstract + fun []=(index: Int, val: E) is abstract # Return pointer to the address to the second element of this array # diff --git a/lib/cocoa/examples/cocoa_message_box.nit b/lib/cocoa/examples/cocoa_message_box.nit index 72e35d7..224c7ab 100644 --- a/lib/cocoa/examples/cocoa_message_box.nit +++ b/lib/cocoa/examples/cocoa_message_box.nit @@ -19,10 +19,6 @@ module cocoa_message_box import cocoa -in "ObjC" `{ - #import -`} - fun dialog in "ObjC" `{ NSAlert *alert = [[[NSAlert alloc] init] autorelease]; [alert setMessageText:@"Hello world!"]; diff --git a/lib/cocoa/examples/hello_cocoa.nit b/lib/cocoa/examples/hello_cocoa.nit index 3a2b168..960b001 100644 --- a/lib/cocoa/examples/hello_cocoa.nit +++ b/lib/cocoa/examples/hello_cocoa.nit @@ -19,10 +19,6 @@ module hello_cocoa import cocoa::foundation -in "ObjC" `{ - #import -`} - # Print `"Hello world!"` to the log fun hello_world in "ObjC" `{ @autoreleasepool { diff --git a/lib/github/api.nit b/lib/github/api.nit index 9a9b4b1..b979b5d 100644 --- a/lib/github/api.nit +++ b/lib/github/api.nit @@ -40,11 +40,11 @@ import github_curl # # ~~~ # var repo = api.load_repo("privat/nit") -# assert repo isa Repo +# assert repo != null # assert repo.name == "nit" # # var user = api.load_user("Morriar") -# assert user isa User +# assert user != null # assert user.login == "Morriar" # ~~~ class GithubAPI @@ -149,9 +149,7 @@ class GithubAPI # assert user.login == "Morriar" fun load_user(login: String): nullable User do var user = new User(self, login) - user.load_from_github - if was_error then return null - return user + return user.load_from_github end # Get the Github repo with `full_name`. @@ -165,9 +163,7 @@ class GithubAPI # assert repo.default_branch.name == "master" fun load_repo(full_name: String): nullable Repo do var repo = new Repo(self, full_name) - repo.load_from_github - if was_error then return null - return repo + return repo.load_from_github end # Get the Github branch with `name`. @@ -176,15 +172,13 @@ class GithubAPI # # var api = new GithubAPI(get_github_oauth) # var repo = api.load_repo("privat/nit") - # assert repo isa Repo + # assert repo != null # var branch = api.load_branch(repo, "master") # assert branch.name == "master" # assert branch.commit isa Commit fun load_branch(repo: Repo, name: String): nullable Branch do var branch = new Branch(self, repo, name) - branch.load_from_github - if was_error then return null - return branch + return branch.load_from_github end # Get the Github commit with `sha`. @@ -193,14 +187,12 @@ class GithubAPI # # var api = new GithubAPI(get_github_oauth) # var repo = api.load_repo("privat/nit") - # assert repo isa Repo + # assert repo != null # var commit = api.load_commit(repo, "64ce1f") # assert commit isa Commit fun load_commit(repo: Repo, sha: String): nullable Commit do var commit = new Commit(self, repo, sha) - commit.load_from_github - if was_error then return null - return commit + return commit.load_from_github end # Get the Github issue #`number`. @@ -214,9 +206,7 @@ class GithubAPI # assert issue.title == "Doc" fun load_issue(repo: Repo, number: Int): nullable Issue do var issue = new Issue(self, repo, number) - issue.load_from_github - if was_error then return null - return issue + return issue.load_from_github end # Get the Github pull request #`number`. @@ -231,9 +221,7 @@ class GithubAPI # assert pull.user.login == "Morriar" fun load_pull(repo: Repo, number: Int): nullable PullRequest do var pull = new PullRequest(self, repo, number) - pull.load_from_github - if was_error then return null - return pull + return pull.load_from_github end # Get the Github label with `name`. @@ -242,14 +230,12 @@ class GithubAPI # # var api = new GithubAPI(get_github_oauth) # var repo = api.load_repo("privat/nit") - # assert repo isa Repo + # assert repo != null # var labl = api.load_label(repo, "ok_will_merge") # assert labl != null fun load_label(repo: Repo, name: String): nullable Label do var labl = new Label(self, repo, name) - labl.load_from_github - if was_error then return null - return labl + return labl.load_from_github end # Get the Github milestone with `id`. @@ -258,14 +244,79 @@ class GithubAPI # # var api = new GithubAPI(get_github_oauth) # var repo = api.load_repo("privat/nit") - # assert repo isa Repo + # assert repo != null # var stone = api.load_milestone(repo, 4) # assert stone.title == "v1.0prealpha" fun load_milestone(repo: Repo, id: Int): nullable Milestone do var milestone = new Milestone(self, repo, id) - milestone.load_from_github + 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 milestone + return event + end + + # Get the Github commit comment with `id`. + # + # Returns `null` if the comment cannot be found. + # + # var api = new GithubAPI(get_github_oauth) + # var repo = api.load_repo("privat/nit") + # assert repo != null + # var comment = api.load_commit_comment(repo, 8982707) + # assert comment.user.login == "Morriar" + # assert comment.body == "For testing purposes..." + # assert comment.commit.sha == "7eacb86d1e24b7e72bc9ac869bf7182c0300ceca" + fun load_commit_comment(repo: Repo, id: Int): nullable CommitComment do + var comment = new CommitComment(self, repo, id) + return comment.load_from_github + end + + # Get the Github issue comment with `id`. + # + # Returns `null` if the comment cannot be found. + # + # var api = new GithubAPI(get_github_oauth) + # var repo = api.load_repo("privat/nit") + # assert repo != null + # var comment = api.load_issue_comment(repo, 6020149) + # assert comment.user.login == "privat" + # assert comment.created_at.to_s == "2012-05-30T20:16:54Z" + # assert comment.issue.number == 10 + fun load_issue_comment(repo: Repo, id: Int): nullable IssueComment do + var comment = new IssueComment(self, repo, id) + return comment.load_from_github + end + + # Get the Github diff comment with `id`. + # + # Returns `null` if the comment cannot be found. + # + # var api = new GithubAPI(get_github_oauth) + # var repo = api.load_repo("privat/nit") + # assert repo != null + # var comment = api.load_review_comment(repo, 21010363) + # assert comment.path == "src/modelize/modelize_property.nit" + # assert comment.original_position == 26 + # assert comment.pull.number == 945 + fun load_review_comment(repo: Repo, id: Int): nullable ReviewComment do + var comment = new ReviewComment(self, repo, id) + return comment.load_from_github end end @@ -288,8 +339,10 @@ abstract class GithubEntity var json: JsonObject is noinit, protected writable # Load `json` from Github API. - private fun load_from_github do + private fun load_from_github: nullable SELF do json = api.load_from_github(key) + if api.was_error then return null + return self end redef fun to_s do return json.to_json @@ -441,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 @@ -570,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 @@ -631,6 +708,27 @@ class Issue return new Milestone.from_json(api, repo, milestone) end + # List of comments made on this issue. + fun comments: Array[IssueComment] do + var res = new Array[IssueComment] + var count = comments_count + var page = 1 + var array = api.get("{key}/comments?page={page}") + if not array isa JsonArray then + return res + end + while not array.is_empty and res.length < count do + for obj in array do + if not obj isa JsonObject then continue + var id = obj["id"].as(Int) + res.add(api.load_issue_comment(repo, id).as(not null)) + end + page += 1 + array = api.get("{key}/comments?page={page}").as(JsonArray) + end + return res + end + # Number of comments on this issue. fun comments_count: Int do return json["comments"].to_s.to_i @@ -658,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"] @@ -848,3 +962,264 @@ class Milestone return new ISODate.from_string(res.to_s) end end + +# A Github comment +# +# There is two kinds of comments: +# +# * `CommitComment` are made on a commit page. +# * `IssueComment` are made on an issue or pull request page. +# * `ReviewComment` are made on the diff associated to a pull request. +abstract class Comment + super RepoEntity + + # Identifier of this comment. + var id: Int + + redef init from_json(api, repo, json) do + self.id = json["id"].as(Int) + super + end + + # User that made this comment. + fun user: User do + return new User.from_json(api, json["user"].as(JsonObject)) + end + + # Creation time in ISODate format. + fun created_at: ISODate do + return new ISODate.from_string(json["created_at"].to_s) + end + + # Last update time in ISODate format (if any). + fun updated_at: nullable ISODate do + if not json.has_key("updated_at") then return null + return new ISODate.from_string(json["updated_at"].to_s) + end + + # Comment body text. + fun body: String do return json["body"].to_s +end + +# A comment made on a commit. +class CommitComment + super Comment + + redef var key is lazy do return "{repo.key}/comments/{id}" + + # Commented commit. + fun commit: Commit do + return api.load_commit(repo, json["commit_id"].to_s).as(not null) + end + + # Position of the comment on the line. + fun position: nullable String do + if not json.has_key("position") then return null + var res = json["position"] + if res == null then return null + return res.to_s + end + + # Line of the comment. + fun line: nullable String do + if not json.has_key("line") then return null + var res = json["line"] + if res == null then return null + return res.to_s + end + + # Path of the commented file. + fun path: String do return json["path"].to_s +end + +# Comments made on Github issue and pull request pages. +# +# Should be accessed from `GithubAPI::load_issue_comment`. +# +# See . +class IssueComment + super Comment + + redef var key is lazy do return "{repo.key}/issues/comments/{id}" + + # Issue that contains `self`. + fun issue: Issue do + var number = issue_url.split("/").last.to_i + return api.load_issue(repo, number).as(not null) + end + + # Link to the issue document on API. + fun issue_url: String do return json["issue_url"].to_s +end + +# Comments made on Github pull request diffs. +# +# Should be accessed from `GithubAPI::load_diff_comment`. +# +# See . +class ReviewComment + super Comment + + redef var key is lazy do return "{repo.key}/pulls/comments/{id}" + + # Pull request that contains `self`. + fun pull: PullRequest do + var number = pull_request_url.split("/").last.to_i + return api.load_pull(repo, number).as(not null) + end + + # Link to the pull request on API. + fun pull_request_url: String do return json["pull_request_url"].to_s + + # Diff hunk. + fun diff_hunk: String do return json["diff_hunk"].to_s + + # Path of commented file. + fun path: String do return json["path"].to_s + + # Position of the comment on the file. + fun position: Int do return json["position"].to_s.to_i + + # Original position in the diff. + fun original_position: Int do return json["original_position"].to_s.to_i + + # Commit referenced by this comment. + fun commit_id: String do return json["commit_id"].to_s + + # 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 . +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 . +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 index 0000000..b6e5af3 --- /dev/null +++ b/lib/github/events.nit @@ -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 +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 diff --git a/lib/glesv2/examples/opengles2_hello_triangle.nit b/lib/glesv2/examples/opengles2_hello_triangle.nit index cfab7ae..cbf851f 100644 --- a/lib/glesv2/examples/opengles2_hello_triangle.nit +++ b/lib/glesv2/examples/opengles2_hello_triangle.nit @@ -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) diff --git a/lib/glesv2/glesv2.nit b/lib/glesv2/glesv2.nit index 01ca43c..06803ae 100644 --- a/lib/glesv2/glesv2.nit +++ b/lib/glesv2/glesv2.nit @@ -146,15 +146,21 @@ extern class GLProgram `{GLuint`} return active_attrib_name_native(index, max_size).to_s end private fun active_attrib_name_native(index, max_size: Int): NativeString `{ + // We get more values than we need, for compatibility. At least the + // NVidia driver tries to fill them even if NULL. + char *name = malloc(max_size); - glGetActiveAttrib(recv, index, max_size, NULL, NULL, NULL, name); + int size; + GLenum type; + glGetActiveAttrib(recv, index, max_size, NULL, &size, &type, name); return name; `} # Size of the active attribute at `index` fun active_attrib_size(index: Int): Int `{ int size; - glGetActiveAttrib(recv, index, 0, NULL, NULL, &size, NULL); + GLenum type; + glGetActiveAttrib(recv, index, 0, NULL, &size, &type, NULL); return size; `} @@ -162,8 +168,9 @@ extern class GLProgram `{GLuint`} # # May only be float related data types (single float, vectors and matrix). fun active_attrib_type(index: Int): GLFloatDataType `{ + int size; GLenum type; - glGetActiveAttrib(recv, index, 0, NULL, &type, NULL, NULL); + glGetActiveAttrib(recv, index, 0, NULL, &size, &type, NULL); return type; `} @@ -175,14 +182,17 @@ extern class GLProgram `{GLuint`} end private fun active_uniform_name_native(index, max_size: Int): NativeString `{ char *name = malloc(max_size); - glGetActiveUniform(recv, index, max_size, NULL, NULL, NULL, name); + int size; + GLenum type; + glGetActiveUniform(recv, index, max_size, NULL, &size, &type, name); return name; `} # Size of the active uniform at `index` fun active_uniform_size(index: Int): Int `{ int size; - glGetActiveUniform(recv, index, 0, NULL, NULL, &size, NULL); + GLenum type; + glGetActiveUniform(recv, index, 0, NULL, &size, &type, NULL); return size; `} @@ -190,8 +200,9 @@ extern class GLProgram `{GLuint`} # # May be any data type supported by OpenGL ES 2.0 shaders. fun active_uniform_type(index: Int): GLDataType `{ - GLenum type; - glGetActiveUniform(recv, index, 0, NULL, &type, NULL, NULL); + int size; + GLenum type = 0; + glGetActiveUniform(recv, index, 0, NULL, &size, &type, NULL); return type; `} end diff --git a/lib/more_collections.nit b/lib/more_collections.nit index 1bcc514..6396ec2 100644 --- a/lib/more_collections.nit +++ b/lib/more_collections.nit @@ -29,7 +29,7 @@ module more_collections # assert m.has_key("four") # assert m["four"] == ['i', 'i', 'i', 'i'] # assert m["zzz"] == new Array[Char] -class MultiHashMap[K: Object, V] +class MultiHashMap[K, V] super HashMap[K, Array[V]] # Add `v` to the array associated with `k`. @@ -59,7 +59,7 @@ end # assert hm2[1, "one"] == 1.0 # assert hm2[2, "not-two"] == null # ~~~~ -class HashMap2[K1: Object, K2: Object, V] +class HashMap2[K1, K2, V] private var level1 = new HashMap[K1, HashMap[K2, V]] # Return the value associated to the keys `k1` and `k2`. @@ -97,7 +97,7 @@ end # assert hm3[1, "one", 11] == 1.0 # assert hm3[2, "not-two", 22] == null # ~~~~ -class HashMap3[K1: Object, K2: Object, K3: Object, V] +class HashMap3[K1, K2, K3, V] private var level1 = new HashMap[K1, HashMap2[K2, K3, V]] # Return the value associated to the keys `k1`, `k2`, and `k3`. @@ -165,7 +165,7 @@ end # assert dma["b"] == [65, 66] # assert dma.default == [65] # ~~~~ -class DefaultMap[K: Object, V] +class DefaultMap[K, V] super HashMap[K, V] # The default value. diff --git a/lib/sdl.nit b/lib/sdl.nit index 5225f9f..16695e2 100644 --- a/lib/sdl.nit +++ b/lib/sdl.nit @@ -21,6 +21,7 @@ module sdl is end import mnit_display +import c in "C header" `{ #include @@ -160,7 +161,26 @@ extern class SDLDisplay `{SDL_Surface *`} fun warp_mouse(x,y: Int) `{ SDL_WarpMouse(x, y); `} # Show or hide the cursor - fun show_cursor(show: Bool) `{ SDL_ShowCursor(show); `} + fun show_cursor=(val: Bool) `{ SDL_ShowCursor(val? SDL_ENABLE: SDL_DISABLE); `} + + # Is the cursor visible? + fun show_cursor: Bool `{ SDL_ShowCursor(SDL_QUERY); `} + + # Grab or release the input + fun grab_input=(val: Bool) `{ SDL_WM_GrabInput(val? SDL_GRAB_ON: SDL_GRAB_OFF); `} + + # Is the input grabbed? + fun grab_input: Bool `{ SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON; `} + + # Are instances of `SDLMouseMotionEvent` ignored? + fun ignore_mouse_motion_events: Bool `{ + return SDL_EventState(SDL_MOUSEMOTION, SDL_QUERY); + `} + + # Do not raise instances of `SDLMouseMotionEvent` if `val` + fun ignore_mouse_motion_events=(val: Bool) `{ + SDL_EventState(SDL_MOUSEMOTION, val? SDL_IGNORE: SDL_ENABLE); + `} end # Basic Drawing figures @@ -225,6 +245,12 @@ extern class SDLImage redef fun height: Int `{ return recv->h; `} fun is_ok: Bool do return not address_is_null + + # Returns a reference to the pixels of the texture + fun pixels: NativeCByteArray `{ return recv->pixels; `} + + # Does this texture has an alpha mask? + fun amask: Bool `{ return recv->format->Amask; `} end # A simple rectangle @@ -284,10 +310,10 @@ class SDLMouseButtonEvent fun is_left_button: Bool do return button == 1 # Is this event raised by the right button? - fun is_right_button: Bool do return button == 2 + fun is_right_button: Bool do return button == 3 # Is this event raised by the middle button? - fun is_middle_button: Bool do return button == 3 + fun is_middle_button: Bool do return button == 2 # Is this event raised by the wheel going down? fun is_down_wheel: Bool do return button == 4 diff --git a/lib/socket/socket.nit b/lib/socket/socket.nit index 77acfbe..d9bc5a3 100644 --- a/lib/socket/socket.nit +++ b/lib/socket/socket.nit @@ -111,7 +111,7 @@ class TCPStream fun ready_to_read(timeout: Int): Bool do if _buffer_pos < _buffer.length then return true - if eof then return false + if end_reached then return false var events = [new NativeSocketPollValues.pollin] return pollin(events, timeout).length != 0 end @@ -172,6 +172,7 @@ class TCPStream if closed then return if socket.close >= 0 then closed = true + end_reached = true end end diff --git a/lib/standard/collection/abstract_collection.nit b/lib/standard/collection/abstract_collection.nit index d5621a9..bb17064 100644 --- a/lib/standard/collection/abstract_collection.nit +++ b/lib/standard/collection/abstract_collection.nit @@ -377,7 +377,7 @@ interface Set[E: Object] end # MapRead are abstract associative collections: `key` -> `item`. -interface MapRead[K: Object, V] +interface MapRead[K, V] # Get the item at `key` # # var x = new HashMap[String, Int] @@ -492,7 +492,7 @@ end # assert map.values.has(1) == true # assert map.values.has(3) == false # -interface Map[K: Object, V] +interface Map[K, V] super MapRead[K, V] # Set the `value` at `key`. @@ -552,7 +552,7 @@ interface Map[K: Object, V] end # Iterators for Map. -interface MapIterator[K: Object, V] +interface MapIterator[K, V] # The current item. # Require `is_ok`. fun item: V is abstract @@ -583,7 +583,7 @@ interface MapIterator[K: Object, V] end # Iterator on a 'keys' point of view of a map -class MapKeysIterator[K: Object, V] +class MapKeysIterator[K, V] super Iterator[K] # The original iterator var original_iterator: MapIterator[K, V] @@ -594,7 +594,7 @@ class MapKeysIterator[K: Object, V] end # Iterator on a 'values' point of view of a map -class MapValuesIterator[K: Object, V] +class MapValuesIterator[K, V] super Iterator[V] # The original iterator var original_iterator: MapIterator[K, V] @@ -941,7 +941,7 @@ end # Associative arrays that internally uses couples to represent each (key, value) pairs. # This is an helper class that some specific implementation of Map may implements. -interface CoupleMap[K: Object, V] +interface CoupleMap[K, V] super Map[K, V] # Return the couple of the corresponding key @@ -968,7 +968,7 @@ end # Iterator on CoupleMap # # Actually it is a wrapper around an iterator of the internal array of the map. -private class CoupleMapIterator[K: Object, V] +private class CoupleMapIterator[K, V] super MapIterator[K, V] redef fun item do return _iter.item.second diff --git a/lib/standard/collection/array.nit b/lib/standard/collection/array.nit index 68f84e7..44ea5d3 100644 --- a/lib/standard/collection/array.nit +++ b/lib/standard/collection/array.nit @@ -536,7 +536,7 @@ end # Associative arrays implemented with an array of (key, value) pairs. -class ArrayMap[K: Object, E] +class ArrayMap[K, E] super CoupleMap[K, E] # O(n) @@ -618,7 +618,7 @@ class ArrayMap[K: Object, E] end end -private class ArrayMapKeys[K: Object, E] +private class ArrayMapKeys[K, E] super RemovableCollection[K] # The original map var map: ArrayMap[K, E] @@ -638,7 +638,7 @@ private class ArrayMapKeys[K: Object, E] redef fun remove_all(key) do self.remove(key) end -private class ArrayMapValues[K: Object, E] +private class ArrayMapValues[K, E] super RemovableCollection[E] # The original map var map: ArrayMap[K, E] diff --git a/lib/standard/collection/hash_collection.nit b/lib/standard/collection/hash_collection.nit index d389c5a..f3857293 100644 --- a/lib/standard/collection/hash_collection.nit +++ b/lib/standard/collection/hash_collection.nit @@ -10,13 +10,18 @@ # You are allowed to redistribute it and sell it, alone or is a part of # another product. -# Introduce Hashmap and Hashset. +# Introduce `HashMap` and `HashSet`. module hash_collection import array +redef class Map[K, V] + # Get a `HashMap[K, V]` as default implementation + new do return new HashMap[K, V] +end + # A HashCollection is an array of HashNode[K] indexed by the K hash value -private abstract class HashCollection[K: Object] +private abstract class HashCollection[K] type N: HashNode[K] var array: nullable NativeArray[nullable N] = null # Used to store items @@ -35,12 +40,14 @@ private abstract class HashCollection[K: Object] # Return the index of the key k fun index_at(k: K): Int do + if k == null then return 0 + var i = k.hash % _capacity if i < 0 then i = - i return i end - # Return the node assosiated with the key + # Return the node associated with the key fun node_at(k: K): nullable N do # cache: `is` is used instead of `==` because it is a faster filter (even if not exact) @@ -52,7 +59,7 @@ private abstract class HashCollection[K: Object] return res end - # Return the node assosiated with the key (but with the index already known) + # Return the node associated with the key (but with the index already known) fun node_at_idx(i: Int, k: K): nullable N do var c = _array[i] @@ -190,7 +197,7 @@ private abstract class HashCollection[K: Object] end end -private abstract class HashNode[K: Object] +private abstract class HashNode[K] var key: K type N: HashNode[K] var next_item: nullable N = null @@ -199,9 +206,20 @@ private abstract class HashNode[K: Object] var next_in_bucklet: nullable N = null end -# A map implemented with a hash table. -# Keys of such a map cannot be null and require a working `hash` method -class HashMap[K: Object, V] +# A `Map` implemented with a hash table. +# +# ~~~ +# var map = new HashMap[nullable String, Int] +# map[null] = 0 +# map["one"] = 1 +# map["two"] = 2 +# +# assert map[null] == 0 +# assert map["one"] == 1 +# assert map.keys.has("two") +# assert map.values.length == 3 +# ~~~ +class HashMap[K, V] super Map[K, V] super HashCollection[K] @@ -249,7 +267,7 @@ class HashMap[K: Object, V] end # View of the keys of a HashMap -private class HashMapKeys[K: Object, V] +private class HashMapKeys[K, V] super RemovableCollection[K] # The original map var map: HashMap[K, V] @@ -270,7 +288,7 @@ private class HashMapKeys[K: Object, V] end # View of the values of a Map -private class HashMapValues[K: Object, V] +private class HashMapValues[K, V] super RemovableCollection[V] # The original map var map: HashMap[K, V] @@ -340,14 +358,14 @@ private class HashMapValues[K: Object, V] end end -private class HashMapNode[K: Object, V] +private class HashMapNode[K, V] super HashNode[K] redef type N: HashMapNode[K, V] var value: V end # A `MapIterator` over a `HashMap`. -class HashMapIterator[K: Object, V] +class HashMapIterator[K, V] super MapIterator[K, V] redef fun is_ok do return _node != null diff --git a/lib/standard/string.nit b/lib/standard/string.nit index c4ae7b0..2c46179 100644 --- a/lib/standard/string.nit +++ b/lib/standard/string.nit @@ -1092,15 +1092,19 @@ class FlatString from = 0 end - var realFrom = index_from + from + var new_from = index_from + from - if (realFrom + count) > index_to then return new FlatString.with_infos(items, index_to - realFrom + 1, realFrom, index_to) + if (new_from + count) > index_to then + var new_len = index_to - new_from + 1 + if new_len <= 0 then return empty + return new FlatString.with_infos(items, new_len, new_from, index_to) + end - if count == 0 then return empty + if count <= 0 then return empty - var to = realFrom + count - 1 + var to = new_from + count - 1 - return new FlatString.with_infos(items, to - realFrom + 1, realFrom, to) + return new FlatString.with_infos(items, to - new_from + 1, new_from, to) end redef fun empty do return "".as(FlatString) @@ -2174,7 +2178,7 @@ redef class Map[K,V] var i = iterator var k = i.key var e = i.item - s.append("{k}{couple_sep}{e or else ""}") + s.append("{k or else ""}{couple_sep}{e or else ""}") # Concat other items i.next @@ -2182,7 +2186,7 @@ redef class Map[K,V] s.append(sep) k = i.key e = i.item - s.append("{k}{couple_sep}{e or else ""}") + s.append("{k or else ""}{couple_sep}{e or else ""}") i.next end return s.to_s diff --git a/lib/websocket/examples/websocket_server.nit b/lib/websocket/examples/websocket_server.nit index 089df1b..8b4584c 100644 --- a/lib/websocket/examples/websocket_server.nit +++ b/lib/websocket/examples/websocket_server.nit @@ -19,7 +19,7 @@ module websocket_server import websocket -var sock = new WebSocket(8088, 1) +var sock = new WebSocketListener(8088, 1) var msg: String @@ -27,19 +27,21 @@ if sock.listener.closed then print sys.errno.strerror end -sock.accept +var cli: TCPStream -while not sock.listener.closed do - if not sock.connected then sock.accept - if sys.stdin.poll_in then - msg = gets - printn "Received message : {msg}" - if msg == "exit" then sock.close - if msg == "disconnect" then sock.disconnect_client - sock.write(msg) - end - if sock.can_read(10) then - msg = sock.read_line - if msg != "" then print msg +while not sock.closed do + cli = sock.accept + while cli.connected do + if sys.stdin.poll_in then + msg = gets + printn "Received message : {msg}" + if msg == "disconnect" then cli.close + cli.write(msg) + end + if cli.can_read(10) then + msg = "" + while cli.can_read(0) do msg += cli.read(100) + if msg != "" then print msg + end end end diff --git a/lib/websocket/websocket.nit b/lib/websocket/websocket.nit index ebf3f49..7e4d329 100644 --- a/lib/websocket/websocket.nit +++ b/lib/websocket/websocket.nit @@ -24,14 +24,11 @@ import base64 intrude import standard::stream -# Websocket compatible server, works as an extra layer to the original Sockets -class WebSocket - super BufferedIStream - super OStream - super PollableIStream - - # Client connection to the server - var client: TCPStream +# Websocket compatible listener +# +# Produces Websocket client-server connections +class WebSocketListener + super Socket # Socket listening to connections on a defined port var listener: TCPServer @@ -39,39 +36,50 @@ class WebSocket # Creates a new Websocket server listening on given port with `max_clients` slots available init(port: Int, max_clients: Int) do - _buffer = new FlatBuffer - _buffer_pos = 0 listener = new TCPServer(port) listener.listen max_clients end - # Accept an incoming connection and initializes the handshake - fun accept + # Accepts an incoming connection + fun accept: WebsocketConnection do assert not listener.closed var client = listener.accept assert client != null - self.client = client + return new WebsocketConnection(listener.port, "", client) + end + + # Stop listening for incoming connections + fun close + do + listener.close + end +end + +# Connection to a websocket client +# +# Can be used to communicate with a client +class WebsocketConnection + super TCPStream + + init do + _buffer = new FlatBuffer + _buffer_pos = 0 var headers = parse_handshake var resp = handshake_response(headers) client.write(resp) end - # Disconnect from a client - fun disconnect_client - do - client.close - end + # Client connection to the server + var client: TCPStream - # Disconnects the client if one is connected - # And stops the server + # Disconnect from a client redef fun close do client.close - listener.close end # Parses the input handshake sent by the client @@ -132,9 +140,9 @@ class WebSocket # Reads an HTTP frame protected fun read_http_frame(buf: Buffer): String do - client.append_line_to(buf) - buf.chars.add('\n') - if buf.has_substring("\r\n\r\n", buf.length - 4) then return buf.to_s + buf.append client.read_line + buf.append("\r\n") + if buf.has_suffix("\r\n\r\n") then return buf.to_s return read_http_frame(buf) end @@ -222,9 +230,9 @@ class WebSocket end # Checks if a connection to a client is available - fun connected: Bool do return client.connected + redef fun connected do return client.connected - redef fun write(msg: Text) + redef fun write(msg) do client.write(frame_message(msg.to_s)) end @@ -238,7 +246,7 @@ class WebSocket unpad_message end - redef fun end_reached do return _buffer_pos >= _buffer.length and client.eof + redef fun end_reached do return client._buffer_pos >= client._buffer.length and client.end_reached # Is there some data available to be read ? fun can_read(timeout: Int): Bool do return client.ready_to_read(timeout) diff --git a/src/compiler/compiler.nit b/src/compiler/compiler.nit index 902a656..ea60c0a 100644 --- a/src/compiler/compiler.nit +++ b/src/compiler/compiler.nit @@ -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 diff --git a/src/compiler/compiler_ffi.nit b/src/compiler/compiler_ffi.nit index ca22005..8466af1 100644 --- a/src/compiler/compiler_ffi.nit +++ b/src/compiler/compiler_ffi.nit @@ -43,7 +43,7 @@ redef class MModule ensure_compile_nitni_base(v) - nitni_ccu.header_c_types.add("#include \"{name}._ffi.h\"\n") + nitni_ccu.header_c_types.add("#include \"{c_name}._ffi.h\"\n") nitni_ccu.header_c_types.add """ extern void nitni_global_ref_incr(void*); extern void nitni_global_ref_decr(void*); @@ -255,11 +255,11 @@ end redef class CCompilationUnit fun write_as_nitni(mmodule: MModule, compdir: String) do - var base_name = "{mmodule.name}._nitni" + var base_name = "{mmodule.c_name}._nitni" var h_file = "{base_name}.h" write_header_to_file( mmodule, "{compdir}/{h_file}", new Array[String], - "{mmodule.cname.to_s.to_upper}_NITG_NITNI_H") + "{mmodule.c_name.to_s.to_upper}_NITG_NITNI_H") var c_file = "{base_name}.c" write_body_to_file( mmodule, "{compdir}/{c_file}", ["\"{h_file}\""] ) diff --git a/src/compiler/separate_compiler.nit b/src/compiler/separate_compiler.nit index 68438c7..9c03910 100644 --- a/src/compiler/separate_compiler.nit +++ b/src/compiler/separate_compiler.nit @@ -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 diff --git a/src/compiler/separate_erasure_compiler.nit b/src/compiler/separate_erasure_compiler.nit index 8a33265..2c90e65 100644 --- a/src/compiler/separate_erasure_compiler.nit +++ b/src/compiler/separate_erasure_compiler.nit @@ -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("\}") diff --git a/src/doc/doc_down.nit b/src/doc/doc_down.nit index 1c77939..1cdc51a 100644 --- a/src/doc/doc_down.nit +++ b/src/doc/doc_down.nit @@ -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) diff --git a/src/doc/doc_pages.nit b/src/doc/doc_pages.nit index f8a1250..38e6cdf 100644 --- a/src/doc/doc_pages.nit +++ b/src/doc/doc_pages.nit @@ -166,7 +166,7 @@ class Nitdoc private fun modules do for mmodule in model.mmodules do - if mmodule.is_fictive then continue + if mmodule.is_fictive or mmodule.is_test_suite then continue var page = new NitdocModule(ctx, model, mainmodule, mmodule) page.render.write_to_file("{ctx.output_dir.to_s}/{page.page_url}") end @@ -211,7 +211,7 @@ class QuickSearch init do for mmodule in model.mmodules do - if mmodule.is_fictive then continue + if mmodule.is_fictive or mmodule.is_test_suite then continue add_result_for(mmodule.name, mmodule.full_name, mmodule.nitdoc_url) end for mclass in model.mclasses do @@ -667,7 +667,7 @@ class NitdocSearch private fun modules_list: Array[MModule] do var sorted = new Array[MModule] for mmodule in model.mmodule_importation_hierarchy do - if mmodule.is_fictive then continue + if mmodule.is_fictive or mmodule.is_test_suite then continue sorted.add mmodule end name_sorter.sort(sorted) @@ -933,7 +933,7 @@ class NitdocModule # Imports var lst = new Array[MModule] for dep in imports do - if dep.is_fictive then continue + if dep.is_fictive or dep.is_test_suite then continue if dep == mmodule then continue lst.add(dep) end @@ -945,7 +945,7 @@ class NitdocModule # Clients lst = new Array[MModule] for dep in clients do - if dep.is_fictive then continue + if dep.is_fictive or dep.is_test_suite then continue if dep == mmodule then continue lst.add(dep) end @@ -1024,10 +1024,10 @@ class NitdocModule fun tpl_dot(mmodules: Collection[MModule]): nullable TplArticle do var poset = new POSet[MModule] for mmodule in mmodules do - if mmodule.is_fictive then continue + if mmodule.is_fictive or mmodule.is_test_suite then continue poset.add_node mmodule for omodule in mmodules do - if mmodule.is_fictive then continue + if omodule.is_fictive or omodule.is_test_suite then continue poset.add_node mmodule if mmodule.in_importation < omodule then poset.add_edge(mmodule, omodule) diff --git a/src/ffi/cpp.nit b/src/ffi/cpp.nit index 8ca389a..a6a8ca3 100644 --- a/src/ffi/cpp.nit +++ b/src/ffi/cpp.nit @@ -124,7 +124,7 @@ class CPPLanguage # write .cpp and .hpp file cpp_file.header_custom.add("extern \"C\" \{\n") - cpp_file.header_custom.add("#include \"{mmodule.name}._ffi.h\"\n") + cpp_file.header_custom.add("#include \"{mmodule.c_name}._ffi.h\"\n") cpp_file.header_custom.add("\}\n") var file = cpp_file.write_to_files(mmodule, compdir) @@ -158,10 +158,10 @@ class CPPCompilationUnit fun write_to_files(mmodule: MModule, compdir: String): ExternCppFile do - var base_name = "{mmodule.name}._ffi" + var base_name = "{mmodule.c_name}._ffi" var h_file = "{base_name}.hpp" - var guard = "{mmodule.cname.to_s.to_upper}_NIT_HPP" + var guard = "{mmodule.c_name.to_s.to_upper}_NIT_HPP" write_header_to_file(mmodule, "{compdir}/{h_file}", new Array[String], guard) diff --git a/src/ffi/ffi.nit b/src/ffi/ffi.nit index 019d201..b854750 100644 --- a/src/ffi/ffi.nit +++ b/src/ffi/ffi.nit @@ -57,7 +57,7 @@ redef class MModule # include dependancies FFI for mod in header_dependencies do - if mod.uses_ffi then ffi_ccu.header_custom.add("#include \"{mod.name}._ffi.h\"\n") + if mod.uses_ffi then ffi_ccu.header_custom.add("#include \"{mod.c_name}._ffi.h\"\n") end ffi_ccu.write_as_impl(self, compdir) @@ -95,7 +95,7 @@ redef class AModule language.compile_module_block(block, ffi_ccu, mmodule) end - ffi_ccu.header_c_base.add( "#include \"{mmodule.name}._nitni.h\"\n" ) + ffi_ccu.header_c_base.add( "#include \"{mmodule.c_name}._nitni.h\"\n" ) ffi_ccu.body_decl.add("#ifdef ANDROID\n") ffi_ccu.body_decl.add(" #include \n") diff --git a/src/ffi/ffi_base.nit b/src/ffi/ffi_base.nit index e470276..babab08 100644 --- a/src/ffi/ffi_base.nit +++ b/src/ffi/ffi_base.nit @@ -152,10 +152,10 @@ end redef class CCompilationUnit fun write_as_impl(mmodule: MModule, compdir: String) do - var base_name = "{mmodule.name}._ffi" + var base_name = "{mmodule.c_name}._ffi" var h_file = "{base_name}.h" - var guard = "{mmodule.cname.to_s.to_upper}_NIT_H" + var guard = "{mmodule.c_name.to_upper}_NIT_H" write_header_to_file(mmodule, "{compdir}/{h_file}", new Array[String], guard) var c_file = "{base_name}.c" diff --git a/src/ffi/header_dependency.nit b/src/ffi/header_dependency.nit index 10c1db3..84bbb29 100644 --- a/src/ffi/header_dependency.nit +++ b/src/ffi/header_dependency.nit @@ -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 diff --git a/src/ffi/objc.nit b/src/ffi/objc.nit index 9ab6f7f..f031289 100644 --- a/src/ffi/objc.nit +++ b/src/ffi/objc.nit @@ -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,9 +100,15 @@ 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.cname}}}._ffi.h" + #include "{{{mmodule.c_name}}}._ffi.h" """ var file = objc_file.write_to_files(mmodule, compdir) @@ -114,10 +143,10 @@ private class ObjCCompilationUnit # Write this compilation unit to Objective-C source files fun write_to_files(mmodule: MModule, compdir: String): ExternObjCFile do - var base_name = "{mmodule.cname}._ffi" + var base_name = "{mmodule.c_name}._ffi" var h_file = "{base_name}_m.h" - var guard = "{mmodule.cname.to_s.to_upper}_NIT_OBJC_H" + var guard = "{mmodule.c_name.to_upper}_NIT_OBJC_H" write_header_to_file(mmodule, compdir/h_file, new Array[String], guard) var c_file = "{base_name}.m" @@ -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 diff --git a/src/interpreter/debugger_socket.nit b/src/interpreter/debugger_socket.nit index 5675a7d..50f98c7 100644 --- a/src/interpreter/debugger_socket.nit +++ b/src/interpreter/debugger_socket.nit @@ -97,15 +97,16 @@ redef class ModelBuilder sock.close sys.set_io(ns,ns,ns) else if self.toolcontext.opt_websocket_mode.value then - var websock = new WebSocket(toolcontext.opt_debug_port.value, 1) - websock.accept - sys.set_io(websock,websock,websock) + var websock = new WebSocketListener(toolcontext.opt_debug_port.value, 1) + var cli = websock.accept + websock.close + sys.set_io(cli,cli,cli) end end fun close_stdstreams do - if sys.stdin isa WebSocket or sys.stdin isa TCPStream then + if sys.stdin isa TCPStream then sys.stdin.close sys.stdout.close sys.stderr.close @@ -118,6 +119,6 @@ redef class Sys do self.stdin = istream self.stdout = ostream - self.stderr = ostream + self.stderr = errstream end end diff --git a/src/interpreter/primitive_types.nit b/src/interpreter/primitive_types.nit index 127815b..0de93d3 100644 --- a/src/interpreter/primitive_types.nit +++ b/src/interpreter/primitive_types.nit @@ -15,22 +15,23 @@ module primitive_types intrude import standard::file +intrude import standard::string # Wrapper for `NativeFile` class PrimitiveNativeFile - var file: FStream + var file: IOS init native_stdin do - file = new IFStream.from_fd(0) + file = sys.stdin end init native_stdout do - file = new OFStream.from_fd(1) + file = sys.stdout end init native_stderr do - file = new OFStream.from_fd(2) + file = sys.stderr end init io_open_read(path: String) do @@ -41,19 +42,42 @@ class PrimitiveNativeFile file = new OFStream.open(path.to_s) end - fun address_is_null: Bool do return file._file.address_is_null + fun address_is_null: Bool do + if file isa FStream then return file.as(FStream)._file.address_is_null + return false + end - fun io_read(buf: NativeString, len: Int): Int do return file._file.io_read(buf, len) + fun io_read(buf: NativeString, len: Int): Int do + if file isa FStream then return file.as(FStream)._file.io_read(buf, len) + var str = file.as(IStream).read(len) + str.to_cstring.copy_to(buf, str.length, 0, 0) + return str.length + end - fun io_write(buf: NativeString, len: Int): Int do return file._file.io_write(buf, len) + fun io_write(buf: NativeString, len: Int): Int do + if file isa FStream then return file.as(FStream)._file.io_write(buf, len) + file.as(OStream).write(buf.to_s_with_length(len)) + return len + end - fun io_close: Int do return file._file.io_close + fun io_close: Int do + if file isa FStream then return file.as(FStream)._file.io_close + file.close + return 0 + end - fun fileno: Int do return file._file.fileno + fun fileno: Int do + if file isa FStream then return file.as(FStream)._file.fileno + return 0 + end - fun flush: Int do return file._file.flush + fun flush: Int do + if file isa FStream then return file.as(FStream)._file.flush + return 0 + end fun set_buffering_type(size, mode: Int): Int do - return file._file.set_buffering_type(size, mode) + if file isa FStream then return file.as(FStream)._file.set_buffering_type(size, mode) + return 0 end end diff --git a/src/loader.nit b/src/loader.nit index 58d3506..a046815 100644 --- a/src/loader.nit +++ b/src/loader.nit @@ -528,6 +528,7 @@ redef class ModelBuilder self.mmodule2nmodule[mmodule] = nmodule if decl != null then + # Extract documentation var ndoc = decl.n_doc if ndoc != null then var mdoc = ndoc.to_mdoc @@ -536,6 +537,8 @@ redef class ModelBuilder else advice(decl, "missing-doc", "Documentation warning: Undocumented module `{mmodule}`") end + # Is the module a test suite? + mmodule.is_test_suite = not decl.get_annotations("test_suite").is_empty end return mmodule diff --git a/src/model/mmodule.nit b/src/model/mmodule.nit index e66f164..d88a0ba 100644 --- a/src/model/mmodule.nit +++ b/src/model/mmodule.nit @@ -76,6 +76,14 @@ class MModule # The group of module in the project if any var mgroup: nullable MGroup + # The project of the module if any + # Safe alias for `mgroup.mproject` + fun mproject: nullable MProject + do + var g = mgroup + if g == null then return null else return g.mproject + end + # The short name of the module redef var name: String @@ -104,6 +112,22 @@ class MModule end end + # The namespace used for entities according to their visibility `v`. + # + # Public entities use only the project as a namespace. + # Private entities use the `full_name` (i.e. "project::module") + # + # This method is used by entities to implement their `full_name`. + fun namespace_for(v: MVisibility): String do + if v <= private_visibility then return full_name + var mgroup = self.mgroup + if mgroup == null then + return full_name + else + return mgroup.mproject.full_name + end + end + # Return the name of the global C identifier associated to `self`. # This name is used to prefix files and other C identifiers associated with `self`. redef var c_name: String is lazy do @@ -117,6 +141,19 @@ class MModule return res end + # C identifier version of `namespace_for`. + # See `c_name` + # + # This method is used by entities to implement their `c_name`. + fun c_namespace_for(v: MVisibility): String do + if v <= private_visibility then return c_name + var mgroup = self.mgroup + if mgroup == null then + return c_name + else + return mgroup.mproject.c_name + end + end # Create a new empty module and register it to a model init @@ -203,5 +240,8 @@ class MModule # exposed to the final user. var is_fictive: Bool = false is writable + # Is `self` a unit test module used by `nitunit`? + var is_test_suite: Bool = false is writable + redef fun parent_concern do return mgroup end diff --git a/src/model/model.nit b/src/model/model.nit index 4d8ddc4..ff12710 100644 --- a/src/model/model.nit +++ b/src/model/model.nit @@ -361,9 +361,13 @@ class MClass # # It is the name of the class prefixed by the full_name of the `intro_mmodule` # Example: `"owner::module::MyClass"` - redef var full_name is lazy do return "{self.intro_mmodule.full_name}::{name}" + redef var full_name is lazy do + return "{self.intro_mmodule.namespace_for(visibility)}::{name}" + end - redef var c_name is lazy do return "{intro_mmodule.c_name}__{name.to_cmangle}" + redef var c_name is lazy do + return "{intro_mmodule.c_namespace_for(visibility)}__{name.to_cmangle}" + end # The number of generic formal parameters # 0 if the class is not generic @@ -539,17 +543,29 @@ class MClassDef # Example: "my_module#intro_module::MyClass" redef var full_name is lazy do if is_intro then + # public gives 'p#A' + # private gives 'p::m#A' + return "{mmodule.namespace_for(mclass.visibility)}#{mclass.name}" + else if mclass.intro_mmodule.mproject != mmodule.mproject then + # public gives 'q::n#p::A' + # private gives 'q::n#p::m::A' + return "{mmodule.full_name}#{mclass.full_name}" + else if mclass.visibility > private_visibility then + # public gives 'p::n#A' return "{mmodule.full_name}#{mclass.name}" else - return "{mmodule.full_name}#{mclass.full_name}" + # private gives 'p::n#::m::A' (redundant p is omitted) + return "{mmodule.full_name}#::{mclass.intro_mmodule.name}::{mclass.name}" end end redef var c_name is lazy do if is_intro then - return mclass.c_name + return "{mmodule.c_namespace_for(mclass.visibility)}___{mclass.c_name}" + else if mclass.intro_mmodule.mproject == mmodule.mproject and mclass.visibility > private_visibility then + return "{mmodule.c_name}___{mclass.name.to_cmangle}" else - return "{mmodule.c_name}__{mclass.c_name.to_cmangle}" + return "{mmodule.c_name}___{mclass.c_name}" end end @@ -1738,11 +1754,12 @@ abstract class MProperty # It is the short-`name` prefixed by the short-name of the class and the full-name of the module. # Example: "my_project::my_module::MyClass::my_method" redef var full_name is lazy do - return "{intro_mclassdef.mmodule.full_name}::{intro_mclassdef.mclass.name}::{name}" + return "{intro_mclassdef.mmodule.namespace_for(visibility)}::{intro_mclassdef.mclass.name}::{name}" end redef var c_name is lazy do - return "{intro_mclassdef.mmodule.c_name}__{intro_mclassdef.mclass.c_name}__{name.to_cmangle}" + # FIXME use `namespace_for` + return "{intro_mclassdef.mmodule.c_name}__{intro_mclassdef.mclass.name.to_cmangle}__{name.to_cmangle}" end # The visibility of the property @@ -2018,42 +2035,66 @@ abstract class MPropDef # Therefore the combination of identifiers is awful, # the worst case being # - # ~~~nitish - # "{mclassdef.mmodule.full_name}#{mclassdef.mclass.intro_mmodule.full_name}::{mclassdef.name}#{mproperty.intro_mclassdef.mmodule.full_name}::{mproperty.intro_mclassdef.name}::{name}" - # ~~~ + # * a property "p::m::A::x" + # * redefined in a refinement of a class "q::n::B" + # * in a module "r::o" + # * so "r::o#q::n::B#p::m::A::x" # # Fortunately, the full-name is simplified when entities are repeated. - # The simplest form is "my_module#MyClass#my_property". + # For the previous case, the simplest form is "p#A#x". redef var full_name is lazy do var res = new FlatBuffer - res.append mclassdef.mmodule.full_name - res.append "#" - if not mclassdef.is_intro then - res.append mclassdef.mclass.intro_mmodule.full_name - res.append "::" - end - res.append mclassdef.name + + # The first part is the mclassdef. Worst case is "r::o#q::n::B" + res.append mclassdef.full_name + res.append "#" - if mproperty.intro_mclassdef.mmodule != mclassdef.mmodule then - res.append mproperty.intro_mclassdef.mmodule.full_name - res.append "::" - end - if mclassdef.mclass != mproperty.intro_mclassdef.mclass then - res.append mproperty.intro_mclassdef.mclass.name - res.append "::" + + if mclassdef.mclass == mproperty.intro_mclassdef.mclass then + # intro are unambiguous in a class + res.append name + else + # Just try to simplify each part + if mclassdef.mmodule.mproject != mproperty.intro_mclassdef.mmodule.mproject then + # precise "p::m" only if "p" != "r" + res.append mproperty.intro_mclassdef.mmodule.full_name + res.append "::" + else if mproperty.visibility <= private_visibility then + # Same project ("p"=="q"), but private visibility, + # does the module part ("::m") need to be displayed + if mclassdef.mmodule.namespace_for(mclassdef.mclass.visibility) != mproperty.intro_mclassdef.mmodule.mproject then + res.append "::" + res.append mproperty.intro_mclassdef.mmodule.name + res.append "::" + end + end + if mclassdef.mclass != mproperty.intro_mclassdef.mclass then + # precise "B" only if not the same class than "A" + res.append mproperty.intro_mclassdef.name + res.append "::" + end + # Always use the property name "x" + res.append mproperty.name end - res.append name return res.to_s end redef var c_name is lazy do var res = new FlatBuffer res.append mclassdef.c_name - res.append "__" - if is_intro then + res.append "___" + if mclassdef.mclass == mproperty.intro_mclassdef.mclass then res.append name.to_cmangle else - res.append mproperty.c_name.to_cmangle + if mclassdef.mmodule != mproperty.intro_mclassdef.mmodule then + res.append mproperty.intro_mclassdef.mmodule.c_name + res.append "__" + end + if mclassdef.mclass != mproperty.intro_mclassdef.mclass then + res.append mproperty.intro_mclassdef.name.to_cmangle + res.append "__" + end + res.append mproperty.name.to_cmangle end return res.to_s end diff --git a/src/model/mproject.nit b/src/model/mproject.nit index 9002009..283d54c 100644 --- a/src/model/mproject.nit +++ b/src/model/mproject.nit @@ -27,6 +27,10 @@ class MProject # The name of the project redef var name: String + redef fun full_name do return name + + redef var c_name = name.to_cmangle is lazy + # The model of the project redef var model: Model diff --git a/src/nitni/nitni_base.nit b/src/nitni/nitni_base.nit index 4f31aaf..6685029 100644 --- a/src/nitni/nitni_base.nit +++ b/src/nitni/nitni_base.nit @@ -22,7 +22,6 @@ module nitni_base import parser import modelbuilder # builder only for externcalls -private import compiler::abstract_compiler redef class MMethod # Short name of this method in C (without the class name) @@ -52,12 +51,6 @@ redef class MMethod end end -redef class MModule - # Mangled name of this module in C - fun cname: String do return c_name # FIXME this is a hack to keep the internal FFI - # API independent of the compilers while still using the `MModule::c_name` service. -end - redef class MMethodDef # Name of the function to callback this method from C, # also used in other functions names used for this method. diff --git a/src/nitpretty.nit b/src/nitpretty.nit index af3fae0..9dd723e 100644 --- a/src/nitpretty.nit +++ b/src/nitpretty.nit @@ -32,6 +32,20 @@ redef class ToolContext var opt_meld = new OptionBool("Show diff between source and output using meld", "--meld") + # Break too long string literals. + var opt_break_str = new OptionBool("Break too long string literals", "--break-strings") + + # Force `do` on the same line as the method signature. + var opt_inline_do = new OptionBool("Force do keyword on the same line as the method signature", + "--inline-do") + + # Force formatting on empty lines. + # + # By default empty lines are kept as they were typed in the file. + # When enabling this option, `nitpretty` will decide where to break lines + # and will put empty lines to separate properties and code blocks. + var opt_skip_empty = new OptionBool("Force formatting of empty lines", "--skip-empty") + # Check formatting instead of pretty printing. # # This option create a tempory pretty printed file then check if @@ -52,9 +66,11 @@ end # process options var toolcontext = new ToolContext -toolcontext.option_context. - add_option(toolcontext.opt_dir, toolcontext.opt_output, toolcontext.opt_diff, - toolcontext.opt_meld, toolcontext.opt_check) +var opts = toolcontext.option_context +opts.add_option(toolcontext.opt_dir, toolcontext.opt_output) +opts.add_option(toolcontext.opt_diff, toolcontext.opt_meld, toolcontext.opt_check) +opts.add_option(toolcontext.opt_break_str, toolcontext.opt_inline_do) +opts.add_option(toolcontext.opt_skip_empty) toolcontext.tooldescription = "Usage: nitpretty [OPTION]... \n" + "Pretty print Nit code from Nit source files." @@ -81,6 +97,16 @@ var dir = toolcontext.opt_dir.value or else ".nitpretty" if not dir.file_exists then dir.mkdir var v = new PrettyPrinterVisitor +if toolcontext.opt_break_str.value then + v.break_strings = true +end +if toolcontext.opt_inline_do.value then + v.inline_do = true +end +if toolcontext.opt_skip_empty.value then + v.skip_empty = true +end + for mmodule in mmodules do var nmodule = mbuilder.mmodule2node(mmodule) if nmodule == null then diff --git a/src/compiler/android_platform.nit b/src/platform/android.nit similarity index 99% rename from src/compiler/android_platform.nit rename to src/platform/android.nit index b7069e3..6ba5502 100644 --- a/src/compiler/android_platform.nit +++ b/src/platform/android.nit @@ -15,10 +15,10 @@ # 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 diff --git a/src/compiler/android_annotations.nit b/src/platform/android_annotations.nit similarity index 100% rename from src/compiler/android_annotations.nit rename to src/platform/android_annotations.nit diff --git a/src/compiler/emscripten_platform.nit b/src/platform/emscripten.nit similarity index 97% rename from src/compiler/emscripten_platform.nit rename to src/platform/emscripten.nit index 6332098..dc2662f 100644 --- a/src/compiler/emscripten_platform.nit +++ b/src/platform/emscripten.nit @@ -15,10 +15,10 @@ # 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) diff --git a/src/platform.nit b/src/platform/platform.nit similarity index 100% rename from src/platform.nit rename to src/platform/platform.nit diff --git a/src/compiler/pnacl_platform.nit b/src/platform/pnacl.nit similarity index 99% rename from src/compiler/pnacl_platform.nit rename to src/platform/pnacl.nit index 3f96318..9fceaad 100644 --- a/src/compiler/pnacl_platform.nit +++ b/src/platform/pnacl.nit @@ -15,10 +15,10 @@ # 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/src/pretty.nit b/src/pretty.nit index 3b9f7ef..2d08571 100644 --- a/src/pretty.nit +++ b/src/pretty.nit @@ -79,7 +79,7 @@ class PrettyPrinterVisitor current_token = nmodule.location.file.first_token visit nmodule catch_up nmodule.location.file.last_token - tpl.add "\n" + if skip_empty then tpl.add "\n" return tpl.as(not null) end @@ -172,7 +172,7 @@ class PrettyPrinterVisitor else abort end - assert current_token.location <= token.location + if current_token.location > token.location then return while current_token != token do visit current_token end @@ -183,7 +183,7 @@ class PrettyPrinterVisitor visit current_token end - while current_token isa TEol do skip + while current_token isa TEol do visit(current_token) end # The template under construction. @@ -223,6 +223,14 @@ class PrettyPrinterVisitor if current_length == 0 and last_line_is_blank then return previous_length = current_length current_length = 0 + if skip_empty then wait_addn += 1 + end + + # Perform `addn` even if not `skip_empty`. + fun forcen do + if current_length == 0 and last_line_is_blank then return + previous_length = current_length + current_length = 0 wait_addn += 1 end @@ -243,6 +251,15 @@ class PrettyPrinterVisitor consume "." end end + + # Do we break string literals that are too long? + var break_strings = false is public writable + + # Do we force `do` to be on the same line as the method signature? + var inline_do = false is public writable + + # Do we force the deletion of empty lines? + var skip_empty = false is public writable end # Base framework redefs @@ -255,9 +272,10 @@ redef class ANodes[E] if e != first then if not e_can_inline then v.add "," - v.addn - v.addt + v.forcen + v.indent += 1 v.addt + v.indent -= 1 else v.add ", " end @@ -308,6 +326,17 @@ redef class Token redef fun was_inline do return true end +redef class TEol + redef fun accept_pretty_printer(v) do + if v.skip_empty then + super + else + v.add text + v.current_token = next_token + end + end +end + redef class Prod redef fun accept_pretty_printer(v) do v.visit first_token @@ -344,7 +373,7 @@ redef class Prod end redef fun was_inline do - return first_token.location.line_start == last_token.location.line_end + return start_token.location.line_start == last_token.location.line_end end end @@ -355,13 +384,13 @@ redef class TComment if is_adoc then v.addt super - v.addn + v.forcen return end if is_licence then super - v.addn + v.forcen if is_last_in_group then v.addn return end @@ -370,7 +399,7 @@ redef class TComment v.addn v.addt super - v.addn + v.forcen v.addn return end @@ -379,13 +408,14 @@ redef class TComment if next_token isa TComment and is_first_in_group then v.addn v.addt super - v.addn + v.forcen var prev_token = self.prev_token if prev_token isa TComment and prev_token.is_inline and is_last_in_group then v.addn return end super + if not v.skip_empty then v.forcen end # Is `self` part of an `ADoc`? @@ -434,7 +464,6 @@ redef class AAnnotations redef fun accept_pretty_printer(v) do v.adds v.consume "is" - if v.can_inline(self) then v.adds for n_item in n_items do @@ -443,21 +472,27 @@ redef class AAnnotations v.add ", " end end - v.finish_line - else if n_items.length > 1 then - v.addn + if not was_inline then + v.finish_line + if v.current_token isa TKwend then v.skip + end + else + v.forcen v.indent += 1 - for n_item in n_items do v.addt v.visit n_item v.finish_line - v.addn + if n_item != n_items.last then + if was_inline then + v.forcen + else + v.addn + end + end end - v.indent -= 1 end - if not was_inline and v.current_token isa TKwend then v.skip end redef fun is_inlinable do @@ -469,6 +504,10 @@ end redef class AAnnotation redef fun accept_pretty_printer(v) do + if n_visibility != null and not n_visibility isa APublicVisibility then + v.visit n_visibility + v.adds + end v.visit n_atid if not n_args.is_empty then if n_opar == null then @@ -494,7 +533,7 @@ redef class AModule v.visit n_moduledecl if not n_imports.is_empty then - v.addn + if v.skip_empty then v.addn for n_import in n_imports do v.catch_up n_import @@ -516,7 +555,7 @@ redef class AModule end if not n_classdefs.is_empty then - v.addn + if v.skip_empty then v.addn for n_classdef in n_classdefs do v.catch_up n_classdef @@ -561,7 +600,7 @@ redef class AModuledecl end v.finish_line - v.addn + if v.skip_empty then v.addn end end @@ -582,7 +621,7 @@ redef class ANoImport v.adds v.visit n_kwend v.finish_line - v.addn + if v.skip_empty then v.addn end end @@ -597,7 +636,7 @@ redef class AStdImport v.adds v.visit n_name v.finish_line - v.addn + if v.skip_empty then v.addn end end @@ -609,9 +648,9 @@ redef class AClassdef v.catch_up n_propdef if n_propdef.n_doc != null or not v.can_inline(n_propdef) then - if n_propdef != n_propdefs.first then v.addn + if v.skip_empty and n_propdef != n_propdefs.first then v.addn v.visit n_propdef - if n_propdef != n_propdefs.last then v.addn + if v.skip_empty and n_propdef != n_propdefs.last then v.addn else v.visit n_propdef end @@ -660,7 +699,7 @@ redef class AStdClassdef end else v.finish_line - v.addn + if v.skip_empty then v.addn v.indent += 1 for n_superclass in n_superclasses do @@ -672,7 +711,7 @@ redef class AStdClassdef end if not n_superclasses.is_empty and not n_propdefs.is_empty then - v.addn + if v.skip_empty then v.addn end super @@ -682,7 +721,7 @@ redef class AStdClassdef v.visit n_kwend v.finish_line - v.addn + if v.skip_empty then v.addn assert v.indent == 0 end @@ -772,6 +811,90 @@ redef class APropdef end end + # Factorize annotations visit for all APropdef. + # + # Return true if annotations were inlined. + fun visit_annotations(v: PrettyPrinterVisitor, n_annotations: nullable AAnnotations): Bool do + var res = v.can_inline(n_annotations) + if n_annotations != null then v.visit n_annotations + return res + end + + # Factorize block visit for APropdefs. + # + # Were annotations printed inline? If so, we need to print the block differently. + fun visit_block(v: PrettyPrinterVisitor, n_block: nullable AExpr, annot_inline: Bool) do + # var can_inline = v.can_inline(n_block) + if n_block == null then return + if n_annotations != null and not annot_inline then + v.forcen + v.addt + end + if v.inline_do then + while not v.current_token isa TKwdo do v.skip + end + var token = v.current_token + var do_inline = true + loop + if token isa TEol then + v.skip + if not v.can_inline(n_block) then + v.forcen + v.addt + do_inline = false + end + end + token = v.current_token + if token isa TKwdo then break + end + if annot_inline and do_inline then v.adds + v.consume "do" + + if v.can_inline(n_block) and do_inline then + v.adds + + if n_block isa ABlockExpr then + if n_block.n_expr.is_empty then + v.visit n_block.n_kwend + else + v.visit n_block.n_expr.first + v.current_token = n_block.n_kwend + v.skip + end + else + v.visit n_block + if v.current_token isa TKwend then v.skip + end + else + v.finish_line + if was_inline then + v.forcen + else + v.addn + end + v.indent += 1 + + if n_block isa ABlockExpr then + n_block.force_block = true + v.visit n_block + v.catch_up n_block.n_kwend + else + v.addt + v.visit n_block + v.forcen + end + + v.indent -= 1 + v.addt + if n_block isa ABlockExpr then + v.visit n_block.n_kwend + else + v.add "end" + end + end + v.finish_line + end + redef fun start_token do if n_doc == null then return super return n_doc.last_token.next_token @@ -798,7 +921,8 @@ redef class AAttrPropdef v.visit n_expr end - if n_annotations != null then v.visit n_annotations + var annot_inline = visit_annotations(v, n_annotations) + visit_block(v, n_block, annot_inline) v.finish_line v.addn end @@ -822,6 +946,7 @@ redef class ATypePropdef v.consume ":" v.adds v.visit n_type + visit_annotations(v, n_annotations) v.finish_line v.addn end @@ -834,7 +959,6 @@ redef class AMethPropdef # TODO: Handle extern annotations var before = v.indent - var can_inline = v.can_inline(self) super if n_kwinit != null then v.visit n_kwinit if n_kwmeth != null then v.visit n_kwmeth @@ -847,72 +971,15 @@ redef class AMethPropdef v.visit n_signature - if n_annotations != null then - v.visit n_annotations - else - v.adds - end + var annot_inline = visit_annotations(v, n_annotations) if n_extern_calls != null or n_extern_code_block != null then - if n_annotations != null then v.adds + v.adds if n_extern_calls != null then v.visit n_extern_calls if n_extern_code_block != null then v.visit n_extern_code_block end - var n_block = self.n_block - - if n_block != null then - while not v.current_token isa TKwdo do v.skip - if n_annotations != null then - if v.can_inline(n_annotations) then - v.adds - else - v.addt - end - end - v.consume "do" - - if can_inline then - v.adds - - if n_block isa ABlockExpr then - if n_block.n_expr.is_empty then - v.visit n_block.n_kwend - else - v.visit n_block.n_expr.first - v.current_token = n_block.n_kwend - v.skip - end - else - v.visit n_block - if v.current_token isa TKwend then v.skip - end - else - v.finish_line - v.addn - v.indent += 1 - - if n_block isa ABlockExpr then - n_block.force_block = true - v.visit n_block - v.catch_up n_block.n_kwend - else - v.addt - v.visit n_block - v.addn - end - - v.indent -= 1 - v.addt - if n_block isa ABlockExpr then - v.visit n_block.n_kwend - else - v.add "end" - end - end - end - - v.finish_line + visit_block(v, n_block, annot_inline) v.addn assert v.indent == before end @@ -934,7 +1001,7 @@ end redef class AMainMethPropdef redef fun accept_pretty_printer(v) do v.visit n_block - v.addn + if v.skip_empty then v.addn end end @@ -980,8 +1047,9 @@ redef class AExternCalls v.visit_list n_extern_calls else v.addn + v.indent += 1 v.addt - v.addt + v.indent -= 1 v.visit_list n_extern_calls end @@ -1087,7 +1155,7 @@ redef class TExternCodeSegment for line in lines do v.add line.r_trim - v.addn + v.forcen end v.addt @@ -1177,11 +1245,18 @@ redef class AIfExpr else if n_then == null then v.add "end" end - v.skip_to last_token.last_real_token_in_line else v.finish_line - v.addn + if was_inline then + v.forcen + else if not v.skip_empty and n_then != null and + n_then.was_inline and + n_then.location.line_end == location.line_start then + v.forcen # Xymus fucking syntax + else + v.addn + end v.indent += 1 if n_then != null then @@ -1191,7 +1266,11 @@ redef class AIfExpr else v.addt v.visit n_then - v.addn + if n_then.was_inline then + v.forcen + else + v.addn + end end end @@ -1210,7 +1289,11 @@ redef class AIfExpr v.visit n_else else v.finish_line - v.addn + if was_inline then + v.forcen + else + v.addn + end v.indent += 1 if n_else isa ABlockExpr then @@ -1219,7 +1302,11 @@ redef class AIfExpr else v.addt v.visit n_else - v.addn + if n_else.was_inline then + v.forcen + else + v.addn + end end if last_token isa TKwend then @@ -1479,7 +1566,6 @@ redef class ACallExpr if not n_expr isa AImplicitSelfExpr and not can_inline then v.addn v.addt - v.addt end v.visit n_id @@ -1640,8 +1726,9 @@ redef class ANewExpr if not can_inline then v.addn + v.indent += 1 v.addt - v.addt + v.indent -= 1 end v.visit n_id @@ -1749,16 +1836,15 @@ redef class AAssertExpr v.visit n_else else v.addn + v.indent += 1 if n_else isa ABlockExpr then - v.indent += 1 n_else.force_block = true v.visit n_else v.indent -= 1 v.addt v.visit n_else.n_kwend else - v.indent += 1 v.addt v.visit n_else v.addn @@ -1897,8 +1983,9 @@ private class ABinOpHelper v.visit bin_expr2 else v.addn + v.indent += 1 v.addt - v.addt + v.indent -= 1 v.visit bin_expr2 end end @@ -2073,9 +2160,13 @@ end redef class AStringFormExpr redef fun accept_pretty_printer(v) do - var can_inline = v.can_inline(self) - - if can_inline then + if not v.break_strings then + # n_string.force_inline = true + v.visit n_string + return + end + if v.can_inline(self) then + n_string.force_inline = true v.visit n_string else var text = n_string.text @@ -2086,7 +2177,11 @@ redef class AStringFormExpr if v.current_length >= v.max_size and i <= text.length - 3 then v.add "\" +" - v.addn + if was_inline then + v.forcen + else + v.addn + end v.indent += 1 v.addt v.indent -= 1 @@ -2103,7 +2198,12 @@ end redef class ASuperstringExpr redef fun accept_pretty_printer(v) do - for n_expr in n_exprs do v.visit n_expr + for n_expr in n_exprs do + if not v.break_strings then + n_expr.force_inline = true + end + v.visit n_expr + end end redef fun must_be_inline do diff --git a/src/semantize/typing.nit b/src/semantize/typing.nit index ae697d4..343edbd 100644 --- a/src/semantize/typing.nit +++ b/src/semantize/typing.nit @@ -609,6 +609,10 @@ redef class AAttrPropdef var nblock = self.n_block if nblock != null then v.visit_stmt(nblock) + if not nblock.after_flow_context.is_unreachable then + # We reach the end of the init without having a return, it is bad + v.error(self, "Control error: Reached end of block (a 'return' with a value was expected).") + end end end end @@ -975,7 +979,7 @@ redef class AForExpr is_col = true end - if mapit_cla != null and v.is_subtype(ittype, mapit_cla.get_mtype([objcla.mclass_type, objcla.mclass_type.as_nullable])) then + if mapit_cla != null and v.is_subtype(ittype, mapit_cla.get_mtype([objcla.mclass_type.as_nullable, objcla.mclass_type.as_nullable])) then # Map Iterator var coltype = ittype.supertype_to(v.mmodule, v.anchor, mapit_cla) var variables = self.variables diff --git a/tests/base_attr_init_val_block.nit b/tests/base_attr_init_val_block.nit index 6d2badc..fdafa3d 100644 --- a/tests/base_attr_init_val_block.nit +++ b/tests/base_attr_init_val_block.nit @@ -24,7 +24,7 @@ class A 2.output var res = a if res == 10 then res = 20 - return res + return res #alt1# return #alt2# end end diff --git a/tests/nitpretty.args b/tests/nitpretty.args index 61b0157..77c26ea 100644 --- a/tests/nitpretty.args +++ b/tests/nitpretty.args @@ -1,3 +1,34 @@ +--skip-empty test_pretty/test_mod1.nit +--skip-empty test_pretty/test_mod2.nit +--skip-empty test_pretty/test_mod3.nit +--skip-empty test_pretty/test_class1.nit +--skip-empty test_pretty/test_class2.nit +--skip-empty test_pretty/test_class3.nit +--skip-empty test_pretty/test_prop1.nit +--skip-empty test_pretty/test_prop2.nit +--skip-empty test_pretty/test_prop3.nit +--skip-empty test_pretty/test_loop1.nit +--skip-empty test_pretty/test_loop2.nit +--skip-empty test_pretty/test_loop3.nit +--skip-empty test_pretty/test_call1.nit +--skip-empty test_pretty/test_call2.nit +--skip-empty test_pretty/test_if1.nit +--skip-empty test_pretty/test_if2.nit +--skip-empty test_pretty/test_if3.nit +--skip-empty test_pretty/test_op1.nit +--skip-empty test_pretty/test_op2.nit +--skip-empty test_pretty/test_op3.nit +--skip-empty test_pretty/test_extern1.nit +--skip-empty test_pretty/test_attr1.nit +--skip-empty test_pretty/test_attr2.nit +--skip-empty test_pretty/test_comments1.nit +--skip-empty test_pretty/test_indent1.nit +--skip-empty test_pretty/test_prims1.nit +--skip-empty test_pretty/test_annot1.nit +--skip-empty --break-strings test_pretty/test_prop1.nit +--skip-empty --break-strings test_pretty/test_indent1.nit +--skip-empty --inline-do test_pretty/test_prop1.nit +--skip-empty --inline-do test_pretty/test_indent1.nit test_pretty/test_mod1.nit test_pretty/test_mod2.nit test_pretty/test_mod3.nit @@ -25,3 +56,7 @@ test_pretty/test_comments1.nit test_pretty/test_indent1.nit test_pretty/test_prims1.nit test_pretty/test_annot1.nit +--break-strings test_pretty/test_prop1.nit +--break-strings test_pretty/test_indent1.nit +--inline-do test_pretty/test_prop1.nit +--inline-do test_pretty/test_indent1.nit diff --git a/tests/sav/base_attr_init_val_block_alt1.res b/tests/sav/base_attr_init_val_block_alt1.res new file mode 100644 index 0000000..e50539b --- /dev/null +++ b/tests/sav/base_attr_init_val_block_alt1.res @@ -0,0 +1 @@ +alt/base_attr_init_val_block_alt1.nit:27,3--8: Error: Return without value in a function. diff --git a/tests/sav/base_attr_init_val_block_alt2.res b/tests/sav/base_attr_init_val_block_alt2.res new file mode 100644 index 0000000..8545480 --- /dev/null +++ b/tests/sav/base_attr_init_val_block_alt2.res @@ -0,0 +1 @@ +alt/base_attr_init_val_block_alt2.nit:23,6: Control error: Reached end of block (a 'return' with a value was expected). diff --git a/tests/sav/fixme/nitpretty_args22.res b/tests/sav/fixme/nitpretty_args22.res deleted file mode 100644 index 4ad3dc3..0000000 --- a/tests/sav/fixme/nitpretty_args22.res +++ /dev/null @@ -1 +0,0 @@ -UNDEFINED diff --git a/tests/sav/fixme/nitpretty_args48.res b/tests/sav/fixme/nitpretty_args48.res new file mode 100644 index 0000000..c3a432c --- /dev/null +++ b/tests/sav/fixme/nitpretty_args48.res @@ -0,0 +1,61 @@ +# 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. + +var a = 1 +var b = 2 + +# 0 +if a == b then # 1 + # 2 +else # 3 + # 4 +end # 5 + +if a == b then print a # printing a + +if a == b then + print a # printing a +end + +if a == b then print a + # end + +if a == b then a = b + +if a == b then end + +if a == b then end + +if a != b then a = b + + +if a > b then + a = b +else + a = b +end + +if a < b then + a = b +else if a == b then + a = b +end + +if a < b then + a = b +else if a == b then + a = b +else + a = b +end diff --git a/tests/sav/fixme/nitpretty_args58.res b/tests/sav/fixme/nitpretty_args58.res new file mode 100644 index 0000000..2e6ac9a --- /dev/null +++ b/tests/sav/fixme/nitpretty_args58.res @@ -0,0 +1,51 @@ +# 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. + +module test_annot1 is platform("android") + +class A + fun goo is intern + + # test + fun foo is a, b + fun bar is a, b do print "1" + fun baz is + a + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + do print "2" +end + +class B + fun foo is a, b + + + fun bar is a, b + do print "1" + + fun baz is a, b + do + bar + print "2" + end + + fun gaz is + a + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + + do + bar + print "2" + end + +end diff --git a/tests/sav/nitpretty_args21.res b/tests/sav/nitpretty_args21.res index 9b58418..7a8fe04 100644 --- a/tests/sav/nitpretty_args21.res +++ b/tests/sav/nitpretty_args21.res @@ -78,8 +78,8 @@ extern class TimeT `{time_t`} # Difference in secondes from start (self if the end time) fun difftime(start: TimeT): Float `{ return difftime(recv, start); `} - private fun intern_poll(in_fds: Array[Int], out_fds: Array[Int]): nullable Int is extern import - Array[Int].length, Array[Int].[], Int.as(nullable Int) `{`} + private fun intern_poll(in_fds: Array[Int], out_fds: Array[Int]): nullable Int is + extern import Array[Int].length, Array[Int].[], Int.as(nullable Int) `{`} end fun address_is_null: Bool is extern "address_is_null" diff --git a/tests/sav/nitpretty_args25.res b/tests/sav/nitpretty_args25.res index 6638706..e8ba342 100644 --- a/tests/sav/nitpretty_args25.res +++ b/tests/sav/nitpretty_args25.res @@ -15,7 +15,8 @@ class Foo fun bar: Bool do return true - fun foo(other: Foo): Foo do + fun foo(other: Foo): Foo + do if other.bar then return other else @@ -34,7 +35,8 @@ class Foo return nb end - fun gaz: Int do + fun gaz: Int + do if bar then # 3 return 1 else @@ -67,7 +69,9 @@ class Test[E] end end - fun save_those_nodes(nodes: Collection[Object]) do for node in nodes do count(node) + fun save_those_nodes(nodes: Collection[Object]) do + for node in nodes do count(node) + end end fun foo do @@ -78,28 +82,12 @@ fun foo do end end -print "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam tincidun" + - "t sapien et velit fringilla varius at non eros. Nunc ut ultricies metus, sit a" + - "met lacinia felis. Donec in facilisis neque, non laoreet nibh. Etiam nec purus" + - " eu orci congue iaculis eu quis lorem. Ut et blandit erat. Cras fermentum pell" + - "entesque ante, ut dapibus ipsum placerat sit amet. Vivamus pharetra, sem vitae" + - " consequat venenatis, diam risus placerat est, sed hendrerit purus justo vitae" + - " lectus. In id quam mattis, rutrum augue eu, vehicula ipsum. Nulla nec egestas" + - " turpis, nec ullamcorper odio. Pellentesque vitae arcu justo. Aliquam sed phar" + - "etra lacus." +print "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam tincidunt sapien et velit fringilla varius at non eros. Nunc ut ultricies metus, sit amet lacinia felis. Donec in facilisis neque, non laoreet nibh. Etiam nec purus eu orci congue iaculis eu quis lorem. Ut et blandit erat. Cras fermentum pellentesque ante, ut dapibus ipsum placerat sit amet. Vivamus pharetra, sem vitae consequat venenatis, diam risus placerat est, sed hendrerit purus justo vitae lectus. In id quam mattis, rutrum augue eu, vehicula ipsum. Nulla nec egestas turpis, nec ullamcorper odio. Pellentesque vitae arcu justo. Aliquam sed pharetra lacus." var lorem = "lorem" var ipsum = "ipsum" # for fun -print "We also need to handle super strings: {lorem} {ipsum} dolor sit amet, con" + - "sectetur adipiscing elit. Aliquam tincidunt sapien et velit fringilla varius a" + - "t non eros. Nunc ut ultricies metus, sit amet lacinia felis. Donec in facilisi" + - "s neque, non laoreet nibh. Etiam nec purus eu orci congue iaculis eu quis {lorem}" + - ". Ut et blandit erat. Cras fermentum pellentesque ante, ut dapibus {ipsum} pla" + - "cerat sit amet. Vivamus pharetra, sem vitae consequat venenatis, diam risus pl" + - "acerat est, sed hendrerit purus justo vitae lectus. In id quam mattis, rutrum " + - "augue eu, vehicula ipsum. Nulla nec egestas turpis, nec ullamcorper odio. Pell" + - "entesque vitae arcu justo. Aliquam sed pharetra lacus." # ending +print "We also need to handle super strings: {lorem} {ipsum} dolor sit amet, consectetur adipiscing elit. Aliquam tincidunt sapien et velit fringilla varius at non eros. Nunc ut ultricies metus, sit amet lacinia felis. Donec in facilisis neque, non laoreet nibh. Etiam nec purus eu orci congue iaculis eu quis {lorem}. Ut et blandit erat. Cras fermentum pellentesque ante, ut dapibus {ipsum} placerat sit amet. Vivamus pharetra, sem vitae consequat venenatis, diam risus placerat est, sed hendrerit purus justo vitae lectus. In id quam mattis, rutrum augue eu, vehicula ipsum. Nulla nec egestas turpis, nec ullamcorper odio. Pellentesque vitae arcu justo. Aliquam sed pharetra lacus." # ending var title = "title" var links = new Array[String] # why not? diff --git a/tests/sav/nitpretty_args27.res b/tests/sav/nitpretty_args27.res index 0406b29..422cc2a 100644 --- a/tests/sav/nitpretty_args27.res +++ b/tests/sav/nitpretty_args27.res @@ -15,15 +15,17 @@ module test_annot1 is platform("android") class A + fun goo is intern + + # test fun foo is a, b + fun bar is a, b do print "1" fun baz is a bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb - do - print "2" - end + do print "2" end class B diff --git a/tests/sav/nitpretty_args28.res b/tests/sav/nitpretty_args28.res new file mode 100644 index 0000000..1944090 --- /dev/null +++ b/tests/sav/nitpretty_args28.res @@ -0,0 +1,51 @@ +# 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. + +# comment 1 +class A + type FOO: Discrete + private var foo: FOO # comment + + # comment 2 + var bar: Int = 10 +end + +class B + super A + + redef type FOO: Int + + # comment 3 + redef fun foo do return bar # comment + + redef fun bar + do + return 10 # comment 4 + end + + fun baz do return # comment 5 + protected fun baz2 do end + + fun other: String do + return "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + + "aaaaaaaaaaaaaaaaaaaaaaaaaa" + end + + fun foo1(arr: Array[String], len: Int, ind: Int): String + do + return "Hello World!" + end +end + +# end diff --git a/tests/sav/nitpretty_args29.res b/tests/sav/nitpretty_args29.res new file mode 100644 index 0000000..4d75c17 --- /dev/null +++ b/tests/sav/nitpretty_args29.res @@ -0,0 +1,127 @@ +# 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. + +class Foo + fun bar: Bool do return true + + fun foo(other: Foo): Foo + do + if other.bar then + return other + else + return self + end + end + + fun baz: Int do + var nb = 0 + + while nb < 10 do + print nb + nb += 1 + end # 1 + + return nb + end + + fun gaz: Int + do + if bar then # 3 + return 1 + else + return -1 # 4 + end + end +end + +class Test[E] + var heap: ArrayHeap[E] + init to(comparator: Comparator[E]) do heap = new ArrayHeap[E](comparator) + + init from(comparator: Comparator[E], items: Collection[E]) do + heap = new ArrayHeap[E].from(comparator, items.to_a) + end + + fun count(k: E): Int do + if heap.has(k) then + return 1 + else + return 0 + end + end + + fun node_at_idx(i: Int, k: E) do + while heap != null do + if heap.is_empty or i == k then # FIXME prefilter because the compiler is not smart enought yet + break + end + end + end + + fun save_those_nodes(nodes: Collection[Object]) do + for node in nodes do count(node) + end +end + +fun foo do + if last_slash > 0 then + return substring(last_slash + 1, length) + else + return null + end +end + +print "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam tincidun" + + "t sapien et velit fringilla varius at non eros. Nunc ut ultricies metus, sit a" + + "met lacinia felis. Donec in facilisis neque, non laoreet nibh. Etiam nec purus" + + " eu orci congue iaculis eu quis lorem. Ut et blandit erat. Cras fermentum pell" + + "entesque ante, ut dapibus ipsum placerat sit amet. Vivamus pharetra, sem vitae" + + " consequat venenatis, diam risus placerat est, sed hendrerit purus justo vitae" + + " lectus. In id quam mattis, rutrum augue eu, vehicula ipsum. Nulla nec egestas" + + " turpis, nec ullamcorper odio. Pellentesque vitae arcu justo. Aliquam sed phar" + + "etra lacus." + +var lorem = "lorem" +var ipsum = "ipsum" # for fun + +print "We also need to handle super strings: {lorem} {ipsum} dolor sit amet, con" + + "sectetur adipiscing elit. Aliquam tincidunt sapien et velit fringilla varius a" + + "t non eros. Nunc ut ultricies metus, sit amet lacinia felis. Donec in facilisi" + + "s neque, non laoreet nibh. Etiam nec purus eu orci congue iaculis eu quis {lorem}" + + ". Ut et blandit erat. Cras fermentum pellentesque ante, ut dapibus {ipsum} pla" + + "cerat sit amet. Vivamus pharetra, sem vitae consequat venenatis, diam risus pl" + + "acerat est, sed hendrerit purus justo vitae lectus. In id quam mattis, rutrum " + + "augue eu, vehicula ipsum. Nulla nec egestas turpis, nec ullamcorper odio. Pell" + + "entesque vitae arcu justo. Aliquam sed pharetra lacus." # ending + +var title = "title" +var links = new Array[String] # why not? + +var body = """ + + + + + + {{{title}}} + + +
+

{{{title}}}

+
    +
  • {{{links.join("
  • \n\t\t\t
  • ")}}}
  • +
+
+ +""" diff --git a/tests/sav/nitpretty_args30.res b/tests/sav/nitpretty_args30.res new file mode 100644 index 0000000..57f7966 --- /dev/null +++ b/tests/sav/nitpretty_args30.res @@ -0,0 +1,48 @@ +# 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. + +# comment 1 +class A + type FOO: Discrete + private var foo: FOO # comment + + # comment 2 + var bar: Int = 10 +end + +class B + super A + + redef type FOO: Int + + # comment 3 + redef fun foo do return bar # comment + + redef fun bar do + return 10 # comment 4 + end + + fun baz do return # comment 5 + protected fun baz2 do end + + fun other: String do + return "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + end + + fun foo1(arr: Array[String], len: Int, ind: Int): String do + return "Hello World!" + end +end + +# end diff --git a/tests/sav/nitpretty_args31.res b/tests/sav/nitpretty_args31.res new file mode 100644 index 0000000..99d53dd --- /dev/null +++ b/tests/sav/nitpretty_args31.res @@ -0,0 +1,109 @@ +# 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. + +class Foo + fun bar: Bool do return true + + fun foo(other: Foo): Foo do + if other.bar then + return other + else + return self + end + end + + fun baz: Int do + var nb = 0 + + while nb < 10 do + print nb + nb += 1 + end # 1 + + return nb + end + + fun gaz: Int do + if bar then # 3 + return 1 + else + return -1 # 4 + end + end +end + +class Test[E] + var heap: ArrayHeap[E] + init to(comparator: Comparator[E]) do heap = new ArrayHeap[E](comparator) + + init from(comparator: Comparator[E], items: Collection[E]) do + heap = new ArrayHeap[E].from(comparator, items.to_a) + end + + fun count(k: E): Int do + if heap.has(k) then + return 1 + else + return 0 + end + end + + fun node_at_idx(i: Int, k: E) do + while heap != null do + if heap.is_empty or i == k then # FIXME prefilter because the compiler is not smart enought yet + break + end + end + end + + fun save_those_nodes(nodes: Collection[Object]) do + for node in nodes do count(node) + end +end + +fun foo do + if last_slash > 0 then + return substring(last_slash + 1, length) + else + return null + end +end + +print "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam tincidunt sapien et velit fringilla varius at non eros. Nunc ut ultricies metus, sit amet lacinia felis. Donec in facilisis neque, non laoreet nibh. Etiam nec purus eu orci congue iaculis eu quis lorem. Ut et blandit erat. Cras fermentum pellentesque ante, ut dapibus ipsum placerat sit amet. Vivamus pharetra, sem vitae consequat venenatis, diam risus placerat est, sed hendrerit purus justo vitae lectus. In id quam mattis, rutrum augue eu, vehicula ipsum. Nulla nec egestas turpis, nec ullamcorper odio. Pellentesque vitae arcu justo. Aliquam sed pharetra lacus." + +var lorem = "lorem" +var ipsum = "ipsum" # for fun + +print "We also need to handle super strings: {lorem} {ipsum} dolor sit amet, consectetur adipiscing elit. Aliquam tincidunt sapien et velit fringilla varius at non eros. Nunc ut ultricies metus, sit amet lacinia felis. Donec in facilisis neque, non laoreet nibh. Etiam nec purus eu orci congue iaculis eu quis {lorem}. Ut et blandit erat. Cras fermentum pellentesque ante, ut dapibus {ipsum} placerat sit amet. Vivamus pharetra, sem vitae consequat venenatis, diam risus placerat est, sed hendrerit purus justo vitae lectus. In id quam mattis, rutrum augue eu, vehicula ipsum. Nulla nec egestas turpis, nec ullamcorper odio. Pellentesque vitae arcu justo. Aliquam sed pharetra lacus." # ending + +var title = "title" +var links = new Array[String] # why not? + +var body = """ + + + + + + {{{title}}} + + +
+

{{{title}}}

+
    +
  • {{{links.join("
  • \n\t\t\t
  • ")}}}
  • +
+
+ +""" diff --git a/tests/sav/nitpretty_args32.res b/tests/sav/nitpretty_args32.res new file mode 100644 index 0000000..f55be8f --- /dev/null +++ b/tests/sav/nitpretty_args32.res @@ -0,0 +1,18 @@ +# 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. + + + +# An empty module + diff --git a/tests/sav/nitpretty_args33.res b/tests/sav/nitpretty_args33.res new file mode 100644 index 0000000..76149a7 --- /dev/null +++ b/tests/sav/nitpretty_args33.res @@ -0,0 +1,24 @@ +# 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. + +# Testing only imports + +# Module comment +module test_mod2 # second comment + +import standard::kernel +#import standard::string + +import template # no need for string +# import standard \ No newline at end of file diff --git a/tests/sav/nitpretty_args34.res b/tests/sav/nitpretty_args34.res new file mode 100644 index 0000000..6ee57a1 --- /dev/null +++ b/tests/sav/nitpretty_args34.res @@ -0,0 +1,25 @@ +# 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. + +# A simple module +module test_mod3 + +# before +print "Hello World" # comment +# after + +# end + + + diff --git a/tests/sav/nitpretty_args35.res b/tests/sav/nitpretty_args35.res new file mode 100644 index 0000000..ed30bc2 --- /dev/null +++ b/tests/sav/nitpretty_args35.res @@ -0,0 +1,24 @@ +# 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. + +# comment 1 +interface A end + +abstract class B # comment 2 +end + +class C end # comment 3 + +enum D end # comment 4 + diff --git a/tests/sav/nitpretty_args36.res b/tests/sav/nitpretty_args36.res new file mode 100644 index 0000000..2a61cf1 --- /dev/null +++ b/tests/sav/nitpretty_args36.res @@ -0,0 +1,25 @@ +# 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. + +module test_class2 + + +# comment +class A end + +class B[T] # comment +end + +private class C[U, V: B[A]] end # comment + diff --git a/tests/sav/nitpretty_args37.res b/tests/sav/nitpretty_args37.res new file mode 100644 index 0000000..feedd55 --- /dev/null +++ b/tests/sav/nitpretty_args37.res @@ -0,0 +1,39 @@ +# 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. + +# comment +class A end + +class B[T] # comment + # comment + super A # comment + + + super C[A, B[A]] + # comment +end + +class C[U, V: B[A]] end # comment + +class D super A end # comment + +class E + + + + super A # comment +end + +# end + diff --git a/tests/sav/nitpretty_args38.res b/tests/sav/nitpretty_args38.res new file mode 100644 index 0000000..31e90fc --- /dev/null +++ b/tests/sav/nitpretty_args38.res @@ -0,0 +1,46 @@ +# 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. + +# comment 1 +class A + type FOO: Discrete + private var foo: FOO # comment + # comment 2 + var bar: Int = 10 +end + +class B + super A + + redef type FOO: Int + # comment 3 + redef fun foo do return bar # comment + redef fun bar + do + return 10 # comment 4 + end + fun baz do return # comment 5 + protected fun baz2 do end + fun other: String do + return "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + end + + fun foo1(arr: Array[String], len: Int, ind: Int): String + do + return "Hello World!" + end +end + +# end + diff --git a/tests/sav/nitpretty_args39.res b/tests/sav/nitpretty_args39.res new file mode 100644 index 0000000..e48e1da --- /dev/null +++ b/tests/sav/nitpretty_args39.res @@ -0,0 +1,32 @@ +# 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. + +class A + fun foo(a, b: Int): Bool do return true # 1 + + fun foo2(a, b: Int): Bool do return true # 2 + + fun foo3(a, b: Int): Bool do return true + + fun foo4(a, b: Int): Bool do + var res = true # 3 + return res # 4 + end + + fun foo5 do end # 5 + # fun foo6 do end +end + +# end + diff --git a/tests/sav/nitpretty_args40.res b/tests/sav/nitpretty_args40.res new file mode 100644 index 0000000..59e2e25 --- /dev/null +++ b/tests/sav/nitpretty_args40.res @@ -0,0 +1,35 @@ +# 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. + +class A + fun foo(aaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: Int): Bool do return true # comment + + fun foo2(a, b: Int): Bool do return true # comment + + fun foo3(a, b: Int): Bool do # comment + return true # comment + end # comment + + fun foo4(a, b: Int): Bool do # comment + var res = true # comment + return res # comment + end # comment + + fun foo5 do end # comment + + fun foo6(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: Int) do print 1 + +end # comment \ No newline at end of file diff --git a/tests/sav/nitpretty_args41.res b/tests/sav/nitpretty_args41.res new file mode 100644 index 0000000..1be308b --- /dev/null +++ b/tests/sav/nitpretty_args41.res @@ -0,0 +1,34 @@ +# 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. + +var a = 1 +var b = 2 + +while a != b do # comment 1 + # comment 2 + var tmp = a + a = b + b = tmp + # comment 3 +end + +# comment 4 +while a != b do a = b # comment 5 + +while a != b do + # comment 6 +end # comment 7 + +# end + diff --git a/tests/sav/nitpretty_args42.res b/tests/sav/nitpretty_args42.res new file mode 100644 index 0000000..6b49ffa --- /dev/null +++ b/tests/sav/nitpretty_args42.res @@ -0,0 +1,47 @@ +# 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. + +var a = 0 +var b = 2 + +do # comment 1 + # comment 2 + var tmp = a + a = b + b = tmp + # comment 3 +end + +# comment 4 +do a = b # comment 5 + +do + # comment 6 +end + +if a > b then loop print a # test + +if a > b then loop print a + + +if a > b then loop print a + + +if a > b then + loop + # comment 7 + print a + end +end + diff --git a/tests/sav/nitpretty_args43.res b/tests/sav/nitpretty_args43.res new file mode 100644 index 0000000..0135aa1 --- /dev/null +++ b/tests/sav/nitpretty_args43.res @@ -0,0 +1,27 @@ +# 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. + +var a = 0 + +for i in [1, 2, 3] do # comment 1 + # comment 2 + a += i +end + +# comment 4 +for i in [1..3] do a += i # comment 5 + +for i in [1..3[ do + # comment 6 +end diff --git a/tests/sav/nitpretty_args44.res b/tests/sav/nitpretty_args44.res new file mode 100644 index 0000000..2cd014e --- /dev/null +++ b/tests/sav/nitpretty_args44.res @@ -0,0 +1,36 @@ +# 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. + +class A + fun foo do end + fun bar(a: Int): Int do return 1 + fun baz(a, b: Int) do end + fun gaz(a: Int, b: Float...) do end +end + +fun top1 do end +fun top2(a: Int) do end + +# comment 1 +var a = new A # comment 2 +a.foo # comment 3 +a.bar 1 # comment 4 +a.baz(1, 2) # comment 5 +top1 # comment 6 +top2 10 # comment 7 + +print 10 # comment 8 + +var b = a.bar(1) + diff --git a/tests/sav/nitpretty_args45.res b/tests/sav/nitpretty_args45.res new file mode 100644 index 0000000..789abdd --- /dev/null +++ b/tests/sav/nitpretty_args45.res @@ -0,0 +1,39 @@ +# 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. + +class A + var attr: Int + fun foo1=(i: Int) do end + fun foo2=(i, j: Int) do end + fun [](a: Int): Int is abstract + fun []=(a, b: Int) do end +end + +class B + fun [](a, b: Int): Int is abstract + fun []=(a, b, c: Int) do end +end + +# comment 1 +var a = new A(10) # comment 2 + +a.foo1 = 10 # comment 3 +a.foo2(1) = 10 # comment 4 +print a[1] # comment 5 +a[1] = 2 # comment 6 +a[2] += 3 # comment 7 + +var b = new B +print b[1, 2] +b[1, 2] = 10 diff --git a/tests/sav/nitpretty_args46.res b/tests/sav/nitpretty_args46.res new file mode 100644 index 0000000..60bf5ef --- /dev/null +++ b/tests/sav/nitpretty_args46.res @@ -0,0 +1,50 @@ +# 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. + +var a = 1 +var b = 2 + +if a == b then a = b + +if a != b then + a = b + a = b +end + +if a > b then + b = a + a = b +else + a = b + a = b +end + +if a < b then + a = b + a = b +else if a == b then + b = a + a = b +end + +if a < b then + a = b + a = b +else if a == b then + b = b + a = b +else + a = b + a = b +end diff --git a/tests/sav/nitpretty_args47.res b/tests/sav/nitpretty_args47.res new file mode 100644 index 0000000..12d8db5 --- /dev/null +++ b/tests/sav/nitpretty_args47.res @@ -0,0 +1,81 @@ +# 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. + +# comment +var a = 1 # comment +# comment +var b = 2 # comment + +# comment +if a == b then a = b # comment + +# comment +if a != b then # comment + # comment + a = b # comment + # comment + a = b # comment + # comment +end # comment + +# comment +if a > b then # comment + # comment + b = a # comment + # comment + a = b # comment + # comment +else # comment + # comment + a = b # comment + # comment + a = b # comment + # comment +end # comment + +# comment +if a < b then # comment + # comment + a = b # comment + # comment + a = b # comment + # comment +else if a == b then # comment + # comment + b = a # comment + # comment + a = b # comment + # comment +end # comment + +# comment +if a < b then # comment + # comment + a = b # comment + # comment + a = b # comment + # comment +else if a == b then # comment + # comment + b = b # comment + # comment + a = b # comment + # comment +else # comment + # comment + a = b # comment + # comment + a = b # comment + # comment +end # comment \ No newline at end of file diff --git a/tests/sav/nitpretty_args48.res b/tests/sav/nitpretty_args48.res new file mode 100644 index 0000000..bfde8c2 --- /dev/null +++ b/tests/sav/nitpretty_args48.res @@ -0,0 +1,59 @@ +# 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. + +var a = 1 +var b = 2 + +# 0 +if a == b then # 1 + # 2 +else # 3 + # 4 +end # 5 + +if a == b then print a # printing a + +if a == b then + print a # printing a +end + +if a == b then print a # end + +if a == b then a = b + +if a == b then end + +if a == b then end + +if a != b then a = b + +if a > b then + a = b +else + a = b +end + +if a < b then + a = b +else if a == b then + a = b +end + +if a < b then + a = b +else if a == b then + a = b +else + a = b +end diff --git a/tests/sav/nitpretty_args49.res b/tests/sav/nitpretty_args49.res new file mode 100644 index 0000000..4fec81e --- /dev/null +++ b/tests/sav/nitpretty_args49.res @@ -0,0 +1,21 @@ +# 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. + +var a: nullable Int = 1 +var b: nullable Int = a.as(Int) +var c: nullable Int = a.as(not null) + +assert c isa Int +assert test1: c isa Int +assert test2: c isa Int else abort diff --git a/tests/sav/nitpretty_args50.res b/tests/sav/nitpretty_args50.res new file mode 100644 index 0000000..c428dcb --- /dev/null +++ b/tests/sav/nitpretty_args50.res @@ -0,0 +1,31 @@ +# 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. + +var a = 1 +var b = 2 + +assert a == 2 +assert not a < 2 # comment 1 +assert a > 2 and b >= 2 +assert b != 2 or a <= 2 +assert b != null # comment 2 + +# comment 3 +print a + b +print a - b # comment 4 +print a * b +print a / b +print a % b + +print -a # comment 5 \ No newline at end of file diff --git a/tests/sav/nitpretty_args51.res b/tests/sav/nitpretty_args51.res new file mode 100644 index 0000000..90425ff --- /dev/null +++ b/tests/sav/nitpretty_args51.res @@ -0,0 +1,27 @@ +# 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. + +var a = 1 +var b = 2 + +assert not a < 2 and (a == b or a > b) # comment 1 +assert not a < 2 and (a == b or ((a > b) or a <= b)) +assert (a > 2 and b >= 2) +assert (b >= 2) + +# comment 3 +var c = a + (b - a) +var d = (a - b) + c # comment 4 +var e = (-a) # comment 5 +var f = -(a - c) diff --git a/tests/sav/fixme/nitpretty_args21.res b/tests/sav/nitpretty_args52.res similarity index 93% rename from tests/sav/fixme/nitpretty_args21.res rename to tests/sav/nitpretty_args52.res index f4a3324..415c33f 100644 --- a/tests/sav/fixme/nitpretty_args21.res +++ b/tests/sav/nitpretty_args52.res @@ -34,9 +34,8 @@ fun errno: Int is extern `{ return errno; `} -fun errnoooooooooooooooooooooooooooooooooooooooooooooooooooooooooo: Int is extern `{ - return errno; -`} +fun errnoooooooooooooooooooooooooooooooooooooooooooooooooooooooooo: Int is + extern `{ return errno; `} private class A var my_attr = 1234 @@ -69,6 +68,7 @@ end extern class TimeT `{time_t`} new `{ return time(NULL); `} new from_i(i: Int) `{ return i; `} + fun update `{ time(&recv); `} fun ctime: String import NativeString.to_s_with_copy `{ @@ -78,10 +78,11 @@ extern class TimeT `{time_t`} # Difference in secondes from start (self if the end time) fun difftime(start: TimeT): Float `{ return difftime(recv, start); `} - private fun intern_poll(in_fds: Array[Int], out_fds: Array[Int]): nullable Int is import - Array[Int].length, Array[Int].[], Int.as(nullable Int) `{`} + private fun intern_poll(in_fds: Array[Int], out_fds: Array[Int]): nullable Int is + extern import Array[Int].length, Array[Int].[], Int.as(nullable Int) `{`} end fun address_is_null: Bool is extern "address_is_null" fun free `{ free(recv); `} + diff --git a/tests/sav/nitpretty_args53.res b/tests/sav/nitpretty_args53.res new file mode 100644 index 0000000..8152504 --- /dev/null +++ b/tests/sav/nitpretty_args53.res @@ -0,0 +1,35 @@ +# 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. + +class A + var a: Int # comment + private var b: nullable Int # happy + protected var c = 10 # ending + var d: Int = 10 + + + + + + # Test test... + var e: Int is writable + var f: Int is protected writable + # Adoc + var k: Int = 10 is protected writable + + + + # more comments +end # end + diff --git a/tests/sav/nitpretty_args54.res b/tests/sav/nitpretty_args54.res new file mode 100644 index 0000000..08a4d49 --- /dev/null +++ b/tests/sav/nitpretty_args54.res @@ -0,0 +1,24 @@ +# 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. + +class Foo + var a: Int + private var b: nullable Int + protected var c = 10 + var d: Int = 10 +end + +var foo = new Foo(1, 2) +print foo._a +foo._a = 10 diff --git a/tests/sav/nitpretty_args55.res b/tests/sav/nitpretty_args55.res new file mode 100644 index 0000000..2096847 --- /dev/null +++ b/tests/sav/nitpretty_args55.res @@ -0,0 +1,98 @@ +# 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. + + +# toplevel comment + + + + + + +# block +# block +# block + + + + + +# Adoc1 +class A # ending comments + + super Object + # super Int + + + super String + # super Truc + + + + # inclass comments + # comm + # ented + # blocks + + + + # Adoc2 + fun foo do + + # comment + + + + var truc + + # comment + # comment + + + + # comment + + + var chose + + # comment + end + + # comm + # ented + # blocks + + + fun bar do end + + + fun baz do end + # comment before end + +end # ending comments + +# comm +# ented +# blocks + +abstract class B # comment +end + +abstract class C end + +abstract class B # comment 2 + +end + +abstract class C end diff --git a/tests/sav/nitpretty_args56.res b/tests/sav/nitpretty_args56.res new file mode 100644 index 0000000..adabdcf --- /dev/null +++ b/tests/sav/nitpretty_args56.res @@ -0,0 +1,111 @@ +# 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. + +class Foo + fun bar: Bool do return true + + fun foo(other: Foo): Foo + do + if other.bar then + return other + else + return self + end + end + + fun baz: Int do + var nb = 0 + while nb < 10 do + print nb + nb += 1 + end # 1 + return nb + end + + fun gaz: Int + do + if bar then # 3 + return 1 + else + return -1 # 4 + end + end +end + +class Test[E] + var heap: ArrayHeap[E] + + init to(comparator: Comparator[E]) do heap = new ArrayHeap[E](comparator) + + init from(comparator: Comparator[E], items: Collection[E]) do + heap = new ArrayHeap[E].from(comparator, items.to_a) + end + + fun count(k: E): Int do + if heap.has(k) then + return 1 + else + return 0 + end + end + + fun node_at_idx(i: Int, k: E) do + while heap != null do + if heap.is_empty or i == k then # FIXME prefilter because the compiler is not smart enought yet + break + end + end + end + + fun save_those_nodes(nodes: Collection[Object]) do + for node in nodes do count(node) + end +end + +fun foo do + if last_slash > 0 then + return substring(last_slash + 1, length) + else + return null + end +end + +print "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam tincidunt sapien et velit fringilla varius at non eros. Nunc ut ultricies metus, sit amet lacinia felis. Donec in facilisis neque, non laoreet nibh. Etiam nec purus eu orci congue iaculis eu quis lorem. Ut et blandit erat. Cras fermentum pellentesque ante, ut dapibus ipsum placerat sit amet. Vivamus pharetra, sem vitae consequat venenatis, diam risus placerat est, sed hendrerit purus justo vitae lectus. In id quam mattis, rutrum augue eu, vehicula ipsum. Nulla nec egestas turpis, nec ullamcorper odio. Pellentesque vitae arcu justo. Aliquam sed pharetra lacus." + +var lorem = "lorem" +var ipsum = "ipsum" # for fun + +print "We also need to handle super strings: {lorem} {ipsum} dolor sit amet, consectetur adipiscing elit. Aliquam tincidunt sapien et velit fringilla varius at non eros. Nunc ut ultricies metus, sit amet lacinia felis. Donec in facilisis neque, non laoreet nibh. Etiam nec purus eu orci congue iaculis eu quis {lorem}. Ut et blandit erat. Cras fermentum pellentesque ante, ut dapibus {ipsum} placerat sit amet. Vivamus pharetra, sem vitae consequat venenatis, diam risus placerat est, sed hendrerit purus justo vitae lectus. In id quam mattis, rutrum augue eu, vehicula ipsum. Nulla nec egestas turpis, nec ullamcorper odio. Pellentesque vitae arcu justo. Aliquam sed pharetra lacus." # ending + +var title = "title" +var links = new Array[String] # why not? + +var body = """ + + + + + + {{{title}}} + + +
+

{{{title}}}

+
    +
  • {{{links.join("
  • \n\t\t\t
  • ")}}}
  • +
+
+ +""" + diff --git a/tests/sav/nitpretty_args57.res b/tests/sav/nitpretty_args57.res new file mode 100644 index 0000000..e385838 --- /dev/null +++ b/tests/sav/nitpretty_args57.res @@ -0,0 +1,48 @@ +# 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. + +# prims + +var a = true +var b = false + +var c = 10 +var d = -10 +var e = 1.12 + +var f = -1.12 +var n = 'a' +var o = null +var p = 0x12345678 + +# strings + +var g = "test" +var h1 = "Hello {g}" +var h2 = "Hello \"{g}\" Hello" +var h3 = "Hello {g}" +var m = """ +bla + bla + +bla""" + +# arrays + +var j = [1, 2, 3] +var k = [1..2[ +var l = [1..2] + + + diff --git a/tests/sav/nitpretty_args58.res b/tests/sav/nitpretty_args58.res new file mode 100644 index 0000000..edc3f3f --- /dev/null +++ b/tests/sav/nitpretty_args58.res @@ -0,0 +1,48 @@ +# 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. + +module test_annot1 is platform("android") + +class A + fun goo is intern + + # test + fun foo is a, b + fun bar is a, b do print "1" + fun baz is + a + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb do print "2" +end + +class B + fun foo is a, b + + + fun bar is a, b do print "1" + + fun baz is a, b + do + bar + print "2" + end + + fun gaz is + a + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + do + bar + print "2" + end + +end diff --git a/tests/sav/nitpretty_args59.res b/tests/sav/nitpretty_args59.res new file mode 100644 index 0000000..dadc656 --- /dev/null +++ b/tests/sav/nitpretty_args59.res @@ -0,0 +1,47 @@ +# 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. + +# comment 1 +class A + type FOO: Discrete + private var foo: FOO # comment + # comment 2 + var bar: Int = 10 +end + +class B + super A + + redef type FOO: Int + # comment 3 + redef fun foo do return bar # comment + redef fun bar + do + return 10 # comment 4 + end + fun baz do return # comment 5 + protected fun baz2 do end + fun other: String do + return "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + + "aaaaaaaaaaaaaaaaaaaaaaaaaa" + end + + fun foo1(arr: Array[String], len: Int, ind: Int): String + do + return "Hello World!" + end +end + +# end + diff --git a/tests/sav/nitpretty_args60.res b/tests/sav/nitpretty_args60.res new file mode 100644 index 0000000..0fd4ac4 --- /dev/null +++ b/tests/sav/nitpretty_args60.res @@ -0,0 +1,127 @@ +# 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. + +class Foo + fun bar: Bool do return true + + fun foo(other: Foo): Foo + do + if other.bar then + return other + else + return self + end + end + + fun baz: Int do + var nb = 0 + while nb < 10 do + print nb + nb += 1 + end # 1 + return nb + end + + fun gaz: Int + do + if bar then # 3 + return 1 + else + return -1 # 4 + end + end +end + +class Test[E] + var heap: ArrayHeap[E] + + init to(comparator: Comparator[E]) do heap = new ArrayHeap[E](comparator) + + init from(comparator: Comparator[E], items: Collection[E]) do + heap = new ArrayHeap[E].from(comparator, items.to_a) + end + + fun count(k: E): Int do + if heap.has(k) then + return 1 + else + return 0 + end + end + + fun node_at_idx(i: Int, k: E) do + while heap != null do + if heap.is_empty or i == k then # FIXME prefilter because the compiler is not smart enought yet + break + end + end + end + + fun save_those_nodes(nodes: Collection[Object]) do + for node in nodes do count(node) + end +end + +fun foo do + if last_slash > 0 then + return substring(last_slash + 1, length) + else + return null + end +end + +print "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam tincidun" + + "t sapien et velit fringilla varius at non eros. Nunc ut ultricies metus, sit a" + + "met lacinia felis. Donec in facilisis neque, non laoreet nibh. Etiam nec purus" + + " eu orci congue iaculis eu quis lorem. Ut et blandit erat. Cras fermentum pell" + + "entesque ante, ut dapibus ipsum placerat sit amet. Vivamus pharetra, sem vitae" + + " consequat venenatis, diam risus placerat est, sed hendrerit purus justo vitae" + + " lectus. In id quam mattis, rutrum augue eu, vehicula ipsum. Nulla nec egestas" + + " turpis, nec ullamcorper odio. Pellentesque vitae arcu justo. Aliquam sed phar" + + "etra lacus." + +var lorem = "lorem" +var ipsum = "ipsum" # for fun + +print "We also need to handle super strings: {lorem} {ipsum} dolor sit amet, con" + + "sectetur adipiscing elit. Aliquam tincidunt sapien et velit fringilla varius a" + + "t non eros. Nunc ut ultricies metus, sit amet lacinia felis. Donec in facilisi" + + "s neque, non laoreet nibh. Etiam nec purus eu orci congue iaculis eu quis {lorem}" + + ". Ut et blandit erat. Cras fermentum pellentesque ante, ut dapibus {ipsum} pla" + + "cerat sit amet. Vivamus pharetra, sem vitae consequat venenatis, diam risus pl" + + "acerat est, sed hendrerit purus justo vitae lectus. In id quam mattis, rutrum " + + "augue eu, vehicula ipsum. Nulla nec egestas turpis, nec ullamcorper odio. Pell" + + "entesque vitae arcu justo. Aliquam sed pharetra lacus." # ending + +var title = "title" +var links = new Array[String] # why not? + +var body = """ + + + + + + {{{title}}} + + +
+

{{{title}}}

+
    +
  • {{{links.join("
  • \n\t\t\t
  • ")}}}
  • +
+
+ +""" + diff --git a/tests/sav/nitpretty_args61.res b/tests/sav/nitpretty_args61.res new file mode 100644 index 0000000..6b5b168 --- /dev/null +++ b/tests/sav/nitpretty_args61.res @@ -0,0 +1,44 @@ +# 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. + +# comment 1 +class A + type FOO: Discrete + private var foo: FOO # comment + # comment 2 + var bar: Int = 10 +end + +class B + super A + + redef type FOO: Int + # comment 3 + redef fun foo do return bar # comment + redef fun bar do + return 10 # comment 4 + end + fun baz do return # comment 5 + protected fun baz2 do end + fun other: String do + return "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + end + + fun foo1(arr: Array[String], len: Int, ind: Int): String do + return "Hello World!" + end +end + +# end + diff --git a/tests/sav/nitpretty_args62.res b/tests/sav/nitpretty_args62.res new file mode 100644 index 0000000..329aa03 --- /dev/null +++ b/tests/sav/nitpretty_args62.res @@ -0,0 +1,109 @@ +# 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. + +class Foo + fun bar: Bool do return true + + fun foo(other: Foo): Foo do + if other.bar then + return other + else + return self + end + end + + fun baz: Int do + var nb = 0 + while nb < 10 do + print nb + nb += 1 + end # 1 + return nb + end + + fun gaz: Int do + if bar then # 3 + return 1 + else + return -1 # 4 + end + end +end + +class Test[E] + var heap: ArrayHeap[E] + + init to(comparator: Comparator[E]) do heap = new ArrayHeap[E](comparator) + + init from(comparator: Comparator[E], items: Collection[E]) do + heap = new ArrayHeap[E].from(comparator, items.to_a) + end + + fun count(k: E): Int do + if heap.has(k) then + return 1 + else + return 0 + end + end + + fun node_at_idx(i: Int, k: E) do + while heap != null do + if heap.is_empty or i == k then # FIXME prefilter because the compiler is not smart enought yet + break + end + end + end + + fun save_those_nodes(nodes: Collection[Object]) do + for node in nodes do count(node) + end +end + +fun foo do + if last_slash > 0 then + return substring(last_slash + 1, length) + else + return null + end +end + +print "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam tincidunt sapien et velit fringilla varius at non eros. Nunc ut ultricies metus, sit amet lacinia felis. Donec in facilisis neque, non laoreet nibh. Etiam nec purus eu orci congue iaculis eu quis lorem. Ut et blandit erat. Cras fermentum pellentesque ante, ut dapibus ipsum placerat sit amet. Vivamus pharetra, sem vitae consequat venenatis, diam risus placerat est, sed hendrerit purus justo vitae lectus. In id quam mattis, rutrum augue eu, vehicula ipsum. Nulla nec egestas turpis, nec ullamcorper odio. Pellentesque vitae arcu justo. Aliquam sed pharetra lacus." + +var lorem = "lorem" +var ipsum = "ipsum" # for fun + +print "We also need to handle super strings: {lorem} {ipsum} dolor sit amet, consectetur adipiscing elit. Aliquam tincidunt sapien et velit fringilla varius at non eros. Nunc ut ultricies metus, sit amet lacinia felis. Donec in facilisis neque, non laoreet nibh. Etiam nec purus eu orci congue iaculis eu quis {lorem}. Ut et blandit erat. Cras fermentum pellentesque ante, ut dapibus {ipsum} placerat sit amet. Vivamus pharetra, sem vitae consequat venenatis, diam risus placerat est, sed hendrerit purus justo vitae lectus. In id quam mattis, rutrum augue eu, vehicula ipsum. Nulla nec egestas turpis, nec ullamcorper odio. Pellentesque vitae arcu justo. Aliquam sed pharetra lacus." # ending + +var title = "title" +var links = new Array[String] # why not? + +var body = """ + + + + + + {{{title}}} + + +
+

{{{title}}}

+
    +
  • {{{links.join("
  • \n\t\t\t
  • ")}}}
  • +
+
+ +""" + diff --git a/tests/sav/nitpretty_args7.res b/tests/sav/nitpretty_args7.res index e404557..ea248bc 100644 --- a/tests/sav/nitpretty_args7.res +++ b/tests/sav/nitpretty_args7.res @@ -29,7 +29,8 @@ class B # comment 3 redef fun foo do return bar # comment - redef fun bar do + redef fun bar + do return 10 # comment 4 end @@ -37,8 +38,12 @@ class B protected fun baz2 do end fun other: String do - return "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + - "aaaaaaaaaaaaaaaaaaaaaaaaaa" + return "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + end + + fun foo1(arr: Array[String], len: Int, ind: Int): String + do + return "Hello World!" end end diff --git a/tests/sav/nitpretty_args9.res b/tests/sav/nitpretty_args9.res index bd21dbb..46c03e1 100644 --- a/tests/sav/nitpretty_args9.res +++ b/tests/sav/nitpretty_args9.res @@ -31,7 +31,5 @@ class A fun foo5 do end # comment fun foo6(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: Int) do - print 1 - end + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: Int) do print 1 end # comment diff --git a/tests/sav/nitunit_args4.res b/tests/sav/nitunit_args4.res index faaa0c9..91eb55f 100644 --- a/tests/sav/nitunit_args4.res +++ b/tests/sav/nitunit_args4.res @@ -5,17 +5,17 @@ Entities: 4; Documented ones: 3; With nitunits: 3; Failures: 0 TestSuites: No test cases found Class suites: 0; Test Cases: 0; Failures: 0 -if true then +if true then assert true end -if true then +if true then assert true end -var a = 1 +var a = 1 assert a == 1 assert a == 1 \ No newline at end of file diff --git a/tests/sav/nitunit_args5.res b/tests/sav/nitunit_args5.res index 7019ad0..356eaf4 100644 --- a/tests/sav/nitunit_args5.res +++ b/tests/sav/nitunit_args5.res @@ -5,7 +5,7 @@ Entities: 6; Documented ones: 5; With nitunits: 3; Failures: 0 TestSuites: No test cases found Class suites: 0; Test Cases: 0; Failures: 0 -assert true # tested -assert true # tested -assert true # tested +assert true # tested +assert true # tested +assert true # tested \ No newline at end of file diff --git a/tests/sav/opengles2_hello_triangle.res b/tests/sav/opengles2_hello_triangle.res deleted file mode 100644 index c1dad34..0000000 --- a/tests/sav/opengles2_hello_triangle.res +++ /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. diff --git a/tests/test_pretty/test_annot1.nit b/tests/test_pretty/test_annot1.nit index 381cc4f..695020f 100644 --- a/tests/test_pretty/test_annot1.nit +++ b/tests/test_pretty/test_annot1.nit @@ -15,6 +15,9 @@ module test_annot1 is platform("android") class A + fun goo is intern + + # test fun foo is a, b fun bar is a, b do print "1" fun baz is a, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb do print "2" diff --git a/tests/test_pretty/test_prop1.nit b/tests/test_pretty/test_prop1.nit index 0b46c27..3b692a5 100644 --- a/tests/test_pretty/test_prop1.nit +++ b/tests/test_pretty/test_prop1.nit @@ -35,6 +35,11 @@ class B end # comment 5 protected fun baz2 do end fun other: String do return "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + + fun foo1(arr: Array[String], len: Int, ind: Int): String + do + return "Hello World!" + end end # end