From: Jean Privat Date: Tue, 25 Nov 2014 01:04:13 +0000 (-0500) Subject: Merge: SELF type X-Git-Tag: v0.6.11~20 X-Git-Url: http://nitlanguage.org?hp=37076db10aaa3b36c3b67c31a4bc47168ae0387f Merge: SELF type If Object defines a virtual type SELF, redefines it automatically in all subclasses. Also checks for some conditions on the declaration of SELF: it must be public, it must not be fixed and it must be declared on Object (or not declared at all). These conditions ensures that its refinements are valid. The error messages when trying to redefining SELF could be improved. Maybe adding a special case preventing any redef of SELF? Pull-Request: #902 Reviewed-by: Jean Privat Reviewed-by: Etienne M. Gagnon Reviewed-by: Lucas Bajolet Reviewed-by: Alexandre Terrasa --- diff --git a/benchmarks/strings/array_to_s_vars/array_to_s_manual.nit b/benchmarks/strings/array_to_s_vars/array_to_s_manual.nit index 843eb93..da6b667 100644 --- a/benchmarks/strings/array_to_s_vars/array_to_s_manual.nit +++ b/benchmarks/strings/array_to_s_vars/array_to_s_manual.nit @@ -21,8 +21,6 @@ redef class NativeArray[E] end redef class Array[E] - super StringCapable - redef fun to_s: String do var l = length var its = _items @@ -35,7 +33,7 @@ redef class Array[E] na[i] = tmp i += 1 end - var ns = calloc_string(sl + 1) + var ns = new NativeString(sl + 1) ns[sl] = '\0' i = 0 var off = 0 diff --git a/contrib/friendz/src/friendz.nit b/contrib/friendz/src/friendz.nit index b8187ff..3877fe2 100644 --- a/contrib/friendz/src/friendz.nit +++ b/contrib/friendz/src/friendz.nit @@ -834,7 +834,7 @@ redef class Display fun measureText(str: String, height: Int): Int do var font = app.game.font - return str.length * (app.game.font.width + app.game.font.hspace) + return str.length * (font.width + font.hspace.to_i) end # displays a debug rectangle diff --git a/contrib/github_merge.nit b/contrib/github_merge.nit index c30732f..0d5e052 100644 --- a/contrib/github_merge.nit +++ b/contrib/github_merge.nit @@ -20,14 +20,14 @@ import template redef class Object # Factorize cast - fun json_as_a: Array[nullable Object] do return self.as(Array[nullable Object]) + fun json_as_a: JsonArray do return self.as(JsonArray) # Factorize cast - fun json_as_map: Map[String, nullable Object] do return self.as(Map[String, nullable Object]) + fun json_as_map: JsonObject do return self.as(JsonObject) end redef class GithubCurl # Get a given pull request (PR) - fun getpr(number: Int): Map[String, nullable Object] + fun getpr(number: Int): JsonObject do var pr = get_and_check("https://api.github.com/repos/privat/nit/pulls/{number}") var prm = pr.json_as_map @@ -46,7 +46,7 @@ redef class GithubCurl end # Get reviewers of a PR - fun getrev(pr: Map[String, nullable Object]): Array[String] + fun getrev(pr: JsonObject): Array[String] do var number = pr["number"].as(Int) var user = pr["user"].json_as_map["login"].as(String) diff --git a/contrib/github_search_for_jni/src/github_search_for_jni.nit b/contrib/github_search_for_jni/src/github_search_for_jni.nit index d12f288..35b19b2 100644 --- a/contrib/github_search_for_jni/src/github_search_for_jni.nit +++ b/contrib/github_search_for_jni/src/github_search_for_jni.nit @@ -19,13 +19,12 @@ module github_search_for_jni import github_api -# The proprieties introduced by this redef are to be used only on HashMap +# The proprieties introduced by this redef are to be used only on a JSON object # representing a Github repository. -redef class HashMap[K, V] +redef class JsonObject # The repository has at least 50% Java code fun has_lots_of_java: Bool do - assert self isa HashMap[String, nullable Object] var java_count = 0 if keys.has("Java") then java_count = self["Java"].as(Int) @@ -43,7 +42,6 @@ redef class HashMap[K, V] # The repository has at least 100 lines of C code fun has_some_c: Bool do - assert self isa HashMap[String, nullable Object] var c_count = 0 if keys.has("C") then c_count = self["C"].as(Int) return c_count > 100 @@ -64,14 +62,14 @@ var per_page = 100 loop # Get a page of the main query var uri = "https://api.github.com/search/repositories?q={main_query}&page={page}&per_page={per_page}&sort=stars" - var obj = curl.get_and_check(uri).as(HashMap[String, nullable Object]) + var obj = curl.get_and_check(uri).as(JsonObject) # Main object has "total_count" and "items" - var items = obj["items"].as(Array[nullable Object]) + var items = obj["items"].as(JsonArray) # "items" is an array of Json objects for item in items do - assert item isa HashMap[String, nullable Object] + assert item isa JsonObject # Each item has "name" and "languages_url" assert item.keys.has("name") @@ -79,7 +77,7 @@ loop # Download the language list var lang_url = item["languages_url"].as(String) - var langs = curl.get_and_check(lang_url).as(HashMap[String, nullable Object]) + var langs = curl.get_and_check(lang_url).as(JsonObject) # The project is of interest if it has lots of Java and at least some C var may_be_of_interest = langs.has_lots_of_java and langs.has_some_c diff --git a/contrib/nitcc/examples/json.sablecc b/contrib/nitcc/examples/json.sablecc index d1e9c6b..0de8914 100644 --- a/contrib/nitcc/examples/json.sablecc +++ b/contrib/nitcc/examples/json.sablecc @@ -9,7 +9,18 @@ frac = '.' d+; exp = e d+; e = ('e'|'E') ('+'|'-')?; -string = '"' (Any-'\\'-'"' | '\\'Any)* '"'; +hexdig = '0'..'9' | 'a'..'z' | 'A'..'Z'; +string = '"' (Any - '\\' - '"' | '\\' ( + '\\' | + '"' | + '/' | + 'b' | + 'f' | + 'n' | + 'r' | + 't' | + 'u' hexdig hexdig hexdig hexdig + ))* '"'; blank = (' '|'\n'|'\t')+; diff --git a/contrib/opportunity/src/opportunity_controller.nit b/contrib/opportunity/src/opportunity_controller.nit index 831d90d..f52f07d 100644 --- a/contrib/opportunity/src/opportunity_controller.nit +++ b/contrib/opportunity/src/opportunity_controller.nit @@ -60,13 +60,18 @@ class OpportunityWelcome var mname = request.string_arg("meetup_name") var mdate = request.string_arg("meetup_date") var mplace = request.string_arg("meetup_place") + var mmodestr = request.string_arg("meetup_mode") + var mmode = 0 if mdate == null then mdate = "" if mplace == null then mplace = "" + if mmodestr != null then + mmode = 1 + end if mname == null then mname = "" var rsp = new HttpResponse(200) var meetpage = new MeetupCreationPage - var meet = new Meetup(mname, mdate, mplace) + var meet = new Meetup(mname, mdate, mplace, mmode) meetpage.ans = ansset meetpage.meet = meet meetpage.error = "'Meetup name' is a mandatory fields." @@ -75,7 +80,7 @@ class OpportunityWelcome end var db = new OpportunityDB.open(db_path) - var meet = new Meetup(mname, mdate, mplace) + var meet = new Meetup(mname, mdate, mplace, mmode) if ansset.is_empty then db.close var rsp = new HttpResponse(200) @@ -176,7 +181,7 @@ class OpportunityAnswerREST redef fun answer(request, uri) do var persid = request.int_arg("pers_id") var ansid = request.int_arg("answer_id") - var ans = request.bool_arg("answer") + var ans = request.int_arg("answer") if persid == null or ansid == null or ans == null then return bad_req var db = new OpportunityDB.open(db_path) db.change_answer(ansid, persid, ans) @@ -197,12 +202,11 @@ class OpportunityMeetupREST var ans = request.string_arg("answers").split("&") if name == null or m_id == null then return bad_req print ans - var ansmap = new HashMap[Int, Bool] + var ansmap = new HashMap[Int, Int] for i in ans do var mp = i.split("=") - var b = false - if mp.last == "true" then b = true var id = mp.first.split("_").last + var b = mp.last.to_i if not id.is_numeric then continue ansmap[id.to_i] = b end @@ -220,7 +224,7 @@ class OpportunityMeetupREST var p = new People(rname, rsurname) for i in m.answers(db) do if not ansmap.has_key(i.id) then - p.answers[i] = false + p.answers[i] = 0 else p.answers[i] = ansmap[i.id] end diff --git a/contrib/opportunity/src/opportunity_model.nit b/contrib/opportunity/src/opportunity_model.nit index aa9adec..7b5bde8 100644 --- a/contrib/opportunity/src/opportunity_model.nit +++ b/contrib/opportunity/src/opportunity_model.nit @@ -31,7 +31,7 @@ class OpportunityDB # Creates the tables and triggers for Opportunity (SQLite3 DB) fun create_db do - assert create_table("IF NOT EXISTS meetups (id CHAR(40) PRIMARY KEY, name TEXT, date TEXT, place TEXT);") else + assert create_table("IF NOT EXISTS meetups (id CHAR(40) PRIMARY KEY, name TEXT, date TEXT, place TEXT, answer_mode INTEGER DEFAULT 0);") else print error or else "?" end assert create_table("IF NOT EXISTS people(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, surname TEXT);") else @@ -68,7 +68,16 @@ class OpportunityDB fun find_meetup_by_id(id: String): nullable Meetup do var req = select("* FROM meetups where id={id.to_sql_string};") for i in req do - return new Meetup.from_db(i[0].to_s, i[1].to_s, i[2].to_s, i[3].to_s) + return new Meetup.from_db(i[0].to_s, i[1].to_s, i[2].to_s, i[3].to_s, i[4].to_i) + end + return null + end + + # Find an `Answer` by its `id` or `null` if it could not be found + fun find_answer_by_id(id: Int): nullable Answer do + var req = select("* FROM answers WHERE id={id};") + for i in req do + return new Answer.from_db(i[0].to_i, i[2].to_s) end return null end @@ -76,16 +85,20 @@ class OpportunityDB # Change an Answer `ansid` for someone with an id `pid` to `resp` # # Returns `true` if the request was sucessful, false otherwise - fun change_answer(pid: Int, ansid: Int, resp: Bool): Bool do - var rsp = 0 - if resp then rsp = 1 - var rq = execute("INSERT OR REPLACE INTO part_answers(id_part, id_ans, value) VALUES({pid},{ansid},{rsp});") - if not rq then + fun change_answer(pid: Int, ansid: Int, resp: Int): Bool do + var p = find_people_by_id(pid) + if p == null then print "Error while updating answer {ansid}:{pid}" - print error or else "Unknown error" return false end - return true + var a = find_answer_by_id(ansid) + if a == null then + print "Error while updating answer {ansid}:{pid}" + return false + end + p.answers[a] = resp + if p.commit(self) then return true + return false end # Removes a person in the Database by its `id` @@ -120,7 +133,10 @@ class People # Surname of the participant var surname: String # Map of the answers of a Meetup and the answers of the participant - var answers: Map[Answer, Bool] = new HashMap[Answer, Bool] + # 0 = No + # 1 = Maybe + # 2 = Yes + var answers: Map[Answer, Int] = new HashMap[Answer, Int] # To be used internally when fetching the `People` in Database private init from_db(id: Int, name, surname: String) do @@ -129,7 +145,7 @@ class People end # Changes an answer `ans` (or adds it) - fun answer=(ans: Answer, resp: Bool) do + fun answer=(ans: Answer, resp: Int) do answers[ans] = resp end @@ -137,12 +153,11 @@ class People # # NOTE: If `self` does not exist in the Database, no answers will be fetched fun load_answers(db: OpportunityDB, meetup: Meetup) do - self.answers = new HashMap[Answer, Bool] - var req = db.select("answers.id, answers.name, part_answers.value FROM part_answers, answers WHERE part_answers.id_part={id} AND answers.id=part_answers.id_ans AND answers.meetup_id={meetup.id.to_sql_string} GROUP BY answers.id;") + self.answers = new HashMap[Answer, Int] + var req = db.select("answers.id, answers.name, part_answers.value FROM part_answers, answers WHERE part_answers.id_part={id} AND answers.id=part_answers.id_ans AND answers.meetup_id={meetup.id.html_escape.to_sql_string} GROUP BY answers.id;") for i in req do var ans = new Answer.from_db(i[0].to_i, i[1].to_s) - answers[ans] = false - if i[2].to_i == 1 then answers[ans] = true + answers[ans] = i[2].to_i end end @@ -150,14 +165,14 @@ class People redef fun commit(db) do if id == -1 then - if not db.execute("INSERT INTO people (name,surname) VALUES ({name.to_sql_string}, {surname.to_sql_string});") then + if not db.execute("INSERT INTO people (name,surname) VALUES ({name.html_escape.to_sql_string}, {surname.html_escape.to_sql_string});") then print "Error while adding people {self}" print db.error or else "Unknown error" return false end id = db.last_insert_rowid else - if not db.execute("UPDATE people SET name={name.to_sql_string}, surname={surname.to_sql_string} WHERE ID={id};") then + if not db.execute("UPDATE people SET name={name.html_escape.to_sql_string}, surname={surname.html_escape.to_sql_string} WHERE ID={id};") then print "Error while updating people {self}" print db.error or else "Unknown error" return false @@ -165,10 +180,18 @@ class People end for i,j in answers do if i.id == -1 then i.commit(db) - var val = 0 - if j then val = 1 - if not db.execute("INSERT OR REPLACE INTO part_answers(id_part, id_ans, value) VALUES ({id},{i.id},{val});") then - print("Error while adding/replacing part_answers {id}|{i.id}|{j}") + var val = j + var s = db.select("* FROM part_answers WHERE id_part={id} AND id_ans={i.id}") + if s != null and s.iterator.is_ok then + if not db.execute("UPDATE part_answers SET value={j} WHERE id_part={id} AND id_ans={i.id};") then + print "Error while updating part_answers {id}|{i.id} = {j}" + print db.error or else "Unknown error" + return false + end + continue + end + if not db.execute("INSERT INTO part_answers(id_part, id_ans, value) VALUES ({id},{i.id},{val});") then + print("Error while adding part_answers {id}|{i.id}|{j}") print db.error or else "Unknown error" return false end @@ -189,13 +212,13 @@ class Meetup var date: String # Place of the meetup var place: String + # Mode of answering to the meetup (atm supports with or without Maybe) + var answer_mode: Int # Builds the object with all the informations found in the database - private init from_db(id, name, date, place: String) do + private init from_db(id, name, date, place: String, mode: Int) do self.id = id - self.name = name - self.date = date - self.place = place + init(name, date, place, mode) end # Gets the answers bound to the current `Meetup` @@ -225,7 +248,7 @@ class Meetup if id == "" then var time = get_time var tmpid = (name + date + place + time.to_s).sha1_to_s - if not db.execute("INSERT INTO meetups (id, name, date, place) VALUES({tmpid.to_sql_string}, {name.to_sql_string}, {date.to_sql_string}, {place.to_sql_string});") then + if not db.execute("INSERT INTO meetups (id, name, date, place, answer_mode) VALUES({tmpid.to_sql_string}, {name.html_escape.to_sql_string}, {date.html_escape.to_sql_string}, {place.html_escape.to_sql_string}, {answer_mode});") then print "Error recording entry Meetup {self}" print db.error or else "Null error" return false @@ -233,7 +256,7 @@ class Meetup id = tmpid return true else - return db.execute("UPDATE meetups (name, date, place) VALUES({name.to_sql_string}, {date.to_sql_string}, {place.to_sql_string}) WHERE ID={id.to_sql_string};") + return db.execute("UPDATE meetups SET name={name.html_escape.to_sql_string}, date={date.html_escape.to_sql_string}, place={place.html_escape.to_sql_string}, answer_mode={answer_mode} WHERE ID={id.to_sql_string};") end end @@ -259,6 +282,11 @@ class Answer self.id = id end + redef fun hash do + if id != -1 then return id + return super + end + # Loads the Meetup associated to `self` # # REQUIRE: is loaded in database @@ -266,12 +294,39 @@ class Answer assert id != -1 var res = db.select("meetups.* FROM meetups, answers WHERE answers.id={id} AND answers.meetup_id=meetups.id;") for i in res do - return new Meetup.from_db(i[0].to_s, i[1].to_s, i[2].to_s, i[3].to_s) + return new Meetup.from_db(i[0].to_s, i[1].to_s, i[2].to_s, i[3].to_s, i[4].to_i) end # If no Meetup could be loaded, the contract was not respected abort end + # Counts the number of positive or maybe answers + fun count(db: OpportunityDB): Int do + if id == -1 then return -1 + var count = 0 + var res = db.select("part_answers.value FROM part_answers WHERE part_answers.id_ans={id};") + if meetup == null then meetup = load_meetup(db) + for i in res do + if meetup.answer_mode == 0 then + count += i[0].to_i + else + if i[0].to_i == 2 then count += 1 + end + end + return count + end + + # Counts the score for this particular answer + fun score(db: OpportunityDB): Int do + if id == -1 then return -1 + var score = 0 + var res = db.select("part_answers.value FROM part_answers WHERE part_answers.id_ans={id};") + for i in res do + score += i[0].to_i + end + return score + end + redef fun commit(db) do var m = meetup if m == null then return false @@ -282,14 +337,14 @@ class Answer end end if id == -1 then - if not db.execute("INSERT INTO answers (name, meetup_id) VALUES({name.to_sql_string}, {m.id.to_sql_string});") then + if not db.execute("INSERT INTO answers (name, meetup_id) VALUES({name.html_escape.to_sql_string}, {m.id.to_sql_string});") then print "Cannot create {self} in database" print db.error or else "Unknown error" return false end id = db.last_insert_rowid else - if not db.execute("UPDATE answers (name) VALUES ({name.to_sql_string}) WHERE meetup_id={m.id.to_sql_string};") then + if not db.execute("UPDATE answers SET name=({name.html_escape.to_sql_string}) WHERE meetup_id={m.id.to_sql_string};") then print "Error updating {self} in database" print db.error or else "Unknown error" return false diff --git a/contrib/opportunity/src/templates/meetup.nit b/contrib/opportunity/src/templates/meetup.nit index 72503cf..e5d1f56 100644 --- a/contrib/opportunity/src/templates/meetup.nit +++ b/contrib/opportunity/src/templates/meetup.nit @@ -26,33 +26,107 @@ class OpportunityMeetupPage # Meetup the page is supposed to show var meetup: nullable Meetup = null + # Answer mode for the meetup + var mode = 0 init from_id(id: String) do var db = new OpportunityDB.open("opportunity") meetup = db.find_meetup_by_id(id) db.close + if meetup != null then mode = meetup.answer_mode + init end init do - header.page_js = """ + header.page_js = "mode = {mode};\n" + header.page_js += """ + function update_scores(){ + var anss = $('.answer'); + var count = {}; + var scores = {}; + var answers = []; + var maxscore = 0; + for(i=0; i < anss.length; i++){ + var incscore = 0; + var inccount = 0; + var idparts = anss[i].id.split("_"); + var ansid = idparts[1]; + var html = anss[i].innerHTML; + if(html === "
✔
"){ + inccount = 1; + incscore = 2; + }else if(html === "
❓
"){ + incscore = 1; + } + var intansid = parseInt(ansid) + if(answers.indexOf(intansid) == -1){ + answers.push(intansid); + } + if(ansid in count){ + count[ansid] += inccount; + }else{ + count[ansid] = inccount; + } + if(ansid in scores){ + scores[ansid] += incscore; + }else{ + scores[ansid] = incscore; + } + if(scores[ansid] > maxscore){ + maxscore = scores[ansid]; + } + } + for(i=0; i < answers.length; i++){ + var ansid = answers[i].toString(); + var el = $('#total'+ansid)[0]; + var ins = "
"+count[ansid]; + if(scores[ansid] >= maxscore){ + ins += "
★"; + } + ins += "
"; + el.innerHTML = ins; + } + } function change_answer(ele, id){ // modify only the currently selected entry if (in_modification_id != id) return; var e = document.getElementById(ele.id); var i = e.innerHTML; - var ans = true; + var ans = true;""" + if mode == 0 then + header.page_js += """ if(i === "
✔
"){ - ans = false; + ans = 0; e.innerHTML = "
✘
" e.style.color = "red"; }else{ + ans = 1; e.innerHTML = "
✔
"; e.style.color = "green"; - } + }""" + + else + header.page_js += """ + if(i === "
✔
"){ + ans = 1; + e.innerHTML = "
❓
" + e.style.color = "#B8860B"; + }else if(i === "
❓
"){ + ans = 0; + e.innerHTML = "
✘
" + e.style.color = "red"; + }else{ + ans = 2; + e.innerHTML = "
✔
"; + e.style.color = "green"; + }""" + end + header.page_js += """ var a = ele.id.split('_') var pid = a[1] var aid = a[2] + update_scores(); $.ajax({ type: "POST", url: "./rest/answer", @@ -65,16 +139,33 @@ class OpportunityMeetupPage } function change_temp_answer(ele){ var e = document.getElementById(ele.id); - var i = e.innerHTML; - var ans = true; + var i = e.innerHTML;""" + if mode == 0 then + header.page_js += """ + if(i === "
✔
"){ + e.innerHTML = "
✘
" + e.style.color = "red"; + }else{ + e.innerHTML = "
✔
"; + e.style.color = "green"; + } + """ + else + header.page_js += """ if(i === "
✔
"){ - ans = false; - e.innerHTML = "
✘
"; + e.innerHTML = "
❓
"; + e.style.color = "#B8860B"; + }else if(i === "
❓
"){ + e.innerHTML = "
✘
" e.style.color = "red"; }else{ e.innerHTML = "
✔
"; e.style.color = "green"; } + """ + end + header.page_js += """ + update_scores(); } function add_part(ele){ var e = document.getElementById(ele.id); @@ -85,11 +176,25 @@ class OpportunityMeetupPage ansmap = {}; for(i=0;i✔"){ - ansmap[curr.attr('id')] = true + ansmap[curr.attr('id')] = 1 }else{ - ansmap[curr.attr('id')] = false - } + ansmap[curr.attr('id')] = 0 + }""" + else + header.page_js += """ + if(curr[0].innerHTML === "
✔
"){ + ansmap[curr.attr('id')] = 2 + }else if(curr[0].innerHTML === "
❓
"){ + ansmap[curr.attr('id')] = 1 + }else{ + ansmap[curr.attr('id')] = 0 + }""" + end + header.page_js += """ } $.ajax({ type: "POST", @@ -111,6 +216,7 @@ class OpportunityMeetupPage var arr = ele.id.split("_") var pid = arr[1] $('#' + ele.id).parent().parent().parent().remove(); + update_scores(); $.ajax({ type: "POST", url: "./rest/people", @@ -120,7 +226,6 @@ class OpportunityMeetupPage } }); } - // ID of line currently open for modification var in_modification_id = null; function modify_people(ele, id){ @@ -192,18 +297,39 @@ redef class Meetup t.add "" t.add i.to_s t.add "" - for j,k in i.answers do + for j, k in i.answers do var color - if k then - color = "green" - else color = "red" - + if answer_mode == 0 then + if k == 1 then + color = "green" + else + color = "red" + end + else + if k == 2 then + color = "green" + else if k == 1 then + color = "#B8860B" + else + color = "red" + end + end t.add """""" t.add "
" - if k then - t.add "✔" + if answer_mode == 0 then + if k == 1 then + t.add "✔" + else + t.add "✘" + end else - t.add "✘" + if k == 2 then + t.add "✔" + else if k == 1 then + t.add "❓" + else + t.add "✘" + end end t.add "
" end @@ -221,6 +347,28 @@ redef class Meetup t.add """
""" t.add "" + # Compute score for each answer + var scores = new HashMap[Int, Int] + var maxsc = 0 + for i in answers(db) do + scores[i.id] = i.score(db) + if scores[i.id] > maxsc then maxsc = scores[i.id] + end + t.add """ + + Total + """ + for i in answers(db) do + t.add """
{{{i.count(db)}}}""" + if scores.has_key(i.id) and scores[i.id] >= maxsc then + t.add """
★""" + end + t.add "
" + end + t.add "" + t.add """ + +""" t.add "" t.add "" return t diff --git a/contrib/opportunity/src/templates/meetup_creation.nit b/contrib/opportunity/src/templates/meetup_creation.nit index 6f42561..5b1a048 100644 --- a/contrib/opportunity/src/templates/meetup_creation.nit +++ b/contrib/opportunity/src/templates/meetup_creation.nit @@ -93,6 +93,12 @@ function new_answer(sender){ +
+ +
+ +
+

Opportunities

""" diff --git a/contrib/opportunity/tests/db_tests.nit b/contrib/opportunity/tests/db_tests.nit index cbec6f7..a5a39a7 100644 --- a/contrib/opportunity/tests/db_tests.nit +++ b/contrib/opportunity/tests/db_tests.nit @@ -47,7 +47,7 @@ db = new OpportunityDB.open("opportunity") var hj = new People("Jack", "Handsome") -var m = new Meetup("Awaken the warrior", "2024/05/28", "Vault of the Warrior") +var m = new Meetup("Awaken the warrior", "2024/05/28", "Vault of the Warrior", 0) assert m.commit(db) var vh = new People("Hunter", "Vault") @@ -66,17 +66,17 @@ var h = new Answer("I have no choice, I'm a hostage") h.meetup = m h.commit(db) -hj.answer(y) = true -hj.answer(n) = false -hj.answer(h) = false +hj.answer(y) = 1 +hj.answer(n) = 0 +hj.answer(h) = 0 -vh.answer(y) = true -vh.answer(n) = false -vh.answer(h) = false +vh.answer(y) = 1 +vh.answer(n) = 0 +vh.answer(h) = 0 -ll.answer(y) = true -ll.answer(n) = false -ll.answer(h) = true +ll.answer(y) = 1 +ll.answer(n) = 0 +ll.answer(h) = 1 hj.commit db vh.commit db diff --git a/examples/rosettacode/ab.nit b/examples/rosettacode/ab.nit index 9138c0c..ce18fc0 100644 --- a/examples/rosettacode/ab.nit +++ b/examples/rosettacode/ab.nit @@ -10,4 +10,8 @@ module ab var words = gets.split(" ") +if words.length != 2 then + print "Expected two numbers" + return +end print words[0].to_i + words[1].to_i diff --git a/examples/shoot/src/shoot_logic.nit b/examples/shoot/src/shoot_logic.nit index 838c78b..824af57 100644 --- a/examples/shoot/src/shoot_logic.nit +++ b/examples/shoot/src/shoot_logic.nit @@ -1052,6 +1052,7 @@ end fun headless_run do + srand_from 0 print "Headless run" # Only run the playscene var scene = new PlayScene(80000,60000) diff --git a/lib/a_star.nit b/lib/a_star.nit index 125b053..4108268 100644 --- a/lib/a_star.nit +++ b/lib/a_star.nit @@ -55,13 +55,6 @@ # ~~~ module a_star -redef class Object - protected fun debug_a_star: Bool do return false - private fun debug(msg: String) do if debug_a_star then - sys.stderr.write "a_star debug: {msg}\n" - end -end - # General graph node class Node type N: Node @@ -130,14 +123,12 @@ class Node var current_bucket = buckets[cost % nbr_buckets] if current_bucket.is_empty then # move to next bucket - debug "b {cost} {cost % nbr_buckets} {buckets[cost % nbr_buckets].hash}" cost += 1 if cost > max_cost then return null bucket_searched += 1 if bucket_searched > nbr_buckets then break else # found a node - debug "c {cost}" frontier_node = current_bucket.pop if frontier_node.open then break @@ -151,7 +142,6 @@ class Node # at destination else if frontier_node == destination or (alt_targets != null and alt_targets.accept(frontier_node)) then - debug "picked {frontier_node}, is destination" var path = new Path[N](cost) @@ -166,11 +156,8 @@ class Node else frontier_node.open = false - debug "w exploring adjacents of {frontier_node}" - for link in frontier_node.links do var peek_node = link.to - debug "v {context.is_blocked(link)} {peek_node.last_pathfinding_evocation != graph.pathfinding_current_evocation} {peek_node.best_cost_up_to > frontier_node.best_cost_up_to + context.cost(link)}, {peek_node.best_cost_up_to} > {frontier_node.best_cost_up_to} + {context.cost(link)}" if not context.is_blocked(link) and (peek_node.last_pathfinding_evocation != graph.pathfinding_current_evocation or (peek_node.open and @@ -190,8 +177,6 @@ class Node var at_bucket = buckets[est_cost % nbr_buckets] at_bucket.add(peek_node) - - debug "u putting {peek_node} at {est_cost} -> {est_cost % nbr_buckets} {at_bucket.hash}, {cost}+{context.cost(link)}" end end end diff --git a/lib/android/platform.nit b/lib/android/platform.nit index dab001d..fca03e0 100644 --- a/lib/android/platform.nit +++ b/lib/android/platform.nit @@ -21,6 +21,8 @@ module platform is new_annotation max_api_version new_annotation target_api_version new_annotation android_manifest + new_annotation android_manifest_application + new_annotation android_manifest_activity end import java diff --git a/lib/app/data_store.nit b/lib/app/data_store.nit index afb6a1d..13891fc 100644 --- a/lib/app/data_store.nit +++ b/lib/app/data_store.nit @@ -34,5 +34,5 @@ interface DataStore fun [](key: String): nullable Object is abstract # Store `value` at `key` - fun []=(key: String, value: Serializable) is abstract + fun []=(key: String, value: nullable Serializable) is abstract end diff --git a/lib/bucketed_game.nit b/lib/bucketed_game.nit index 45a439c..09a4ee8 100644 --- a/lib/bucketed_game.nit +++ b/lib/bucketed_game.nit @@ -83,6 +83,8 @@ class Buckets[G: Game] var current_bucket = buckets[current_bucket_key] var next_bucket = new HashSet[Bucketable[G]] + buckets[current_bucket_key] = next_bucket + self.next_bucket = next_bucket for e in current_bucket do var act_at = e.act_at @@ -96,9 +98,6 @@ class Buckets[G: Game] end end end - - self.next_bucket = next_bucket - buckets[current_bucket_key] = next_bucket end end diff --git a/lib/counter.nit b/lib/counter.nit index 670fc59..3d1555b 100644 --- a/lib/counter.nit +++ b/lib/counter.nit @@ -19,10 +19,33 @@ import poset # A counter counts occurrences of things # Use this instead of a `HashMap[E, Int]` +# +# ~~~ +# var c = new Counter[String].from(["a", "a", "b", "b", "b", "c"]) +# assert c["a"] == 2 +# assert c["b"] == 3 +# assert c["c"] == 1 +# assert c["d"] == 0 +# ~~~ +# +# The counter class can also be used to gather statistical informations. +# +# ~~~~ +# assert c.length == 3 # because 3 distinct values +# assert c.max == "b" # because "b" has the most count (3) +# assert c.avg == 2.0 # because it is the mean of the counts +# ~~~~ class Counter[E: Object] super Map[E, Int] # Total number of counted occurrences + # + # ~~~ + # var c = new Counter[String] + # assert c.sum == 0 + # c.inc_all(["a", "a", "b", "b", "b", "c"]) + # assert c.sum == 6 + # ~~~ var sum: Int = 0 private var map = new HashMap[E, Int] @@ -64,7 +87,24 @@ class Counter[E: Object] sum += 1 end + # Count one more for each element of `es` + fun inc_all(es: Collection[E]) + do + for e in es do inc(e) + end + + # A new Counter initialized with `inc_all`. + init from(es: Collection[E]) + do + inc_all(es) + end + # Return an array of elements sorted by occurrences + # + # ~~~ + # var c = new Counter[String].from(["a", "a", "b", "b", "b", "c"]) + # assert c.sort == ["c", "a", "b"] + # ~~~ fun sort: Array[E] do var res = map.keys.to_a @@ -77,7 +117,7 @@ class Counter[E: Object] # @toimplement by default just call `to_s` on the element protected fun element_to_s(e: E): String do - do return e.to_s + return e.to_s end # Display statistical information @@ -130,7 +170,14 @@ class Counter[E: Object] end end - # Return the element with the highest value + # Return the element with the highest value (aka. the mode) + # + # ~~~ + # var c = new Counter[String].from(["a", "a", "b", "b", "b", "c"]) + # assert c.max == "b" + # ~~~ + # + # If more than one max exists, the first one is returned. fun max: nullable E do var max: nullable Int = null var elem: nullable E = null @@ -144,6 +191,13 @@ class Counter[E: Object] end # Return the couple with the lowest value + # + # ~~~ + # var c = new Counter[String].from(["a", "a", "b", "b", "b", "c"]) + # assert c.min == "c" + # ~~~ + # + # If more than one min exists, the first one is returned. fun min: nullable E do var min: nullable Int = null var elem: nullable E = null @@ -156,13 +210,24 @@ class Counter[E: Object] return elem end - # Values average + # Values average (aka. arithmetic mean) + # + # ~~~ + # var c = new Counter[String].from(["a", "a", "b", "b", "b", "c"]) + # assert c.avg == 2.0 + # ~~~ fun avg: Float do if values.is_empty then return 0.0 return (sum / values.length).to_f end # The standard derivation of the counter values + # + # ~~~ + # var c = new Counter[String].from(["a", "a", "b", "b", "b", "c"]) + # assert c.std_dev > 0.81 + # assert c.std_dev < 0.82 + # ~~~ fun std_dev: Float do var avg = self.avg var sum = 0.0 diff --git a/lib/dummy_array.nit b/lib/dummy_array.nit index 21da4bd..88e7008 100644 --- a/lib/dummy_array.nit +++ b/lib/dummy_array.nit @@ -12,7 +12,6 @@ class DummyArray super Set[Int] - super ArrayCapable[Int] private var capacity: Int redef var length: Int private var keys: NativeArray[Int] @@ -79,8 +78,8 @@ class DummyArray init(capacity: Int) do _capacity = capacity - _keys = calloc_array(capacity) - _values = calloc_array(capacity) + _keys = new NativeArray[Int](capacity) + _values = new NativeArray[Int](capacity) end end diff --git a/lib/github_api.nit b/lib/github_api.nit index 2394592..39fca84 100644 --- a/lib/github_api.nit +++ b/lib/github_api.nit @@ -45,7 +45,7 @@ class GithubCurl # Get the requested URI, and check the HTTP response. Then convert to JSON # and check for Github errors. - fun get_and_check(uri: String): nullable Object + fun get_and_check(uri: String): nullable Jsonable do var request = new CurlHTTPRequest(uri, self) request.user_agent = user_agent @@ -53,8 +53,8 @@ class GithubCurl var response = request.execute if response isa CurlResponseSuccess then - var obj = response.body_str.json_to_nit_object - if obj isa HashMap[String, nullable Object] then + var obj = response.body_str.parse_json + if obj isa JsonObject then if obj.keys.has("message") then print "Message from Github API: {obj["message"] or else ""}" print "Requested URI: {uri}" diff --git a/lib/hash_debug.nit b/lib/hash_debug.nit index b618729..8426097 100644 --- a/lib/hash_debug.nit +++ b/lib/hash_debug.nit @@ -121,7 +121,7 @@ do super end -redef class HashCollection[K,N] +redef class HashCollection[K] redef fun node_at_idx(i,k) do sys.gt_count += 1 diff --git a/lib/java/java.nit b/lib/java/java.nit index 56a375f..c3db430 100644 --- a/lib/java/java.nit +++ b/lib/java/java.nit @@ -27,7 +27,7 @@ # most of JNI functions. You can use it to further customize the behavior # of your code. module java is - c_compiler_option("-I $(JAVA_HOME)/include/") + c_compiler_option "-I $(JAVA_HOME)/include/ -I $(JAVA_HOME)/include/linux/" c_linker_option("-L $(JNI_LIB_PATH) -ljvm") new_annotation extra_java_files end diff --git a/lib/json/dynamic.nit b/lib/json/dynamic.nit index ec3ba25..d15ceb7 100644 --- a/lib/json/dynamic.nit +++ b/lib/json/dynamic.nit @@ -20,8 +20,8 @@ # to get the underlying Json data. It can also be used as any Json types. module dynamic +import error private import static -import standard class JsonValue var value: nullable Object @@ -123,14 +123,14 @@ class JsonValue # # assert """{"a": 123}""".to_json_value.is_map # assert not "123".to_json_value.is_map - fun is_map: Bool do return value isa HashMap[String, nullable Object] + fun is_map: Bool do return value isa MapRead[String, nullable Object] # Get this value as a `Map[String, JsonValue]` # # require: `self.is_map` fun to_map: Map[String, JsonValue] do var value = value - assert value isa HashMap[String, nullable Object] + assert value isa MapRead[String, nullable Object] var map = new HashMap[String, JsonValue] for k, v in value do map[k] = new JsonValue(v) @@ -145,7 +145,7 @@ class JsonValue # assert "[1, 2, 3, 4, 5]".to_json_value.is_array # assert "[null, true, false, 0.0, 1, \"str\"]".to_json_value.is_array # assert """["a", "b", "c"]""".to_json_value.is_array - fun is_array: Bool do return value isa Array[nullable Object] + fun is_array: Bool do return value isa SequenceRead[nullable Object] # Get this value as an `Array[JsonValue]` # @@ -155,13 +155,42 @@ class JsonValue fun to_a: Array[JsonValue] do var value = value - assert value isa Array[nullable Object] + assert value isa SequenceRead[nullable Object] var a = new Array[JsonValue] for e in value do a.add(new JsonValue(e)) return a end + ### Error + + # Is this value an error? + # + # assert "[]".to_json_value[0].is_error + # assert "[".to_json_value.is_error + # assert not "[]".to_json_value.is_error + fun is_error: Bool do return value isa Error + + # Get this value as a `Error`. + # + # require: `self.is_error` + fun to_error: Error do return value.as(Error) + + ### JsonParseError + + # Is this value a parse error? + # + # assert "[".to_json_value.is_parse_error + # assert not "[]".to_json_value.is_parse_error + fun is_parse_error: Bool do return value isa JsonParseError + + # Get this value as a `JsonParseError`. + # + # require: `self.is_parse_error` + fun to_parse_error: JsonParseError do return value.as(JsonParseError) + + ### Children access + # Iterator over the values of the array `self` # # require: `self.is_array` @@ -181,17 +210,39 @@ class JsonValue # assert """{"a": 123}""".to_json_value["a"].to_i == 123 # assert """{"123": "a"}""".to_json_value[123].to_s == "a" # assert """{"John Smith": 1980}""".to_json_value[["John ", "Smith"]].to_i == 1980 + # assert """{"a": 123}""".to_json_value["b"].is_error # # assert """["a", "b", "c"]""".to_json_value[0].to_s == "a" - fun [](key: Object): JsonValue - do + # assert """["a", "b", "c"]""".to_json_value[3].is_error + fun [](key: Object): JsonValue do var value = value - if value isa HashMap[String, nullable Object] then - return new JsonValue(value[key.to_s]) - else if value isa Array[nullable Object] then - assert key isa Int - return new JsonValue(value[key]) - else abort + var result: nullable Object + if is_error then + return self + else if value isa MapRead[String, nullable Object] then + key = key.to_s + if value.has_key(key) then + result = value[key] + else + result = new JsonKeyError("Key `{key}` not found.", self, key) + end + else if value isa SequenceRead[nullable Object] then + if key isa Int then + if key < value.length and key >= 0 then + result = value[key] + else + result = new JsonKeyError("Index `{key}` out of bounds.", + self, key) + end + else + result = new JsonKeyError("Invalid key type. Expecting `Int`. Got `{key.class_name}`.", + self, key) + end + else + result = new JsonKeyError("Invalid `[]` access on a `{json_type}` JsonValue.", + self, key) + end + return new JsonValue(result) end # Advanced query to get a value within the map `self` or it's children. @@ -203,24 +254,78 @@ class JsonValue # assert """{"a": {"t": true, "f": false}}""".to_json_value.get("a").is_map # assert """{"a": {"t": true, "f": false}}""".to_json_value.get("a.t").to_bool # assert not """{"a": {"t": true, "f": false}}""".to_json_value.get("a.f").to_bool + # assert """{"a": {"t": true, "f": false}}""".to_json_value.get("a.t.t").is_error # assert """{"a": {"b": {"c": {"d": 123}}}}""".to_json_value.get("a.b.c.d").to_i == 123 - fun get(query: String): JsonValue - do + # assert """{"a": {"b": {"c": {"d": 123}}}}""".to_json_value.get("a.z.c.d").is_error + fun get(query: String): JsonValue do var keys = query.split(".") var value = value - for key in keys do - assert value isa HashMap[String, nullable Object] - value = value[key] + if is_error then return self + for i in [0..keys.length[ do + var key = keys[i] + if value isa MapRead[String, nullable Object] then + if value.has_key(key) then + value = value[key] + else + var sub_query = sub_query_to_s(keys, i) + var e = new JsonKeyError("Key `{key}` not found.", + self, sub_query) + return new JsonValue(e) + end + else + var sub_query = sub_query_to_s(keys, i) + var val_type = (new JsonValue(value)).json_type + var e = new JsonKeyError("Value at `{sub_query}` is not a map. Got type `{val_type}`", + self, sub_query) + return new JsonValue(e) + end end return new JsonValue(value) end + + # Concatenate all keys up to `last` for debugging purposes. + # + # Note: This method deletes elements in `keys`. + private fun sub_query_to_s(keys: Array[String], last: Int): String do + last += 1 + for j in [last..keys.length[ do keys.pop + return keys.join(".") + end + + # Return a human-readable description of the type. + # + # For debugging purpose only. + fun json_type: String do + if is_array then return "array" + if is_bool then return "bool" + if is_float then return "float" + if is_int then return "int" + if is_null then return "null" + if is_map then return "map" + if is_string then return "string" + if is_parse_error then return "parse_error" + if is_error then return "error" + return "undefined" + end end -redef class String +# Keyed access failed. +class JsonKeyError + super Error + + # The value on which the access was requested. + var json_value: JsonValue + + # The requested key. + # + # In the case of `JsonValue.get`, the sub-query that failed. + var key: Object +end + +redef class Text # Parse `self` to obtain a `JsonValue` - fun to_json_value: JsonValue - do - var value = json_to_nit_object + fun to_json_value: JsonValue do + var value = parse_json return new JsonValue(value) end end diff --git a/lib/json/error.nit b/lib/json/error.nit new file mode 100644 index 0000000..dab1689 --- /dev/null +++ b/lib/json/error.nit @@ -0,0 +1,31 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# This file is free software, which comes along with NIT. This software is +# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. You can modify it is you want, provided this header +# is kept unaltered, and a notification of the changes is added. +# You are allowed to redistribute it and sell it, alone or is a part of +# another product. + +# Errors related to JSON parsing. +module json::error + +import nitcc_runtime + +# Ill-formed JSON. +class JsonParseError + super Error + + # The location of the error in the original text. + var position: nullable Position + + redef fun to_s do + var p = position + if p isa Position then + return "[{p}] {super}" + else + return super + end + end +end diff --git a/lib/json/json.nit b/lib/json/json.nit index 9353350..b458d01 100644 --- a/lib/json/json.nit +++ b/lib/json/json.nit @@ -1,6 +1,7 @@ # This file is part of NIT ( http://www.nitlanguage.org ). # # Copyright 2014 Alexis Laferrière +# Copyright 2014 Jean-Christophe Beaupré # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,14 +15,19 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Offers two APIs to manipulate read Json strings. +# Provides two APIs to manipulate JSON strings. +# +# Both `dynamic` and `static` modules provide at least a method to parse a +# value written in JSON, but only `static` provide a method to translate a +# value into JSON. # # The `dynamic` module provides a simple interface to get information -# from a Json document. You must be careful as all services are provided on +# from a JSON document. You must be careful as all services are provided on # each nodes and a wrongful use can `abort`. # -# The `static` module converts a Json string to a nullable Nit object. The object -# must then be type checked before it can be used. +# The `static` module provides a common interface for anything that can be +# translated into a JSON document. The provided parsing method return a +# nullable Nit object that must then be type-checked before it can be used. module json import static diff --git a/lib/json/json_lexer.nit b/lib/json/json_lexer.nit index f597c82..3273525 100644 --- a/lib/json/json_lexer.nit +++ b/lib/json/json_lexer.nit @@ -36,6 +36,10 @@ redef class Object private fun dfastate_28: DFAState28 do return once new DFAState28 private fun dfastate_29: DFAState29 do return once new DFAState29 private fun dfastate_30: DFAState30 do return once new DFAState30 + private fun dfastate_31: DFAState31 do return once new DFAState31 + private fun dfastate_32: DFAState32 do return once new DFAState32 + private fun dfastate_33: DFAState33 do return once new DFAState33 + private fun dfastate_34: DFAState34 do return once new DFAState34 end class MyNToken super NToken @@ -391,6 +395,75 @@ private class DFAState30 super DFAState redef fun trans(char) do var c = char.ascii - return dfastate_2 + if c <= 33 then return null + if c <= 34 then return dfastate_2 + if c <= 46 then return null + if c <= 47 then return dfastate_2 + if c <= 91 then return null + if c <= 92 then return dfastate_2 + if c <= 97 then return null + if c <= 98 then return dfastate_2 + if c <= 101 then return null + if c <= 102 then return dfastate_2 + if c <= 109 then return null + if c <= 110 then return dfastate_2 + if c <= 113 then return null + if c <= 114 then return dfastate_2 + if c <= 115 then return null + if c <= 116 then return dfastate_2 + if c <= 117 then return dfastate_31 + return null + end +end +private class DFAState31 + super DFAState + redef fun trans(char) do + var c = char.ascii + if c <= 47 then return null + if c <= 57 then return dfastate_32 + if c <= 64 then return null + if c <= 90 then return dfastate_32 + if c <= 96 then return null + if c <= 122 then return dfastate_32 + return null + end +end +private class DFAState32 + super DFAState + redef fun trans(char) do + var c = char.ascii + if c <= 47 then return null + if c <= 57 then return dfastate_33 + if c <= 64 then return null + if c <= 90 then return dfastate_33 + if c <= 96 then return null + if c <= 122 then return dfastate_33 + return null + end +end +private class DFAState33 + super DFAState + redef fun trans(char) do + var c = char.ascii + if c <= 47 then return null + if c <= 57 then return dfastate_34 + if c <= 64 then return null + if c <= 90 then return dfastate_34 + if c <= 96 then return null + if c <= 122 then return dfastate_34 + return null + end +end +private class DFAState34 + super DFAState + redef fun trans(char) do + var c = char.ascii + if c <= 47 then return null + if c <= 57 then return dfastate_2 + if c <= 64 then return null + if c <= 90 then return dfastate_2 + if c <= 96 then return null + if c <= 122 then return dfastate_2 + return null end end diff --git a/lib/json/static.nit b/lib/json/static.nit index 51800fc..29e5c22 100644 --- a/lib/json/static.nit +++ b/lib/json/static.nit @@ -1,6 +1,8 @@ # This file is part of NIT ( http://www.nitlanguage.org ). # # Copyright 2014 Alexis Laferrière +# Copyright 2014 Alexandre Terrasa +# Copyright 2014 Jean-Christophe Beaupré # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,17 +18,308 @@ # Static interface to get Nit objects from a Json string. # -# `String::json_to_nit_object` returns an equivalent Nit object from +# `Text::parse_json` returns an equivalent Nit object from # the Json source. This object can then be type checked by the usual # languages features (`isa` and `as`). module static -import standard +import error private import json_parser private import json_lexer +# Something that can be translated to JSON. +interface Jsonable + # Encode `self` in JSON. + # + # SEE: `append_json` + fun to_json: String is abstract + + # Append the JSON representation of `self` to the specified buffer. + # + # SEE: `to_json` + fun append_json(buffer: Buffer) do + buffer.append(to_json) + end +end + +redef class Text + super Jsonable + + redef fun append_json(buffer) do + buffer.add '\"' + for i in [0..self.length[ do + var char = self[i] + if char == '\\' then + buffer.append "\\\\" + else if char == '\"' then + buffer.append "\\\"" + else if char == '\/' then + buffer.append "\\/" + else if char < 16.ascii then + if char == '\n' then + buffer.append "\\n" + else if char == '\r' then + buffer.append "\\r" + else if char == '\t' then + buffer.append "\\t" + else if char == 0x0C.ascii then + buffer.append "\\f" + else if char == 0x08.ascii then + buffer.append "\\b" + else + buffer.append "\\u000{char.ascii.to_hex}" + end + else if char < ' ' then + buffer.append "\\u00{char.ascii.to_hex}" + else + buffer.add char + end + end + buffer.add '\"' + end + + # Encode `self` in JSON. + # + # assert "\t\"http://example.com\"\r\n\0\\".to_json == + # "\"\\t\\\"http:\\/\\/example.com\\\"\\r\\n\\u0000\\\\\"" + redef fun to_json do + var buffer = new FlatBuffer + append_json(buffer) + return buffer.write_to_string + end + + # Parse `self` as JSON. + # + # If `self` is not a valid JSON document or contains an unsupported escape + # sequence, return a `JSONParseError`. + # + # Example with `JsonObject`: + # + # var obj = "\{\"foo\": \{\"bar\": true, \"goo\": [1, 2, 3]\}\}".parse_json + # assert obj isa JsonObject + # assert obj["foo"] isa JsonObject + # assert obj["foo"].as(JsonObject)["bar"] == true + # + # Example with `JsonArray`: + # + # var arr = "[1, 2, 3]".parse_json + # assert arr isa JsonArray + # assert arr.length == 3 + # assert arr.first == 1 + # assert arr.last == 3 + # + # Example with `String`: + # + # var str = "\"foo, bar, baz\"".parse_json + # assert str isa String + # assert str == "foo, bar, baz" + # + # Example of a syntaxic error: + # + # var bad = "\{foo: \"bar\"\}".parse_json + # assert bad isa JsonParseError + # assert bad.position.col_start == 2 + fun parse_json: nullable Jsonable do + var lexer = new Lexer_json(to_s) + var parser = new Parser_json + var tokens = lexer.lex + parser.tokens.add_all(tokens) + var root_node = parser.parse + if root_node isa NStart then + return root_node.n_0.to_nit_object + else if root_node isa NError then + return new JsonParseError(root_node.message, root_node.position) + else abort + end +end + +redef class Buffer + + # Append the JSON representation of `jsonable` to `self`. + # + # Append `"null"` for `null`. + private fun append_json_of(jsonable: nullable Jsonable) do + if jsonable isa Jsonable then + append jsonable.to_json + else + append "null" + end + end +end + +redef class Int + super Jsonable + + # Encode `self` in JSON. + # + # assert 0.to_json == "0" + # assert (-42).to_json == "-42" + redef fun to_json do return self.to_s +end + +redef class Float + super Jsonable + + # Encode `self` in JSON. + # + # Note: Because this method use `to_s`, it may lose precision. + # + # ~~~ + # # Will not work as expected. + # # assert (-0.0).to_json == "-0.0" + # + # assert (.5).to_json == "0.5" + # assert (0.0).to_json == "0.0" + # ~~~ + redef fun to_json do return self.to_s +end + +redef class Bool + super Jsonable + + # Encode `self` in JSON. + # + # assert true.to_json == "true" + # assert false.to_json == "false" + redef fun to_json do return self.to_s +end + +# A map that can be translated into a JSON object. +interface JsonMapRead[K: String, V: nullable Jsonable] + super MapRead[K, V] + super Jsonable + + redef fun append_json(buffer) do + buffer.append "\{" + var it = iterator + if it.is_ok then + append_json_entry(it, buffer) + while it.is_ok do + buffer.append "," + append_json_entry(it, buffer) + end + end + it.finish + buffer.append "\}" + end + + # Encode `self` in JSON. + # + # var obj = new JsonObject + # obj["foo"] = "bar" + # assert obj.to_json == "\{\"foo\":\"bar\"\}" + # obj = new JsonObject + # obj["baz"] = null + # assert obj.to_json == "\{\"baz\":null\}" + redef fun to_json do + var buffer = new FlatBuffer + append_json(buffer) + return buffer.write_to_string + end + + private fun append_json_entry(iterator: MapIterator[String, nullable Jsonable], + buffer: Buffer) do + buffer.append iterator.key.to_json + buffer.append ":" + buffer.append_json_of(iterator.item) + iterator.next + end +end + +# A JSON Object. +class JsonObject + super JsonMapRead[String, nullable Jsonable] + super HashMap[String, nullable Jsonable] +end + +# A sequence that can be translated into a JSON array. +class JsonSequenceRead[E: nullable Jsonable] + super Jsonable + super SequenceRead[E] + + redef fun append_json(buffer) do + buffer.append "[" + var it = iterator + if it.is_ok then + append_json_entry(it, buffer) + while it.is_ok do + buffer.append "," + append_json_entry(it, buffer) + end + end + it.finish + buffer.append "]" + end + + # Encode `self` in JSON. + # + # var arr = new JsonArray.with_items("foo", null) + # assert arr.to_json == "[\"foo\",null]" + # arr.pop + # assert arr.to_json =="[\"foo\"]" + # arr.pop + # assert arr.to_json =="[]" + redef fun to_json do + var buffer = new FlatBuffer + append_json(buffer) + return buffer.write_to_string + end + + private fun append_json_entry(iterator: Iterator[nullable Jsonable], + buffer: Buffer) do + buffer.append_json_of(iterator.item) + iterator.next + end +end + +# A JSON array. +class JsonArray + super JsonSequenceRead[nullable Jsonable] + super Array[nullable Jsonable] +end + +redef class JsonParseError + super Jsonable + + # Get the JSON representation of `self`. + # + # var err = new JsonParseError("foo", new Position(1, 2, 3, 4, 5, 6)) + # assert err.to_json == "\{\"error\":\"JsonParseError\"," + + # "\"position\":\{" + + # "\"pos_start\":1,\"pos_end\":2," + + # "\"line_start\":3,\"line_end\":4," + + # "\"col_start\":5,\"col_end\":6" + + # "\},\"message\":\"foo\"\}" + redef fun to_json do + return "\{\"error\":\"JsonParseError\"," + + "\"position\":{position.to_json}," + + "\"message\":{message.to_json}\}" + end +end + +redef class Position + super Jsonable + + # Get the JSON representation of `self`. + # + # var pos = new Position(1, 2, 3, 4, 5, 6) + # assert pos.to_json == "\{" + + # "\"pos_start\":1,\"pos_end\":2," + + # "\"line_start\":3,\"line_end\":4," + + # "\"col_start\":5,\"col_end\":6" + + # "\}" + redef fun to_json do + return "\{\"pos_start\":{pos_start},\"pos_end\":{pos_end}," + + "\"line_start\":{line_start},\"line_end\":{line_end}," + + "\"col_start\":{col_start},\"col_end\":{col_end}\}" + end +end + +################################################################################ +# Redef parser + redef class Nvalue - fun to_nit_object: nullable Object is abstract + fun to_nit_object: nullable Jsonable is abstract end redef class Nvalue_number @@ -55,17 +348,46 @@ redef class Nvalue_null end redef class Nstring - # FIXME support \n, etc. - fun to_nit_string: String do return text.substring(1, text.length-2). - replace("\\\\", "\\").replace("\\\"", "\"").replace("\\b", "\b"). - replace("\\/", "/").replace("\\n", "\n").replace("\\r", "\r"). - replace("\\t", "\t") + fun to_nit_string: String do + var res = new FlatBuffer + var i = 1 + while i < text.length - 1 do + var char = text[i] + if char == '\\' then + i += 1 + char = text[i] + if char == 'b' then + char = 0x08.ascii + else if char == 'f' then + char = 0x0C.ascii + else if char == 'n' then + char = '\n' + else if char == 'r' then + char = '\r' + else if char == 't' then + char = '\t' + else if char == 'u' then + var code = text.substring(i + 1, 4).to_hex + # TODO UTF-16 escaping is not supported yet. + if code >= 128 then + char = '?' + else + char = code.ascii + end + i += 4 + end + # `"`, `/` or `\` => Keep `char` as-is. + end + res.add char + i += 1 + end + return res.write_to_string + end end redef class Nvalue_object - redef fun to_nit_object - do - var obj = new HashMap[String, nullable Object] + redef fun to_nit_object do + var obj = new JsonObject var members = n_members if members != null then var pairs = members.pairs @@ -94,13 +416,13 @@ end redef class Npair fun name: String do return n_string.to_nit_string - fun value: nullable Object do return n_value.to_nit_object + fun value: nullable Jsonable do return n_value.to_nit_object end redef class Nvalue_array redef fun to_nit_object do - var arr = new Array[nullable Object] + var arr = new JsonArray var elements = n_elements if elements != null then var items = elements.items @@ -126,25 +448,3 @@ end redef class Nelements_head redef fun items do return [n_value] end - -redef class Text - fun json_to_nit_object: nullable Object - do - var lexer = new Lexer_json(to_s) - var parser = new Parser_json - var tokens = lexer.lex - parser.tokens.add_all(tokens) - var root_node = parser.parse - if root_node isa NStart then - return root_node.n_0.to_nit_object - else if root_node isa NLexerError then - var pos = root_node.position - print "Json lexer error: {root_node.message} at {pos or else ""} for {root_node}" - return null - else if root_node isa NParserError then - var pos = root_node.position - print "Json parsing error: {root_node.message} at {pos or else ""} for {root_node}" - return null - else abort - end -end diff --git a/lib/json_serialization.nit b/lib/json_serialization.nit index 6a2d82a..f090b24 100644 --- a/lib/json_serialization.nit +++ b/lib/json_serialization.nit @@ -71,16 +71,16 @@ end class JsonDeserializer super Deserializer - var root: nullable Object - var path = new Array[HashMap[String, nullable Object]] + var root: nullable Jsonable + var path = new Array[JsonObject] var id_to_object = new HashMap[Int, Object] var just_opened_id: nullable Int = null init(text: Text) do - var root = text.json_to_nit_object - if root isa HashMap[String, nullable Object] then path.add(root) + var root = text.parse_json + if root isa JsonObject then path.add(root) self.root = root end @@ -107,7 +107,7 @@ class JsonDeserializer # Convert from simple Json object to Nit object private fun convert_object(object: nullable Object): nullable Object do - if object isa HashMap[String, nullable Object] then + if object isa JsonObject then assert object.keys.has("__kind") var kind = object["__kind"] @@ -197,18 +197,11 @@ redef class Bool end redef class Char - redef fun serialize_to_json(v) do v.stream.write "\{\"__kind\": \"char\", \"__val\": \"{to_s.to_json_s}\"\}" + redef fun serialize_to_json(v) do v.stream.write "\{\"__kind\": \"char\", \"__val\": {to_s.to_json}\}" end redef class String - redef fun serialize_to_json(v) do v.stream.write("\"{to_json_s}\"") - - private fun to_json_s: String do return self.replace("\\", "\\\\"). - replace("\"", "\\\"").replace("/", "\\/"). - replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t") - # FIXME add support for unicode char when supported by Nit strings - # FIXME add support for \f! # .replace("\f", "\\f") - # FIXME add support for \b .replace("\b", "\\b") + redef fun serialize_to_json(v) do v.stream.write(to_json) end redef class NativeString @@ -259,7 +252,7 @@ redef class Array[E] v.notify_of_creation self var length = v.deserialize_attribute("__length").as(Int) - var arr = v.path.last["__items"].as(Array[nullable Object]) + var arr = v.path.last["__items"].as(SequenceRead[nullable Object]) for i in length.times do var obj = v.convert_object(arr[i]) self.add obj diff --git a/lib/jvm.nit b/lib/jvm.nit index 56080a5..8012746 100644 --- a/lib/jvm.nit +++ b/lib/jvm.nit @@ -173,6 +173,7 @@ extern class JavaVM `{JavaVM *`} JavaVM_jni_error(NULL, "Could not attach current thread to Java VM", res); return NULL; } + return env; `} end @@ -216,36 +217,41 @@ extern class JniEnv `{JNIEnv *`} # Call a method on `obj` designed by `method_id` with an array `args` of argument returning a JavaObject fun call_object_method(obj: JavaObject, method_id: JMethodID, args: nullable Array[nullable Object]): JavaObject import convert_args_to_jni `{ jvalue * args_tab = JniEnv_convert_args_to_jni(recv, args); - (*recv)->CallObjectMethod(recv, obj, method_id, args_tab); + jobject res = (*recv)->CallObjectMethod(recv, obj, method_id, args_tab); free(args_tab); + return res; `} # Call a method on `obj` designed by `method_id` with an array `args` of arguments returning a Bool fun call_boolean_method(obj: JavaObject, method_id: JMethodID, args: nullable Array[nullable Object]): Bool import convert_args_to_jni `{ jvalue * args_tab = JniEnv_convert_args_to_jni(recv, args); - return (*recv)->CallBooleanMethod(recv, obj, method_id, args_tab); + jboolean res = (*recv)->CallBooleanMethod(recv, obj, method_id, args_tab); free(args_tab); + return res; `} # Call a method on `obj` designed by `method_id` with an array `args` of arguments returning a Char fun call_char_method(obj: JavaObject, method_id: JMethodID, args: nullable Array[nullable Object]): Char import convert_args_to_jni `{ jvalue * args_tab = JniEnv_convert_args_to_jni(recv, args); - return (*recv)->CallCharMethod(recv, obj, method_id, args_tab); + jchar res = (*recv)->CallCharMethod(recv, obj, method_id, args_tab); free(args_tab); + return res; `} # Call a method on `obj` designed by `method_id` with an array `args` of arguments returning an Int fun call_int_method(obj: JavaObject, method_id: JMethodID, args: nullable Array[nullable Object]): Int import convert_args_to_jni `{ jvalue * args_tab = JniEnv_convert_args_to_jni(recv, args); - return (*recv)->CallIntMethod(recv, obj, method_id, args_tab); + jint res = (*recv)->CallIntMethod(recv, obj, method_id, args_tab); free(args_tab); + return res; `} # Call a method on `obj` designed by `method_id` with an array `args` of arguments returning a Float fun call_float_method(obj: JavaObject, method_id: JMethodID, args: nullable Array[nullable Object]): Float import convert_args_to_jni `{ jvalue * args_tab = JniEnv_convert_args_to_jni(recv, args); - return (*recv)->CallFloatMethod(recv, obj, method_id, args_tab); + jfloat res = (*recv)->CallFloatMethod(recv, obj, method_id, args_tab); free(args_tab); + return res; `} # Call a method on `obj` designed by `method_id` with an array `args` of arguments returning a NativeString diff --git a/lib/markdown/markdown.nit b/lib/markdown/markdown.nit index 5b73d3b..add43e1 100644 --- a/lib/markdown/markdown.nit +++ b/lib/markdown/markdown.nit @@ -30,6 +30,7 @@ import template # SEE: `String::md_to_html` for a shortcut. class MarkdownProcessor + # `MarkdownEmitter` used for ouput. var emitter: MarkdownEmitter is noinit init do self.emitter = new MarkdownEmitter(self) @@ -261,6 +262,101 @@ class MarkdownProcessor return new LineOther end + # Get the token kind at `pos`. + fun token_at(text: Text, pos: Int): Token do + var c0: Char + var c1: Char + var c2: Char + + if pos > 0 then + c0 = text[pos - 1] + else + c0 = ' ' + end + var c = text[pos] + + if pos + 1 < text.length then + c1 = text[pos + 1] + else + c1 = ' ' + end + if pos + 2 < text.length then + c2 = text[pos + 2] + else + c2 = ' ' + end + + if c == '*' then + if c1 == '*' then + if c0 != ' ' or c2 != ' ' then + return new TokenStrongStar(pos, c) + else + return new TokenEmStar(pos, c) + end + end + if c0 != ' ' or c1 != ' ' then + return new TokenEmStar(pos, c) + else + return new TokenNone(pos, c) + end + else if c == '_' then + if c1 == '_' then + if c0 != ' ' or c2 != ' 'then + return new TokenStrongUnderscore(pos, c) + else + return new TokenEmUnderscore(pos, c) + end + end + if c0 != ' ' or c1 != ' ' then + return new TokenEmUnderscore(pos, c) + else + return new TokenNone(pos, c) + end + else if c == '!' then + if c1 == '[' then return new TokenImage(pos, c) + return new TokenNone(pos, c) + else if c == '[' then + return new TokenLink(pos, c) + else if c == ']' then + return new TokenNone(pos, c) + else if c == '`' then + if c1 == '`' then + return new TokenCodeDouble(pos, c) + else + return new TokenCodeSingle(pos, c) + end + else if c == '\\' then + if c1 == '\\' or c1 == '[' or c1 == ']' or c1 == '(' or c1 == ')' or c1 == '{' or c1 == '}' or c1 == '#' or c1 == '"' or c1 == '\'' or c1 == '.' or c1 == '<' or c1 == '>' or c1 == '*' or c1 == '+' or c1 == '-' or c1 == '_' or c1 == '!' or c1 == '`' or c1 == '~' or c1 == '^' then + return new TokenEscape(pos, c) + else + return new TokenNone(pos, c) + end + else if c == '<' then + return new TokenHTML(pos, c) + else if c == '&' then + return new TokenEntity(pos, c) + else if c == '^' then + if c0 == '^' or c1 == '^' then + return new TokenNone(pos, c) + else + return new TokenSuper(pos, c) + end + else + return new TokenNone(pos, c) + end + end + + # Find the position of a `token` in `self`. + fun find_token(text: Text, start: Int, token: Token): Int do + var pos = start + while pos < text.length do + if token_at(text, pos).is_same_type(token) then + return pos + end + pos += 1 + end + return -1 + end end # Emit output corresponding to blocks content. @@ -276,11 +372,6 @@ class MarkdownEmitter # Default is `HTMLDecorator` var decorator: Decorator = new HTMLDecorator is writable - # Create a new `MardownEmitter` using the default `HTMLDecorator` - init(processor: MarkdownProcessor) do - self.processor = processor - end - # Create a new `MarkdownEmitter` using a custom `decorator`. init with_decorator(processor: MarkdownProcessor, decorator: Decorator) do init processor @@ -312,7 +403,7 @@ class MarkdownEmitter current_text = text current_pos = start while current_pos < text.length do - var mt = text.token_at(current_pos) + var mt = processor.token_at(text, current_pos) if (token != null and not token isa TokenNone) and (mt.is_same_type(token) or (token isa TokenEmStar and mt isa TokenStrongStar) or @@ -1112,8 +1203,7 @@ class MDLine var next_empty: Bool = false is writable # Initialize a new MDLine from its string value - init(value: String) do - self.value = value + init do self.leading = process_leading if leading != value.length then self.is_empty = false @@ -1675,7 +1765,7 @@ abstract class TokenCode redef fun emit(v) do var a = pos + next_pos + 1 - var b = v.current_text.find_token(a, self) + var b = v.processor.find_token(v.current_text.as(not null), a, self) if b > 0 then v.current_pos = b + next_pos while a < b and v.current_text[a] == ' ' do a += 1 @@ -1967,102 +2057,6 @@ end redef class Text - # Get the token kind at `pos`. - private fun token_at(pos: Int): Token do - var c0: Char - var c1: Char - var c2: Char - - if pos > 0 then - c0 = self[pos - 1] - else - c0 = ' ' - end - var c = self[pos] - - if pos + 1 < length then - c1 = self[pos + 1] - else - c1 = ' ' - end - if pos + 2 < length then - c2 = self[pos + 2] - else - c2 = ' ' - end - - if c == '*' then - if c1 == '*' then - if c0 != ' ' or c2 != ' ' then - return new TokenStrongStar(pos, c) - else - return new TokenEmStar(pos, c) - end - end - if c0 != ' ' or c1 != ' ' then - return new TokenEmStar(pos, c) - else - return new TokenNone(pos, c) - end - else if c == '_' then - if c1 == '_' then - if c0 != ' ' or c2 != ' 'then - return new TokenStrongUnderscore(pos, c) - else - return new TokenEmUnderscore(pos, c) - end - end - if c0 != ' ' or c1 != ' ' then - return new TokenEmUnderscore(pos, c) - else - return new TokenNone(pos, c) - end - else if c == '!' then - if c1 == '[' then return new TokenImage(pos, c) - return new TokenNone(pos, c) - else if c == '[' then - return new TokenLink(pos, c) - else if c == ']' then - return new TokenNone(pos, c) - else if c == '`' then - if c1 == '`' then - return new TokenCodeDouble(pos, c) - else - return new TokenCodeSingle(pos, c) - end - else if c == '\\' then - if c1 == '\\' or c1 == '[' or c1 == ']' or c1 == '(' or c1 == ')' or c1 == '{' or c1 == '}' or c1 == '#' or c1 == '"' or c1 == '\'' or c1 == '.' or c1 == '<' or c1 == '>' or c1 == '*' or c1 == '+' or c1 == '-' or c1 == '_' or c1 == '!' or c1 == '`' or c1 == '~' or c1 == '^' then - return new TokenEscape(pos, c) - else - return new TokenNone(pos, c) - end - else if c == '<' then - return new TokenHTML(pos, c) - else if c == '&' then - return new TokenEntity(pos, c) - else if c == '^' then - if c0 == '^' or c1 == '^' then - return new TokenNone(pos, c) - else - return new TokenSuper(pos, c) - end - else - return new TokenNone(pos, c) - end - end - - # Find the position of a `token` in `self`. - private fun find_token(start: Int, token: Token): Int do - var pos = start - while pos < length do - if token_at(pos).is_same_type(token) then - return pos - end - pos += 1 - end - return -1 - end - # Get the position of the next non-space character. private fun skip_spaces(start: Int): Int do var pos = start diff --git a/lib/mnit/mnit_injected_input.nit b/lib/mnit/mnit_injected_input.nit index 4ed9664..a72b34d 100644 --- a/lib/mnit/mnit_injected_input.nit +++ b/lib/mnit/mnit_injected_input.nit @@ -78,6 +78,8 @@ redef class App var env = "MNIT_SRAND".environ if env != "" then srand_from(env.to_i) + else + srand_from(0) end var input = "MNIT_READ_INPUT".environ diff --git a/lib/mnit/tileset.nit b/lib/mnit/tileset.nit index 568fad5..5bd5d4d 100644 --- a/lib/mnit/tileset.nit +++ b/lib/mnit/tileset.nit @@ -70,11 +70,11 @@ class TileSetFont # Additional space to insert horizontally between characters # A negave value will display tile overlaped - var hspace: Int = 0 is writable + var hspace: Numeric = 0.0 is writable # Additional space to insert vertically between characters # A negave value will display tile overlaped - var vspace: Int = 0 is writable + var vspace: Numeric = 0.0 is writable # The glyph (tile) associated to the caracter `c` according to `chars` # Returns null if `c` is not in `chars` @@ -91,10 +91,11 @@ redef class Display # '\n' are rendered as carriage return fun text(text: String, font: TileSetFont, x, y: Numeric) do + x = x.to_f var cx = x - var cy = y - var sw = font.width + font.hspace - var sh = font.height + font.vspace + var cy = y.to_f + var sw = font.width.to_f + font.hspace.to_f + var sh = font.height.to_f + font.vspace.to_f for c in text.chars do if c == '\n' then cx = x diff --git a/lib/mnit_android/android_app.nit b/lib/mnit_android/android_app.nit index 725c612..87afb4a 100644 --- a/lib/mnit_android/android_app.nit +++ b/lib/mnit_android/android_app.nit @@ -15,7 +15,12 @@ # limitations under the License. # Impements the services of `mnit:app` using the API from the Android ndk -module android_app +module android_app is + android_manifest_activity """ + android:theme="@android:style/Theme.NoTitleBar.Fullscreen" + android:configChanges="orientation|keyboardHidden" + android:screenOrientation="portrait"""" +end import mnit import android diff --git a/lib/mnit_android/android_assets.nit b/lib/mnit_android/android_assets.nit index 20704b6..2c703bb 100644 --- a/lib/mnit_android/android_assets.nit +++ b/lib/mnit_android/android_assets.nit @@ -129,8 +129,8 @@ redef class Opengles1Image int has_alpha; unsigned int row_bytes; - png_bytepp row_pointers; - unsigned char *pixels; + png_bytepp row_pointers = NULL; + unsigned char *pixels = NULL; unsigned int i; unsigned char sig[8]; @@ -166,23 +166,24 @@ redef class Opengles1Image png_get_IHDR( png_ptr, info_ptr, &width, &height, &depth, &color_type, NULL, NULL, NULL); - if (color_type == PNG_COLOR_TYPE_RGBA) - has_alpha = 1; - else if (color_type == PNG_COLOR_TYPE_RGB) - has_alpha = 0; - else { - LOGW("unknown color_type"); - goto close_png_ptr; + has_alpha = color_type & PNG_COLOR_MASK_ALPHA; + + // If we get gray and alpha only, standardize the format of the pixels. + // GA is not supported by OpenGL ES 1. + if (!(color_type & PNG_COLOR_MASK_COLOR)) { + png_set_gray_to_rgb(png_ptr); + png_set_palette_to_rgb(png_ptr); + png_read_update_info(png_ptr, info_ptr); } LOGW("w: %i, h: %i", width, height); row_bytes = png_get_rowbytes(png_ptr, info_ptr); pixels = malloc(row_bytes * height); - row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height); + row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height); - for (i=0; i"} for {root_node}" - return new JsonError("JsonLexerError", msg) - else if root_node isa NParserError then - var pos = root_node.position - var msg = "{root_node.message} at {pos or else ""} for {root_node}" - return new JsonError("JsonParsingError", msg) - else abort - end -end - diff --git a/lib/neo4j/neo4j.nit b/lib/neo4j/neo4j.nit index b84a60b..efe4f6a 100644 --- a/lib/neo4j/neo4j.nit +++ b/lib/neo4j/neo4j.nit @@ -64,6 +64,7 @@ module neo4j import curl_json +import error # Handles Neo4j server start and stop command # @@ -336,29 +337,31 @@ class Neo4jClient # Parse the cURL `response` as a JSON string private fun parse_response(response: CurlResponse): Jsonable do if response isa CurlResponseSuccess then - if response.body_str.is_empty then + var str = response.body_str + if str.is_empty then return new JsonObject + var res = str.parse_json + if res isa JsonParseError then + var e = new NeoError(res.to_s, "JsonParseError") + e.cause = res + return e + end + if res == null then + # empty response wrap it in empty object return new JsonObject - else - var str = response.body_str - var res = str.to_jsonable - if res == null then - # empty response wrap it in empty object - return new JsonObject - else if res isa JsonObject and res.has_key("exception") then - var error = "Neo4jError::{res["exception"] or else "null"}" - var msg = "" - if res.has_key("message") then - msg = res["message"].to_s - end - return new JsonError(error, msg.to_json) - else - return res + else if res isa JsonObject and res.has_key("exception") then + var error = "Neo4jError::{res["exception"] or else "null"}" + var msg = "" + if res.has_key("message") then + msg = res["message"].to_s end + return new NeoError(msg, error) + else + return res end else if response isa CurlResponseFailed then - return new JsonError("Curl error", "{response.error_msg} ({response.error_code})") + return new NeoError("{response.error_msg} ({response.error_code})", "CurlError") else - return new JsonError("Curl error", "Unexpected response '{response}'") + return new NeoError("Unexpected response \"{response}\".", "CurlError") end end end @@ -896,7 +899,7 @@ class NeoBatch fun save_edges(edges: Collection[NeoEdge]) do for edge in edges do save_edge(edge) # Execute the batch and update local nodes - fun execute: List[JsonError] do + fun execute: List[NeoError] do var request = new JsonPOST(client.batch_url, client.curl) # request.headers["X-Stream"] = "true" var json_jobs = new JsonArray @@ -908,16 +911,16 @@ class NeoBatch end # Associate data from response in original nodes and edges - private fun finalize_batch(response: Jsonable): List[JsonError] do - var errors = new List[JsonError] + private fun finalize_batch(response: Jsonable): List[NeoError] do + var errors = new List[NeoError] if not response isa JsonArray then - errors.add(new JsonError("Neo4jError", "Unexpected batch response format")) + errors.add(new NeoError("Unexpected batch response format.", "Neo4jError")) return errors end # print " {res.length} jobs executed" for res in response do if not res isa JsonObject then - errors.add(new JsonError("Neo4jError", "Unexpected job format in batch response")) + errors.add(new NeoError("Unexpected job format in batch response.", "Neo4jError")) continue end var id = res["id"].as(Int) diff --git a/lib/pthreads/extra.nit b/lib/pthreads/extra.nit new file mode 100644 index 0000000..416b174 --- /dev/null +++ b/lib/pthreads/extra.nit @@ -0,0 +1,62 @@ +# This file is part of NIT (http://www.nitlanguage.org). +# +# Copyright 2014 Alexis Laferrière +# +# 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. + +# Offers some POSIX threads services that are not available on all platforms +module extra is + c_compiler_option("-pthread") + c_linker_option("-pthread") +end + +intrude import pthreads + +in "C" `{ + // TODO protect with: #ifdef WITH_LIBGC + #ifndef ANDROID + #define GC_THREADS + #include + #endif +`} + +redef extern class NativePthread + fun cancel: Bool `{ + return pthread_cancel(*recv); + `} +end + +redef class Thread + # Cancel the execution of the thread + fun cancel + do + if native == null then return + native.cancel + native = null + end +end + +# Does not return if the running thread is to be cancelled +fun test_cancel `{ pthread_testcancel(); `} + +private extern class NativePthreadBarrier in "C" `{ pthread_barrier_t * `} + new(count: Int) `{ + pthread_barrier_t *barrier = malloc(sizeof(pthread_barrier_t)); + int res = pthread_barrier_init(barrier, NULL, count); + return barrier; + `} + + fun destroy `{ pthread_barrier_destroy(recv); `} + + fun wait `{ pthread_barrier_wait(recv); `} +end diff --git a/lib/pthreads/pthreads.nit b/lib/pthreads/pthreads.nit index 1e76e28..94cf078 100644 --- a/lib/pthreads/pthreads.nit +++ b/lib/pthreads/pthreads.nit @@ -34,9 +34,10 @@ in "C" `{ // TODO protect with: #ifdef WITH_LIBGC // We might have to add the next line to gc_chooser.c too, especially // if we get an error like "thread not registered with GC". + #ifndef ANDROID #define GC_THREADS #include - //#endif + #endif `} redef class Sys @@ -114,10 +115,6 @@ private extern class NativePthread in "C" `{ pthread_t * `} return (nullable_Object)thread_return; `} - fun cancel: Bool `{ - return pthread_cancel(*recv); - `} - fun attr: NativePthreadAttr `{ pthread_attr_t *pattr = malloc(sizeof(pthread_attr_t)); pthread_getattr_np(*recv, pattr); @@ -192,18 +189,6 @@ private extern class NativePthreadMutexAttr in "C" `{ pthread_mutexattr_t * `} # pthread_mutexattr_setrobust_np end -private extern class NativePthreadBarrier in "C" `{ pthread_barrier_t * `} - new(count: Int) `{ - pthread_barrier_t *barrier = malloc(sizeof(pthread_barrier_t)); - int res = pthread_barrier_init(barrier, NULL, count); - return barrier; - `} - - fun destroy `{ pthread_barrier_destroy(recv); `} - - fun wait `{ pthread_barrier_wait(recv); `} -end - private extern class NativePthreadKey in "C" `{ pthread_key_t * `} new `{ pthread_key_t *key = malloc(sizeof(pthread_key_t)); @@ -222,6 +207,27 @@ private extern class NativePthreadKey in "C" `{ pthread_key_t * `} `} end +private extern class NativePthreadCond in "C" `{ pthread_cond_t * `} + new `{ + pthread_cond_t cond; + int r = pthread_cond_init(&cond, NULL); + if (r == 0) { + pthread_cond_t *pcond = malloc(sizeof(pthread_cond_t)); + memmove(pcond, &cond, sizeof(pthread_cond_t)); + return pcond; + } + return NULL; + `} + + fun destroy `{ pthread_cond_destroy(recv); `} + + fun signal `{ pthread_cond_signal(recv); `} + + fun broadcast `{ pthread_cond_broadcast(recv); `} + + fun wait(mutex: NativePthreadMutex) `{ pthread_cond_wait(recv, mutex); `} +end + # ## Nity part # @@ -272,14 +278,6 @@ abstract class Thread return r end - # Cancel the execution of the thread - fun cancel - do - if native == null then return - native.cancel - native = null - end - redef fun finalize do if native == null then return @@ -298,9 +296,6 @@ end # Exit current thread and return `value` to caller of `Thread::join` fun exit_thread(value: nullable Object) `{ pthread_exit(value); `} -# Does not return if the running thread is to be cancelled -fun test_cancel `{ pthread_testcancel(); `} - # Returns the handle to the running `Thread` fun thread: Thread do @@ -364,24 +359,36 @@ end class Barrier super Finalizable + private var mutex = new Mutex + private var cond: nullable NativePthreadCond = new NativePthreadCond + # Number of threads that must be waiting for `wait` to unblock var count: Int - private var native: nullable NativePthreadBarrier is noinit - - init do native = new NativePthreadBarrier(count) + private var threads_waiting = 0 # Wait at this barrier and block until there are a `count` threads waiting - fun wait do native.wait + fun wait + do + mutex.lock + threads_waiting += 1 + if threads_waiting == count then + threads_waiting = 0 + cond.broadcast + else + cond.wait(mutex.native.as(not null)) + end + mutex.unlock + end redef fun finalize do - var native = self.native - if native != null then - native.destroy - native.free + var cond = self.cond + if cond != null then + cond.destroy + cond.free end - self.native = null + self.cond = null end end diff --git a/lib/standard/collection/array.nit b/lib/standard/collection/array.nit index 7d710bd..ca6e9fa 100644 --- a/lib/standard/collection/array.nit +++ b/lib/standard/collection/array.nit @@ -251,7 +251,6 @@ end # assert a == b class Array[E] super AbstractArray[E] - super ArrayCapable[E] redef fun [](index) do @@ -286,7 +285,7 @@ class Array[E] var c = _capacity if cap <= c then return while c <= cap do c = c * 2 + 2 - var a = calloc_array(c) + var a = new NativeArray[E](c) if _capacity > 0 then _items.copy_to(a, _length) _items = a _capacity = c @@ -317,7 +316,7 @@ class Array[E] init with_capacity(cap: Int) do assert positive: cap >= 0 - _items = calloc_array(cap) + _items = new NativeArray[E](cap) _capacity = cap _length = 0 end @@ -326,7 +325,7 @@ class Array[E] init filled_with(value: E, count: Int) do assert positive: count >= 0 - _items = calloc_array(count) + _items = new NativeArray[E](count) _capacity = count _length = count var i = 0 @@ -769,12 +768,6 @@ end # Native classes ############################################################## -# Subclasses of this class can create native arrays -interface ArrayCapable[E] - # Get a new array of `size` elements. - protected fun calloc_array(size: Int): NativeArray[E] is intern -end - # Native Nit array # Access are unchecked and it has a fixed size # Not for public use: may become private. diff --git a/lib/standard/collection/hash_collection.nit b/lib/standard/collection/hash_collection.nit index 6490024..92b8d5c 100644 --- a/lib/standard/collection/hash_collection.nit +++ b/lib/standard/collection/hash_collection.nit @@ -16,8 +16,8 @@ module hash_collection import array # A HashCollection is an array of HashNode[K] indexed by the K hash value -private abstract class HashCollection[K: Object, N: HashNode[Object]] - super ArrayCapable[nullable N] +private abstract class HashCollection[K: Object] + type N: HashNode[K] private var array: nullable NativeArray[nullable N] = null # Used to store items private var capacity: Int = 0 # Size of _array @@ -163,7 +163,7 @@ private abstract class HashCollection[K: Object, N: HashNode[Object]] _last_accessed_key = null # get a new array - var new_array = calloc_array(cap) + var new_array = new NativeArray[nullable N](cap) _array = new_array # clean the new array @@ -203,7 +203,9 @@ end # Keys of such a map cannot be null and require a working `hash` method class HashMap[K: Object, V] super Map[K, V] - super HashCollection[K, HashMapNode[K, V]] + super HashCollection[K] + + redef type N: HashMapNode[K, V] is fixed redef fun [](key) do @@ -389,7 +391,9 @@ end # Keys of such a map cannot be null and require a working `hash` method class HashSet[E: Object] super Set[E] - super HashCollection[E, HashSetNode[E]] + super HashCollection[E] + + redef type N: HashSetNode[E] is fixed redef fun length do return _the_length diff --git a/lib/standard/collection/union_find.nit b/lib/standard/collection/union_find.nit index e865703..f9ac76f 100644 --- a/lib/standard/collection/union_find.nit +++ b/lib/standard/collection/union_find.nit @@ -37,6 +37,17 @@ class DisjointSet[E: Object] # The node in the hiearchical structure for each element private var nodes = new HashMap[E, DisjointSetNode] + # The number of subsets in the partition + # + # var s = new DisjointSet[Int] + # s.add_all([1,2,3,4,5]) + # assert s.number_of_subsets == 5 + # s.union_all([1,4,5]) + # assert s.number_of_subsets == 3 + # s.union(4,5) + # assert s.number_of_subsets == 3 + var number_of_subsets: Int = 0 + # Get the root node of an element # require: `has(e)` private fun find(e:E): DisjointSetNode @@ -84,6 +95,7 @@ class DisjointSet[E: Object] if nodes.has_key(e) then return var ne = new DisjointSetNode nodes[e] = ne + number_of_subsets += 1 end # Are two elements in the same subset? @@ -171,6 +183,7 @@ class DisjointSet[E: Object] ne.rank = er+1 end end + number_of_subsets -= 1 end # Combine the subsets of all elements of `es` diff --git a/lib/standard/kernel.nit b/lib/standard/kernel.nit index 6d2e4c6..a179e9a 100644 --- a/lib/standard/kernel.nit +++ b/lib/standard/kernel.nit @@ -353,6 +353,21 @@ universal Float end end + # Compare float numbers with a given precision. + # + # Because of the loss of precision in floating numbers, + # the `==` method is often not the best way to compare them. + # + # ~~~ + # assert 0.01.is_approx(0.02, 0.1) == true + # assert 0.01.is_approx(0.02, 0.001) == false + # ~~~ + fun is_approx(other, precision: Float): Bool + do + assert precision >= 0.0 + return self <= other + precision and self >= other - precision + end + redef fun max(other) do if self < other then diff --git a/lib/standard/math.nit b/lib/standard/math.nit index 5a980aa..6214a65 100644 --- a/lib/standard/math.nit +++ b/lib/standard/math.nit @@ -138,6 +138,14 @@ redef class Float # assert 2.0.floor == 2.0 # assert (-1.5).floor == -2.0 fun floor: Float `{ return floor(recv); `} + + # Rounds the value of a float to its nearest integer value + # + # assert 1.67.round == 2.0 + # assert 1.34.round == 1.0 + # assert -1.34.round == -1.0 + # assert -1.67.round == -2.0 + fun round: Float is extern "round" # Returns a random `Float` in `[0.0 .. self[`. fun rand: Float is extern "kernel_Float_Float_rand_0" @@ -178,7 +186,31 @@ redef class Collection[ E ] end end +redef class Sys + init + do + srand + end +end + fun atan2(x: Float, y: Float): Float is extern "kernel_Any_Any_atan2_2" fun pi: Float is extern "kernel_Any_Any_pi_0" + +# Initialize the pseudo-random generator with the given seed. +# The pseudo-random generator is used by the method `rand` and other to generate sequence of numbers. +# These sequences are repeatable by calling `srand_from` with a same seed value. +# +# ~~~~ +# srand_from(0) +# var a = 10.rand +# var b = 100.rand +# srand_from(0) +# assert 10.rand == a +# assert 100.rand == b +# ~~~~ fun srand_from(x: Int) is extern "kernel_Any_Any_srand_from_1" + +# Reinitialize the pseudo-random generator used by the method `rand` and other. +# This method is automatically invoked at the begin of the program, so usually, there is no need to manually invoke it. +# The only exception is in conjunction with `srand_from` to reset the pseudo-random generator. fun srand is extern "kernel_Any_Any_srand_0" diff --git a/lib/standard/string.nit b/lib/standard/string.nit index 28ad7b5..48cb238 100644 --- a/lib/standard/string.nit +++ b/lib/standard/string.nit @@ -30,7 +30,6 @@ intrude import collection::array # High-level abstraction for all text representations abstract class Text super Comparable - super StringCapable redef type OTHER: Text @@ -515,6 +514,29 @@ abstract class Text return b.to_s end + # Escape to include in a Makefile + # + # Unfortunately, some characters are not escapable in Makefile. + # These characters are `;`, `|`, `\`, and the non-printable ones. + # They will be rendered as `"?{hex}"`. + fun escape_to_mk: String do + var b = new FlatBuffer + for i in [0..length[ do + var c = chars[i] + if c == '$' then + b.append("$$") + else if c == ':' or c == ' ' or c == '#' then + b.add('\\') + b.add(c) + else if c.ascii < 32 or c == ';' or c == '|' or c == '\\' or c == '=' then + b.append("?{c.ascii.to_base(16, false)}") + else + b.add(c) + end + end + return b.to_s + end + # Return a string where Nit escape sequences are transformed. # # var s = "\\n" @@ -969,7 +991,7 @@ class FlatString redef fun reversed do - var native = calloc_string(self.length + 1) + var native = new NativeString(self.length + 1) var length = self.length var items = self.items var pos = 0 @@ -1007,7 +1029,7 @@ class FlatString redef fun to_upper do - var outstr = calloc_string(self.length + 1) + var outstr = new NativeString(self.length + 1) var out_index = 0 var myitems = self.items @@ -1027,7 +1049,7 @@ class FlatString redef fun to_lower do - var outstr = calloc_string(self.length + 1) + var outstr = new NativeString(self.length + 1) var out_index = 0 var myitems = self.items @@ -1072,7 +1094,7 @@ class FlatString if real_items != null then return real_items.as(not null) else - var newItems = calloc_string(length + 1) + var newItems = new NativeString(length + 1) self.items.copy_to(newItems, length, index_from, 0) newItems[length] = '\0' self.real_items = newItems @@ -1150,7 +1172,7 @@ class FlatString var total_length = my_length + its_length - var target_string = calloc_string(my_length + its_length + 1) + var target_string = new NativeString(my_length + its_length + 1) self.items.copy_to(target_string, my_length, index_from, 0) if s isa FlatString then @@ -1181,7 +1203,7 @@ class FlatString var my_items = self.items - var target_string = calloc_string((final_length) + 1) + var target_string = new NativeString(final_length + 1) target_string[final_length] = '\0' @@ -1479,7 +1501,7 @@ class FlatBuffer # The COW flag can be set at false here, since # it does a copy of the current `Buffer` written = false - var a = calloc_string(c+1) + var a = new NativeString(c+1) if length > 0 then items.copy_to(a, length, 0, 0) items = a capacity = c @@ -1495,7 +1517,7 @@ class FlatBuffer redef fun to_cstring do if is_dirty then - var new_native = calloc_string(length + 1) + var new_native = new NativeString(length + 1) new_native[length] = '\0' if length > 0 then items.copy_to(new_native, length, 0, 0) real_items = new_native @@ -1511,7 +1533,7 @@ class FlatBuffer do capacity = s.length + 1 length = s.length - items = calloc_string(capacity) + items = new NativeString(capacity) if s isa FlatString then s.items.copy_to(items, length, s.index_from, 0) else if s isa FlatBuffer then @@ -1531,7 +1553,7 @@ class FlatBuffer do assert cap >= 0 # _items = new NativeString.calloc(cap) - items = calloc_string(cap+1) + items = new NativeString(cap+1) capacity = cap length = 0 end @@ -1588,7 +1610,7 @@ class FlatBuffer redef fun reverse do written = false - var ns = calloc_string(capacity) + var ns = new NativeString(capacity) var si = length - 1 var ni = 0 var it = items @@ -1659,7 +1681,6 @@ end private class FlatBufferCharView super BufferCharView - super StringCapable redef type SELFTYPE: FlatBuffer @@ -2095,7 +2116,6 @@ end # Native strings are simple C char * extern class NativeString `{ char* `} - super StringCapable # Creates a new NativeString with a capacity of `length` new(length: Int) is intern fun [](index: Int): Char is intern @@ -2127,7 +2147,7 @@ extern class NativeString `{ char* `} fun to_s_with_copy: FlatString do var length = cstring_length - var new_self = calloc_string(length + 1) + var new_self = new NativeString(length + 1) copy_to(new_self, length, 0, 0) var str = new FlatString.with_infos(new_self, length, 0, length - 1) new_self[length] = '\0' @@ -2136,11 +2156,6 @@ extern class NativeString `{ char* `} end end -# StringCapable objects can create native strings -interface StringCapable - protected fun calloc_string(size: Int): NativeString is intern -end - redef class Sys private var args_cache: nullable Sequence[String] diff --git a/lib/standard/string_nit.c b/lib/standard/string_nit.c index 0159249..1a11e99 100644 --- a/lib/standard/string_nit.c +++ b/lib/standard/string_nit.c @@ -14,7 +14,7 @@ // Integer to NativeString method char* native_int_to_s(long recv){ int len = snprintf(NULL, 0, "%ld", recv); - char* str = malloc(len); + char* str = malloc(len+1); sprintf(str, "%ld", recv); return str; } diff --git a/lib/string_experimentations/utf8.nit b/lib/string_experimentations/utf8.nit index 5feef35..b7a74ce 100644 --- a/lib/string_experimentations/utf8.nit +++ b/lib/string_experimentations/utf8.nit @@ -214,7 +214,7 @@ redef class FlatString redef fun to_cstring do if real_items != null then return real_items.as(not null) - var new_items = calloc_string(bytelen + 1) + var new_items = new NativeString(bytelen + 1) self.items.copy_to(new_items, bytelen, index[index_from].pos, 0) new_items[bytelen] = '\0' self.real_items = new_items @@ -245,7 +245,7 @@ redef class FlatString redef fun reversed do - var native = calloc_string(self.bytelen + 1) + var native = new NativeString(self.bytelen + 1) var length = self.length var index = self.index var pos = 0 @@ -278,7 +278,7 @@ redef class FlatString var my_real_len = length var my_real_fin_len = my_real_len * i - var target_string = calloc_string((finlen) + 1) + var target_string = new NativeString((finlen) + 1) var my_index = index var new_index = new StringIndex(my_real_fin_len) @@ -300,7 +300,7 @@ redef class FlatString redef fun to_upper do - var outstr = calloc_string(self.bytelen + 1) + var outstr = new NativeString(self.bytelen + 1) var out_index = 0 var index = self.index @@ -322,7 +322,7 @@ redef class FlatString redef fun to_lower do - var outstr = calloc_string(self.bytelen + 1) + var outstr = new NativeString(self.bytelen + 1) var out_index = 0 var index = self.index @@ -406,7 +406,7 @@ redef class NativeString var real_len = new Container[Int](0) var length = cstring_length var x = make_index(length, real_len) - var new_self = calloc_string(length + 1) + var new_self = new NativeString(length + 1) copy_to(new_self, length, 0, 0) return new FlatString.with_infos_index(new_self, real_len.item, 0, real_len.item - 1, x, length) end diff --git a/lib/string_experimentations/utf8_noindex.nit b/lib/string_experimentations/utf8_noindex.nit index c473a3c..db51f0a 100644 --- a/lib/string_experimentations/utf8_noindex.nit +++ b/lib/string_experimentations/utf8_noindex.nit @@ -401,7 +401,7 @@ redef class FlatString end redef fun reversed do - var new_str = calloc_string(bytelen) + var new_str = new NativeString(bytelen) var s_pos = bytelen var my_pos = index_from var its = items @@ -415,7 +415,7 @@ redef class FlatString end redef fun to_upper do - var ns = calloc_string(bytelen) + var ns = new NativeString(bytelen) var offset = 0 for i in [0 .. length[ do @@ -427,7 +427,7 @@ redef class FlatString end redef fun to_lower do - var ns = calloc_string(bytelen) + var ns = new NativeString(bytelen) var offset = 0 for i in [0 .. length[ do @@ -441,7 +441,7 @@ redef class FlatString redef fun +(o) do if o isa Buffer then o = o.to_s if o isa FlatString then - var new_str = calloc_string(bytelen + o.bytelen + 1) + var new_str = new NativeString(bytelen + o.bytelen + 1) var new_bytelen = bytelen + o.bytelen new_str[new_bytelen] = '\0' var newlen = length + o.length @@ -461,7 +461,7 @@ redef class FlatString var new_bytelen = mybtlen * i var mylen = length var newlen = mylen * i - var ns = calloc_string(new_bytelen + 1) + var ns = new NativeString(new_bytelen + 1) ns[new_bytelen] = '\0' var offset = 0 while i > 0 do @@ -499,7 +499,7 @@ redef class FlatString redef fun to_cstring do if real_items != null then return real_items.as(not null) - var new_items = calloc_string(bytelen + 1) + var new_items = new NativeString(bytelen + 1) self.items.copy_to(new_items, bytelen, index_from, 0) new_items[bytelen] = '\0' self.real_items = new_items @@ -523,7 +523,7 @@ redef class FlatBuffer with_capacity(50) for i in s.substrings do self.append(i) end - items = calloc_string(s.bytelen) + items = new NativeString(s.bytelen) if s isa FlatString then s.items.copy_to(items, s.bytelen, s.index_from, 0) else @@ -611,7 +611,7 @@ redef class FlatBuffer var c = capacity if cap <= c then return while c <= cap do c = c * 2 + 2 - var a = calloc_string(c+1) + var a = new NativeString(c+1) if bytelen > 0 then items.copy_to(a, bytelen, 0, 0) items = a capacity = c @@ -635,7 +635,7 @@ redef class FlatBuffer redef fun reverse do - var nns = calloc_string(bytelen) + var nns = new NativeString(bytelen) var ns = items var btlen = bytelen var myp = 0 @@ -701,7 +701,7 @@ redef class FlatBuffer end redef fun to_cstring do - var ns = calloc_string(bytelen) + var ns = new NativeString(bytelen) items.copy_to(ns, bytelen, 0, 0) return ns end @@ -723,7 +723,7 @@ redef class NativeString redef fun to_s_with_copy do var length = cstring_length - var new_self = calloc_string(length + 1) + var new_self = new NativeString(length + 1) copy_to(new_self, length, 0, 0) return new FlatString.with_bytelen(new_self, 0, length - 1, length) end diff --git a/src/compiler/abstract_compiler.nit b/src/compiler/abstract_compiler.nit index 16c0e4b..abfbf3f 100644 --- a/src/compiler/abstract_compiler.nit +++ b/src/compiler/abstract_compiler.nit @@ -315,7 +315,14 @@ class MakefileToolchain var outname = outfile(mainmodule) - var outpath = compile_dir.relpath(outname) + var real_outpath = compile_dir.relpath(outname) + var outpath = real_outpath.escape_to_mk + if outpath != real_outpath then + # If the name is crazy and need escaping, we will do an indirection + # 1. generate the binary in the .nit_compile dir under an escaped name + # 2. copy the binary at the right place in the `all` goal. + outpath = mainmodule.c_name + end var makename = makefile_name(mainmodule) var makepath = "{compile_dir}/{makename}" var makefile = new OFStream.open(makepath) @@ -348,7 +355,11 @@ class MakefileToolchain makefile.write("ifdef NEED_LIBUNWIND\n\tLDLIBS += -lunwind\nendif\n") - makefile.write("all: {outpath}\n\n") + makefile.write("all: {outpath}\n") + if outpath != real_outpath then + makefile.write("\tcp -- {outpath.escape_to_sh} {real_outpath.escape_to_sh.replace("$","$$")}") + end + makefile.write("\n") var ofiles = new Array[String] var dep_rules = new Array[String] @@ -413,9 +424,12 @@ endif if not pkgconfigs.is_empty then pkg = "`pkg-config --libs {pkgconfigs.join(" ")}`" end - makefile.write("{outpath}: {dep_rules.join(" ")}\n\t$(CC) $(LDFLAGS) -o {outpath} {ofiles.join(" ")} $(LDLIBS) {pkg}\n\n") + makefile.write("{outpath}: {dep_rules.join(" ")}\n\t$(CC) $(LDFLAGS) -o {outpath.escape_to_sh} {ofiles.join(" ")} $(LDLIBS) {pkg}\n\n") # Clean - makefile.write("clean:\n\trm {ofiles.join(" ")} 2>/dev/null\n\n") + makefile.write("clean:\n\trm {ofiles.join(" ")} 2>/dev/null\n") + if outpath != real_outpath then + makefile.write("\trm -- {outpath.escape_to_sh} 2>/dev/null\n") + end makefile.close self.toolcontext.info("Generated makefile: {makepath}", 2) @@ -524,9 +538,9 @@ abstract class AbstractCompiler stream.write("static const C_Nit_Names map[{names.length}] = \{\n") for i in names.keys do stream.write("\{\"") - stream.write(i) + stream.write(i.escape_to_c) stream.write("\",\"") - stream.write(names[i]) + stream.write(names[i].escape_to_c) stream.write("\"\},\n") end stream.write("\};\n") diff --git a/src/compiler/android_annotations.nit b/src/compiler/android_annotations.nit index cc24d6e..ad34b9a 100644 --- a/src/compiler/android_annotations.nit +++ b/src/compiler/android_annotations.nit @@ -44,6 +44,9 @@ class AndroidProject # Custom lines to add to the AndroidManifest.xml in the node var manifest_application_lines = new Array[String] + # Custom lines to add to AndroidManifest.xml as attributes inside the node + var manifest_activity_attributes = new Array[String] + # Minimum API level required for the application to run var min_api: nullable Int = null @@ -107,6 +110,9 @@ redef class ModelBuilder annots = collect_annotations_on_modules("android_manifest_application", mmodule) for an in annots do project.manifest_application_lines.add an.arg_as_string(self) or else "" + annots = collect_annotations_on_modules("android_manifest_activity", mmodule) + for an in annots do project.manifest_activity_attributes.add an.arg_as_string(self) or else "" + # Get the date and time (down to the minute) as string var local_time = new Tm.localtime var local_time_s = local_time.strftime("%y%m%d%H%M") diff --git a/src/compiler/android_platform.nit b/src/compiler/android_platform.nit index 55468fd..1cf6ba8 100644 --- a/src/compiler/android_platform.nit +++ b/src/compiler/android_platform.nit @@ -124,10 +124,12 @@ class AndroidToolchain # Also copy over the java files dir = "{android_project_root}/src/" - var extra_java_files = compiler.mainmodule.extra_java_files - if extra_java_files != null then for file in extra_java_files do - var path = file.filename - path.file_copy_to("{dir}/{path.basename("")}") + for mmodule in compiler.mainmodule.in_importation.greaters do + var extra_java_files = mmodule.extra_java_files + if extra_java_files != null then for file in extra_java_files do + var path = file.filename + path.file_copy_to(dir/path.basename("")) + end end ## Generate delagating makefile @@ -178,13 +180,11 @@ $(call import-module,android/native_app_glue) This will take care of integrating with our NDK code. --> - - + + diff --git a/src/compiler/global_compiler.nit b/src/compiler/global_compiler.nit index 113b549..94dda37 100644 --- a/src/compiler/global_compiler.nit +++ b/src/compiler/global_compiler.nit @@ -116,7 +116,7 @@ class GlobalCompiler init do - var file = new_file("{mainmodule.name}.nitgg") + var file = new_file("{mainmodule.c_name}.nitgg") self.header = new CodeWriter(file) self.live_primitive_types = new Array[MClassType] for t in runtime_type_analysis.live_types do @@ -396,6 +396,7 @@ class GlobalCompilerVisitor redef fun native_array_instance(elttype: MType, length: RuntimeVariable): RuntimeVariable do var ret_type = self.get_class("NativeArray").get_mtype([elttype]) + ret_type = anchor(ret_type).as(MClassType) return self.new_expr("NEW_{ret_type.c_name}({length})", ret_type) end diff --git a/src/doc/doc_pages.nit b/src/doc/doc_pages.nit index 5d71b02..78ccd7f 100644 --- a/src/doc/doc_pages.nit +++ b/src/doc/doc_pages.nit @@ -17,6 +17,7 @@ module doc_pages import toolcontext import doc_model +private import json::static redef class ToolContext private var opt_dir = new OptionString("output directory", "-d", "--dir") @@ -182,9 +183,7 @@ end # All entities are grouped by name to make the research easier. class QuickSearch - private var mmodules = new HashSet[MModule] - private var mclasses = new HashSet[MClass] - private var mpropdefs = new HashMap[String, Set[MPropDef]] + private var table = new QuickSearchTable var ctx: ToolContext var model: Model @@ -192,51 +191,72 @@ class QuickSearch init do for mmodule in model.mmodules do if mmodule.is_fictive then continue - mmodules.add mmodule + add_result_for(mmodule.name, mmodule.full_name, mmodule.nitdoc_url) end for mclass in model.mclasses do if mclass.visibility < ctx.min_visibility then continue - mclasses.add mclass + add_result_for(mclass.name, mclass.full_name, mclass.nitdoc_url) end for mproperty in model.mproperties do if mproperty.visibility < ctx.min_visibility then continue if mproperty isa MAttribute then continue - if not mpropdefs.has_key(mproperty.name) then - mpropdefs[mproperty.name] = new HashSet[MPropDef] + for mpropdef in mproperty.mpropdefs do + var full_name = mpropdef.mclassdef.mclass.full_name + var cls_url = mpropdef.mclassdef.mclass.nitdoc_url + var def_url = "{cls_url}#{mpropdef.mproperty.nitdoc_id}" + add_result_for(mproperty.name, full_name, def_url) end - mpropdefs[mproperty.name].add_all(mproperty.mpropdefs) end end + private fun add_result_for(query: String, txt: String, url: String) do + table[query].add new QuickSearchResult(txt, url) + end + fun render: Template do var tpl = new Template - tpl.add "var nitdocQuickSearchRawList=\{ " - for mmodule in mmodules do - tpl.add "\"{mmodule.name}\":[" - tpl.add "\{txt:\"{mmodule.full_name}\",url:\"{mmodule.nitdoc_url}\"\}," - tpl.add "]," - end - for mclass in mclasses do - var full_name = mclass.intro.mmodule.full_name - tpl.add "\"{mclass.name}\":[" - tpl.add "\{txt:\"{full_name}\",url:\"{mclass.nitdoc_url}\"\}," - tpl.add "]," - end - for mproperty, mprops in mpropdefs do - tpl.add "\"{mproperty}\":[" - for mpropdef in mprops do - var full_name = mpropdef.mclassdef.mclass.full_name - var cls_url = mpropdef.mclassdef.mclass.nitdoc_url - var def_url = "{cls_url}#{mpropdef.mproperty.nitdoc_id}" - tpl.add "\{txt:\"{full_name}\",url:\"{def_url}\"\}," - end - tpl.add "]," - end - tpl.add " \};" + var buffer = new RopeBuffer + tpl.add buffer + buffer.append "var nitdocQuickSearchRawList=" + table.append_json buffer + buffer.append ";" return tpl end end +# The result map for QuickSearch. +private class QuickSearchTable + super JsonMapRead[String, QuickSearchResultList] + super HashMap[String, QuickSearchResultList] + + redef fun provide_default_value(key) do + var v = new QuickSearchResultList + self[key] = v + return v + end +end + +# A QuickSearch result list. +private class QuickSearchResultList + super JsonSequenceRead[QuickSearchResult] + super Array[QuickSearchResult] +end + +# A QuickSearch result. +private class QuickSearchResult + super Jsonable + + # The text of the link. + var txt: String + + # The destination of the link. + var url: String + + redef fun to_json do + return "\{\"txt\":{txt.to_json},\"url\":{url.to_json}\}" + end +end + # Nitdoc base page # Define page structure and properties abstract class NitdocPage diff --git a/src/ffi/java.nit b/src/ffi/java.nit index fa3cc84..9191141 100644 --- a/src/ffi/java.nit +++ b/src/ffi/java.nit @@ -242,7 +242,7 @@ redef class MModule # Tell the C compiler where to find jni.h and how to link with libjvm private fun insert_compiler_options do - c_compiler_options = "{c_compiler_options} -I $(JAVA_HOME)/include/" + c_compiler_options = "{c_compiler_options} -I $(JAVA_HOME)/include/ -I $(JAVA_HOME)/include/linux/" c_linker_options = "{c_linker_options} -L $(JNI_LIB_PATH) -ljvm" end diff --git a/src/interpreter/naive_interpreter.nit b/src/interpreter/naive_interpreter.nit index 86bba5f..476608c 100644 --- a/src/interpreter/naive_interpreter.nit +++ b/src/interpreter/naive_interpreter.nit @@ -901,6 +901,8 @@ redef class AMethPropdef return v.bool_instance(args[0].to_f.is_nan) else if pname == "is_inf_extern" then return v.bool_instance(args[0].to_f.is_inf != 0) + else if pname == "round" then + return v.float_instance(args[0].to_f.round) end else if cname == "NativeString" then if pname == "new" then @@ -1046,6 +1048,9 @@ redef class AMethPropdef return v.native_string_instance(txt) else if pname == "get_time" then return v.int_instance(get_time) + else if pname == "srand" then + srand + return null else if pname == "srand_from" then srand_from(args[1].to_i) return null diff --git a/src/markdown.nit b/src/markdown.nit index 01a054c..e254480 100644 --- a/src/markdown.nit +++ b/src/markdown.nit @@ -27,6 +27,9 @@ private class Doc2Mdwn # The lines of the current code block, empty is no current code block var curblock = new Array[String] + # Count empty lines between code blocks + var empty_lines = 0 + fun work(mdoc: MDoc): HTMLTag do var root = new HTMLTag("div") @@ -70,16 +73,18 @@ private class Doc2Mdwn # Is codeblock? Then just collect them if indent >= 3 then + for i in [0..empty_lines[ do curblock.add("") + empty_lines = 0 # to allows 4 spaces including the one that follows the # curblock.add(text) continue end - # Was a codblock just before the current line ? - close_codeblock(n or else root) - # fence opening if text.substring(0,3) == "~~~" then + # Was a codblock just before the current line ? + close_codeblock(n or else root) + var l = 3 while l < text.length and text.chars[l] == '~' do l += 1 in_fence = text.substring(0, l) @@ -96,9 +101,15 @@ private class Doc2Mdwn if text.is_empty or indent < lastindent then n = null ul = null - if text.is_empty then continue + if text.is_empty then + if not curblock.is_empty then empty_lines += 1 + continue + end end + # Was a codblock just before the current line ? + close_codeblock(n or else root) + # Special first word: new paragraph if text.has_prefix("TODO") or text.has_prefix("FIXME") then n = new HTMLTag("p") @@ -186,15 +197,20 @@ private class Doc2Mdwn do # Is there a codeblock to manage? if not curblock.is_empty then + empty_lines = 0 + # determine the smalest indent var minindent = -1 for text in curblock do var indent = 0 while indent < text.length and text.chars[indent] == ' ' do indent += 1 + # skip white lines + if indent >= text.length then continue if minindent == -1 or indent < minindent then minindent = indent end end + if minindent < 0 then minindent = 0 # Generate the text var btext = new FlatBuffer diff --git a/src/modelbuilder.nit b/src/modelbuilder.nit index 83f5e0e..1ae7e45 100644 --- a/src/modelbuilder.nit +++ b/src/modelbuilder.nit @@ -705,6 +705,13 @@ class ModelBuilder self.toolcontext.info("{mmodule} imports {imported_modules.join(", ")}", 3) mmodule.set_imported_mmodules(imported_modules) + # Force standard to be public if imported + for sup in mmodule.in_importation.greaters do + if sup.name == "standard" then + mmodule.set_visibility_for(sup, public_visibility) + end + end + # TODO: Correctly check for useless importation # It is even doable? var directs = mmodule.in_importation.direct_greaters diff --git a/src/testing/testing_doc.nit b/src/testing/testing_doc.nit index f393950..7bb39ca 100644 --- a/src/testing/testing_doc.nit +++ b/src/testing/testing_doc.nit @@ -36,6 +36,9 @@ class NitUnitExecutor redef fun process_code(n: HTMLTag, text: String) do + # Skip non-blocks + if n.tag != "pre" then return + # Try to parse it var ast = toolcontext.parse_something(text) @@ -98,7 +101,7 @@ class NitUnitExecutor toolcontext.modelbuilder.unit_entities += 1 cpt += 1 - var file = "{prefix}{cpt}.nit" + var file = "{prefix}-{cpt}.nit" toolcontext.info("Execute doc-unit {tc.attrs["name"]} in {file}", 1) diff --git "a/tests/--base_very bad name@1&$|;:.ext'\"<>{}`~!#^*()_=+[]\\,?.nit" "b/tests/--base_very bad name@1&$|;:.ext'\"<>{}`~!#^*()_=+[]\\,?.nit" new file mode 100644 index 0000000..11c4b4c --- /dev/null +++ "b/tests/--base_very bad name@1&$|;:.ext'\"<>{}`~!#^*()_=+[]\\,?.nit" @@ -0,0 +1,17 @@ +# 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. + +import kernel + +1.output diff --git a/tests/base_import_standard.nit b/tests/base_import_standard.nit new file mode 100644 index 0000000..2e76488 --- /dev/null +++ b/tests/base_import_standard.nit @@ -0,0 +1,17 @@ +# 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. + +private import template + +print 1 diff --git a/tests/base_import_standard2.nit b/tests/base_import_standard2.nit new file mode 100644 index 0000000..da5111e --- /dev/null +++ b/tests/base_import_standard2.nit @@ -0,0 +1,17 @@ +# 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. + +import base_import_standard + +print 2 diff --git a/tests/base_init_linext.nit b/tests/base_init_linext.nit index ac93fb4..ac1d618 100644 --- a/tests/base_init_linext.nit +++ b/tests/base_init_linext.nit @@ -31,7 +31,7 @@ class B 'B'.output '1'.output ' '.output - inita + super 'B'.output '2'.output ' '.output @@ -45,7 +45,7 @@ class C 'C'.output '1'.output ' '.output - inita + super 'C'.output '2'.output ' '.output @@ -58,52 +58,12 @@ class D super C init do 'D'.output - '0'.output - ' '.output -#alt1# inita -#alt3# inita -#alt5# inita -#alt7# inita -#alt9# inita -#alt11# inita -#alt13# inita -#alt15# inita - 'D'.output '1'.output ' '.output -#alt2# initb -#alt3# initb -#alt6# initb -#alt7# initb -#alt10# initb -#alt11# initb -#alt14# initb -#alt15# initb + super 'D'.output '2'.output ' '.output -#alt4# initc -#alt5# initc -#alt6# initc -#alt7# initc -#alt12# initc -#alt13# initc -#alt14# initc -#alt15# initc - 'D'.output - '3'.output - ' '.output -#alt8# inite -#alt9# inite -#alt10# inite -#alt11# inite -#alt12# inite -#alt13# inite -#alt14# inite -#alt15# inite - 'D'.output - '4'.output - ' '.output end init inite do diff --git a/tests/base_init_linext2.nit b/tests/base_init_linext2.nit index 7b5bfc4..aa032c0 100644 --- a/tests/base_init_linext2.nit +++ b/tests/base_init_linext2.nit @@ -68,7 +68,7 @@ class C 'C'.output '1'.output ' '.output - inita + super 'C'.output '2'.output ' '.output diff --git a/tests/cc.skip b/tests/cc.skip index 2e20b7e..93a2d8f 100644 --- a/tests/cc.skip +++ b/tests/cc.skip @@ -1,10 +1,3 @@ bcm2835 -gtk3_6 -gtk3_8 -posix_ext -physical_interface_for_mpd_on_rpi blink input -android_app -android_assets -opengles1 diff --git a/tests/emscripten.skip b/tests/emscripten.skip index c782ec0..e69de29 100644 --- a/tests/emscripten.skip +++ b/tests/emscripten.skip @@ -1,2 +0,0 @@ -init_inherit -init_linext diff --git a/tests/error_prop_loc.nit b/tests/error_prop_loc.nit index b74fc3c..4872f08 100644 --- a/tests/error_prop_loc.nit +++ b/tests/error_prop_loc.nit @@ -14,22 +14,25 @@ # See the License for the specific language governing permissions and # limitations under the License. -import end -class Object -end +import kernel class A - fun toto do end + fun toto do 1.output end class B super A - redef fun toto do end + redef fun toto do 2.output end class C super A - redef fun toto do end + redef fun toto do 3.output end class D super B super C end + +(new A).toto +(new B).toto +(new C).toto +#alt1#(new D).toto diff --git a/tests/nitg-e.skip b/tests/nitg-e.skip index c782ec0..e69de29 100644 --- a/tests/nitg-e.skip +++ b/tests/nitg-e.skip @@ -1,2 +0,0 @@ -init_inherit -init_linext diff --git a/tests/nitg-g.skip b/tests/nitg-g.skip index fb091a0..7175bb7 100644 --- a/tests/nitg-g.skip +++ b/tests/nitg-g.skip @@ -1,3 +1,2 @@ -init_inherit -init_linext nitg +nitdoc diff --git a/tests/nitg-s.skip b/tests/nitg-s.skip index c782ec0..e69de29 100644 --- a/tests/nitg-s.skip +++ b/tests/nitg-s.skip @@ -1,2 +0,0 @@ -init_inherit -init_linext diff --git a/tests/nitg-sg.skip b/tests/nitg-sg.skip index 5f17ed8..e69de29 100644 --- a/tests/nitg-sg.skip +++ b/tests/nitg-sg.skip @@ -1,3 +0,0 @@ -init_inherit -init_linext -android diff --git a/tests/niti.skip b/tests/niti.skip index baf5b76..1fec913 100644 --- a/tests/niti.skip +++ b/tests/niti.skip @@ -1,5 +1,3 @@ -init_inherit -init_linext test_mem shoot_logic bench_ @@ -16,7 +14,6 @@ nitg_args6 nitg_args8 test_markdown_args1 pep8analysis -nitcc_parser_gen emscripten nitserial_args nitunit_args diff --git a/tests/nitunit.args b/tests/nitunit.args index cc7239d..70d5027 100644 --- a/tests/nitunit.args +++ b/tests/nitunit.args @@ -1,3 +1,4 @@ test_nitunit.nit --no-color -o $WRITE test_nitunit.nit --gen-suite --only-show test_nitunit.nit --gen-suite --only-show --private +test_nitunit2.nit -o $WRITE diff --git a/tests/nitvm.skip b/tests/nitvm.skip index afed2b6..da1d367 100644 --- a/tests/nitvm.skip +++ b/tests/nitvm.skip @@ -1,5 +1,3 @@ -init_inherit -init_linext test_mem shoot_logic bench_ diff --git "a/tests/sav/--base_very bad name@1&$|;:.ext'\"<>{}`~!#^*()_=+[]\\,?.res" "b/tests/sav/--base_very bad name@1&$|;:.ext'\"<>{}`~!#^*()_=+[]\\,?.res" new file mode 100644 index 0000000..d00491f --- /dev/null +++ "b/tests/sav/--base_very bad name@1&$|;:.ext'\"<>{}`~!#^*()_=+[]\\,?.res" @@ -0,0 +1 @@ +1 diff --git a/tests/sav/ab.res b/tests/sav/ab.res index a9dbe22..a5dab0a 100644 --- a/tests/sav/ab.res +++ b/tests/sav/ab.res @@ -1 +1 @@ -Runtime error: Assert 'index' failed (../lib/standard/collection/array.nit:258) +Expected two numbers diff --git a/tests/sav/base_import_standard.res b/tests/sav/base_import_standard.res new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/tests/sav/base_import_standard.res @@ -0,0 +1 @@ +1 diff --git a/tests/sav/base_import_standard2.res b/tests/sav/base_import_standard2.res new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/tests/sav/base_import_standard2.res @@ -0,0 +1 @@ +2 diff --git a/tests/sav/base_init_inherit.res b/tests/sav/base_init_inherit.res index 04165c5..2240200 100644 --- a/tests/sav/base_init_inherit.res +++ b/tests/sav/base_init_inherit.res @@ -4,5 +4,5 @@ B{A}ba C{B{A}}cba Ama A2ma -B{A}nbma -O{C{B{A}}}onmcba +B{A}nmba +O{C{B{A}}}oncmba diff --git a/tests/sav/base_init_inherit2_alt0.res b/tests/sav/base_init_inherit2_alt0.res index 0212e99..6717ee4 100644 --- a/tests/sav/base_init_inherit2_alt0.res +++ b/tests/sav/base_init_inherit2_alt0.res @@ -2,4 +2,4 @@ Aa Aba Aca Amca -Anbmca +Anmcba diff --git a/tests/sav/base_init_inherit2_alt1.res b/tests/sav/base_init_inherit2_alt1.res index 3868b73..4e63661 100644 --- a/tests/sav/base_init_inherit2_alt1.res +++ b/tests/sav/base_init_inherit2_alt1.res @@ -2,4 +2,4 @@ Aa B{A}ba Aca Amca -B{A}nbmca +B{A}nmcba diff --git a/tests/sav/base_init_inherit2_alt2.res b/tests/sav/base_init_inherit2_alt2.res index 5bb2c66..5707297 100644 --- a/tests/sav/base_init_inherit2_alt2.res +++ b/tests/sav/base_init_inherit2_alt2.res @@ -2,4 +2,4 @@ Aa Aba C{A}ca C{A}mca -C{A}nbmca +C{A}nmcba diff --git a/tests/sav/base_init_inherit2_alt3.res b/tests/sav/base_init_inherit2_alt3.res index bf88578..863486b 100644 --- a/tests/sav/base_init_inherit2_alt3.res +++ b/tests/sav/base_init_inherit2_alt3.res @@ -1 +1 @@ -alt/base_init_inherit2_alt3.nit:75,7: Error: Explicit constructor required in N since multiple inheritance of constructor is forbiden. Conflicting classes are B, C. Costructors are base_init_inherit2_alt3::B::cb, base_init_inherit2_alt3::A::ca, base_init_inherit2_alt3::C::cc. +Aa diff --git a/tests/sav/base_init_inherit3_alt0.res b/tests/sav/base_init_inherit3_alt0.res index 9a3590f..d25bc4f 100644 --- a/tests/sav/base_init_inherit3_alt0.res +++ b/tests/sav/base_init_inherit3_alt0.res @@ -2,6 +2,6 @@ Aa Ama B{A}ba Ana -B{A}omba -B{A}pbna -B{A}qmbna +B{A}obma +B{A}pnba +B{A}qnbma diff --git a/tests/sav/base_init_inherit3_alt1.res b/tests/sav/base_init_inherit3_alt1.res index 3a08969..3aef777 100644 --- a/tests/sav/base_init_inherit3_alt1.res +++ b/tests/sav/base_init_inherit3_alt1.res @@ -2,6 +2,6 @@ Aa Ama B{A}ba Ana -B{A}omba -B{A}pbna -B{A}qombna +B{A}obma +B{A}pnba +B{A}qonbma diff --git a/tests/sav/base_init_inherit3_alt2.res b/tests/sav/base_init_inherit3_alt2.res index 77e587f..340bcfd 100644 --- a/tests/sav/base_init_inherit3_alt2.res +++ b/tests/sav/base_init_inherit3_alt2.res @@ -2,6 +2,6 @@ Aa Ama B{A}ba Ana -B{A}omba -B{A}pbna -B{A}qmpbna +B{A}obma +B{A}pnba +B{A}qpnbma diff --git a/tests/sav/base_init_inherit3_alt3.res b/tests/sav/base_init_inherit3_alt3.res index 7293394..486e174 100644 --- a/tests/sav/base_init_inherit3_alt3.res +++ b/tests/sav/base_init_inherit3_alt3.res @@ -2,6 +2,6 @@ Aa Ama B{A}ba Ana -B{A}omba -B{A}pbna -B{A}qompbna +B{A}obma +B{A}pnba +B{A}qponbma diff --git a/tests/sav/base_init_inherit4_alt0.res b/tests/sav/base_init_inherit4_alt0.res index 1df3160..b14d378 100644 --- a/tests/sav/base_init_inherit4_alt0.res +++ b/tests/sav/base_init_inherit4_alt0.res @@ -1,4 +1,4 @@ Bba -Bomba -Bpbna -Bqmbna +Bobma +Bpnba +Bqnbma diff --git a/tests/sav/base_init_inherit4_alt1.res b/tests/sav/base_init_inherit4_alt1.res index 1b94fae..5fa8ab0 100644 --- a/tests/sav/base_init_inherit4_alt1.res +++ b/tests/sav/base_init_inherit4_alt1.res @@ -1,4 +1,4 @@ Bba -Bomba -Bpbna -Bqombna +Bobma +Bpnba +Bqonbma diff --git a/tests/sav/base_init_inherit4_alt2.res b/tests/sav/base_init_inherit4_alt2.res index 5d31ef6..652e57b 100644 --- a/tests/sav/base_init_inherit4_alt2.res +++ b/tests/sav/base_init_inherit4_alt2.res @@ -1,4 +1,4 @@ Bba -Bomba -Bpbna -Bqmpbna +Bobma +Bpnba +Bqpnbma diff --git a/tests/sav/base_init_inherit4_alt3.res b/tests/sav/base_init_inherit4_alt3.res index 65961af..d7b2cd6 100644 --- a/tests/sav/base_init_inherit4_alt3.res +++ b/tests/sav/base_init_inherit4_alt3.res @@ -1,4 +1,4 @@ Bba -Bomba -Bpbna -Bqompbna +Bobma +Bpnba +Bqponbma diff --git a/tests/sav/base_init_inherit5.res b/tests/sav/base_init_inherit5.res index c67526f..246f558 100644 --- a/tests/sav/base_init_inherit5.res +++ b/tests/sav/base_init_inherit5.res @@ -2,5 +2,5 @@ A1a B2{A1}ba C3{B2{A1}}cba A1ma -B2{A1}nbma -O4{C3{B2{A1}}}onmcba +B2{A1}nmba +O4{C3{B2{A1}}}oncmba diff --git a/tests/sav/base_init_inherit6_alt1.res b/tests/sav/base_init_inherit6_alt1.res index 893493f..a912b09 100644 --- a/tests/sav/base_init_inherit6_alt1.res +++ b/tests/sav/base_init_inherit6_alt1.res @@ -1 +1,5 @@ -alt/base_init_inherit6_alt1.nit:32,10--14: Error: init is not a constructor in B. +1 +2 +1 +3 +1 diff --git a/tests/sav/base_init_inherit6_alt2.res b/tests/sav/base_init_inherit6_alt2.res index 900503c..ce7a77e 100644 --- a/tests/sav/base_init_inherit6_alt2.res +++ b/tests/sav/base_init_inherit6_alt2.res @@ -1 +1,5 @@ -alt/base_init_inherit6_alt2.nit:33,10--18: Error: foo is not a constructor in B. +1 +2 +1 +3 +2 diff --git a/tests/sav/base_init_inherit_alt1.res b/tests/sav/base_init_inherit_alt1.res index a63698b..1243025 100644 --- a/tests/sav/base_init_inherit_alt1.res +++ b/tests/sav/base_init_inherit_alt1.res @@ -1,11 +1,19 @@ -alt/base_init_inherit_alt1.nit:95,2--9: Error: ca is not a constructor in B. -alt/base_init_inherit_alt1.nit:96,2--10: Error: ca2 is not a constructor in B. -alt/base_init_inherit_alt1.nit:98,2--9: Error: ca is not a constructor in C. -alt/base_init_inherit_alt1.nit:99,2--10: Error: ca2 is not a constructor in C. -alt/base_init_inherit_alt1.nit:100,2--9: Error: cb is not a constructor in C. -alt/base_init_inherit_alt1.nit:104,2--9: Error: ca is not a constructor in N. -alt/base_init_inherit_alt1.nit:105,2--10: Error: ca2 is not a constructor in N. -alt/base_init_inherit_alt1.nit:107,2--9: Error: ca is not a constructor in O. -alt/base_init_inherit_alt1.nit:108,2--10: Error: ca2 is not a constructor in O. -alt/base_init_inherit_alt1.nit:109,2--9: Error: cb is not a constructor in O. -alt/base_init_inherit_alt1.nit:110,2--9: Error: cc is not a constructor in O. +Aa +A2a +B{A}ba +Aba +A2ba +C{B{A}}cba +Acba +A2cba +B{A}cba +Ama +A2ma +B{A}nmba +Anmba +A2nmba +O{C{B{A}}}oncmba +Aoncmba +A2oncmba +B{A}oncmba +C{B{A}}oncmba diff --git a/tests/sav/base_init_linext.res b/tests/sav/base_init_linext.res index 6f74ed3..b0e29f8 100644 --- a/tests/sav/base_init_linext.res +++ b/tests/sav/base_init_linext.res @@ -1 +1 @@ -B1 A B2 C1 C2 D0 D1 D2 D3 D4 +D1 C1 B1 A B2 C2 D2 diff --git a/tests/sav/base_init_linext2.res b/tests/sav/base_init_linext2.res index c12605c..daa73b2 100644 --- a/tests/sav/base_init_linext2.res +++ b/tests/sav/base_init_linext2.res @@ -3,6 +3,6 @@ A2x B1 A B2 A B3 A B4y -C1 A C2 +C1 C2 A2z C3z -D1 B1 A B2 C1 C2 D2 D3 +D1 B1 A B2 D2 D3 diff --git a/tests/sav/base_init_linext2_alt1.res b/tests/sav/base_init_linext2_alt1.res index 1b64c0f..fc63fc7 100644 --- a/tests/sav/base_init_linext2_alt1.res +++ b/tests/sav/base_init_linext2_alt1.res @@ -1 +1 @@ -alt/base_init_linext2_alt1.nit:100,1--5: Error: No contructor named initd in superclasses. +alt/base_init_linext2_alt1.nit:100,1--5: Error: No super method to call for initd. diff --git a/tests/sav/base_init_linext2_alt2.res b/tests/sav/base_init_linext2_alt2.res index c7c14d4..fe7551d 100644 --- a/tests/sav/base_init_linext2_alt2.res +++ b/tests/sav/base_init_linext2_alt2.res @@ -1 +1,8 @@ -alt/base_init_linext2_alt2.nit:99,2--5: Error: there is no available compatible constructor in B. Discarded candidates are base_init_linext2_alt2::B::initb, base_init_linext2_alt2::B::init_par, base_init_linext2_alt2::B::init_par2(c: Char). +A +A2x +B1 A B2 +A B3 +A B4y +C1 C2 +A2z C3z +C1 C2 D1 D2 D3 diff --git a/tests/sav/base_init_linext2_alt3.res b/tests/sav/base_init_linext2_alt3.res index 924b31d..7eadb94 100644 --- a/tests/sav/base_init_linext2_alt3.res +++ b/tests/sav/base_init_linext2_alt3.res @@ -3,6 +3,6 @@ A2x B1 A B2 A B3 A B4y -C1 A C2 +C1 C2 A2z C3z D1 B1 A B2 D2 C1 C2 D3 diff --git a/tests/sav/base_init_linext2_alt4.res b/tests/sav/base_init_linext2_alt4.res index 1bd61e3..9bc59e1 100644 --- a/tests/sav/base_init_linext2_alt4.res +++ b/tests/sav/base_init_linext2_alt4.res @@ -1 +1,8 @@ -alt/base_init_linext2_alt4.nit:99,2--5: Error: there is no available compatible constructor in B. Discarded candidates are base_init_linext2_alt4::B::initb, base_init_linext2_alt4::B::init_par, base_init_linext2_alt4::B::init_par2(c: Char). +A +A2x +B1 A B2 +A B3 +A B4y +C1 C2 +A2z C3z +D1 C1 C2 B1 A B2 D2 D3 diff --git a/tests/sav/base_init_linext2_alt5.res b/tests/sav/base_init_linext2_alt5.res index d04a73a..bc59762 100644 --- a/tests/sav/base_init_linext2_alt5.res +++ b/tests/sav/base_init_linext2_alt5.res @@ -1 +1,8 @@ -alt/base_init_linext2_alt5.nit:109,1--5: Error: Only one super constructor invocation of class B is allowed. +A +A2x +B1 A B2 +A B3 +A B4y +C1 C2 +A2z C3z +D1 B1 A B2 D2 B1 A B2 D3 diff --git a/tests/sav/base_init_linext_alt0.res b/tests/sav/base_init_linext_alt0.res index 90938b0..6d4b14b 100644 --- a/tests/sav/base_init_linext_alt0.res +++ b/tests/sav/base_init_linext_alt0.res @@ -1,5 +1,5 @@ A B1 A B2 C1 A C2 -B1 A B2 C1 C2 D0 D1 D2 D3 D4 -E1 A E2 B1 B2 E3 C1 C2 E4 +D1 C1 B1 A B2 C2 D2 +E1 D1 C1 B1 A B2 C2 D2 E2 D1 C1 B1 A B2 C2 D2 E3 D1 C1 B1 A B2 C2 D2 E4 diff --git a/tests/sav/base_init_linext_alt1.res b/tests/sav/base_init_linext_alt1.res deleted file mode 100644 index 04e3275..0000000 --- a/tests/sav/base_init_linext_alt1.res +++ /dev/null @@ -1 +0,0 @@ -D0 A B1 B2 C1 C2 D1 D2 D3 D4 diff --git a/tests/sav/base_init_linext_alt10.res b/tests/sav/base_init_linext_alt10.res deleted file mode 100644 index 683e93c..0000000 --- a/tests/sav/base_init_linext_alt10.res +++ /dev/null @@ -1 +0,0 @@ -D0 D1 B1 A B2 D2 D3 E1 E2 E3 C1 C2 E4 D4 diff --git a/tests/sav/base_init_linext_alt11.res b/tests/sav/base_init_linext_alt11.res deleted file mode 100644 index edef552..0000000 --- a/tests/sav/base_init_linext_alt11.res +++ /dev/null @@ -1 +0,0 @@ -D0 A D1 B1 B2 D2 D3 E1 E2 E3 C1 C2 E4 D4 diff --git a/tests/sav/base_init_linext_alt12.res b/tests/sav/base_init_linext_alt12.res deleted file mode 100644 index a92a06b..0000000 --- a/tests/sav/base_init_linext_alt12.res +++ /dev/null @@ -1 +0,0 @@ -D0 D1 D2 C1 A C2 D3 E1 E2 B1 B2 E3 E4 D4 diff --git a/tests/sav/base_init_linext_alt13.res b/tests/sav/base_init_linext_alt13.res deleted file mode 100644 index cea7bbd..0000000 --- a/tests/sav/base_init_linext_alt13.res +++ /dev/null @@ -1 +0,0 @@ -D0 A D1 D2 C1 C2 D3 E1 E2 B1 B2 E3 E4 D4 diff --git a/tests/sav/base_init_linext_alt14.res b/tests/sav/base_init_linext_alt14.res deleted file mode 100644 index ce9cfc0..0000000 --- a/tests/sav/base_init_linext_alt14.res +++ /dev/null @@ -1 +0,0 @@ -D0 D1 B1 A B2 D2 C1 C2 D3 E1 E2 E3 E4 D4 diff --git a/tests/sav/base_init_linext_alt15.res b/tests/sav/base_init_linext_alt15.res deleted file mode 100644 index d48d0e2..0000000 --- a/tests/sav/base_init_linext_alt15.res +++ /dev/null @@ -1 +0,0 @@ -D0 A D1 B1 B2 D2 C1 C2 D3 E1 E2 E3 E4 D4 diff --git a/tests/sav/base_init_linext_alt2.res b/tests/sav/base_init_linext_alt2.res deleted file mode 100644 index 0d383df..0000000 --- a/tests/sav/base_init_linext_alt2.res +++ /dev/null @@ -1 +0,0 @@ -D0 D1 B1 A B2 C1 C2 D2 D3 D4 diff --git a/tests/sav/base_init_linext_alt3.res b/tests/sav/base_init_linext_alt3.res deleted file mode 100644 index 539f8ad..0000000 --- a/tests/sav/base_init_linext_alt3.res +++ /dev/null @@ -1 +0,0 @@ -D0 A D1 B1 B2 C1 C2 D2 D3 D4 diff --git a/tests/sav/base_init_linext_alt4.res b/tests/sav/base_init_linext_alt4.res deleted file mode 100644 index 2aa8b4e..0000000 --- a/tests/sav/base_init_linext_alt4.res +++ /dev/null @@ -1 +0,0 @@ -B1 A B2 D0 D1 D2 C1 C2 D3 D4 diff --git a/tests/sav/base_init_linext_alt5.res b/tests/sav/base_init_linext_alt5.res deleted file mode 100644 index 7883af4..0000000 --- a/tests/sav/base_init_linext_alt5.res +++ /dev/null @@ -1 +0,0 @@ -D0 A B1 B2 D1 D2 C1 C2 D3 D4 diff --git a/tests/sav/base_init_linext_alt6.res b/tests/sav/base_init_linext_alt6.res deleted file mode 100644 index ce5e04a..0000000 --- a/tests/sav/base_init_linext_alt6.res +++ /dev/null @@ -1 +0,0 @@ -D0 D1 B1 A B2 D2 C1 C2 D3 D4 diff --git a/tests/sav/base_init_linext_alt7.res b/tests/sav/base_init_linext_alt7.res deleted file mode 100644 index c075e86..0000000 --- a/tests/sav/base_init_linext_alt7.res +++ /dev/null @@ -1 +0,0 @@ -D0 A D1 B1 B2 D2 C1 C2 D3 D4 diff --git a/tests/sav/base_init_linext_alt8.res b/tests/sav/base_init_linext_alt8.res deleted file mode 100644 index 305d19c..0000000 --- a/tests/sav/base_init_linext_alt8.res +++ /dev/null @@ -1 +0,0 @@ -D0 D1 D2 D3 E1 A E2 B1 B2 E3 C1 C2 E4 D4 diff --git a/tests/sav/base_init_linext_alt9.res b/tests/sav/base_init_linext_alt9.res deleted file mode 100644 index 322c6ab..0000000 --- a/tests/sav/base_init_linext_alt9.res +++ /dev/null @@ -1 +0,0 @@ -D0 A D1 D2 D3 E1 E2 B1 B2 E3 C1 C2 E4 D4 diff --git a/tests/sav/base_init_linext_raf.res b/tests/sav/base_init_linext_raf.res index 2d4d642..27671d4 100644 --- a/tests/sav/base_init_linext_raf.res +++ b/tests/sav/base_init_linext_raf.res @@ -1,4 +1,4 @@ A b1 B1 A B2 b2 c1 C1 A C2 c2 -d1 b1 B1 A B2 b2 c1 C1 C2 c2 D0 D1 D2 D3 D4 d2 +d1 D1 c1 C1 b1 B1 A B2 b2 C2 c2 D2 d2 diff --git a/tests/sav/error_prop_loc.res b/tests/sav/error_prop_loc.res index 6a6e994..01e79c3 100644 --- a/tests/sav/error_prop_loc.res +++ b/tests/sav/error_prop_loc.res @@ -1 +1,3 @@ -Property inheritance conflict in class D for `toto': conflicting properties are defined in B, C +1 +2 +3 diff --git a/tests/sav/error_prop_loc_alt1.res b/tests/sav/error_prop_loc_alt1.res new file mode 100644 index 0000000..ca9822e --- /dev/null +++ b/tests/sav/error_prop_loc_alt1.res @@ -0,0 +1,5 @@ +alt/error_prop_loc_alt1.nit:38,1--12: Warning: conflicting property definitions for property toto in D: error_prop_loc_alt1#B#toto error_prop_loc_alt1#C#toto +1 +2 +3 +3 diff --git a/tests/sav/error_redef_1alt4_alt5.res b/tests/sav/error_redef_1alt4_alt5.res index 18f8f3d..e69de29 100644 --- a/tests/sav/error_redef_1alt4_alt5.res +++ b/tests/sav/error_redef_1alt4_alt5.res @@ -1 +0,0 @@ -alt/error_redef_1alt4_alt5.nit:30,12--13: Redef error: The procedure B::f1 redefines the function A::f1. diff --git a/tests/sav/error_redef_1alt4_alt9.res b/tests/sav/error_redef_1alt4_alt9.res index da892e9..e69de29 100644 --- a/tests/sav/error_redef_1alt4_alt9.res +++ b/tests/sav/error_redef_1alt4_alt9.res @@ -1 +0,0 @@ -alt/error_redef_1alt4_alt9.nit:34,15: Syntax error: untyped parameter. diff --git a/tests/sav/fixme/error_prop_loc.res b/tests/sav/fixme/error_prop_loc.res deleted file mode 100644 index e69de29..0000000 diff --git a/tests/sav/fixme/error_redef_1alt4_alt5.res b/tests/sav/fixme/error_redef_1alt4_alt5.res deleted file mode 100644 index e69de29..0000000 diff --git a/tests/sav/fixme/error_redef_1alt4_alt9.res b/tests/sav/fixme/error_redef_1alt4_alt9.res deleted file mode 100644 index e69de29..0000000 diff --git a/tests/sav/fixme/test_inheritance_raf.res b/tests/sav/fixme/test_inheritance_raf.res deleted file mode 100644 index dd8e78f..0000000 --- a/tests/sav/fixme/test_inheritance_raf.res +++ /dev/null @@ -1,16 +0,0 @@ -1 -1 -5 -5 -1 -2 -5 -2 -1 -1 -3 -7 -1 -2 -3 -4 diff --git a/tests/sav/nitc/base_for_nullable.res b/tests/sav/nitc/base_for_nullable.res deleted file mode 100644 index a75893d..0000000 --- a/tests/sav/nitc/base_for_nullable.res +++ /dev/null @@ -1 +0,0 @@ -base_for_nullable.nit:21,10--13: Type error: 'for' on a nullable expression. diff --git a/tests/sav/nitc/base_for_nullable_alt1.res b/tests/sav/nitc/base_for_nullable_alt1.res deleted file mode 100644 index 1baed81..0000000 --- a/tests/sav/nitc/base_for_nullable_alt1.res +++ /dev/null @@ -1 +0,0 @@ -alt/base_for_nullable_alt1.nit:21,10--13: Type error: 'for' on a nullable expression. diff --git a/tests/sav/nitc/base_for_nullable_alt2.res b/tests/sav/nitc/base_for_nullable_alt2.res deleted file mode 100644 index 14de0ee..0000000 --- a/tests/sav/nitc/base_for_nullable_alt2.res +++ /dev/null @@ -1 +0,0 @@ -alt/base_for_nullable_alt2.nit:21,10--13: Type error: 'for' on a nullable expression. diff --git a/tests/sav/nitg-e/fixme/base_attr_init_val_int_alt1.res b/tests/sav/nitg-common/fixme/base_attr_init_val_int_alt1.res similarity index 100% rename from tests/sav/nitg-e/fixme/base_attr_init_val_int_alt1.res rename to tests/sav/nitg-common/fixme/base_attr_init_val_int_alt1.res diff --git a/tests/sav/nitg-e/fixme/base_attr_init_val_int_alt2.res b/tests/sav/nitg-common/fixme/base_attr_init_val_int_alt2.res similarity index 100% rename from tests/sav/nitg-e/fixme/base_attr_init_val_int_alt2.res rename to tests/sav/nitg-common/fixme/base_attr_init_val_int_alt2.res diff --git a/tests/sav/nitg-e/fixme/base_attr_init_val_int_alt3.res b/tests/sav/nitg-common/fixme/base_attr_init_val_int_alt3.res similarity index 100% rename from tests/sav/nitg-e/fixme/base_attr_init_val_int_alt3.res rename to tests/sav/nitg-common/fixme/base_attr_init_val_int_alt3.res diff --git a/tests/sav/nitg-e/fixme/base_attr_init_val_int_alt4.res b/tests/sav/nitg-common/fixme/base_attr_init_val_int_alt4.res similarity index 100% rename from tests/sav/nitg-e/fixme/base_attr_init_val_int_alt4.res rename to tests/sav/nitg-common/fixme/base_attr_init_val_int_alt4.res diff --git a/tests/sav/nitg-e/fixme/base_attr_init_val_raf_alt1.res b/tests/sav/nitg-common/fixme/base_attr_init_val_raf_alt1.res similarity index 100% rename from tests/sav/nitg-e/fixme/base_attr_init_val_raf_alt1.res rename to tests/sav/nitg-common/fixme/base_attr_init_val_raf_alt1.res diff --git a/tests/sav/nitg-e/fixme/base_attr_nullable_int_alt1.res b/tests/sav/nitg-common/fixme/base_attr_nullable_int_alt1.res similarity index 100% rename from tests/sav/nitg-e/fixme/base_attr_nullable_int_alt1.res rename to tests/sav/nitg-common/fixme/base_attr_nullable_int_alt1.res diff --git a/tests/sav/nitg-e/fixme/base_attr_nullable_int_alt2.res b/tests/sav/nitg-common/fixme/base_attr_nullable_int_alt2.res similarity index 100% rename from tests/sav/nitg-e/fixme/base_attr_nullable_int_alt2.res rename to tests/sav/nitg-common/fixme/base_attr_nullable_int_alt2.res diff --git a/tests/sav/nitg-e/fixme/base_attr_nullable_int_alt3.res b/tests/sav/nitg-common/fixme/base_attr_nullable_int_alt3.res similarity index 100% rename from tests/sav/nitg-e/fixme/base_attr_nullable_int_alt3.res rename to tests/sav/nitg-common/fixme/base_attr_nullable_int_alt3.res diff --git a/tests/sav/nitg-e/fixme/base_attr_nullable_int_alt4.res b/tests/sav/nitg-common/fixme/base_attr_nullable_int_alt4.res similarity index 100% rename from tests/sav/nitg-e/fixme/base_attr_nullable_int_alt4.res rename to tests/sav/nitg-common/fixme/base_attr_nullable_int_alt4.res diff --git a/tests/sav/nitg-e/fixme/base_attr_nullable_int_alt5.res b/tests/sav/nitg-common/fixme/base_attr_nullable_int_alt5.res similarity index 100% rename from tests/sav/nitg-e/fixme/base_attr_nullable_int_alt5.res rename to tests/sav/nitg-common/fixme/base_attr_nullable_int_alt5.res diff --git a/tests/sav/nitg-e/fixme/base_covar_int2_alt3.res b/tests/sav/nitg-common/fixme/base_covar_int2_alt3.res similarity index 100% rename from tests/sav/nitg-e/fixme/base_covar_int2_alt3.res rename to tests/sav/nitg-common/fixme/base_covar_int2_alt3.res diff --git a/tests/sav/nitg-e/fixme/base_covar_int2_alt5.res b/tests/sav/nitg-common/fixme/base_covar_int2_alt5.res similarity index 100% rename from tests/sav/nitg-e/fixme/base_covar_int2_alt5.res rename to tests/sav/nitg-common/fixme/base_covar_int2_alt5.res diff --git a/tests/sav/nitg-e/fixme/base_covar_int_alt3.res b/tests/sav/nitg-common/fixme/base_covar_int_alt3.res similarity index 100% rename from tests/sav/nitg-e/fixme/base_covar_int_alt3.res rename to tests/sav/nitg-common/fixme/base_covar_int_alt3.res diff --git a/tests/sav/nitg-e/fixme/base_for_finish.res b/tests/sav/nitg-common/fixme/base_for_finish.res similarity index 100% rename from tests/sav/nitg-e/fixme/base_for_finish.res rename to tests/sav/nitg-common/fixme/base_for_finish.res diff --git a/tests/sav/nitg-e/fixme/base_gen_reassign_alt4.res b/tests/sav/nitg-e/fixme/base_gen_reassign_alt4.res index 37e9ff8..980ce17 100644 --- a/tests/sav/nitg-e/fixme/base_gen_reassign_alt4.res +++ b/tests/sav/nitg-e/fixme/base_gen_reassign_alt4.res @@ -1,4 +1,4 @@ -Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/standard/kernel.nit:396) +Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/standard/kernel.nit:411) 11 21 31 diff --git a/tests/sav/nitg-e/fixme/base_gen_reassign_alt5.res b/tests/sav/nitg-e/fixme/base_gen_reassign_alt5.res index 37e9ff8..980ce17 100644 --- a/tests/sav/nitg-e/fixme/base_gen_reassign_alt5.res +++ b/tests/sav/nitg-e/fixme/base_gen_reassign_alt5.res @@ -1,4 +1,4 @@ -Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/standard/kernel.nit:396) +Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/standard/kernel.nit:411) 11 21 31 diff --git a/tests/sav/nitg-e/fixme/base_gen_reassign_alt6.res b/tests/sav/nitg-e/fixme/base_gen_reassign_alt6.res index 37e9ff8..980ce17 100644 --- a/tests/sav/nitg-e/fixme/base_gen_reassign_alt6.res +++ b/tests/sav/nitg-e/fixme/base_gen_reassign_alt6.res @@ -1,4 +1,4 @@ -Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/standard/kernel.nit:396) +Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/standard/kernel.nit:411) 11 21 31 diff --git a/tests/sav/nitg-g/fixme/base_attr_init_val_int_alt1.res b/tests/sav/nitg-g/fixme/base_attr_init_val_int_alt1.res deleted file mode 100644 index c508d53..0000000 --- a/tests/sav/nitg-g/fixme/base_attr_init_val_int_alt1.res +++ /dev/null @@ -1 +0,0 @@ -false diff --git a/tests/sav/nitg-g/fixme/base_attr_init_val_int_alt2.res b/tests/sav/nitg-g/fixme/base_attr_init_val_int_alt2.res deleted file mode 100644 index f76dd23..0000000 Binary files a/tests/sav/nitg-g/fixme/base_attr_init_val_int_alt2.res and /dev/null differ diff --git a/tests/sav/nitg-g/fixme/base_attr_init_val_int_alt3.res b/tests/sav/nitg-g/fixme/base_attr_init_val_int_alt3.res deleted file mode 100644 index 573541a..0000000 --- a/tests/sav/nitg-g/fixme/base_attr_init_val_int_alt3.res +++ /dev/null @@ -1 +0,0 @@ -0 diff --git a/tests/sav/nitg-g/fixme/base_attr_init_val_int_alt4.res b/tests/sav/nitg-g/fixme/base_attr_init_val_int_alt4.res deleted file mode 100644 index 945da8f..0000000 --- a/tests/sav/nitg-g/fixme/base_attr_init_val_int_alt4.res +++ /dev/null @@ -1 +0,0 @@ -0.000000 diff --git a/tests/sav/nitg-g/fixme/base_attr_init_val_raf_alt1.res b/tests/sav/nitg-g/fixme/base_attr_init_val_raf_alt1.res deleted file mode 100644 index 2f1465d..0000000 --- a/tests/sav/nitg-g/fixme/base_attr_init_val_raf_alt1.res +++ /dev/null @@ -1,3 +0,0 @@ -1 -1 -0 diff --git a/tests/sav/nitg-g/fixme/base_attr_nullable_int_alt1.res b/tests/sav/nitg-g/fixme/base_attr_nullable_int_alt1.res deleted file mode 100644 index 5625f1f..0000000 --- a/tests/sav/nitg-g/fixme/base_attr_nullable_int_alt1.res +++ /dev/null @@ -1,7 +0,0 @@ -0 -0 -1 -2 -10 -20 -30 diff --git a/tests/sav/nitg-g/fixme/base_attr_nullable_int_alt2.res b/tests/sav/nitg-g/fixme/base_attr_nullable_int_alt2.res deleted file mode 100644 index 2e8046c..0000000 --- a/tests/sav/nitg-g/fixme/base_attr_nullable_int_alt2.res +++ /dev/null @@ -1,7 +0,0 @@ -1 -0 -1 -2 -10 -20 -30 diff --git a/tests/sav/nitg-g/fixme/base_attr_nullable_int_alt3.res b/tests/sav/nitg-g/fixme/base_attr_nullable_int_alt3.res deleted file mode 100644 index f0c5f8f..0000000 --- a/tests/sav/nitg-g/fixme/base_attr_nullable_int_alt3.res +++ /dev/null @@ -1,8 +0,0 @@ -0 -0 -0 -1 -2 -10 -20 -30 diff --git a/tests/sav/nitg-g/fixme/base_attr_nullable_int_alt4.res b/tests/sav/nitg-g/fixme/base_attr_nullable_int_alt4.res deleted file mode 100644 index a12c8e0..0000000 --- a/tests/sav/nitg-g/fixme/base_attr_nullable_int_alt4.res +++ /dev/null @@ -1,7 +0,0 @@ -10 -0 -1 -2 -10 -20 -30 diff --git a/tests/sav/nitg-g/fixme/base_attr_nullable_int_alt5.res b/tests/sav/nitg-g/fixme/base_attr_nullable_int_alt5.res deleted file mode 100644 index f343f0e..0000000 --- a/tests/sav/nitg-g/fixme/base_attr_nullable_int_alt5.res +++ /dev/null @@ -1,8 +0,0 @@ -10 -20 -0 -1 -2 -10 -20 -30 diff --git a/tests/sav/nitg-g/fixme/base_covar_int2_alt3.res b/tests/sav/nitg-g/fixme/base_covar_int2_alt3.res deleted file mode 100644 index fbffc32..0000000 --- a/tests/sav/nitg-g/fixme/base_covar_int2_alt3.res +++ /dev/null @@ -1,4 +0,0 @@ -1 -1 -1 -aa diff --git a/tests/sav/nitg-g/fixme/base_covar_int2_alt5.res b/tests/sav/nitg-g/fixme/base_covar_int2_alt5.res deleted file mode 100644 index 5f6d34c..0000000 --- a/tests/sav/nitg-g/fixme/base_covar_int2_alt5.res +++ /dev/null @@ -1,5 +0,0 @@ -1 -1 -1 -1 -a diff --git a/tests/sav/nitg-g/fixme/base_covar_int_alt3.res b/tests/sav/nitg-g/fixme/base_covar_int_alt3.res deleted file mode 100644 index d3413ee..0000000 --- a/tests/sav/nitg-g/fixme/base_covar_int_alt3.res +++ /dev/null @@ -1,5 +0,0 @@ -true -true -true -false -true diff --git a/tests/sav/nitg-g/fixme/base_for_finish.res b/tests/sav/nitg-g/fixme/base_for_finish.res deleted file mode 100644 index 390c4e4..0000000 --- a/tests/sav/nitg-g/fixme/base_for_finish.res +++ /dev/null @@ -1,16 +0,0 @@ -1 -2 -3 -0 - -1 -100 -2 -0 - -1 -10 -20 -100 -2 -10 diff --git a/tests/sav/nitg-s/fixme/base_attr_init_val_int_alt1.res b/tests/sav/nitg-s/fixme/base_attr_init_val_int_alt1.res deleted file mode 100644 index c508d53..0000000 --- a/tests/sav/nitg-s/fixme/base_attr_init_val_int_alt1.res +++ /dev/null @@ -1 +0,0 @@ -false diff --git a/tests/sav/nitg-s/fixme/base_attr_init_val_int_alt2.res b/tests/sav/nitg-s/fixme/base_attr_init_val_int_alt2.res deleted file mode 100644 index f76dd23..0000000 Binary files a/tests/sav/nitg-s/fixme/base_attr_init_val_int_alt2.res and /dev/null differ diff --git a/tests/sav/nitg-s/fixme/base_attr_init_val_int_alt3.res b/tests/sav/nitg-s/fixme/base_attr_init_val_int_alt3.res deleted file mode 100644 index 573541a..0000000 --- a/tests/sav/nitg-s/fixme/base_attr_init_val_int_alt3.res +++ /dev/null @@ -1 +0,0 @@ -0 diff --git a/tests/sav/nitg-s/fixme/base_attr_init_val_int_alt4.res b/tests/sav/nitg-s/fixme/base_attr_init_val_int_alt4.res deleted file mode 100644 index 945da8f..0000000 --- a/tests/sav/nitg-s/fixme/base_attr_init_val_int_alt4.res +++ /dev/null @@ -1 +0,0 @@ -0.000000 diff --git a/tests/sav/nitg-s/fixme/base_attr_init_val_raf_alt1.res b/tests/sav/nitg-s/fixme/base_attr_init_val_raf_alt1.res deleted file mode 100644 index 2f1465d..0000000 --- a/tests/sav/nitg-s/fixme/base_attr_init_val_raf_alt1.res +++ /dev/null @@ -1,3 +0,0 @@ -1 -1 -0 diff --git a/tests/sav/nitg-s/fixme/base_attr_nullable_int_alt1.res b/tests/sav/nitg-s/fixme/base_attr_nullable_int_alt1.res deleted file mode 100644 index 5625f1f..0000000 --- a/tests/sav/nitg-s/fixme/base_attr_nullable_int_alt1.res +++ /dev/null @@ -1,7 +0,0 @@ -0 -0 -1 -2 -10 -20 -30 diff --git a/tests/sav/nitg-s/fixme/base_attr_nullable_int_alt2.res b/tests/sav/nitg-s/fixme/base_attr_nullable_int_alt2.res deleted file mode 100644 index 2e8046c..0000000 --- a/tests/sav/nitg-s/fixme/base_attr_nullable_int_alt2.res +++ /dev/null @@ -1,7 +0,0 @@ -1 -0 -1 -2 -10 -20 -30 diff --git a/tests/sav/nitg-s/fixme/base_attr_nullable_int_alt3.res b/tests/sav/nitg-s/fixme/base_attr_nullable_int_alt3.res deleted file mode 100644 index f0c5f8f..0000000 --- a/tests/sav/nitg-s/fixme/base_attr_nullable_int_alt3.res +++ /dev/null @@ -1,8 +0,0 @@ -0 -0 -0 -1 -2 -10 -20 -30 diff --git a/tests/sav/nitg-s/fixme/base_attr_nullable_int_alt4.res b/tests/sav/nitg-s/fixme/base_attr_nullable_int_alt4.res deleted file mode 100644 index a12c8e0..0000000 --- a/tests/sav/nitg-s/fixme/base_attr_nullable_int_alt4.res +++ /dev/null @@ -1,7 +0,0 @@ -10 -0 -1 -2 -10 -20 -30 diff --git a/tests/sav/nitg-s/fixme/base_attr_nullable_int_alt5.res b/tests/sav/nitg-s/fixme/base_attr_nullable_int_alt5.res deleted file mode 100644 index f343f0e..0000000 --- a/tests/sav/nitg-s/fixme/base_attr_nullable_int_alt5.res +++ /dev/null @@ -1,8 +0,0 @@ -10 -20 -0 -1 -2 -10 -20 -30 diff --git a/tests/sav/nitg-s/fixme/base_covar_int2_alt3.res b/tests/sav/nitg-s/fixme/base_covar_int2_alt3.res deleted file mode 100644 index fbffc32..0000000 --- a/tests/sav/nitg-s/fixme/base_covar_int2_alt3.res +++ /dev/null @@ -1,4 +0,0 @@ -1 -1 -1 -aa diff --git a/tests/sav/nitg-s/fixme/base_covar_int2_alt5.res b/tests/sav/nitg-s/fixme/base_covar_int2_alt5.res deleted file mode 100644 index 5f6d34c..0000000 --- a/tests/sav/nitg-s/fixme/base_covar_int2_alt5.res +++ /dev/null @@ -1,5 +0,0 @@ -1 -1 -1 -1 -a diff --git a/tests/sav/nitg-s/fixme/base_covar_int_alt3.res b/tests/sav/nitg-s/fixme/base_covar_int_alt3.res deleted file mode 100644 index d3413ee..0000000 --- a/tests/sav/nitg-s/fixme/base_covar_int_alt3.res +++ /dev/null @@ -1,5 +0,0 @@ -true -true -true -false -true diff --git a/tests/sav/nitg-s/fixme/base_for_finish.res b/tests/sav/nitg-s/fixme/base_for_finish.res deleted file mode 100644 index 390c4e4..0000000 --- a/tests/sav/nitg-s/fixme/base_for_finish.res +++ /dev/null @@ -1,16 +0,0 @@ -1 -2 -3 -0 - -1 -100 -2 -0 - -1 -10 -20 -100 -2 -10 diff --git a/tests/sav/nitg-sg/fixme/base_attr_init_val_int_alt1.res b/tests/sav/nitg-sg/fixme/base_attr_init_val_int_alt1.res deleted file mode 100644 index c508d53..0000000 --- a/tests/sav/nitg-sg/fixme/base_attr_init_val_int_alt1.res +++ /dev/null @@ -1 +0,0 @@ -false diff --git a/tests/sav/nitg-sg/fixme/base_attr_init_val_int_alt2.res b/tests/sav/nitg-sg/fixme/base_attr_init_val_int_alt2.res deleted file mode 100644 index f76dd23..0000000 Binary files a/tests/sav/nitg-sg/fixme/base_attr_init_val_int_alt2.res and /dev/null differ diff --git a/tests/sav/nitg-sg/fixme/base_attr_init_val_int_alt3.res b/tests/sav/nitg-sg/fixme/base_attr_init_val_int_alt3.res deleted file mode 100644 index 573541a..0000000 --- a/tests/sav/nitg-sg/fixme/base_attr_init_val_int_alt3.res +++ /dev/null @@ -1 +0,0 @@ -0 diff --git a/tests/sav/nitg-sg/fixme/base_attr_init_val_int_alt4.res b/tests/sav/nitg-sg/fixme/base_attr_init_val_int_alt4.res deleted file mode 100644 index 945da8f..0000000 --- a/tests/sav/nitg-sg/fixme/base_attr_init_val_int_alt4.res +++ /dev/null @@ -1 +0,0 @@ -0.000000 diff --git a/tests/sav/nitg-sg/fixme/base_attr_init_val_raf_alt1.res b/tests/sav/nitg-sg/fixme/base_attr_init_val_raf_alt1.res deleted file mode 100644 index 2f1465d..0000000 --- a/tests/sav/nitg-sg/fixme/base_attr_init_val_raf_alt1.res +++ /dev/null @@ -1,3 +0,0 @@ -1 -1 -0 diff --git a/tests/sav/nitg-sg/fixme/base_attr_nullable_int_alt1.res b/tests/sav/nitg-sg/fixme/base_attr_nullable_int_alt1.res deleted file mode 100644 index 5625f1f..0000000 --- a/tests/sav/nitg-sg/fixme/base_attr_nullable_int_alt1.res +++ /dev/null @@ -1,7 +0,0 @@ -0 -0 -1 -2 -10 -20 -30 diff --git a/tests/sav/nitg-sg/fixme/base_attr_nullable_int_alt2.res b/tests/sav/nitg-sg/fixme/base_attr_nullable_int_alt2.res deleted file mode 100644 index 2e8046c..0000000 --- a/tests/sav/nitg-sg/fixme/base_attr_nullable_int_alt2.res +++ /dev/null @@ -1,7 +0,0 @@ -1 -0 -1 -2 -10 -20 -30 diff --git a/tests/sav/nitg-sg/fixme/base_attr_nullable_int_alt3.res b/tests/sav/nitg-sg/fixme/base_attr_nullable_int_alt3.res deleted file mode 100644 index f0c5f8f..0000000 --- a/tests/sav/nitg-sg/fixme/base_attr_nullable_int_alt3.res +++ /dev/null @@ -1,8 +0,0 @@ -0 -0 -0 -1 -2 -10 -20 -30 diff --git a/tests/sav/nitg-sg/fixme/base_attr_nullable_int_alt4.res b/tests/sav/nitg-sg/fixme/base_attr_nullable_int_alt4.res deleted file mode 100644 index a12c8e0..0000000 --- a/tests/sav/nitg-sg/fixme/base_attr_nullable_int_alt4.res +++ /dev/null @@ -1,7 +0,0 @@ -10 -0 -1 -2 -10 -20 -30 diff --git a/tests/sav/nitg-sg/fixme/base_attr_nullable_int_alt5.res b/tests/sav/nitg-sg/fixme/base_attr_nullable_int_alt5.res deleted file mode 100644 index f343f0e..0000000 --- a/tests/sav/nitg-sg/fixme/base_attr_nullable_int_alt5.res +++ /dev/null @@ -1,8 +0,0 @@ -10 -20 -0 -1 -2 -10 -20 -30 diff --git a/tests/sav/nitg-sg/fixme/base_covar_int2_alt3.res b/tests/sav/nitg-sg/fixme/base_covar_int2_alt3.res deleted file mode 100644 index fbffc32..0000000 --- a/tests/sav/nitg-sg/fixme/base_covar_int2_alt3.res +++ /dev/null @@ -1,4 +0,0 @@ -1 -1 -1 -aa diff --git a/tests/sav/nitg-sg/fixme/base_covar_int2_alt5.res b/tests/sav/nitg-sg/fixme/base_covar_int2_alt5.res deleted file mode 100644 index 5f6d34c..0000000 --- a/tests/sav/nitg-sg/fixme/base_covar_int2_alt5.res +++ /dev/null @@ -1,5 +0,0 @@ -1 -1 -1 -1 -a diff --git a/tests/sav/nitg-sg/fixme/base_covar_int_alt3.res b/tests/sav/nitg-sg/fixme/base_covar_int_alt3.res deleted file mode 100644 index d3413ee..0000000 --- a/tests/sav/nitg-sg/fixme/base_covar_int_alt3.res +++ /dev/null @@ -1,5 +0,0 @@ -true -true -true -false -true diff --git a/tests/sav/nitg-sg/fixme/base_for_finish.res b/tests/sav/nitg-sg/fixme/base_for_finish.res deleted file mode 100644 index 390c4e4..0000000 --- a/tests/sav/nitg-sg/fixme/base_for_finish.res +++ /dev/null @@ -1,16 +0,0 @@ -1 -2 -3 -0 - -1 -100 -2 -0 - -1 -10 -20 -100 -2 -10 diff --git a/tests/sav/nitg-sg/fixme/test_platform_android.res b/tests/sav/nitg-sg/fixme/test_platform_android.res new file mode 100644 index 0000000..4ad3dc3 --- /dev/null +++ b/tests/sav/nitg-sg/fixme/test_platform_android.res @@ -0,0 +1 @@ +UNDEFINED diff --git a/tests/sav/nitserial_args1.res b/tests/sav/nitserial_args1.res index 2ebbe38..e95605c 100644 --- a/tests/sav/nitserial_args1.res +++ b/tests/sav/nitserial_args1.res @@ -12,8 +12,6 @@ redef class Deserializer if name == "Array[Serializable]" then return new Array[Serializable].from_deserializer(self) if name == "Array[String]" then return new Array[String].from_deserializer(self) if name == "Array[Object]" then return new Array[Object].from_deserializer(self) - if name == "Array[Match]" then return new Array[Match].from_deserializer(self) - if name == "Array[FlatBuffer]" then return new Array[FlatBuffer].from_deserializer(self) return super end end diff --git a/tests/sav/nituml_args3.res b/tests/sav/nituml_args3.res index af28f14..e248df6 100644 --- a/tests/sav/nituml_args3.res +++ b/tests/sav/nituml_args3.res @@ -41,7 +41,7 @@ Bool [ Object -> Bool [dir=back arrowtail=open style=dashed]; Float [ - label = "{Float||}" + label = "{Float||+ is_approx(other: Float, precision: Float): Bool\l}" ] Numeric -> Float [dir=back arrowtail=open style=dashed]; diff --git a/tests/sav/nituml_args4.res b/tests/sav/nituml_args4.res index 6189897..9a7b30f 100644 --- a/tests/sav/nituml_args4.res +++ b/tests/sav/nituml_args4.res @@ -41,7 +41,7 @@ Bool [ Object -> Bool [dir=back arrowtail=open style=dashed]; Float [ - label = "{Float||}" + label = "{Float||+ is_approx(other: Float, precision: Float): Bool\l}" ] Numeric -> Float [dir=back arrowtail=open style=dashed]; diff --git a/tests/sav/nitunit_args1.res b/tests/sav/nitunit_args1.res index 3a07d20..12b7181 100644 --- a/tests/sav/nitunit_args1.res +++ b/tests/sav/nitunit_args1.res @@ -1,6 +1,6 @@ -test_nitunit.nit:20,1--22,0: ERROR: nitunit.test_nitunit.test_nitunit::X. (in .nitunit/test_nitunit2.nit): Runtime error: Assert failed (.nitunit/test_nitunit2.nit:5) +test_nitunit.nit:20,1--22,0: ERROR: nitunit.test_nitunit.test_nitunit::X. (in .nitunit/test_nitunit-2.nit): Runtime error: Assert failed (.nitunit/test_nitunit-2.nit:5) -test_nitunit.nit:23,2--25,0: FAILURE: nitunit.test_nitunit.test_nitunit::X.test_nitunit::X::foo (in .nitunit/test_nitunit3.nit): .nitunit/test_nitunit3.nit:5,8--27: Error: Method or variable 'undefined_identifier' unknown in Sys. +test_nitunit.nit:23,2--25,0: FAILURE: nitunit.test_nitunit.test_nitunit::X.test_nitunit::X::foo (in .nitunit/test_nitunit-3.nit): .nitunit/test_nitunit-3.nit:5,8--27: Error: Method or variable 'undefined_identifier' unknown in Sys. test_test_nitunit.nit:36,2--40,4: ERROR: test_foo1 (in file .nitunit/test_test_nitunit_TestX_test_foo1.nit): Runtime error: Assert failed (test_test_nitunit.nit:39) @@ -11,8 +11,8 @@ TestSuites: Class suites: 1; Test Cases: 3; Failures: 1 assert true assert false -assert undefined_identifier -outoutout \ No newline at end of file diff --git a/tests/sav/nitunit_args4.res b/tests/sav/nitunit_args4.res new file mode 100644 index 0000000..faaa0c9 --- /dev/null +++ b/tests/sav/nitunit_args4.res @@ -0,0 +1,21 @@ +DocUnits: +DocUnits Success +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 + + assert true + +end +if true then + + assert true + +end +var a = 1 +assert a == 1 +assert a == 1 + \ No newline at end of file diff --git a/tests/sav/test_ffi_java_types.res b/tests/sav/test_ffi_java_types.res index 6471338..05d33ed 100644 --- a/tests/sav/test_ffi_java_types.res +++ b/tests/sav/test_ffi_java_types.res @@ -6,7 +6,7 @@ 10 1 1 -2 -3 10 +2 20 +3 diff --git a/tests/sav/test_inheritance_raf.res b/tests/sav/test_inheritance_raf.res index a007f82..dd8e78f 100644 --- a/tests/sav/test_inheritance_raf.res +++ b/tests/sav/test_inheritance_raf.res @@ -1 +1,16 @@ -Property inheritance conflict in class B for `i': conflicting properties are defined in B, A +1 +1 +5 +5 +1 +2 +5 +2 +1 +1 +3 +7 +1 +2 +3 +4 diff --git a/tests/sav/test_json_static.res b/tests/sav/test_json_static.res index 0a122d4..22ab94a 100644 Binary files a/tests/sav/test_json_static.res and b/tests/sav/test_json_static.res differ diff --git a/tests/sav/test_new_native_alt1.res b/tests/sav/test_new_native_alt1.res index bf79e4b..ba6c5fe 100644 --- a/tests/sav/test_new_native_alt1.res +++ b/tests/sav/test_new_native_alt1.res @@ -1,4 +1,4 @@ -Runtime error: Cast failed. Expected `E`, got `Bool` (../lib/standard/collection/array.nit:789) +Runtime error: Cast failed. Expected `E`, got `Bool` (../lib/standard/collection/array.nit:782) NativeString N Nit diff --git a/tests/search_tests.sh b/tests/search_tests.sh index ee239cc..c4e3593 100755 --- a/tests/search_tests.sh +++ b/tests/search_tests.sh @@ -15,7 +15,7 @@ stop=false while [ "$stop" = false ]; do - case $1 in + case "$1" in -v) verbose=true; shift;; *) stop=true esac @@ -42,29 +42,31 @@ for f in "$@"; do echo "$f" continue fi - b=`basename "$f" .nit` + b=`basename -- "$f" .nit` ;; *.res) - b=`basename "$f" .res` + b=`basename -- "$f" .res` ;; *) - b=`basename "$f"` + b=`basename -- "$f"` ;; esac + # remove bad chars + c=`echo "$b" | sed 's/\([\\.*^$]\|\[\|]\)/./g'` # Remove alts of args test variations - c=`echo "$b" | sed 's/\(_[0-9]*alt[0-9][0-9]*\)/\\\\(\1\\\\)\\\\?/g;s/\(_args[0-9][0-9]*\)/\\\\(\1\\\\)\\\\?/'` + c=`echo "$c" | sed 's/\(_[0-9]*alt[0-9][0-9]*\)/\\\\(\1\\\\)\\\\?/g;s/\(_args[0-9][0-9]*\)/\\\\(\1\\\\)\\\\?/'` b=`echo "$b" | sed 's/_[0-9]*alt[0-9][0-9]*//g;s/_args[0-9][0-9]*//'` # Search the orig nit file in the list - cat listfull.out | grep "\b$c.nit" || { + cat listfull.out | grep -- "\(^\|/\)$c.nit" || { res=1 echo >&2 "No test $b.nit found for $f" test "$verbose" == "true" || continue # Search the nit file outside the list... - find ../../nit* -name $b.nit >&2 + find ../../nit* -name "$b.nit" >&2 # Search the nit file in the git history... - git log -1 -- $b.nit >&2 + git log -1 -- "$b.nit" >&2 # Search the orig file in the git history... - git log -1 -- $f >&2 + git log -1 -- "$f" >&2 } done diff --git a/tests/test_ffi_java_types.nit b/tests/test_ffi_java_types.nit index 642abeb..19ca640 100644 --- a/tests/test_ffi_java_types.nit +++ b/tests/test_ffi_java_types.nit @@ -27,11 +27,11 @@ extern class JavaArrayList in "Java" `{ java.util.ArrayList `} return new ArrayList(); `} - fun add(o: Int) in "Java" `{ recv.add(o); `} + fun add(o: JavaString) in "Java" `{ recv.add(o); `} redef fun output in "Java" `{ for (Object i: recv) { - System.out.println((long)i); + System.out.println((String)i); } `} @@ -41,12 +41,12 @@ extern class JavaArrayList in "Java" `{ java.util.ArrayList `} end var ll = new JavaArrayList -ll.add(1) -ll.add(2) -ll.add(1) -ll.add(3) -ll.add(20) -ll.add(10) +ll.add "1".to_java_string +ll.add "2".to_java_string +ll.add "1".to_java_string +ll.add "3".to_java_string +ll.add "20".to_java_string +ll.add "10".to_java_string ll.output ll.sort ll.output diff --git a/tests/test_gen.nit b/tests/test_gen.nit index 0d15f98..019f202 100644 --- a/tests/test_gen.nit +++ b/tests/test_gen.nit @@ -28,7 +28,7 @@ class Toto[E] end class TestNative - super ArrayCapable[Int] + init do @@ -39,7 +39,7 @@ do a[1] = 2 print(a[0]) print(a[1]) - b = calloc_array(5) + b = new NativeArray[Int](5) b[0]=200 b[1]=300 print(b[0]) diff --git a/tests/test_json_static.nit b/tests/test_json_static.nit index b510725..db6b1cf 100644 --- a/tests/test_json_static.nit +++ b/tests/test_json_static.nit @@ -1,6 +1,7 @@ # This file is part of NIT ( http://www.nitlanguage.org ). # # Copyright 2014 Alexis Laferrière +# Copyright 2014 Jean-Christophe Beaupré # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -22,9 +23,11 @@ end var a = "\{\"__kind\": \"obj\", \"__id\": 0, \"__class\": \"C\", \"a\": \{\"__kind\": \"obj\", \"__id\": 1, \"__class\": \"A\", \"b\": true, \"c\": \"a\", \"f\": 0.123, \"i\": 1234, \"s\": \"asdf\", \"n\": null, \"array\": [88, \"hello\", null]\}, \"b\": \{\"__kind\": \"obj\", \"__id\": 2, \"__class\": \"B\", \"b\": false, \"c\": \"b\", \"f\": 123.123, \"i\": 2345, \"s\": \"hjkl\", \"n\": null, \"array\": [88, \"hello\", null], \"ii\": 1111, \"ss\": \"qwer\"\}, \"aa\": \{\"__kind\": \"ref\", \"__id\": 1\}\}" var b = "\{\"__kind\": \"obj\", \"__id\": 0, \"__class\": \"A\", \"b\": true, \"c\": \"a\", \"f\": 0.123, \"i\": 1234, \"s\": \"asdf\", \"n\": null, \"array\": [88, \"hello\", null]\}" +var c = "\{\"foo\":\"bar\\\"\\\\\\/\\b\\f\\n\\r\\t\\u0020\\u0000\"\}" +var d = "\{ \"face with tears of joy\" : \"\\uD83D\\uDE02\" \}" -for s in [a, b] do - var obj = s.json_to_nit_object +for s in [a, b, c, d] do + var obj = s.parse_json print "# Json: {s}" print "# Nit: {obj or else ""}" end diff --git a/tests/test_native_array.nit b/tests/test_native_array.nit index aac7a83..467fa78 100644 --- a/tests/test_native_array.nit +++ b/tests/test_native_array.nit @@ -13,11 +13,11 @@ # limitations under the License. class Toto - super ArrayCapable[Int] + fun toto do - var a = calloc_array(3) + var a = new NativeArray[Int](3) a[0] = 10 a[1] = 20 a[2] = 30 diff --git a/tests/test_neo4j.nit b/tests/test_neo4j.nit index f8cbd4b..7ee824c 100644 --- a/tests/test_neo4j.nit +++ b/tests/test_neo4j.nit @@ -43,7 +43,7 @@ assert res1.is_linked print res1["name"].to_s print res1["age"].to_s print res1["status"].to_s -print res1["groups"].to_s +print res1["groups"].to_json print res1.labels.join(" ") assert res1.out_edges.is_empty @@ -92,7 +92,7 @@ assert res4.is_linked print res4["name"].to_s print res4["age"].to_s print res4["status"].to_s -print res4["groups"].to_s +print res4["groups"].to_json print res4.labels.join(" ") assert res4.in_edges.is_empty assert not res4.out_edges.is_empty diff --git a/tests/test_neo4j_batch.nit b/tests/test_neo4j_batch.nit index e6ac890..7455557 100644 --- a/tests/test_neo4j_batch.nit +++ b/tests/test_neo4j_batch.nit @@ -65,7 +65,7 @@ assert res4.is_linked print res4["name"].to_s print res4["age"].to_s print res4["status"].to_s -print res4["groups"].to_s +print res4["groups"].to_json print res4.labels.join(" ") assert res4.in_edges.is_empty assert not res4.out_edges.is_empty diff --git a/tests/test_nitunit2.nit b/tests/test_nitunit2.nit new file mode 100644 index 0000000..899ff94 --- /dev/null +++ b/tests/test_nitunit2.nit @@ -0,0 +1,43 @@ +# 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 fence unit +# +# ~~~~ +# if true then +# +# assert true +# +# end +# ~~~~ +fun foo1 do end + +# a block unit +# +# if true then +# +# assert true +# +# end +fun bar2 do end + +# a context continuation +# +# var a = 1 +# assert a == 1 +# +# bla bla +# +# assert a == 1 +fun foo3 do end diff --git a/tests/tests.sh b/tests/tests.sh index 76ecf2c..8720ca3 100755 --- a/tests/tests.sh +++ b/tests/tests.sh @@ -27,13 +27,13 @@ unset NIT_DIR # Get the first Java lib available shopt -s nullglob -paths=`echo /usr/lib/jvm/*/` -paths=($paths) -JAVA_HOME=${paths[0]} +JAVA_HOME=$(dirname $(dirname $(readlink -f $(which javac)))) paths=`echo $JAVA_HOME/jre/lib/*/{client,server}/` paths=($paths) JNI_LIB_PATH=${paths[0]} +echo $JAVA_HOME +echo $JNI_LIB_PATH shopt -u nullglob outdir="out" @@ -65,7 +65,7 @@ saferun() local o= local a= while [ $stop = false ]; do - case $1 in + case "$1" in -o) o="$2"; shift; shift;; -a) a="-a"; shift;; *) stop=true @@ -129,8 +129,8 @@ function compare_to_result() local pattern="$1" local sav="$2" if [ ! -r "$sav" ]; then return 0; fi - test "`cat "$sav"`" = "UNDEFINED" && return 1 - diff -u "$sav" "$outdir/$pattern.res" > "$outdir/$pattern.diff.sav.log" + test "`cat -- "$sav"`" = "UNDEFINED" && return 1 + diff -u -- "$sav" "$outdir/$pattern.res" > "$outdir/$pattern.diff.sav.log" if [ "$?" == 0 ]; then return 1 fi @@ -146,6 +146,13 @@ function compare_to_result() fi } +function xmlesc() +{ + sed 's/&/\&/g; s//\>/g; s/"/\"/g; s/'"'"'/\'/g'<>$xml "" + echo >>$xml "" #for sav in "sav/$engine/fixme/$pattern.res" "sav/$engine/$pattern.res" "sav/fixme/$pattern.res" "sav/$pattern.res" "sav/$pattern.sav"; do for savdir in $savdirs; do sav=$savdir/fixme/$pattern.res @@ -225,7 +232,7 @@ function process_result() if [ -n "$SAV" ]; then if [ -n "$OLD" ]; then echo "[*ok*] $outdir/$pattern.res $SAV - but $OLD remains!" - echo >>$xml "" + echo >>$xml "" remains="$remains $OLD" else echo "[ok] $outdir/$pattern.res $SAV" @@ -234,7 +241,7 @@ function process_result() elif [ -n "$FIXME" ]; then if [ -n "$OLD" ]; then echo "[*fixme*] $outdir/$pattern.res $FIXME - but $OLD remains!" - echo >>$xml "" + echo >>$xml "" remains="$remains $OLD" else echo "[fixme] $outdir/$pattern.res $FIXME" @@ -247,41 +254,41 @@ function process_result() todos="$todos $pattern" elif [ -n "$SOSO" ]; then echo "[======= soso $outdir/$pattern.res $SOSO =======]" - echo >>$xml "" + echo >>$xml "" echo >>$xml ">$xml -n 50 + cat -v -- "$outdir/$pattern.diff.sav.log" | head >>$xml -n 50 echo >>$xml "]]>" nok="$nok $pattern" echo "$ii" >> "$ERRLIST" elif [ -n "$SOSOF" ]; then echo "[======= fixme soso $outdir/$pattern.res $SOSOF =======]" - echo >>$xml "" + echo >>$xml "" echo >>$xml ">$xml -n 50 + cat -v -- "$outdir/$pattern.diff.sav.log" | head >>$xml -n 50 echo >>$xml "]]>" nok="$nok $pattern" echo "$ii" >> "$ERRLIST" elif [ -n "$NSAV" ]; then echo "[======= fail $outdir/$pattern.res $NSAV =======]" - echo >>$xml "" + echo >>$xml "" echo >>$xml ">$xml -n 50 + cat -v -- "$outdir/$pattern.diff.sav.log" | head >>$xml -n 50 echo >>$xml "]]>" nok="$nok $pattern" echo "$ii" >> "$ERRLIST" elif [ -n "$NFIXME" ]; then echo "[======= changed $outdir/$pattern.res $NFIXME ======]" - echo >>$xml "" + echo >>$xml "" echo >>$xml ">$xml -n 50 + cat -v -- "$outdir/$pattern.diff.sav.log" | head >>$xml -n 50 echo >>$xml "]]>" nok="$nok $pattern" echo "$ii" >> "$ERRLIST" - elif [ -s $outdir/$pattern.res ]; then + elif [ -s "$outdir/$pattern.res" ]; then echo "[=== no sav ===] $outdir/$pattern.res is not empty" echo >>$xml "" echo >>$xml ">$xml $outdir/$pattern.res + cat -v >>$xml -- "$outdir/$pattern.res" echo >>$xml "]]>" nos="$nos $pattern" echo "$ii" >> "$ERRLIST" @@ -290,9 +297,9 @@ function process_result() echo "[0k] $outdir/$pattern.res is empty" ok="$ok $pattern" fi - if test -s $outdir/$pattern.cmp.err; then + if test -s "$outdir/$pattern.cmp.err"; then echo >>$xml ">$xml $outdir/$pattern.cmp.err + cat -v >>$xml -- "$outdir/$pattern.cmp.err" echo >>$xml "]]>" fi echo >>$xml "" @@ -303,12 +310,12 @@ need_skip() test "$noskip" = true && return 1 if echo "$1" | grep -f "$engine.skip" >/dev/null 2>&1; then echo "=> $2: [skip]" - echo >>$xml "" + echo >>$xml "" return 0 fi if test -n "$isinterpret" && echo "$1" | grep -f "exec.skip" >/dev/null 2>&1; then echo "=> $2: [skip exec]" - echo >>$xml "" + echo >>$xml "" return 0 fi return 1 @@ -373,22 +380,27 @@ case $engine in engine=nitg-s; enginebinname=nitg; OPT="--separate $OPT --compile-dir $compdir" + savdirs="sav/nitg-common/" ;; nitg-s) enginebinname=nitg; OPT="--separate $OPT --compile-dir $compdir" + savdirs="sav/nitg-common/" ;; nitg-e) enginebinname=nitg; OPT="--erasure $OPT --compile-dir $compdir" + savdirs="sav/nitg-common/" ;; nitg-sg) enginebinname=nitg; OPT="--semi-global $OPT --compile-dir $compdir" + savdirs="sav/nitg-common/" ;; nitg-g) enginebinname=nitg; OPT="--global $OPT --compile-dir $compdir" + savdirs="sav/nitg-common/" ;; nit) engine=niti @@ -465,16 +477,16 @@ fi echo >$xml "" for ii in "$@"; do - if [ ! -f $ii ]; then + if [ ! -f "$ii" ]; then echo "File '$ii' does not exist." continue fi - f=`basename "$ii" .nit` + f=`basename -- "$ii" .nit` pack="tests.${engine}".`echo $ii | perl -p -e 's|^../([^/]*)/([a-zA-Z_]*).*|\1.\2| || s|^([a-zA-Z]*)[^_]*_([a-zA-Z]*).*|\1.\2| || s|\W*([a-zA-Z_]*).*|\1|'` # Sould we skip the file for this engine? - need_skip $f $f $pack && continue + need_skip "$f" "$f" "$pack" && continue tmp=${ii/../AA} if [ "x$tmp" = "x$ii" ]; then @@ -483,12 +495,12 @@ for ii in "$@"; do includes="-I alt" fi - for i in "$ii" `./alterner.pl --start '#' --altsep '_' $ii`; do - bf=`basename $i .nit` + for i in "$ii" `./alterner.pl --start '#' --altsep '_' -- "$ii"`; do + bf=`basename -- "$i" .nit` ff="$outdir/$bf" # Sould we skip the alternative for this engine? - need_skip $bf $bf $pack && continue + need_skip "$bf" "$bf" "$pack" && continue echo -n "=> $bf: " @@ -507,7 +519,7 @@ for ii in "$@"; do if [ -n "$isinterpret" ]; then cat > "$ff.bin" < "$ff.cmp.err" @@ -529,8 +541,8 @@ END saferun -o "$ff.time.out" $NITC --no-color $OPT -o "$ffout" $includes $nocc "$i" 2> "$ff.cmp.err" > "$ff.compile.log" ERR=$? if [ "x$verbose" = "xtrue" ]; then - cat "$ff.compile.log" - cat >&2 "$ff.cmp.err" + cat -- "$ff.compile.log" + cat >&2 -- "$ff.cmp.err" fi fi if [ "$engine" = "emscripten" ]; then @@ -538,24 +550,24 @@ END chmod +x "$ff.bin" if grep "Fatal Error: more than one primitive class" "$ff.compile.log" > /dev/null; then echo " [skip] do no not imports kernel" - echo >>$xml "" + echo >>$xml "" continue fi fi if [ "$ERR" != 0 ]; then echo -n "! " - cat "$ff.compile.log" "$ff.cmp.err" > "$ff.res" - process_result $bf $bf $pack + cat -- "$ff.compile.log" "$ff.cmp.err" > "$ff.res" + process_result "$bf" "$bf" "$pack" elif [ -n "$nocc" ]; then # not compiled echo -n "nocc " > "$ff.res" - process_result $bf $bf $pack + process_result "$bf" "$bf" "$pack" elif [ -x "$ff.bin" ]; then if skip_exec "$bf"; then # No exec > "$ff.res" - process_result $bf $bf $pack + process_result "$bf" "$bf" "$pack" break fi echo -n ". " @@ -567,21 +579,21 @@ END fi NIT_NO_STACK=1 LD_LIBRARY_PATH=$JNI_LIB_PATH \ saferun -a -o "$ff.time.out" "$ff.bin" $args < "$inputs" > "$ff.res" 2>"$ff.err" - mv $ff.time.out $ff.times.out - awk '{ SUM += $1} END { print SUM }' $ff.times.out > $ff.time.out + mv "$ff.time.out" "$ff.times.out" + awk '{ SUM += $1} END { print SUM }' "$ff.times.out" > "$ff.time.out" if [ "x$verbose" = "xtrue" ]; then - cat "$ff.res" - cat >&2 "$ff.err" + cat -- "$ff.res" + cat >&2 -- "$ff.err" fi if [ -f "$ff.write" ]; then - cat "$ff.write" >> "$ff.res" + cat -- "$ff.write" >> "$ff.res" elif [ -d "$ff.write" ]; then - LANG=C /bin/ls -F $ff.write >> "$ff.res" + LANG=C /bin/ls -F "$ff.write" >> "$ff.res" fi - cp "$ff.res" "$ff.res2" - cat "$ff.cmp.err" "$ff.err" "$ff.res2" > "$ff.res" - process_result $bf $bf $pack + cp -- "$ff.res" "$ff.res2" + cat -- "$ff.cmp.err" "$ff.err" "$ff.res2" > "$ff.res" + process_result "$bf" "$bf" "$pack" if [ -f "$f.args" ]; then fargs=$f.args @@ -594,13 +606,13 @@ END name="$bf args $cptr" # Sould we skip the input for this engine? - need_skip $bff " $name" $pack && continue + need_skip "$bff" " $name" "$pack" && continue # use a specific inputs file, if required if [ -f "$bff.inputs" ]; then ffinputs="$bff.inputs" else - ffinputs=$inputs + ffinputs="$inputs" fi rm -rf "$fff.res" "$fff.err" "$fff.write" 2> /dev/null @@ -613,30 +625,30 @@ END chmod +x "$fff.bin" WRITE="$fff.write" saferun -o "$fff.time.out" sh -c "NIT_NO_STACK=1 $fff.bin < $ffinputs > $fff.res 2>$fff.err" if [ "x$verbose" = "xtrue" ]; then - cat "$fff.res" - cat >&2 "$fff.err" + cat -- "$fff.res" + cat >&2 -- "$fff.err" fi if [ -f "$fff.write" ]; then - cat "$fff.write" >> "$fff.res" + cat -- "$fff.write" >> "$fff.res" elif [ -d "$fff.write" ]; then - LANG=C /bin/ls -F $fff.write >> "$fff.res" + LANG=C /bin/ls -F -- "$fff.write" >> "$fff.res" fi if [ -s "$fff.err" ]; then - cp "$fff.res" "$fff.res2" - cat "$fff.err" "$fff.res2" > "$fff.res" + cp -- "$fff.res" "$fff.res2" + cat -- "$fff.err" "$fff.res2" > "$fff.res" fi - process_result $bff " $name" $pack - done < $fargs + process_result "$bff" " $name" "$pack" + done < "$fargs" fi elif [ -f "$ff.bin" ]; then #Not executable (platform?)" > "$ff.res" - process_result $bf "$bf" $pack + process_result "$bf" "$bf" "$pack" else echo -n "! " - cat "$ff.cmp.err" > "$ff.res" + cat -- "$ff.cmp.err" > "$ff.res" echo "Compilation error" > "$ff.res" - process_result $bf "$bf" $pack + process_result "$bf" "$bf" "$pack" fi done done