This PR change the way class members are parsed.
Before, the order was strict: class annotations, then extern code block, then super clauses, then properties.
After, annotations and super clauses can appear in any order within the properties
The need is to enable class annotations inside the class (cf #1158) I did not find another simple way to do this.
Now, one can write
~~~nit
class B
super A
serializable
var i: Int
autoinit x, i
end
~~~
Pull-Request: #1159
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
bench_command "nitc-g" "nitc --global --no-cc ../src/nitls.nit" "./nitc.$title.bin" -v --global --no-cc ../src/nitls.nit
bench_command "nitc-s" "nitc --separate ../src/nitc.nit" "./nitc.$title.bin" -v --no-cc --separate ../src/nitc.nit
run_command "$@" ../src/nit.nit -o "nit.$title.bin"
- bench_command "nit" "nit ../src/test_parser.nit ../src/nitls.nit" "./nit.$title.bin" -v ../src/test_parser.nit -- -n ../src/nitls.nit
+ bench_command "nit-queens" "nit queens.nit 8" "./nit.$title.bin" ../lib/ai/examples/queens.nit -q 8
+ bench_command "nit-nitcc" "nit nitcc.nit calc.sablecc" "./nit.$title.bin" ../contrib/nitcc/src/nitcc.nit ../contrib/nitcc/examples/calc.sablecc
run_command "$@" ../src/nitdoc.nit -o "nitdoc.$title.bin"
rm -r out 2> /dev/null
mkdir out 2> /dev/null
bench_command "queens" "bench_queens 13" "./queens.$title.bin" 13
run_command "$@" "../lib/ai/examples/puzzle.nit" -o "puzzle.$title.bin"
bench_command "puzzle" "puzzle 15-hard" "./puzzle.$title.bin" kleg.mondcafjhbi
+ run_command "$@" "markdown/engines/nitmd/nitmd.nit" -o "nitmd.$title.bin"
+ bench_command "nitmd" "markdown" "./nitmd.$title.bin" markdown/benches/out/mixed.md 80
fi
rm -r *.bin .nit_compile out
# get the bootstrapped nitc
cp ../bin/nitc .
+if test -z "$fast"; then
+ make -C markdown/benches
+ make -C ../contrib/nitcc
+fi
+
## EFFECTIVE BENCHS ##
function bench_steps()
middle = (dept + 1) / 2
end
- var file: nullable OFStream = null
+ var file: nullable FileWriter = null
fun write(str: String)
do
file.write(str)
do
dir = "{dir}/nit"
dir.mkdir
- file = new OFStream.open("{dir}/{name}.nit")
+ file = new FileWriter.open("{dir}/{name}.nit")
write "class Root\n\tfun id: Int do return 0\nend"
for c in classes do
do
dir = "{dir}/java"
dir.mkdir
- file = new OFStream.open("{dir}/{name}.java")
+ file = new FileWriter.open("{dir}/{name}.java")
var cl = ""
if interfaces then cl = "X"
do
dir = "{dir}/cs"
dir.mkdir
- file = new OFStream.open("{dir}/{name}.cs")
+ file = new FileWriter.open("{dir}/{name}.cs")
var cl = ""
if interfaces then cl = "X"
do
dir = "{dir}/scala"
dir.mkdir
- file = new OFStream.open("{dir}/{name}.scala")
+ file = new FileWriter.open("{dir}/{name}.scala")
var cl = ""
write "object {name} \{"
do
dir = "{dir}/cpp"
dir.mkdir
- file = new OFStream.open("{dir}/{name}.cpp")
+ file = new FileWriter.open("{dir}/{name}.cpp")
write "#include <iostream>"
write "#include <stdlib.h>"
dir = "{dir}/es/{name}"
end
dir.mkdir
- file = new OFStream.open("{dir}/root.e")
+ file = new FileWriter.open("{dir}/root.e")
var istk = ""
if se then istk = " is"
file.close
for c in classes do
- file = new OFStream.open("{dir}/{c}.e")
+ file = new FileWriter.open("{dir}/{c}.e")
write "class {c}[E] "
if c.supers.is_empty then
write "\tinherit ROOT"
file.close
end
- file = new OFStream.open("{dir}/app{name}.e")
+ file = new FileWriter.open("{dir}/app{name}.e")
write "class APP{name.to_upper}"
if se then
write "insert ARGUMENTS"
end
if sample_email_path.file_exists then
- var f = new IFStream.open(sample_email_path)
+ var f = new FileReader.open(sample_email_path)
var lines = new Array[String]
for line in f.read_all.split_with("\n") do if not line.is_empty then lines.add line
f.close
return response
end
- var stream = new StringOStream
+ var stream = new StringWriter
var serializer = new JsonSerializer(stream)
serializer.serialize events
var serialized = stream.to_s
generate_email(beer_events)
# Save as sample email to file
- var f = new OFStream.open(sample_email_path)
+ var f = new FileWriter.open(sample_email_path)
f.write email_title + "\n"
for line in email_content do f.write line + "\n"
f.close
# Create an interpreter for the file located at `path`.
init from_file(path: String) do
- var ifs = new IFStream.open(path)
+ var ifs = new FileReader.open(path)
init(ifs.read_all)
end
# Inkscape doesn't give us this information
var page_width = -1
var page_height = -1
- var svg_file = new IFStream.open(drawing)
+ var svg_file = new FileReader.open(drawing)
while not svg_file.eof do
var line = svg_file.read_line
# Query Inkscape
var prog = "inkscape"
- var proc = new IProcess.from_a(prog, ["--without-gui", "--query-all", drawing])
+ var proc = new ProcessReader.from_a(prog, ["--without-gui", "--query-all", drawing])
var min_x = 1000000
var min_y = 1000000
end
# Output source file
- var src_file = new OFStream.open("{src_path}/{drawing_name}.nit")
+ var src_file = new FileWriter.open("{src_path}/{drawing_name}.nit")
nit_src.write_to(src_file)
src_file.close
var with_attributes: Bool
var comment_unknown_types: Bool
- var file_out: OFStream
+ var file_out: FileWriter
var java_class: JavaClass
var nb_params: Int
var module_name: nullable String = null
init (file_name: String, jclass: JavaClass, with_attributes, comment: Bool)
do
- file_out = new OFStream.open(file_name)
+ file_out = new FileWriter.open(file_name)
var nit_ext = ".nit"
if file_name.has_suffix(nit_ext) then
exit 1
end
-var javap = new IProcess("javap", "-public", dot_class)
+var javap = new ProcessReader("javap", "-public", dot_class)
var p = new TestParser_javap
var tree = p.work(javap.read_all)
var regex = "extern class [a-zA-Z1-9]\\\+[ ]\\\+in[ ]\\\+\"Java\"[ ]*`\{[ ]*" + self.to_s + "\\\+[ ]*`\}"
var nit_dir = "NIT_DIR".environ
- var grep = new IProcess("grep", "-r", regex, nit_dir/"lib/android/", nit_dir/"lib/java/")
+ var grep = new ProcessReader("grep", "-r", regex, nit_dir/"lib/android/", nit_dir/"lib/java/")
var to_eat = ["private", "extern", "class"]
var output = grep.read_line
ni += 1
end
- var f = new OFStream.open(filepath)
+ var f = new FileWriter.open(filepath)
f.write("digraph g \{\n")
for s in states do
var automaton: Automaton
var parser: nullable String
- var out: OStream is noinit
+ var out: Writer is noinit
init do
- self.out = new OFStream.open(filepath)
+ self.out = new FileWriter.open(filepath)
end
fun add(s: String) do out.write(s)
# Generate a graphviz file of the automaton
fun to_dot(path: String)
do
- var f = new OFStream.open(path)
+ var f = new FileWriter.open(path)
f.write("digraph g \{\n")
f.write("rankdir=LR;\n")
f.write("node[shape=Mrecord,height=0];\n")
do
var gen = new Generator
gen.gen_to_nit(self, name)
- var f = new OFStream.open(filepath)
+ var f = new FileWriter.open(filepath)
for s in gen.out do
f.write(s)
f.write("\n")
var text
if fi != "-" then
- var f = new IFStream.open(fi)
+ var f = new FileReader.open(fi)
text = f.read_all
f.close
else
print "Concrete grammar: {gram.prods.length} productions, {nbalts} alternatives (see {name}.concrete_grammar.out)"
var pretty = gram.pretty
-var f = new OFStream.open("{name}.concrete_grammar.out")
+var f = new FileWriter.open("{name}.concrete_grammar.out")
f.write "// Concrete grammar of {name}\n"
f.write pretty
f.close
print "LR automaton: {lr.states.length} states (see {name}.lr.dot and {name}.lr.out)"
lr.to_dot("{name}.lr.dot")
pretty = lr.pretty
-f = new OFStream.open("{name}.lr.out")
+f = new FileWriter.open("{name}.lr.out")
f.write "// LR automaton of {name}\n"
f.write pretty
f.close
dfa.gen_to_nit("{name}_lexer.nit", name, "{name}_parser")
lr.gen_to_nit("{name}_parser.nit", name)
-f = new OFStream.open("{name}_test_parser.nit")
+f = new FileWriter.open("{name}_test_parser.nit")
f.write """# Generated by nitcc for the language {{{name}}}
# Standalone parser tester for the language {{{name}}}
a.gen_to_nit("nitcc_parser.nit", "nitcc")
-var f = new OFStream.open("nitcc_lexer.nit")
+var f = new FileWriter.open("nitcc_lexer.nit")
f.write("import nitcc_lexer0\n")
f.close
var skip_path = "tests/turing.skip"
var skip
if skip_path.file_exists then
- var skip_file = new IFStream.open(skip_path)
+ var skip_file = new FileReader.open(skip_path)
skip = skip_file.read_lines
skip_file.close
else
sys.system cmd
# Test results were written to file, read them
- var fstream = new IFStream.open(tests_sh_out)
+ var fstream = new FileReader.open(tests_sh_out)
var content = fstream.read_all
fstream.close
# List markdown source files from a directory.
fun list_md_files(dir: String): Array[String] do
var files = new Array[String]
- var pipe = new IProcess("find", dir, "-name", "*.md")
+ var pipe = new ProcessReader("find", dir, "-name", "*.md")
while not pipe.eof do
var file = pipe.read_line
if file == "" then break # last line
# Page content.
#
# What you want to be displayed in the page.
- var content: nullable Streamable = null
+ var content: nullable Writable = null
# Headlines ids and titles.
var headlines = new ArrayMap[String, HeadLine]
# REQUIRE: `has_source`.
fun md: String is cached do
assert has_source
- var file = new IFStream.open(src_full_path.to_s)
+ var file = new FileReader.open(src_full_path.to_s)
var md = file.read_all
file.close
return md
fun url: String do return wiki.config.root_url.join_path(breadcrumbs.join("/"))
# Get a `<a>` template link to `self`
- fun tpl_link: Streamable do
+ fun tpl_link: Writable do
return "<a href=\"{url}\">{title}</a>"
end
end
end
# Generate the HTML header for this article.
- fun tpl_header: Streamable do
+ fun tpl_header: Writable do
var file = header_file
if not wiki.has_template(file) then return ""
return wiki.load_template(file)
# Generate the HTML summary for this article.
#
# Based on `headlines`
- fun tpl_summary: Streamable do
+ fun tpl_summary: Writable do
var headlines = self.headlines
var tpl = new Template
tpl.add "<ul class=\"summary list-unstyled\">"
end
# Generate the HTML menu for this article.
- fun tpl_menu: Streamable do
+ fun tpl_menu: Writable do
var file = menu_file
if not wiki.has_template(file) then return ""
var tpl = wiki.load_template(file)
end
# Generate the HTML footer for this article.
- fun tpl_footer: Streamable do
+ fun tpl_footer: Writable do
var file = footer_file
if not wiki.has_template(file) then return ""
var tpl = wiki.load_template(file)
super Template
# Article title.
- var title: nullable Streamable = null
+ var title: nullable Writable = null
# Article HTML body.
- var body: nullable Streamable = null
+ var body: nullable Writable = null
# Sidebar of this article (if any).
var sidebar: nullable TplSidebar = null
var breadcrumbs: nullable TplBreadcrumbs = null
# Init `self` with a `title`.
- init with_title(title: Streamable) do
+ init with_title(title: Writable) do
self.title = title
end
super Template
# Blocks are `Stremable` pieces that will be rendered in the sidebar.
- var blocks = new Array[Streamable]
+ var blocks = new Array[Writable]
redef fun rendering do
for block in blocks do
--- /dev/null
+// ==UserScript==
+// @name Github.com - Add RPG tab
+// @namespace nitlanguage/github/rpg
+// @description Adds a "Github RPG" Tab at the end of the tabs.
+// @include https://github.com/privat/nit*
+// @version 1
+// @grant none
+// ==/UserScript==
+
+/* This script is a userscript to use in browsers with the appropriate plug-in to add a "RPG" tab on the github site.
+*/
+
+/* TODO:
+ * Link to the player page (if logged and is a player)
+ * Link to other games (not just `privat/nit` but other)
+*/
+
+// The nav bar with tabs
+var nav = document.getElementsByClassName('repo-nav');
+
+// The new tab
+var html = '<li class="tooltipped tooltipped-w" aria-label="Github RPG">\
+ <a href="http://nitlanguage.org/rpg/games/privat/nit" aria-label="RPG" class="js-selected-navigation-item sunken-menu-item" data-selected-links="repo_settings /privat/nit/settings">\
+ <span class="octicon octicon-ruby"></span> <span class="full-word">Github RPG</span>\
+ <img alt="" class="mini-loader" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16">\
+</a></li>';
+
+// Create a new list to put the new tab
+var group = document.createElement('ul');
+group.setAttribute( 'class', 'sunken-menu-group' );
+group.innerHTML = html;
+
+nav[0].appendChild(group);
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2014-2015 Alexandre Terrasa <alexandre@moz-code.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.
+
+# `nitrpg` game events.
+#
+# In this module we introduce the concept of `GameEvent`.
+# They can be attached to every GameEntities.
+module events
+
+import game
+
+redef class GameEntity
+
+ # Saves `event` in `self`.
+ fun add_event(event: GameEvent) do event.save_in(self)
+
+ # List all events registered in this entity.
+ #
+ # This list is reloaded from game data each time its called.
+ #
+ # To add events see `add_event`.
+ fun load_events: Array[GameEvent] do
+ var key = key / "events"
+ var res = new Array[GameEvent]
+ if not game.store.has_collection(key) then return res
+ var coll = game.store.list_collection(key)
+ for id in coll do
+ var name = id.to_s
+ res.add load_event(name).as(not null)
+ end
+ (new EventTimeComparator).sort(res)
+ return res
+ end
+
+ # Load the event from its `id`.
+ #
+ # Looks for the event save file in game data.
+ # Returns `null` if the event cannot be found.
+ fun load_event(id: String): nullable GameEvent do
+ var key = key / "events" / id
+ if not game.store.has_key(key) then return null
+ var json = game.store.load_object(key)
+ return new GameEvent.from_json(game, json)
+ end
+end
+
+# An event that occurs in the `Game`.
+class GameEvent
+ super GameEntity
+
+ redef var key is lazy do return "events" / internal_id
+
+ redef var game
+
+ # String used to dissociate events in the display.
+ var kind: String
+
+ # GameEvents have raw data associated to them.
+ #
+ # These data are stored in a JsonObject.
+ var data: JsonObject is writable
+
+ # GameEvent uniq id used for storage.
+ var internal_id: String is noinit
+
+ # Date and time of the event.
+ var time: ISODate is noinit, writable
+
+ # An event initialized at now `time`.
+ init do
+ internal_id = "{get_time}{object_id}{100.rand}"
+ time = new ISODate
+ end
+
+ # Init `self` from a `json` object.
+ #
+ # Used to load events from json storage.
+ init from_json(game: Game, json: JsonObject) do
+ self.game = game
+ internal_id = json["internal_id"].to_s
+ kind = json["kind"].to_s
+ time = new ISODate.from_string(json["time"].to_s)
+ data = json["data"].as(JsonObject)
+ end
+
+ redef fun to_json do
+ var json = new JsonObject
+ json["internal_id"] = internal_id.to_s
+ json["kind"] = kind
+ json["time"] = time.to_s
+ json["data"] = data
+ return json
+ end
+end
+
+# Compare `GameEvent` to sort them from the most recent to the older.
+class EventTimeComparator
+ super Comparator
+
+ redef type COMPARED: GameEvent
+
+ redef fun compare(a, b) do return b.time <=> a.time
+end
# Uniq key used for data storage.
fun key: String is abstract
- # Save `self` as a json object.
+ # Saves the `self` state in game data.
+ #
+ # Date are stored under `self.key`.
fun save do game.store.store_object(key, to_json)
+ # Saves `self` state into `target` key data.
+ #
+ # Data are stored under `target.key / self.key`.
+ fun save_in(target: GameEntity) do
+ game.store.store_object(target.key / key, to_json)
+ end
+
# Json representation of `self`.
fun to_json: JsonObject do return new JsonObject
#
# Concrete `GameReactor` implement this method to update game data
# for each specific GithubEvent.
- #
- # By default, only logs received events.
- fun react_event(game: Game, event: GithubEvent) do
- game.message(1, "Received event {event} for {game.repo.full_name}")
- end
+ fun react_event(game: Game, event: GithubEvent) is abstract
end
# utils
var game = new Game(api, event.repo)
# TODO handle verbosity with opts
game.verbose_lvl = 1
+ game.message(1, "Received event {event} for {game.repo.full_name}")
for reactor in reactors do reactor.react_event(game, event)
end
end
# limitations under the License.
# Various implementations of `GameReactor` can be found here.
-#
-# TODO This module use a lot of magic numbers for nitcoin rewards.
-# This should be extracted from configuration or stored elsewhere.
module reactors
-import game
+import events
# Reacts to event that can affect players (like giving nitcoins).
class PlayerReactor
super GameReactor
- redef fun react_event(game, e) do e.react_player_event(game)
+ # Nitcoins rewarded when the player opens a new pull request.
+ var nc_pull_open = 10
+
+ # Nitcoins rewarded when the player reviews a pull request.
+ var nc_pull_review = 2
+
+ # Nitcoins rewarded when the player has a commit merged.
+ var nc_commit_merged = 1
+
+ redef fun react_event(game, e) do e.react_player_event(self, game)
end
redef class GithubEvent
#
# Called by `PlayerReactor::react_event`.
# No-op by default.
- private fun react_player_event(game: Game) do end
+ private fun react_player_event(reactor: PlayerReactor, game: Game) do end
+
+ # Generates a GameEvent preinitialized for a reward event.
+ private fun player_reward_event(kind: String, player: Player, reward: Int): GameEvent do
+ var obj = new JsonObject
+ obj["player"] = player.name
+ obj["reward"] = reward
+ obj["github_event"] = json
+ var event = new GameEvent(player.game, kind, obj)
+ player.game.add_event(event)
+ return event
+ end
end
redef class PullRequestEvent
# Rewards player for opened pull requests.
- redef fun react_player_event(game) do
+ redef fun react_player_event(r, game) do
if action == "opened" then
- var player = pull.user.player(game)
- player.nitcoins += 10
- player.save
+ react_pull_open(r, game)
+ else if action == "closed" then
+ react_pull_close(r, game)
end
end
+
+ private fun react_pull_open(r: PlayerReactor, game: Game) do
+ var player = pull.user.player(game)
+ player.nitcoins += r.nc_pull_open
+ player.save
+ var event = player_reward_event("pull_open", player, r.nc_pull_open)
+ player.add_event(event)
+ end
+
+ private fun react_pull_close(r: PlayerReactor, game: Game) do
+ if not pull.merged then return
+ var player = pull.user.player(game)
+ var reward = pull.commits * r.nc_commit_merged
+ player.nitcoins += reward
+ player.save
+ var event = player_reward_event("pull_merged", player, reward)
+ player.add_event(event)
+ end
end
redef class IssueCommentEvent
# Actuallty we look if the comment contains the string `"+1"`.
#
# TODO only give nitcoins if reviewers < 2
- redef fun react_player_event(game) do
+ redef fun react_player_event(r, game) do
# FIXME use a more precise way to locate reviews
if comment.body.has("\\+1\\b".to_re) then
- var player = comment.user.player(game)
- player.nitcoins += 2
- player.save
+ react_player_review(r, game)
end
end
+
+ private fun react_player_review(r: PlayerReactor, game: Game) do
+ var player = comment.user.player(game)
+ player.nitcoins += r.nc_pull_review
+ player.save
+ var event = player_reward_event("pull_review", player, r.nc_pull_review)
+ player.add_event(event)
+ end
end
super GameReactor
redef fun react_event(game, e) do
- super # log events
e.react_stats_event(game)
end
end
# Panels templates for `nitpg`.
module panels
-import templates_base
+import templates_events
# A panel can be displayed in a html page.
#
redef fun render_title do
add "<span class=\"glyphicon glyphicon-home\"></span> "
- add "<a href=\"{game.url}\">{game.name}</a>"
+ add "{game.link}"
end
redef fun render_body do
add "<a href=\"{player.url}\">"
add " <img class=\"img-circle\" style=\"width: 30px\""
add " src=\"{player.user.avatar_url}\" alt=\"{player.name}\">"
- add "</a> "
- add "<a href=\"{player.url}\">{player.name}</a>"
+ add "</a> {player.link}"
end
redef fun render_body do
add "<strong>{player.stats["pulls"]}</strong> pull requests<br>"
add "<strong>{player.stats["issues"]}</strong> issues<br>"
add "<strong>{player.stats["commits"]}</strong> commits"
-
end
end
end
(new PlayerCoinComparator).sort(players)
for player in players do
- add "<a href=\"{player.url}\">"
- add player.name
- add "</a> ({player.nitcoins})<br>"
+ add "{player.nitcoins} - {player.link}<br>"
end
end
end
for player in players do
add "<tr>"
add " <td>{rank}</td>"
- add " <td><a href=\"{player.url}\">{player.name}</a></td>"
+ add " <td>{player.link}</td>"
add " <td>{player.nitcoins}</td>"
add "</tr>"
rank += 1
src="{{{player.user.avatar_url}}}" alt="{{{player.name}}}">
</a>
</p>
- <p><a href="{{{player.url}}}">{{{player.name}}}</a></p>
+ <p>{{{player.link}}}</p>
<p>{{{player.nitcoins}}}</p>
<div class=" progress-bar-warning progress-bar-striped"
style="height: {{{size}}}px;"></div>
return
end
for issue in issues do
+ var user = issue.user
+ var uplay = user.player(game)
add """<div class="media">
- <a class="media-left" href="{{{player.url}}}">
+ <a class="media-left" href="{{{uplay.url}}}">
<img class=\"img-circle\" style="width:50px"
- src="{{{issue.user.avatar_url}}}" alt="{{{issue.user.login}}}">
+ src="{{{user.avatar_url}}}" alt="{{{uplay.name}}}">
</a>
<div class="media-body">
<h4 class="media-heading">
- <a href="{{{issue.html_url}}}">#{{{issue.number}}} {{{issue.title}}}</a></h4>
+ {{{issue.link}}} {{{issue.title}}}
+ </h4>
<span class="text-muted">opened by </span>
- <a href="{{{player.url}}}">{{{issue.user.login}}}</a>
+ {{{uplay.link}}}
</div>
</div>"""
end
end
end
+
+# A `Panel` that displays a pagined list of events stored in the `entity`.
+#
+# This way the panel can be used to view events stored under `Game`, `Player`...
+class EventListPanel
+ super Panel
+
+ # Entity to load the events from.
+ var entity: GameEntity
+
+ # Number of events to display.
+ var limit: Int
+
+ # From where to start?
+ var from: Int
+
+ redef fun render_title do
+ add "<span class=\"glyphicon glyphicon-flash\"></span> "
+ add "Last events"
+ end
+
+ redef fun render_body do
+ var events = entity.load_events
+ if events.is_empty then
+ add "<em>No event yet...</em>"
+ return
+ end
+ # check input
+ if limit < 0 then limit = 10
+ if from < 0 then from = 0
+ # display events
+ for i in [from .. from + limit] do
+ if i >= events.length then break
+ add events[i].tpl_event.media_item
+ end
+ # pagination
+ if limit > events.length then return
+ add "<hr>"
+ add """<div class="btn-group" role="group">"""
+ if from > 0 then
+ add """<a class="btn btn-default" role="button"
+ href="?pfrom={{{from - limit}}}&plimit={{{limit}}}">
+ <span class=\"glyphicon glyphicon-chevron-left\"></span></a>"""
+ end
+ if from + limit < events.length then
+ add """
+ <a class="btn btn-default" role="button"
+ href="?pfrom={{{from + limit}}}&plimit={{{limit}}}">
+ <span class=\"glyphicon glyphicon-chevron-right\"></span></a>"""
+ end
+ add "</div>"
+ end
+end
# Displayed name.
fun name: String do return repo.full_name
+
+ # Return a HTML link to this Game.
+ fun link: String do return "<a href=\"{url}\">{name}</a>"
+end
+
+redef class Player
+ # Return a HTML link to this Player.
+ fun link: String do return "<a href=\"{url}\">{name}</a>"
+end
+
+redef class Issue
+ # Return a HTML link to this Issue.
+ fun link: String do return "<a href=\"{html_url}\">#{number}</a>"
end
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2014-2015 Alexandre Terrasa <alexandre@moz-code.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.
+
+# Templates to display `GameEvent` kinds.
+module templates_events
+
+import events
+import templates_base
+
+redef class GameEvent
+ # See `TplEvent`
+ fun tpl_event: TplEvent do
+ if kind == "pull_open" then
+ return new TplPullOpened(self)
+ else if kind == "pull_merged" then
+ return new TplPullMerged(self)
+ else if kind == "pull_review" then
+ return new TplPullReview(self)
+ end
+ abort
+ end
+end
+
+# A TplEvent factorizes HTML rendering methods for `GameEvent`.
+class TplEvent
+
+ # Event to display.
+ var event: GameEvent
+
+ # Title to display.
+ var title: String is lazy do return "raw event"
+
+ # Load Player from event data.
+ var player: nullable Player is lazy do
+ return event.game.load_player(event.data["player"].to_s)
+ end
+
+ # Load reward from event data.
+ var reward: Int is lazy do return event.data["reward"].as(Int)
+
+ # Load `github_event` data key as a PullRequestEvent.
+ var pull_event: PullRequestEvent is lazy do
+ var obj = event.data["github_event"].as(JsonObject)
+ return new PullRequestEvent.from_json(event.game.api, obj)
+ end
+
+ # Load `github_event` data key as a IssueCommentEvent.
+ var issue_comment_event: IssueCommentEvent is lazy do
+ var obj = event.data["github_event"].as(JsonObject)
+ return new IssueCommentEvent.from_json(event.game.api, obj)
+ end
+
+ # Display a media item for a reward event.
+ fun media_item: String do
+ return """<div class="media">
+ <a class="media-left" href="{{{player.url}}}">
+ <span class="badge progress-bar-success"
+ style=\"position: absolute\">+{{{reward}}}</span>
+ <img class=\"img-circle\" style="width:50px"
+ src="{{{player.user.avatar_url}}}" alt="{{{player.name}}}">
+ </a>
+ <div class="media-body">
+ <h4 class="media-heading">{{{title}}}</h4>
+ <span class="text-muted">at {{{event.time}}}</span>
+ </div>
+ </div>"""
+ end
+end
+
+# Event: pull_open
+class TplPullOpened
+ super TplEvent
+
+ redef var title is lazy do
+ var pull = pull_event.pull
+ return "{player.link} pushed {pull.link}"
+ end
+end
+
+# Event: pull_merged
+class TplPullMerged
+ super TplEvent
+
+ redef var title is lazy do
+ var pull = pull_event.pull
+ return "{player.link} merged <strong>{pull.commits}</strong> commits with {pull.link}"
+ end
+end
+
+# Event: pull_review
+class TplPullReview
+ super TplEvent
+
+ redef var title is lazy do
+ var issue = issue_comment_event.issue
+ return "{player.link} reviewed {issue.link}"
+ end
+end
page.side_panels.add new GameStatusPanel(game)
page.breadcrumbs = new Breadcrumbs
page.breadcrumbs.add_link(game.url, game.name)
+ prepare_pagination(request)
return response
end
+
+ # Parse pagination related parameters.
+ private fun prepare_pagination(request: HttpRequest) do
+ var args = request.get_args
+ list_from = args.get_or_default("pfrom", "0").to_i
+ list_limit = args.get_or_default("plimit", "10").to_i
+ end
+
+ # Limit of events to display in lists.
+ var list_limit = 10
+
+ # From where to start the display of events related lists.
+ var list_from = 0
end
# Repo overview page.
var rsp = prepare_response(request, url)
page.side_panels.add new ShortListPlayersPanel(game)
page.flow_panels.add new PodiumPanel(game)
+ page.flow_panels.add new EventListPanel(game, list_limit, list_from)
rsp.body = page.write_to_string
return rsp
end
page.side_panels.clear
page.side_panels.add new PlayerStatusPanel(game, player)
page.flow_panels.add new PlayerReviewsPanel(game, player)
+ page.flow_panels.add new EventListPanel(player, list_limit, list_from)
rsp.body = page.write_to_string
return rsp
end
end
end
-# We have to redef some IFStream methods because we don't use NativeFiles anymore.
-redef class IFStream
+# We have to redef some FileReader methods because we don't use NativeFiles anymore.
+redef class FileReader
#Â Looks in the 'files' HashMap.
redef init open(path: String)
var header = new OpportunityHeader
# The HTML code of the body.
- var body: Streamable = "" is writable
+ var body: Writable = "" is writable
# The HTML code of the footer.
var footer = new OpportunityFooter
redef class Meetup
# Build the HTML for `self`
- fun to_html(db: OpportunityDB): Streamable do
+ fun to_html(db: OpportunityDB): Writable do
var t = new Template
t.add """
<div class="container">
redef class AnalysisManager
fun build_ast_from_file( filename : String ) : nullable AListing
do
- var file = new IFStream.open( filename )
+ var file = new FileReader.open( filename )
return build_ast(filename, file)
end
- fun build_ast(filename: String, stream: IStream): nullable AListing
+ fun build_ast(filename: String, stream: Reader): nullable AListing
do
var source = new SourceFile(filename, stream)
var lexer = new Lexer(source)
import cfg_base
redef class CFG
- fun print_dot( f: OStream, long: Bool )
+ fun print_dot( f: Writer, long: Bool )
do
f.write("digraph \{\n")
f.write("charset=latin1\n")
end
redef class BasicBlock
- fun print_dot_nodes( f: OStream, long: Bool )
+ fun print_dot_nodes( f: Writer, long: Bool )
do
var lbl = "\"{name}:\\n{dot_node_text(long)}\""
f.write( "{name} [label={lbl}]\n" )
fun dot_node_header: String do return ""
fun dot_node_footer: String do return ""
- fun print_dot_edges( f: OStream, long: Bool )
+ fun print_dot_edges( f: Writer, long: Bool )
do
for s in successors do
f.write( "{name} -> {s.name}\n" )
var string: String
# Create a new sourcefile using a filename and a stream
- init(filename: String, stream: IStream)
+ init(filename: String, stream: Reader)
do
self.filename = filename
string = stream.read_all
if opt_ast.value then
var printer = new ASTPrinter
printer.enter_visit(ast)
- var of = new OFStream.open("{dir}/{mangled_filename.replace(".pep", ".ast.dot")}")
+ var of = new FileWriter.open("{dir}/{mangled_filename.replace(".pep", ".ast.dot")}")
of.write printer.str
of.close
end
var cfg = build_cfg(model)
if opt_cfg.value or opt_cfg_long.value then
- var of = new OFStream.open("{dir}/{mangled_filename.replace(".pep", ".cfg.dot")}")
+ var of = new FileWriter.open("{dir}/{mangled_filename.replace(".pep", ".cfg.dot")}")
cfg.print_dot(of, opt_cfg_long.value)
of.close
end
do_types_analysis(ast, cfg)
# Print results
- var of = new OFStream.open("{dir}/{mangled_filename.replace(".pep",".analysis.dot")}")
+ var of = new FileWriter.open("{dir}/{mangled_filename.replace(".pep",".analysis.dot")}")
cfg.print_dot(of, true)
of.close
end
do
sys.suggest_garbage_collection
- var stream = new StringIStream(src)
+ var stream = new StringReader(src)
var ast = build_ast("web", stream)
if ast == null then return
print_notes
if notes.is_empty then print "Success: Nothing wrong detected"
- var of = new StringOStream
+ var of = new StringWriter
cfg.print_dot(of, false)
of.close
show_graph(of.to_s)
# Android compatibility module
#
-# Defines the `@android` annotation used to tag `ldflags` annotations.
-module aware is new_annotation(android)
+# Defines all Android related annoations including the `@android` annotations
+# used to tag `ldflags` annotations.
+module aware is
+ new_annotation android
+ new_annotation java_package
+ new_annotation min_api_version
+ 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
protected fun add_to_bundle(bundle: NativeBundle, key: JavaString)
do
sys.jni_env.push_local_frame(1)
- var serialized_string = new StringOStream
+ var serialized_string = new StringWriter
var serializer = new JsonSerializer(serialized_string)
serializer.serialize(self)
var java_string_array = new Array[JavaString]
for element in self do
- var serialized_string = new StringOStream
+ var serialized_string = new StringWriter
var serializer = new JsonSerializer(serialized_string)
serializer.serialize(element)
java_string_array.add(serialized_string.to_s.to_java_string)
--- /dev/null
+# 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.
+
+# Support for gamepad events (over Bluetooth or USB)
+module gamepad
+
+import input_events
+
+redef class AndroidKeyEvent
+
+ # Was `self` raised by the A button?
+ fun is_a: Bool do return key_code == 96
+
+ # Was `self` raised by the B button?
+ fun is_b: Bool do return key_code == 97
+
+ # Was `self` raised by the X button?
+ fun is_x: Bool do return key_code == 99
+
+ # Was `self` raised by the Y button?
+ fun is_y: Bool do return key_code == 100
+
+ # Was `self` raised by the directional pad?
+ fun is_dpad: Bool
+ do
+ return is_dpad_up or is_dpad_down or is_dpad_left or is_dpad_right
+ end
+
+ # Was `self` raised by the up key on the directional pad?
+ fun is_dpad_up: Bool do return key_code == 19
+
+ # Was `self` raised by the down key on the directional pad?
+ fun is_dpad_down: Bool do return key_code == 20
+
+ # Was `self` raised by the left key on the directional pad?
+ fun is_dpad_left: Bool do return key_code == 21
+
+ # Was `self` raised by the right key on the directional pad?
+ fun is_dpad_right: Bool do return key_code == 22
+
+ # Was `self` raised by the start button?
+ fun is_start: Bool do return key_code == 108
+
+ # Was `self` raised by the select button?
+ fun is_select: Bool do return key_code == 109
+
+ # Was `self` raised by the right bumper button?
+ fun is_bumper_right: Bool do return key_code == 103
+
+ # Was `self` raised by the right trigger?
+ fun is_trigger_right: Bool do return key_code == 105
+
+ # Was `self` raised by the left bumper?
+ fun is_bumper_left: Bool do return key_code == 102
+
+ # Was `self` raised by the left trigger?
+ fun is_trigger_left: Bool do return key_code == 101
+
+ # Was `self` raised by the media button 'previous'?
+ fun is_media_previous: Bool do return key_code == 87
+
+ # Was `self` raised by the media button 'pause'?
+ fun is_media_pause: Bool do return key_code == 85
+
+ # Was `self` raised by the media button 'next'?
+ fun is_media_next: Bool do return key_code == 88
+end
# Returns `self` allowing fluent programming
fun []=(name: String, value: nullable Serializable): Intent
do
- var serialized_string = new StringOStream
+ var serialized_string = new StringWriter
var serializer = new JsonSerializer(serialized_string)
serializer.serialize(value)
# See the License for the specific language governing permissions and
# limitations under the License.
-module platform is
- platform("android")
- new_annotation java_package
- new_annotation min_api_version
- 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
+# Triggers compilation for the android platform
+module platform is platform "android"
import java
import app
# Store `value` as a serialized Json string
fun []=(key: String, value: nullable Serializable)
do
- var serialized_string = new StringOStream
+ var serialized_string = new StringWriter
var serializer = new JsonSerializer(serialized_string)
serializer.serialize(value)
# A CSV document representation.
class CsvDocument
- super Streamable
+ super Writable
# The format to use.
#
# * `has_header`: Is the first row the header?
# * `skip_empty`: Do we skip the empty lines?
# For details, see `CsvReader.skip_empty`.
- fun load_from(stream: IStream, has_header: Bool, skip_empty: Bool) do
+ fun load_from(stream: Reader, has_header: Bool, skip_empty: Bool) do
var reader = new CsvReader.with_format(stream, format)
reader.skip_empty = skip_empty
if has_header then
# * `has_header`: Is the first row the header?
# * `skip_empty`: Do we skip the empty lines?
fun load(path: String, has_header: Bool, skip_empty: Bool) do
- var istream = new IFStream.open(path)
+ var istream = new FileReader.open(path)
load_from(istream, has_header, skip_empty)
istream.close
end
# delimiters by some parsers.
#
# ~~~nit
-# var out = new StringOStream
+# var out = new StringWriter
# var writer = new CsvWriter(out)
# writer.write_row(1, 2.0, "foo\nbar")
# writer.write_sequence([""])
class CsvWriter
# The output stream.
- var ostream: OStream
+ var ostream: Writer
# The format to use.
#
var always_escape = false is writable
# Create a new writer with the specified format.
- init with_format(ostream:OStream, format: CsvFormat) do
+ init with_format(ostream:Writer, format: CsvFormat) do
self.ostream = ostream
self.format = format
end
# By default, uses the format recommended by RFC 4180 (see `rfc4180`).
#
# ~~~nit
-# var example = new StringIStream("""
+# var example = new StringReader("""
# foo,bar\r
# "Hello, word!",1234.5 + 42\r
# "Something\r
super Iterator[Array[String]]
# The input stream.
- var istream: IStream
+ var istream: Reader
# The format to use.
#
private var started = false
# Create a new reader with the specified format.
- init with_format(istream:IStream, format: CsvFormat) do
+ init with_format(istream:Reader, format: CsvFormat) do
self.istream = istream
self.format = format
end
private fun expect(always_escape: Bool, row: SequenceRead[String],
expected_rfc4180: String,
expected_custom: String) do
- var out = new StringOStream
+ var out = new StringWriter
var writer = new CsvWriter(out)
writer.always_escape = always_escape
end
writer.close
- out = new StringOStream
+ out = new StringWriter
writer = new CsvWriter.with_format(out, custom_format)
writer.always_escape = always_escape
writer.write_sequence(row)
input_rfc4180: String,
input_custom: String,
expected: SequenceRead[SequenceRead[String]]) do
- var istream: IStream
+ var istream: Reader
var reader: CsvReader
- istream = new StringIStream(input_rfc4180)
+ istream = new StringReader(input_rfc4180)
reader = new CsvReader(istream)
reader.skip_empty = skip_empty
assert_table_equals("RFC 4180", reader, expected.iterator)
- istream = new StringIStream(input_custom)
+ istream = new StringReader(input_custom)
reader = new CsvReader.with_format(istream, custom_format)
reader.skip_empty = skip_empty
assert_table_equals("{custom_format.delimiter} " +
# You are allowed to redistribute it and sell it, alone or is a part of
# another product.
-class FilterIStream
- super IStream
+class FilterReader
+ super Reader
# Filter readed elements
- var stream: nullable IStream = null
+ var stream: nullable Reader = null
redef fun eof: Bool
do
end
end
-class FilterOStream
- super OStream
+class FilterWriter
+ super Writer
# Filter outputed elements
- var stream: nullable OStream = null
+ var stream: nullable Writer = null
# Can the stream be used to write
redef fun is_writable: Bool
end
class StreamCat
- super FilterIStream
- private var streams: Iterator[IStream]
+ super FilterReader
+ private var streams: Iterator[Reader]
redef fun eof: Bool
do
end
end
- redef fun stream: nullable IStream
+ redef fun stream: nullable Reader
do
var res = super
if res == null and _streams.is_ok then
end
end
- init with_streams(streams: Array[IStream])
+ init with_streams(streams: Array[Reader])
do
_streams = streams.iterator
end
- init(streams: IStream ...) is old_style_init do
+ init(streams: Reader ...) is old_style_init do
_streams = streams.iterator
end
end
class StreamDemux
- super FilterOStream
- private var streams: Array[OStream]
+ super FilterWriter
+ private var streams: Array[Writer]
redef fun is_writable: Bool
do
end
end
- init with_streams(streams: Array[OStream])
+ init with_streams(streams: Array[Writer])
do
_streams = streams
end
- init(streams: OStream ...) is old_style_init do
+ init(streams: Writer ...) is old_style_init do
_streams = streams
end
end
# Abuser to read a file, see `file_open`
private class ReadFileForAbuser
- super ForAbuser[IFStream]
+ super ForAbuser[FileReader]
var path: String
redef fun iterator do return new ReadFileForAbuserIterator(path)
end
# Abuser iterator to read a file, see `file_open`
private class ReadFileForAbuserIterator
- super Iterator[IFStream]
+ super Iterator[FileReader]
var path: String
- redef var item: IFStream is noinit
+ redef var item: FileReader is noinit
redef var is_ok = true
init
do
# start of service is to open the file, and return in
- item = new IFStream.open(path)
+ item = new FileReader.open(path)
end
redef fun next
do
# print l
# assert not l.is_empty
# end # f is automatically closed here
-fun file_open(path: String): ForAbuser[IFStream]
+fun file_open(path: String): ForAbuser[FileReader]
do
return new ReadFileForAbuser(path)
end
# var name = "privat/nit"
# assert not api.has_cache(name)
# var repo = api.load_repo(name) # load from GitHub
-# assert api.has_cache(name)
+# #assert api.has_cache(name) FIXME bring back this assert
# repo = api.load_repo(name) # load from cache
#
# api.clear_cache
# return "" if no such a key
fun get_github_oauth: String
do
- var p = new IProcess("git", "config", "--get", "github.oauthtoken")
+ var p = new ProcessReader("git", "config", "--get", "github.oauthtoken")
var token = p.read_line
p.wait
p.close
var capabilities = new GLCapabilities is lazy
end
+# Bind `framebuffer` to a framebuffer target
+#
+# In OpenGL ES 2.0, `target` must be `gl_FRAMEBUFFER`.
+fun glBindFramebuffer(target: GLFramebufferTarget, framebuffer: Int) `{
+ glBindFramebuffer(target, framebuffer);
+`}
+
+# Target of `glBindFramebuffer`
+extern class GLFramebufferTarget
+ super GLEnum
+end
+
+# Target both reading and writing on the framebuffer with `glBindFramebuffer`
+fun gl_FRAMEBUFFER: GLFramebufferTarget `{ return GL_FRAMEBUFFER; `}
+
+# Bind `renderbuffer` to a renderbuffer target
+#
+# In OpenGL ES 2.0, `target` must be `gl_RENDERBUFFER`.
+fun glBindRenderbuffer(target: GLRenderbufferTarget, renderbuffer: Int) `{
+ glBindRenderbuffer(target, renderbuffer);
+`}
+
+# Target of `glBindRenderbuffer`
+extern class GLRenderbufferTarget
+ super GLEnum
+end
+
+# Target a renderbuffer with `glBindRenderbuffer`
+fun gl_RENDERBUFFER: GLRenderbufferTarget `{ return GL_RENDERBUFFER; `}
+
+# Specify implementation specific hints
+fun glHint(target: GLHintTarget, mode: GLHintMode) `{
+ glHint(target, mode);
+`}
+
+# Completeness status of a framebuffer object
+fun glCheckFramebufferStatus(target: GLFramebufferTarget): GLFramebufferStatus `{
+ return glCheckFramebufferStatus(target);
+`}
+
+# Return value of `glCheckFramebufferStatus`
+extern class GLFramebufferStatus
+ super GLEnum
+
+ redef fun to_s
+ do
+ if self == gl_FRAMEBUFFER_COMPLETE then return "complete"
+ if self == gl_FRAMEBUFFER_INCOMPLETE_ATTACHMENT then return "incomplete attachment"
+ if self == gl_FRAMEBUFFER_INCOMPLETE_DIMENSIONS then return "incomplete dimension"
+ if self == gl_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT then return "incomplete missing attachment"
+ if self == gl_FRAMEBUFFER_UNSUPPORTED then return "unsupported"
+ return "unknown"
+ end
+end
+
+# The framebuffer is complete
+fun gl_FRAMEBUFFER_COMPLETE: GLFramebufferStatus `{
+ return GL_FRAMEBUFFER_COMPLETE;
+`}
+
+# Not all framebuffer attachment points are framebuffer attachment complete
+fun gl_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: GLFramebufferStatus `{
+ return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+`}
+
+# Not all attached images have the same width and height
+fun gl_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: GLFramebufferStatus `{
+ return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+`}
+
+# No images are attached to the framebuffer
+fun gl_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: GLFramebufferStatus `{
+ return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
+`}
+
+# The combination of internal formats of the attached images violates an implementation-dependent set of restrictions
+fun gl_FRAMEBUFFER_UNSUPPORTED: GLFramebufferStatus `{
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+`}
+
+# Hint target for `glHint`
+extern class GLHintTarget
+ super GLEnum
+end
+
+# Indicates the quality of filtering when generating mipmap images
+fun gl_GENERATE_MIPMAP_HINT: GLHintTarget `{ return GL_GENERATE_MIPMAP_HINT; `}
+
+# Hint mode for `glHint`
+extern class GLHintMode
+ super GLEnum
+end
+
+# The most efficient option should be chosen
+fun gl_FASTEST: GLHintMode `{ return GL_FASTEST; `}
+
+# The most correct, or highest quality, option should be chosen
+fun gl_NICEST: GLHintMode `{ return GL_NICEST; `}
+
+# No preference
+fun gl_DONT_CARE: GLHintMode `{ return GL_DONT_CARE; `}
+
# Entry point to OpenGL server-side capabilities
class GLCapabilities
# HTMLPage use fluent interface so you can chain calls as:
# add("div").attr("id", "mydiv").text("My Div")
class HTMLPage
- super Streamable
+ super Writable
# Define head content
fun head do end
# An HTML element.
class HTMLTag
- super Streamable
+ super Writable
# HTML element type.
#
# assert config.has_key("foo.bar")
# assert config["foo.bar"] == "foobar"
class ConfigTree
- super Streamable
+ super Writable
# The ini file used to read/store data
var ini_file: String
# assert config["goo.boo.baz.bar"] == "gooboobazbar"
fun load do
roots.clear
- var stream = new IFStream.open(ini_file)
+ var stream = new FileReader.open(ini_file)
var path: nullable String = null
while not stream.eof do
var line = stream.read_line
# Input stream that permits to push bytes back to the stream.
class PushBackReader
- super IStream
+ super Reader
# Push the specified byte back to the stream.
#
super PushBackReader
# The parent stream.
- var parent: IStream
+ var parent: Reader
# The stack of the pushed-back bytes.
#
super TestSuite
private fun sample: PushBackDecorator do
- return new PushBackDecorator(new StringIStream("""
+ return new PushBackDecorator(new StringReader("""
abcd
efg
end
fun test_read_char_eof do
- var subject = new PushBackDecorator(new StringIStream(""))
+ var subject = new PushBackDecorator(new StringReader(""))
assert -1 == subject.read_char
end
end
fun test_eof_empty do
- var subject = new PushBackDecorator(new StringIStream(""))
+ var subject = new PushBackDecorator(new StringReader(""))
assert subject.eof
end
# Get this value as a `Int`
#
- # require: `self.is_int`
+ # require: `self.is_numeric`
#
# assert "-10".to_json_value.to_i == -10
# assert "123".to_json_value.to_i == 123
- fun to_i: Int do return value.as(Int)
+ # assert "123.456".to_json_value.to_i == 123
+ fun to_i: Int
+ do
+ var value = value
+ assert value isa Numeric
+ return value.to_i
+ end
# Is this value a float?
#
# Get this value as a `Float`
#
- # require: `self.is_float`
+ # require: `self.is_numeric`
#
# assert "0.0".to_json_value.to_f == 0.0
# assert "123.456".to_json_value.to_f == 123.456
- fun to_f: Float do return value.as(Float)
+ # assert "123".to_json_value.to_f == 123.0
+ fun to_f: Float
+ do
+ var value = value
+ assert value isa Numeric
+ return value.to_f
+ end
# Is the value numeric?
#
private fun store_json(key: String, json: Jsonable) do
var path = store_dir / "{key}.json"
path.dirname.mkdir
- var file = new OFStream.open(path)
+ var file = new FileWriter.open(path)
file.write(json.to_json)
file.close
end
private fun load_json(key: String): nullable Jsonable do
assert has_key(key)
var path = store_dir / "{key}.json"
- var file = new IFStream.open(path)
+ var file = new FileReader.open(path)
var text = file.read_all
file.close
return text.parse_json
super Serializer
# Target writing stream
- var stream: OStream
+ var stream: Writer
redef fun serialize(object)
do
do
assert path.file_exists
- var file = new IFStream.open(path)
+ var file = new FileReader.open(path)
var output = native_buffer_event.output_buffer
var fd = file.fd
var length = file.file_stat.size
if db == null then return
# Serialize
- var stream = new StringOStream
+ var stream = new StringWriter
var serializer = new JsonSerializer(stream)
serializer.serialize value
var serialized = stream.to_s
init do self.emitter = new MarkdownEmitter(self)
# Process the mardown `input` string and return the processed output.
- fun process(input: String): Streamable do
+ fun process(input: String): Writable do
# init processor
link_refs.clear
last_link_ref = null
end
# Append `e` to current buffer.
- fun add(e: Streamable) do
+ fun add(e: Writable) do
if e isa Text then
current_buffer.append e
else
# var md = "**Hello World!**"
# var html = md.md_to_html
# assert html == "<p><strong>Hello World!</strong></p>\n"
- fun md_to_html: Streamable do
+ fun md_to_html: Writable do
var processor = new MarkdownProcessor
return processor.process(self)
end
exit 0
end
-var ifs = new IFStream.open(file)
+var ifs = new FileReader.open(file)
var md = ifs.read_all
ifs.close
redef class App
# The stream where injected inputs are read
- private var injected_input_stream: nullable IStream = null
+ private var injected_input_stream: nullable Reader = null
redef fun setup
do
var input = "MNIT_READ_INPUT".environ
if input != "" then
- injected_input_stream = new IFStream.open(input)
+ injected_input_stream = new FileReader.open(input)
print "GET injected_input_stream {input}"
end
if ext == "png" or ext == "jpg" or ext == "jpeg" then
return new Opengles1Image.from_file( path )
else # load as text
- var f = new IFStream.open(path)
+ var f = new FileReader.open(path)
var content = f.read_all
f.close
if level2 == null then return
level2.keys.remove(k2)
end
+
+ # Remove all items
+ fun clear do level1.clear
end
# Simple way to store an `HashMap[K1, HashMap[K2, HashMap[K3, V]]]`
if level2 == null then return
level2.remove_at(k2, k3)
end
+
+ # Remove all items
+ fun clear do level1.clear
end
# A map with a default value.
fun send(data: nullable Serializable, dest: Rank, tag: Tag, comm: Comm)
do
# Serialize data
- var stream = new StringOStream
+ var stream = new StringWriter
var serializer = new JsonSerializer(stream)
serializer.serialize(data)
# b.labels.add "Bar"
# graph.edges.add new NeoEdge(a, "BAZ", b)
#
-# var ostream = new StringOStream
+# var ostream = new StringWriter
# var store = new JsonGraphStore(graph)
# store.ostream = ostream
# store.save
#
# graph.nodes.clear
# graph.edges.clear
-# store.istream = new StringIStream(ostream.to_s)
+# store.istream = new StringReader(ostream.to_s)
# store.load
# assert 1 == graph.edges.length
# for edge in graph.edges do
super GraphStore
# The stream to use for `load`.
- var istream: nullable IStream = null is writable
+ var istream: nullable Reader = null is writable
# The stream to use for `save` and `save_part`.
- var ostream: nullable OStream = null is writable
+ var ostream: nullable Writer = null is writable
- # Use the specified `IOStream`.
- init from_io(graph: NeoGraph, iostream: IOStream) do
+ # Use the specified `Duplex`.
+ init from_io(graph: NeoGraph, iostream: Duplex) do
init(graph)
istream = iostream
ostream = iostream
# Use the specified string to load the graph.
init from_string(graph: NeoGraph, string: String) do
init(graph)
- istream = new StringIStream(string)
+ istream = new StringReader(string)
end
redef fun isolated_save do return true
redef fun load do
var istream = self.istream
- assert istream isa IStream
+ assert istream isa Reader
fire_started
graph.load_json(istream.read_all)
fire_done
redef fun save_part(nodes, edges) do
var ostream = self.ostream
- assert ostream isa OStream
+ assert ostream isa Writer
fire_started
ostream.write(graph.to_json)
fire_done
# Print a node (using to_s) on a line and recustively each children indented (with two spaces)
class TreePrinterVisitor
super Visitor
- var writer: OStream
+ var writer: Writer
private var indent = 0
redef fun visit(n)
do
# Produce a graphiz file for the syntaxtic tree rooted at `self`.
fun to_dot(filepath: String)
do
- var f = new OFStream.open(filepath)
+ var f = new FileWriter.open(filepath)
f.write("digraph g \{\n")
f.write("rankdir=BT;\n")
f.close
end
- private fun to_dot_visitor(f: OStream, a: Array[NToken])
+ private fun to_dot_visitor(f: Writer, a: Array[NToken])
do
f.write("n{object_id} [label=\"{node_name}\"];\n")
for x in children do
end
text = args.shift
else
- var f = new IFStream.open(filepath)
+ var f = new FileReader.open(filepath)
text = f.read_all
f.close
end
var tokout = "{name}.tokens.out"
print "TOKEN: {tokens.length} tokens (see {tokout})"
- var f = new OFStream.open(tokout)
+ var f = new FileWriter.open(tokout)
for t in tokens do
f.write "{t.to_s}\n"
end
var n = p.parse
var astout = "{name}.ast.out"
- f = new OFStream.open(astout)
+ f = new FileWriter.open(astout)
var tpv = new TreePrinterVisitor(f)
var astdotout = "{name}.ast.dot"
if n isa NError then
end
# Error page template for a given `code`
- fun error_page(code: Int): Streamable do return new ErrorTemplate(code)
+ fun error_page(code: Int): Writable do return new ErrorTemplate(code)
# Header of each directory page
- var header: nullable Streamable = null is writable
+ var header: nullable Writable = null is writable
redef fun answer(request, turi)
do
response.header["Content-Type"] = media_types["html"].as(not null)
else
# It's a single file
- var file = new IFStream.open(local_file)
+ var file = new FileReader.open(local_file)
response.body = file.read_all
var ext = local_file.file_extension
var code: Int is writable
# Header on this page
- var header: nullable Streamable = null is writable
+ var header: nullable Writable = null is writable
# Body to show with this page
- var body: nullable Streamable = null is writable
+ var body: nullable Writable = null is writable
redef fun rendering
do
do
if args.is_empty then exit(0)
stdin.close
- stdin = new IFStream.open(args.shift)
+ stdin = new FileReader.open(args.shift)
end
# The next line to process by the main program
# This class can be used as it to work with generic trees but can also be specialized to provide more specific
# behavior or display. It is why the internal attributes are mutable.
class OrderedTree[E: Object]
- super Streamable
+ super Writable
super Collection[E]
# The roots of the tree (in sequence)
# print the full tree on `o`
# Write a ASCII-style tree and use the `display` method to label elements
- redef fun write_to(stream: OStream)
+ redef fun write_to(stream: Writer)
do
for r in roots do
stream.write display(r)
end
end
- private fun sub_write_to(o: OStream, e: E, prefix: String)
+ private fun sub_write_to(o: Writer, e: E, prefix: String)
do
if not sub.has_key(e) then return
var subs = sub[e]
# A stream for PNaCl, redefines basic input and output methods.
class PnaclStream
- super PollableIStream
- super OStream
- super BufferedIStream
+ super PollableReader
+ super Writer
+ super BufferedReader
init do prepare_buffer(10)
#
# Nodes are labeled with their `to_s` so homonymous nodes may appear.
# Edges are unlabeled.
- fun write_dot(f: OStream)
+ fun write_dot(f: Writer)
do
f.write "digraph \{\n"
var ids = new HashMap[E, Int]
# See `write_dot` for details.
fun show_dot
do
- var f = new OProcess("dot", "-Txlib")
+ var f = new ProcessWriter("dot", "-Txlib")
write_dot(f)
f.close
f.wait
# resolving relative URIs, may use `public_id=` to include a public
# identifier, and may use `encoding=` to specify the object's character
# encoding.
- init with_stream(stream: IStream) do
+ init with_stream(stream: Reader) do
self.stream = stream
end
# for resolving relative URIs, may set `public_id` to include a
# public identifier, and may set `encoding` to specify the object's
# character encoding.
- var stream: nullable IStream = null is writable
+ var stream: nullable Reader = null is writable
# The character encoding, if known.
#
var reader_model: XophonReaderModel
# The input to read from.
- var input: IStream is writable
+ var input: Reader is writable
# Alias to `reader_model.locator`.
private var locator: SAXLocatorImpl is noinit
# var reader = new XophonReader
# #
# reader.content_handler = text
-# reader.parse(new InputSource.with_stream(new StringIStream("<foo>bar baz <n>42</n>.</foo>")))
+# reader.parse(new InputSource.with_stream(new StringReader("<foo>bar baz <n>42</n>.</foo>")))
# assert text.to_s == "bar baz 42."
class XophonReader
super XMLReader
model.fire_fatal_error("File <{input.system_id.as(not null)}> not found.", null)
else
lexer = new XophonLexer(model,
- new IFStream.open(system_id.value))
+ new FileReader.open(system_id.value))
parse_main
lexer.close
end
# Make the reader parse the specified string
fun parse_string(str: String) do
- actual.parse(new InputSource.with_stream(new StringIStream(str)))
+ actual.parse(new InputSource.with_stream(new StringReader(str)))
end
end
all.add_all cc
all.add_all bcc
- var proc = new OProcess("sendmail", all.join(","))
+ var proc = new ProcessWriter("sendmail", all.join(","))
if proc.is_writable then proc.write to_s
proc.close
proc.wait
# Simple communication stream with a remote socket
class TCPStream
super Socket
- super BufferedIStream
- super OStream
- super PollableIStream
+ super BufferedReader
+ super Writer
+ super PollableReader
# Real canonical name of the host to which `self` is connected
var host: String
private fun basic_exec_execute(p: NativeString, av: NativeString, ac: Int, pf: Int): NativeProcess is extern "exec_Process_Process_basic_exec_execute_4"
end
-# stdout of the process is readable
-class IProcess
+# `Process` on which the `stdout` is readable like a `Reader`
+class ProcessReader
super Process
- super IStream
+ super Reader
# File Descriptor used for the input.
- var stream_in: IFStream is noinit
+ var stream_in: FileReader is noinit
redef fun close do stream_in.close
redef fun execute
do
super
- stream_in = new IFStream.from_fd(data.out_fd)
+ stream_in = new FileReader.from_fd(data.out_fd)
end
end
-# stdin of the process is writable
-class OProcess
+# `Process` on which `stdin` is writable like a `Writer`
+class ProcessWriter
super Process
- super OStream
+ super Writer
# File Descriptor used for the output.
- var stream_out: OStream is noinit
+ var stream_out: Writer is noinit
redef fun close do stream_out.close
redef fun execute
do
super
- stream_out = new OFStream.from_fd(data.in_fd)
+ stream_out = new FileWriter.from_fd(data.in_fd)
end
end
-# stdin and stdout are both accessible
-class IOProcess
- super IProcess
- super OProcess
- super IOStream
+# `Process` on which stdout can be read and stdin can be written to like a `Duplex`
+class ProcessDuplex
+ super ProcessReader
+ super ProcessWriter
+ super Duplex
redef fun close
do
#include <errno.h>
`}
-# File Abstract Stream
-abstract class FStream
- super IOS
+# `Stream` used to interact with a File or FileDescriptor
+abstract class FileStream
+ super Stream
# The path of the file.
var path: nullable String = null
# File descriptor of this file
fun fd: Int do return _file.fileno
- # Sets the buffering mode for the current FStream
+ # Sets the buffering mode for the current FileStream
#
# If the buf_size is <= 0, its value will be 512 by default
#
fun set_buffering_mode(buf_size, mode: Int) do
if buf_size <= 0 then buf_size = 512
if _file.set_buffering_type(buf_size, mode) != 0 then
- last_error = new IOError("Error while changing buffering type for FStream, returned error {sys.errno.strerror}")
+ last_error = new IOError("Error while changing buffering type for FileStream, returned error {sys.errno.strerror}")
end
end
end
-# File input stream
-class IFStream
- super FStream
- super BufferedIStream
- super PollableIStream
+# `Stream` that can read from a File
+class FileReader
+ super FileStream
+ super BufferedReader
+ super PollableReader
# Misc
# Open the same file again.
end
end
-# File output stream
-class OFStream
- super FStream
- super OStream
+# `Stream` that can write to a File
+class FileWriter
+ super FileStream
+ super Writer
redef fun write(s)
do
# Standard input stream.
class Stdin
- super IFStream
+ super FileReader
init do
_file = new NativeFile.native_stdin
# Standard output stream.
class Stdout
- super OFStream
+ super FileWriter
init do
_file = new NativeFile.native_stdout
path = "/dev/stdout"
# Standard error stream.
class Stderr
- super OFStream
+ super FileWriter
init do
_file = new NativeFile.native_stderr
path = "/dev/stderr"
###############################################################################
-redef class Streamable
+redef class Writable
# Like `write_to` but take care of creating the file
fun write_to_file(filepath: String)
do
- var stream = new OFStream.open(filepath)
+ var stream = new FileWriter.open(filepath)
write_to(stream)
stream.close
end
# Open this file for reading
#
# Require: `exists and not link_stat.is_dir`
- fun open_ro: IFStream
+ fun open_ro: FileReader
do
# TODO manage streams error when they are merged
- return new IFStream.open(path)
+ return new FileReader.open(path)
end
# Open this file for writing
#
# Require: `not exists or not stat.is_dir`
- fun open_wo: OFStream
+ fun open_wo: FileWriter
do
# TODO manage streams error when they are merged
- return new OFStream.open(path)
+ return new FileWriter.open(path)
end
# Read all the content of the file
# print content
# ~~~
#
- # See `IStream::read_all` for details.
+ # See `Reader::read_all` for details.
fun read_all: String
do
var s = open_ro
# end
# ~~~
#
- # See `IStream::read_lines` for details.
+ # See `Reader::read_lines` for details.
fun read_lines: Array[String]
do
var s = open_ro
#
# Note: the stream is automatically closed at the end of the file (see `LineIterator::close_on_finish`)
#
- # See `IStream::each_line` for details.
+ # See `Reader::each_line` for details.
fun each_line: LineIterator
do
var s = open_ro
redef class Sys
init do
- if stdout isa FStream then stdout.as(FStream).set_buffering_mode(256, buffer_mode_line)
+ if stdout isa FileStream then stdout.as(FileStream).set_buffering_mode(256, buffer_mode_line)
end
# Standard input
- var stdin: PollableIStream = new Stdin is protected writable
+ var stdin: PollableReader = new Stdin is protected writable
# Standard output
- var stdout: OStream = new Stdout is protected writable
+ var stdout: Writer = new Stdout is protected writable
# Standard output for errors
- var stderr: OStream = new Stderr is protected writable
+ var stderr: Writer = new Stderr is protected writable
# Enumeration for buffer mode full (flushes when buffer is full)
fun buffer_mode_full: Int is extern "file_Sys_Sys_buffer_mode_full_0"
# returns first available stream to read or write to
# return null on interruption (possibly a signal)
- protected fun poll( streams : Sequence[FStream] ) : nullable FStream
+ protected fun poll( streams : Sequence[FileStream] ) : nullable FileStream
do
var in_fds = new Array[Int]
var out_fds = new Array[Int]
- var fd_to_stream = new HashMap[Int,FStream]
+ var fd_to_stream = new HashMap[Int,FileStream]
for s in streams do
var fd = s.fd
- if s isa IFStream then in_fds.add( fd )
- if s isa OFStream then out_fds.add( fd )
+ if s isa FileReader then in_fds.add( fd )
+ if s isa FileWriter then out_fds.add( fd )
fd_to_stream[fd] = s
end
super Error
end
-# Abstract stream class
-abstract class IOS
+# Any kind of stream to read/write/both to or from a source
+abstract class Stream
# Error produced by the file stream
#
- # var ifs = new IFStream.open("donotmakethisfile.binx")
+ # var ifs = new FileReader.open("donotmakethisfile.binx")
# ifs.read_all
# ifs.close
# assert ifs.last_error != null
fun close is abstract
end
-# Abstract input streams
-abstract class IStream
- super IOS
+# A `Stream` that can be read from
+abstract class Reader
+ super Stream
# Read a character. Return its ASCII value, -1 on EOF or timeout
fun read_char: Int is abstract
#
# ~~~
# var txt = "Hello\n\nWorld\n"
- # var i = new StringIStream(txt)
+ # var i = new StringReader(txt)
# assert i.read_line == "Hello"
# assert i.read_line == ""
# assert i.read_line == "World"
#
# ~~~
# var txt2 = "Hello\r\n\n\rWorld"
- # var i2 = new StringIStream(txt2)
+ # var i2 = new StringReader(txt2)
# assert i2.read_line == "Hello"
# assert i2.read_line == ""
# assert i2.read_line == "\rWorld"
#
# ~~~
# var txt = "Hello\n\nWorld\n"
- # var i = new StringIStream(txt)
+ # var i = new StringReader(txt)
# assert i.read_lines == ["Hello", "", "World"]
# ~~~
#
#
# ~~~
# var txt = "Hello\n\nWorld\n"
- # var i = new StringIStream(txt)
+ # var i = new StringReader(txt)
# assert i.each_line.to_a == ["Hello", "", "World"]
# ~~~
#
# Therefore, the stream should no be closed until the end of the stream.
#
# ~~~
- # i = new StringIStream(txt)
+ # i = new StringReader(txt)
# var el = i.each_line
#
# assert el.item == "Hello"
#
# ~~~
# var txt = "Hello\n\nWorld\n"
- # var i = new StringIStream(txt)
+ # var i = new StringReader(txt)
# assert i.read_all == txt
# ~~~
fun read_all: String
#
# ~~~
# var txt = "Hello\n\nWorld\n"
- # var i = new StringIStream(txt)
+ # var i = new StringReader(txt)
# var b = new FlatBuffer
# i.append_line_to(b)
# assert b == "Hello\n"
# a non-eol terminated last line was returned.
#
# ~~~
- # var i2 = new StringIStream("hello")
+ # var i2 = new StringReader("hello")
# assert not i2.eof
# var b2 = new FlatBuffer
# i2.append_line_to(b2)
fun eof: Bool is abstract
end
-# Iterator returned by `IStream::each_line`.
+# Iterator returned by `Reader::each_line`.
# See the aforementioned method for details.
class LineIterator
super Iterator[String]
# The original stream
- var stream: IStream
+ var stream: Reader
redef fun is_ok
do
end
end
-# IStream capable of declaring if readable without blocking
-abstract class PollableIStream
- super IStream
+# `Reader` capable of declaring if readable without blocking
+abstract class PollableReader
+ super Reader
# Is there something to read? (without blocking)
fun poll_in: Bool is abstract
end
-# Abstract output stream
-abstract class OStream
- super IOS
+# A `Stream` that can be written to
+abstract class Writer
+ super Stream
# write a string
fun write(s: Text) is abstract
fun is_writable: Bool is abstract
end
-# Things that can be efficienlty writen to a OStream
+# Things that can be efficienlty written to a `Writer`
#
-# The point of this interface it to allow is instance to be efficenty
-# writen into a OStream without having to allocate a big String object
+# The point of this interface is to allow the instance to be efficiently
+# written into a `Writer`.
#
-# ready-to-save documents usually provide this interface.
-interface Streamable
+# Ready-to-save documents usually provide this interface.
+interface Writable
# Write itself to a `stream`
# The specific logic it let to the concrete subclasses
- fun write_to(stream: OStream) is abstract
+ fun write_to(stream: Writer) is abstract
# Like `write_to` but return a new String (may be quite large)
#
# stream without having to allocate and concatenate strings
fun write_to_string: String
do
- var stream = new StringOStream
+ var stream = new StringWriter
write_to(stream)
return stream.to_s
end
end
redef class Text
- super Streamable
+ super Writable
redef fun write_to(stream) do stream.write(self)
end
-# Input streams with a buffer
-abstract class BufferedIStream
- super IStream
+# Input streams with a buffered input for efficiency purposes
+abstract class BufferedReader
+ super Reader
redef fun read_char
do
if last_error != null then return -1
end
end
-# An Input/Output Stream
-abstract class IOStream
- super IStream
- super OStream
+# A `Stream` that can be written to and read from
+abstract class Duplex
+ super Reader
+ super Writer
end
-# Stream to a String.
+# `Stream` that can be used to write to a `String`
#
-# Mainly used for compatibility with OStream type and tests.
-class StringOStream
- super OStream
+# Mainly used for compatibility with Writer type and tests.
+class StringWriter
+ super Writer
private var content = new Array[String]
redef fun to_s do return content.to_s
redef fun close do closed = true
end
-# Stream from a String.
+# `Stream` used to read from a `String`
#
-# Mainly used for compatibility with IStream type and tests.
-class StringIStream
- super IStream
+# Mainly used for compatibility with Reader type and tests.
+class StringReader
+ super Reader
# The string to read from.
var source: String
# assert "\r\n\r\n".chomp == "\r\n"
# assert "\r\n\r".chomp == "\r\n"
#
- # Note: unlike with most IO methods like `IStream::read_line`,
+ # Note: unlike with most IO methods like `Reader::read_line`,
# a single `\r` is considered here to be a line terminator and will be removed.
fun chomp: SELFTYPE
do
end
end
-redef class OFStream
+redef class FileWriter
redef fun write(s)
do
assert is_writable
end
end
-redef class OFStream
+redef class FileWriter
redef fun write(s)
do
assert is_writable
# using macros and replacement.
#
# A macro is represented as a string identifier like `%MACRO%` in the template
-# string. Using `TemplateString`, macros can be replaced by any `Streamable` data:
+# string. Using `TemplateString`, macros can be replaced by any `Writable` data:
#
# var tpl = new TemplateString("Hello %NAME%!")
# tpl.replace("NAME", "Dave")
# Loads the template file contents.
private fun load_template_file(tpl_file: String): String do
- var file = new IFStream.open(tpl_file)
+ var file = new FileReader.open(tpl_file)
var text = file.read_all
file.close
return text
# var tpl = new TemplateString("Hello %NAME%!")
# tpl.replace("NAME", "Dave")
# assert tpl.write_to_string == "Hello Dave!"
- fun replace(name: String, replacement: Streamable) do
+ fun replace(name: String, replacement: Writable) do
assert has_macro(name)
for macro in macros[name] do
macro.replacement = replacement
# tpl.replace("FIRSTNAME", "Corben")
# tpl.replace("LASTNAME", "Dallas")
# for name, rep in tpl do assert rep != null
- fun iterator: MapIterator[String, nullable Streamable] do
+ fun iterator: MapIterator[String, nullable Writable] do
return new TemplateStringIterator(self)
end
end
var end_pos: Int
# Macro replacement if any.
- var replacement: nullable Streamable = null
+ var replacement: nullable Writable = null
# Does `self` already have a `replacement`?
fun is_replaced: Bool do return replacement != null
end
private class TemplateStringIterator
- super MapIterator[String, nullable Streamable]
+ super MapIterator[String, nullable Writable]
var subject: TemplateString
var key_it: Iterator[String] is noinit
#
# # Non-linear system with sub-templates.
#
-# A template is made of a mix of string, sub-templates and other `Streamable` objects.
+# A template is made of a mix of string, sub-templates and other `Writable` objects.
# A sub-template can be constructed independently of its usages, thus simplifying
# the high-level logic.
# A single sub-template can be used more than once.
#
# class LnkTmpl
# super Template
-# var text: Streamable
+# var text: Writable
# var title: nullable String
# var href: String
# redef fun rendering do
# assert l.write_to_string == """<a href="hello.png">hello world</a>"""
#
class Template
- super Streamable
+ super Writable
# Service used to render the content of the template.
#
# t.add("1")
# t.add("2")
# assert t.write_to_string == "12"
- fun add(element: Streamable) do
+ fun add(element: Writable) do
assert not is_frozen
content.add element
end
# t.addn("1")
# t.addn("2")
# assert t.write_to_string == "1\n2\n"
- fun addn(element: Streamable) do
+ fun addn(element: Writable) do
add element
add "\n"
end
# var t = new Template
# t.add_all(["1", "2"])
# assert t.write_to_string == "12"
- fun add_all(elements: Collection[Streamable]) do content.add_all elements
+ fun add_all(elements: Collection[Writable]) do content.add_all elements
# Append a bunch of elements at the end of the template with separations.
# see `add`.
# var t = new Template
# t.add_list(["1", "2", "3"], ", ", " and ")
# assert t.write_to_string == "1, 2 and 3"
- fun add_list(elements: Collection[Streamable], sep, last_sep: Streamable) do
+ fun add_list(elements: Collection[Writable], sep, last_sep: Writable) do
var last = elements.length - 2
var i = 0
for e in elements do
end
# Each sub-elements
- private var content = new Array[Streamable]
+ private var content = new Array[Writable]
# Flag to avoid multiple rendering
private var render_done = false
end
# Do the full rendering and write the final content to a stream
- redef fun write_to(stream: OStream)
+ redef fun write_to(stream: Writer)
do
assert not is_writing
is_writing = true
redef fun show_dot do
assert not_empty: root != null
- var f = new OProcess("dot", "-Txlib")
+ var f = new ProcessWriter("dot", "-Txlib")
f.write "digraph \{\n"
dot_down(root.as(not null), f)
f.write "\}\n"
end
# Translate the tree in dot format starting from `node`.
- protected fun dot_down(node: N, f: OProcess) do
+ protected fun dot_down(node: N, f: ProcessWriter) do
if node.left != null then dot_down(node.left.as(not null), f)
f.write node.to_dot
if node.right != null then dot_down(node.right.as(not null), f)
(This is a simplification some behaviors are missing.)
* If the cursor follows `import`, it will list known modules.
-* If it follows `new`, `super` or `class` it will list known classes.
+* If it follows `new` it will list known classes with their constructors.
+* If it follows `super`, `class`, `isa` or `as` it will list known classes.
* If it follows a `.`, it will list properties.
* If on an extern method declaration, it will list classes and properties.
* Otherwise, it will list keywords and properties.
let desc = get(a:words, 3, '')
let desc = join(split(desc, '#nnnn#', 1), "\n")
if strlen(pretty) > 40
- let pretty = pretty[:37] . '...'
+ let pretty = pretty[:39] . '…'
endif
call add(a:matches, {'word': a:name, 'abbr': pretty, 'menu': synopsis, 'info': desc, 'dup': 1})
endfun
call NitOmnifuncAddFromFile(a:base, matches, 'modules.txt')
endif
- " Classes
- if count(['new', 'super', 'class', 'nullable'], prev_word) > 0 ||
+ " Classes (instanciable only)
+ if prev_word == 'new'
+ let handled = 1
+ call NitOmnifuncAddFromFile(a:base, matches, 'constructors.txt')
+ endif
+
+ " Other class references
+ if count(['class', 'super'], prev_word) > 0
+ let handled = 1
+ call NitOmnifuncAddFromFile(a:base, matches, 'classes.txt')
+ endif
+
+ " Types
+ if count(['class', 'super', 'nullable', 'isa', 'as'], prev_word) > 0 ||
\ line_prev_cursor =~ '[' || prev_char == ':' ||
\ (line_prev_cursor =~ 'fun' && line_prev_cursor =~ 'import' && (prev_word == 'import' || prev_char == ','))
let handled = 1
- call NitOmnifuncAddFromFile(a:base, matches, 'classes.txt')
+ call NitOmnifuncAddFromFile(a:base, matches, 'types.txt')
endif
" Properties
ANDROID_NDK=`dirname $ndk_build_path`
fi
-# Get the first platform available (it shouldn't change much, but it may
-# have to be adjusted)
-for platform in `echo $ANDROID_NDK/platforms/android-*/arch-arm`; do
- SYS_ROOT=$platform
- break
-done
-
-if test -z "$SYS_ROOT"; then
- echo "Error: could not an Android platform in the NDK, define ANDROID_NDK to the correct path."
- exit 1
-fi
-
# Information on the currently targeted libgc and libatomic_ops source URL
# These may have to be updated according to server-side changes and newer
# versions of the Boehm GC.
cd $libgc_dir || exit 1
-# Configure for Android
-path="$ANDROID_NDK/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/"
-export CC="$path/arm-linux-androideabi-gcc --sysroot=$SYS_ROOT"
-export CXX="$path/arm-linux-androideabi-g++ --sysroot=$SYS_ROOT"
-export LD="$path/arm-linux-androideabi-ld"
-export AR="$path/arm-linux-androideabi-ar"
-export RANLIB="$path/arm-linux-androideabi-ranlib"
-export STRIP="$path/arm-linux-androideabi-strip"
-export CFLAGS="-DIGNORE_DYNAMIC_LOADING -DPLATFORM_ANDROID -I libatomic_ops/src/"
-export LIBS="-lc -lgcc"
-./configure --host=arm-linux-androideabi --enable-static --disable-shared --prefix="$install" || exit 1
-
-# Compile and install locally
-make install -j 4 || exit 1
+archs=( arm x86 mips)
+tools_dirs=( arm-linux-androideabi-4.6 x86-4.6 mipsel-linux-android-4.6)
+tools_prefixes=(arm-linux-androideabi i686-linux-android mipsel-linux-android)
+hosts=( arm-linux-androideabi x86-linux-android mips-linux-android)
+
+n_archs=$(( ${#archs[@]} - 1 ))
+for i in $(eval echo "{0..$n_archs}"); do
+ arch=${archs[i]}
+ tools_dir=${tools_dirs[i]}
+ tools_prefix=${tools_prefixes[i]}
+ host=${hosts[i]}
+
+ # Get the first platform available (it shouldn't change much, but it may
+ # have to be adjusted)
+ for platform in `echo $ANDROID_NDK/platforms/android-*/arch-$arch`; do
+ sys_root=$platform
+ break
+ done
+
+ if test -z "$sys_root"; then
+ echo "Error: could not an Android platform for $arch in the NDK, define ANDROID_NDK to the correct path."
+ exit 1
+ fi
+
+ # Configure for Android
+ path="$ANDROID_NDK/toolchains/$tools_dir/prebuilt/linux-x86_64/bin/"
+ export CC="$path/$tools_prefix-gcc --sysroot=$sys_root"
+ export CXX="$path/$tools_prefix-g++ --sysroot=$sys_root"
+ export LD="$path/$tools_prefix-ld"
+ export AR="$path/$tools_prefix-ar"
+ export RANLIB="$path/$tools_prefix-ranlib"
+ export STRIP="$path/$tools_prefix-strip"
+ export CFLAGS="-DIGNORE_DYNAMIC_LOADING -DPLATFORM_ANDROID -I libatomic_ops/src/"
+ export LIBS="-lc -lgcc"
+ ./configure --host=$host --enable-static --disable-shared --prefix="$install/$arch/" || exit 1
+
+ # Compile and install locally
+ make install -j 4 || exit 1
+done
body_impl.add( efc.to_writer )
end
- fun compile_header_core( stream : OStream )
+ fun compile_header_core( stream : Writer )
do
header_c_base.write_to( stream )
header_custom.write_to( stream )
header_decl.write_to( stream )
end
- fun compile_body_core( stream : OStream )
+ fun compile_body_core( stream : Writer )
do
body_decl.write_to( stream )
body_custom.write_to( stream )
var hfilename = compiler.header.file.name + ".h"
var hfilepath = "{compile_dir}/{hfilename}"
- var h = new OFStream.open(hfilepath)
+ var h = new FileWriter.open(hfilepath)
for l in compiler.header.decl_lines do
h.write l
h.write "\n"
for f in compiler.files do
var i = 0
var count = 0
- var file: nullable OFStream = null
+ var file: nullable FileWriter = null
for vis in f.writers do
if vis == compiler.header then continue
var total_lines = vis.lines.length + vis.decl_lines.length
var cfilepath = "{compile_dir}/{cfilename}"
self.toolcontext.info("new C source files to compile: {cfilepath}", 3)
cfiles.add(cfilename)
- file = new OFStream.open(cfilepath)
+ file = new FileWriter.open(cfilepath)
file.write "#include \"{f.name}.0.h\"\n"
count = total_lines
end
var cfilename = "{f.name}.0.h"
var cfilepath = "{compile_dir}/{cfilename}"
- var hfile: nullable OFStream = null
- hfile = new OFStream.open(cfilepath)
+ var hfile: nullable FileWriter = null
+ hfile = new FileWriter.open(cfilepath)
hfile.write "#include \"{hfilename}\"\n"
for key in f.required_declarations do
if not compiler.provided_declarations.has_key(key) then
end
var makename = makefile_name(mainmodule)
var makepath = "{compile_dir}/{makename}"
- var makefile = new OFStream.open(makepath)
+ var makefile = new FileWriter.open(makepath)
var linker_options = new HashSet[String]
for m in mainmodule.in_importation.greaters do
if not compiler.linker_script.is_empty then
var linker_script_path = "{compile_dir}/linker_script"
ofiles.add "linker_script"
- var f = new OFStream.open(linker_script_path)
+ var f = new FileWriter.open(linker_script_path)
for l in compiler.linker_script do
f.write l
f.write "\n"
do
var compile_dir = modelbuilder.compile_dir
- var stream = new OFStream.open("{compile_dir}/c_functions_hash.c")
+ var stream = new FileWriter.open("{compile_dir}/c_functions_hash.c")
stream.write("#include <string.h>\n")
stream.write("#include <stdlib.h>\n")
stream.write("#include \"c_functions_hash.h\"\n")
stream.write("\}\n")
stream.close
- stream = new OFStream.open("{compile_dir}/c_functions_hash.h")
+ stream = new FileWriter.open("{compile_dir}/c_functions_hash.h")
stream.write("const char* get_nit_name(register const char* procname, register unsigned int len);\n")
stream.close
var full_comment: String is lazy do return content.join("\n").html_escape
# Synopsys in a template
- var tpl_short_comment: Streamable is lazy do
+ var tpl_short_comment: Writable is lazy do
var res = new Template
var syn = nitdoc_inline_processor.process(content.first)
res.add "<span class=\"synopsys nitdoc\">{syn}</span>"
end
# Full comment in a template
- var tpl_comment: Streamable is lazy do
+ var tpl_comment: Writable is lazy do
var res = new Template
var lines = content.to_a
res.add "<div class=\"nitdoc\">"
var output_dir = v.ctx.output_dir
var path = output_dir / id
var path_sh = path.escape_to_sh
- var file = new OFStream.open("{path}.dot")
+ var file = new FileWriter.open("{path}.dot")
file.write(dot)
file.close
sys.system("\{ test -f {path_sh}.png && test -f {path_sh}.s.dot && diff -- {path_sh}.dot {path_sh}.s.dot >/dev/null 2>&1 ; \} || \{ cp -- {path_sh}.dot {path_sh}.s.dot && dot -Tpng -o{path_sh}.png -Tcmapx -o{path_sh}.map {path_sh}.s.dot ; \}")
- var fmap = new IFStream.open("{path}.map")
+ var fmap = new FileReader.open("{path}.map")
var map = fmap.read_all
fmap.close
var sections = new Array[TplSection]
# Footer content if any
- var footer: nullable Streamable = null is writable
+ var footer: nullable Writable = null is writable
# JS scripts to append at the end of the body
var scripts = new Array[TplScript]
super Template
# Brand link to display in first position of the top menu
- private var brand: nullable Streamable = null is writable
+ private var brand: nullable Writable = null is writable
# Elements of the topmenu
- private var elts = new Array[Streamable]
+ private var elts = new Array[Writable]
# The page url where the top menu is displayed.
#
end
# Add a content between `<li>` tags
- fun add_item(content: Streamable, is_active: Bool) do
+ fun add_item(content: Writable, is_active: Bool) do
var tpl = new Template
tpl.add "<li"
if is_active then
end
# Add a raw content to the menu
- fun add_raw(content: Streamable) do
+ fun add_raw(content: Writable) do
elts.add content
end
# Content to display in the box
# box will not be rendered if the content is null
- var content: nullable Streamable = null is writable
+ var content: nullable Writable = null is writable
# Is the box opened by default
# otherwise, the user will have to clic on the title to display the content
self.id = title.to_cmangle
end
- init with_content(title: String, content: Streamable) do
+ init with_content(title: String, content: Writable) do
init(title)
self.content = content
end
super TplSummaryElt
# Text to display
- var text: Streamable
+ var text: Writable
# Children of this entry
# Will be displayed as a tree
# Title to display if any
# if both `title` and `summary_title` are null then
# the section will not appear in the summary
- var title: nullable Streamable = null is writable
+ var title: nullable Writable = null is writable
# Subtitle to display if any
- var subtitle: nullable Streamable = null is writable
+ var subtitle: nullable Writable = null is writable
# Title that appear in the summary
# if null use `title` instead
# Parent article/section if any
var parent: nullable TplSectionElt = null
- init with_title(id: String, title: Streamable) do
+ init with_title(id: String, title: Writable) do
init(id)
self.title = title
end
super TplSectionElt
# Content for this article
- var content: nullable Streamable = null is writable
- var source_link: nullable Streamable = null is writable
+ var content: nullable Writable = null is writable
+ var source_link: nullable Writable = null is writable
- init with_content(id: String, title: Streamable, content: Streamable) do
+ init with_content(id: String, title: Writable, content: Writable) do
with_title(id, title)
self.content = content
end
super Template
# Comment to display
- var comment: nullable Streamable = null is writable
+ var comment: nullable Writable = null is writable
# Namespace for this definition
- var namespace: nullable Streamable = null is writable
+ var namespace: nullable Writable = null is writable
# Location link to display
- var location: nullable Streamable = null is writable
+ var location: nullable Writable = null is writable
private fun render_info do
addn "<div class='info text-right'>"
class TplSearchPage
super TplSectionElt
- var modules = new Array[Streamable]
- var classes = new Array[Streamable]
- var props = new Array[Streamable]
+ var modules = new Array[Writable]
+ var classes = new Array[Writable]
+ var props = new Array[Writable]
redef fun rendering do
var title = self.title
var href: String is writable
# The raw HTML content to display in the link
- var text: Streamable is writable
+ var text: Writable is writable
# The unescaped optional title.
var title: nullable String = null is writable
# CSS classes of the <li> element
var css_classes = new Array[String]
- init with_content(content: Streamable) do append(content)
+ init with_content(content: Writable) do append(content)
- init with_classes(content: Streamable, classes: Array[String]) do
+ init with_classes(content: Writable, classes: Array[String]) do
with_content(content)
css_classes = classes
end
# Append `content` to the item
# similar to `self.content.add`
- fun append(content: Streamable) do self.content.add content
+ fun append(content: Writable) do self.content.add content
redef fun rendering do
add "<li class='{css_classes.join(" ")}'>"
# The panel name.
#
# Displayed in the tab header or in the pointing link.
- var name: Streamable
+ var name: Writable
# Is the panel visible by default?
var is_active = false is writable
# Body of the panel
- var content: nullable Streamable = null is writable
+ var content: nullable Writable = null is writable
# Get a link pointing to this panel.
- fun tpl_link_to: Streamable do
+ fun tpl_link_to: Writable do
var lnk = new Template
lnk.add "<a data-target='#{id}' data-toggle='pill'>"
lnk.add name
super Template
# Content of the label if any
- var content: nullable Streamable = null is writable
+ var content: nullable Writable = null is writable
# CSS classes of the <span> element
var css_classes = new Array[String]
- init with_content(content: Streamable) do self.content = content
+ init with_content(content: Writable) do self.content = content
init with_classes(classes: Array[String]) do self.css_classes = classes
redef fun rendering do
super Template
var attrs = new Array[TagAttribute]
- var content: nullable Streamable = null is writable
+ var content: nullable Writable = null is writable
init do
attrs.add(new TagAttribute("type", "text/javascript"))
# Generate files used by the Vim plugin to autocomplete with doc
#
-# There is 3 files generated, each with a different target: modules, classes,
-# and properties. Each line describe a different entity, with 4 values:
+# There is 3 files generated, each with a different target: modules, types,
+# properties and constructors. Each line describe a different entity,
+# with 4 values:
#
# 1. Short name to use in autocompletion
# 2. Full signature
# 4. Full doc with extra
#
# The priority with those files is for them to be analyzed efficiently, for
-# this reason, the data is prepared in advant and some information may be
+# this reason, the data is prepared in advance and some information may be
# duplicated.
module vim_autocomplete
import modelbuilder
import phase
import modelize::modelize_class
+import model_utils
redef class ToolContext
# Phase generating the files for the Vim plugin
private fun field_separator: String do return "#====#"
private fun line_separator: String do return "#nnnn#"
- private fun write_to_stream(stream: OStream)
+ private fun write_to_stream(stream: Writer)
do
# 1. Short name for autocompletion
- stream.write name
+ stream.write complete_name
stream.write field_separator
# 2. Full signature
- stream.write name
+ stream.write complete_name
write_signature_to_stream(stream)
stream.write field_separator
# 3. Doc synopsis
- var mdoc = mdoc
+ var mdoc = complete_mdoc
if mdoc != null then
stream.write mdoc.content.first
end
stream.write "\n"
end
- private fun write_signature_to_stream(stream: OStream) do end
+ private fun write_signature_to_stream(stream: Writer) do end
+
+ # Actual name used in completion
+ private fun complete_name: String do return name
+
+ # Doc to use in completion
+ private fun complete_mdoc: nullable MDoc do return mdoc
end
redef class MMethodDef
end
end
+# Use `MClassDef` as anchor for its constructors only
+redef class MClassDef
+ private var target_constructor: nullable MMethodDef = null
+
+ redef fun complete_name
+ do
+ var target_constructor = target_constructor
+ assert target_constructor != null
+
+ var params
+ var mparameters = mclass.mparameters
+ if not mparameters.is_empty then
+ params = "[{mparameters.join(", ")}]"
+ else
+ params = ""
+ end
+
+ if target_constructor.name != "init" and target_constructor.name != "new" then
+ return name + params + "." + target_constructor.name
+ end
+
+ return name + params
+ end
+
+ redef fun complete_mdoc
+ do
+ var target_constructor = target_constructor
+ assert target_constructor != null
+
+ if target_constructor.name != "init" and target_constructor.name != "new" then
+ return target_constructor.mdoc
+ end
+
+ return mdoc
+ end
+end
+
private class AutocompletePhase
super Phase
var compile_dir = "NIT_VIM_DIR".environ
if compile_dir.is_empty then compile_dir = "HOME".environ / ".vim/nit"
compile_dir.mkdir
- var modules_stream = new OFStream.open(compile_dir / "modules.txt")
- var classes_stream = new OFStream.open(compile_dir / "classes.txt")
- var properties_stream = new OFStream.open(compile_dir / "properties.txt")
+
+ var modules_stream = new FileWriter.open(compile_dir / "modules.txt")
+ var classes_stream = new FileWriter.open(compile_dir / "classes.txt")
+ var constructors_stream = new FileWriter.open(compile_dir / "constructors.txt")
+ var types_stream = new FileWriter.open(compile_dir / "types.txt")
+ var properties_stream = new FileWriter.open(compile_dir / "properties.txt")
# Got all known modules
var model = mainmodule.model
end
# TODO list other modules from the Nit lib
- # TODO list submodules
# Get all known classes
for mclass in model.mclasses do
if not mainmodule.is_visible(mclass.intro_mmodule, public_visibility) then continue
+ var mclass_intro = mclass.intro
+
+ # Can it be instantiated?
+ if mclass.kind != interface_kind and mclass.kind != abstract_kind then
+
+ for prop in mclass.all_mproperties(mainmodule, public_visibility) do
+ if prop isa MMethod and prop.is_init then
+ mclass_intro.target_constructor = prop.intro
+ mclass_intro.write_to_stream constructors_stream
+ end
+ end
+ mclass_intro.target_constructor = null
+ end
- mclass.intro.write_to_stream classes_stream
+ # Always add to types and classes
+ mclass.mclass_type.write_to_stream classes_stream
+ mclass.mclass_type.write_to_stream types_stream
end
# Get all known properties
var intro_mmodule = mproperty.intro_mclassdef.mmodule
if not mainmodule.is_visible(intro_mmodule, public_visibility) then continue
+ # Is it a virtual type?
+ if mproperty isa MVirtualTypeProp then
+ mproperty.intro.write_to_stream types_stream
+ continue
+ end
+
+ # Skip properties beginning with @ or _
+ var first_letter = mproperty.name.chars.first
+ if first_letter == '@' or first_letter == '_' then continue
+
mproperty.intro.write_to_stream properties_stream
end
# Close streams
- for stream in [modules_stream, classes_stream, properties_stream] do
- stream.close
+ for stream in [modules_stream, classes_stream, properties_stream,
+ types_stream, constructors_stream] do
+ stream.close
var error = stream.last_error
if error != null then
toolcontext.error(null, "Failed to write Vim autocomplete file: {error}")
var cmd_args = opt.command
var proc
if cmd_args.length == 1 then
- proc = new IProcess.from_a(cmd_args[0], new Array[String])
+ proc = new ProcessReader.from_a(cmd_args[0], new Array[String])
else if cmd_args.length > 1 then
var rest_args = cmd_args.subarray(1, cmd_args.length-1)
- proc = new IProcess.from_a(cmd_args[0], rest_args)
+ proc = new ProcessReader.from_a(cmd_args[0], rest_args)
else abort
# wait for its completion
fun write_header_to_file(mmodule: MModule, file: String, includes: Array[String], guard: String)
do
- var stream = new OFStream.open( file )
+ var stream = new FileWriter.open( file )
# header comments
var module_info = "/*\n\tExtern implementation of Nit module {mmodule.name}\n*/\n"
fun write_body_to_file(mmodule: MModule, file: String, includes: Array[String])
do
- var stream = new OFStream.open(file)
+ var stream = new FileWriter.open(file)
var module_info = "/*\n\tExtern implementation of Nit module {mmodule.name}\n*/\n"
end
# check availability of pkg-config
- var proc_which = new IProcess("which", "pkg-config")
+ var proc_which = new ProcessReader("which", "pkg-config")
proc_which.wait
var status = proc_which.status
if status != 0 then
readonly
writable
autoinit
+noautoinit
cached
nosuper
old_style_init
if not in_path then return
else
# Is _glslangValidator_ installed?
- var proc_which = new IProcess("which", "glslangValidator")
+ var proc_which = new ProcessReader("which", "glslangValidator")
proc_which.wait
proc_which.close
var status = proc_which.status
shader.write_to_file path
# Execute the validator
- var proc_validator = new IProcess("glslangValidator", path)
+ var proc_validator = new ProcessReader("glslangValidator", path)
proc_validator.wait
var lines = proc_validator.read_all.split('\n')
proc_validator.close
end
redef class Sys
- private fun set_io(istream: PollableIStream, ostream: OStream, errstream: OStream)
+ private fun set_io(istream: PollableReader, ostream: Writer, errstream: Writer)
do
self.stdin = istream
self.stdout = ostream
# Wrapper for `NativeFile`
class PrimitiveNativeFile
- var file: IOS
+ var file: Stream
init native_stdin do
file = sys.stdin
end
init io_open_read(path: String) do
- file = new IFStream.open(path.to_s)
+ file = new FileReader.open(path.to_s)
end
init io_open_write(path: String) do
- file = new OFStream.open(path.to_s)
+ file = new FileWriter.open(path.to_s)
end
fun address_is_null: Bool do
- if file isa FStream then return file.as(FStream)._file.address_is_null
+ if file isa FileStream then return file.as(FileStream)._file.address_is_null
return false
end
fun io_read(buf: NativeString, len: Int): Int do
- if file isa FStream then return file.as(FStream)._file.io_read(buf, len)
- var str = file.as(IStream).read(len)
+ if file isa FileStream then return file.as(FileStream)._file.io_read(buf, len)
+ var str = file.as(Reader).read(len)
str.to_cstring.copy_to(buf, str.length, 0, 0)
return str.length
end
fun io_write(buf: NativeString, len: Int): Int do
- if file isa FStream then return file.as(FStream)._file.io_write(buf, len)
- file.as(OStream).write(buf.to_s_with_length(len))
+ if file isa FileStream then return file.as(FileStream)._file.io_write(buf, len)
+ file.as(Writer).write(buf.to_s_with_length(len))
return len
end
fun io_close: Int do
- if file isa FStream then return file.as(FStream)._file.io_close
+ if file isa FileStream then return file.as(FileStream)._file.io_close
file.close
return 0
end
fun fileno: Int do
- if file isa FStream then return file.as(FStream)._file.fileno
+ if file isa FileStream then return file.as(FileStream)._file.fileno
return 0
end
fun flush: Int do
- if file isa FStream then return file.as(FStream)._file.flush
+ if file isa FileStream then return file.as(FileStream)._file.flush
return 0
end
fun set_buffering_type(size, mode: Int): Int do
- if file isa FStream then return file.as(FStream)._file.set_buffering_type(size, mode)
+ if file isa FileStream then return file.as(FileStream)._file.set_buffering_type(size, mode)
return 0
end
end
if not readme.file_exists then readme = dirpath2.join_path("README")
if readme.file_exists then
var mdoc = new MDoc
- var s = new IFStream.open(readme)
+ var s = new FileReader.open(readme)
while not s.eof do
mdoc.content.add(s.read_line)
end
self.toolcontext.info("load module {filename}", 2)
# Load the file
- var file = new IFStream.open(filename)
+ var file = new FileReader.open(filename)
var lexer = new Lexer(new SourceFile(filename, file))
var parser = new Parser(lexer)
var tree = parser.parse
var string: String is noinit
# The original stream used to initialize `string`
- var stream: IStream
+ var stream: Reader
init
do
end
end
buf.append("\}\n")
- var f = new OFStream.open(toolcontext.output_dir.join_path("class_hierarchy.dot"))
+ var f = new FileWriter.open(toolcontext.output_dir.join_path("class_hierarchy.dot"))
f.write(buf.to_s)
f.close
end
end
end
buf.append("\}\n")
- var f = new OFStream.open(toolcontext.output_dir.join_path("classdef_hierarchy.dot"))
+ var f = new FileWriter.open(toolcontext.output_dir.join_path("classdef_hierarchy.dot"))
f.write(buf.to_s)
f.close
end
end
end
buf.append("</body></html>\n")
- var f = new OFStream.open(toolcontext.output_dir.join_path("model.html"))
+ var f = new FileWriter.open(toolcontext.output_dir.join_path("model.html"))
f.write(buf.to_s)
f.close
end
# The visibility of the property
var visibility: MVisibility
+ # Is the property usable as an initializer?
+ var is_autoinit = false is writable
+
init
do
intro_mclassdef.intro_mproperties.add(self)
# Interesting elements must be selected. See `mmodules`, ``
# Display configuration can be set. See `cluster_group`, `project_group`
class MProjectDot
- super Streamable
+ super Writable
# The model where to look for information
var model: Model
var project_group = true is writable
# Recursively generate node and clusters for a mgroup
- private fun dot_cluster(o: OStream, mgroup: MGroup)
+ private fun dot_cluster(o: Writer, mgroup: MGroup)
do
# Open the cluster, if required
if mgroup.parent == null then
mparameters.add(mparameter)
end
initializers.add(npropdef.mpropdef.mproperty)
+ npropdef.mpropdef.mproperty.is_autoinit = true
end
if npropdef isa AAttrPropdef then
if npropdef.mpropdef == null then return # Skip broken attribute
# For autoinit attributes, call the reader to force
# the lazy initialization of the attribute.
initializers.add(npropdef.mreadpropdef.mproperty)
+ npropdef.mreadpropdef.mproperty.is_autoinit = true
continue
end
if npropdef.has_value then continue
if msetter == null then
# No setter, it is a old-style attribute, so just add it
initializers.add(npropdef.mpropdef.mproperty)
+ npropdef.mpropdef.mproperty.is_autoinit = true
else
# Add the setter to the list
initializers.add(msetter.mproperty)
+ msetter.mproperty.is_autoinit = true
end
end
end
return
end
- # Search the longest-one and checks for conflict
- var longest = spropdefs.first
- if spropdefs.length > 1 then
- # Check for conflict in the order of initializers
- # Each initializer list must me a prefix of the longest list
- # part 1. find the longest list
- for spd in spropdefs do
- if spd.initializers.length > longest.initializers.length then longest = spd
+ # Look at the autoinit class-annotation
+ var autoinit = nclassdef.get_single_annotation("autoinit", self)
+ var noautoinit = nclassdef.get_single_annotation("noautoinit", self)
+ if autoinit != null then
+ # Just throws the collected initializers
+ mparameters.clear
+ initializers.clear
+
+ if noautoinit != null then
+ error(autoinit, "Error: `autoinit` and `noautoinit` are incompatible.")
+ end
+
+ if autoinit.n_args.is_empty then
+ error(autoinit, "Syntax error: `autoinit` expects method identifiers, use `noautoinit` to clear all autoinits.")
end
- # part 2. compare
- for spd in spropdefs do
- var i = 0
- for p in spd.initializers do
- if p != longest.initializers[i] then
- self.error(nclassdef, "Error: conflict for inherited inits {spd}({spd.initializers.join(", ")}) and {longest}({longest.initializers.join(", ")})")
- return
+
+ # Get and check each argument
+ for narg in autoinit.n_args do
+ var id = narg.as_id
+ if id == null then
+ error(narg, "Syntax error: `autoinit` expects method identifiers.")
+ return
+ end
+
+ # Search the property.
+ # To avoid bad surprises, try to get the setter first.
+ var p = try_get_mproperty_by_name(narg, mclassdef, id + "=")
+ if p == null then
+ p = try_get_mproperty_by_name(narg, mclassdef, id)
+ end
+ if p == null then
+ error(narg, "Error: unknown method `{id}`")
+ return
+ end
+ if not p.is_autoinit then
+ error(narg, "Error: `{p}` is not an autoinit method")
+ return
+ end
+
+ # Register the initializer and the parameters
+ initializers.add(p)
+ var pd = p.intro
+ if pd isa MMethodDef then
+ # Get the signature resolved for the current receiver
+ var sig = pd.msignature.resolve_for(mclassdef.mclass.mclass_type, mclassdef.bound_mtype, mclassdef.mmodule, false)
+ mparameters.add_all sig.mparameters
+ else
+ # TODO attributes?
+ abort
+ end
+ end
+ else if noautoinit != null then
+ if initializers.is_empty then
+ warning(noautoinit, "useless-noautoinit", "Warning: the list of autoinit is already empty.")
+ end
+ # Just clear initializers
+ mparameters.clear
+ initializers.clear
+ else
+ # Search the longest-one and checks for conflict
+ var longest = spropdefs.first
+ if spropdefs.length > 1 then
+ # Check for conflict in the order of initializers
+ # Each initializer list must me a prefix of the longest list
+ # part 1. find the longest list
+ for spd in spropdefs do
+ if spd.initializers.length > longest.initializers.length then longest = spd
+ end
+ # part 2. compare
+ for spd in spropdefs do
+ var i = 0
+ for p in spd.initializers do
+ if p != longest.initializers[i] then
+ self.error(nclassdef, "Error: conflict for inherited inits {spd}({spd.initializers.join(", ")}) and {longest}({longest.initializers.join(", ")})")
+ return
+ end
+ i += 1
end
- i += 1
end
end
- end
- # Can we just inherit?
- if spropdefs.length == 1 and mparameters.is_empty and defined_init == null then
- self.toolcontext.info("{mclassdef} inherits the basic constructor {longest}", 3)
- mclassdef.mclass.root_init = longest
- return
- end
+ # Can we just inherit?
+ if spropdefs.length == 1 and mparameters.is_empty and defined_init == null then
+ self.toolcontext.info("{mclassdef} inherits the basic constructor {longest}", 3)
+ mclassdef.mclass.root_init = longest
+ return
+ end
- # Combine the inherited list to what is collected
- if longest.initializers.length > 0 then
- mparameters.prepend longest.new_msignature.mparameters
- initializers.prepend longest.initializers
+ # Combine the inherited list to what is collected
+ if longest.initializers.length > 0 then
+ mparameters.prepend longest.new_msignature.mparameters
+ initializers.prepend longest.initializers
+ end
end
# If we already have a basic init definition, then setup its initializers
has_value = n_expr != null or n_block != null
var atnoinit = self.get_single_annotation("noinit", modelbuilder)
+ if atnoinit == null then atnoinit = self.get_single_annotation("noautoinit", modelbuilder)
if atnoinit != null then
noinit = true
if has_value then
- modelbuilder.error(atnoinit, "Error: `noinit` attributes cannot have an initial value")
+ modelbuilder.error(atnoinit, "Error: `noautoinit` attributes cannot have an initial value")
return
end
end
var v = new HighlightVisitor
toolcontext.info("write {dir}/style.css", 1)
- var f = new OFStream.open("{dir}/style.css")
+ var f = new FileWriter.open("{dir}/style.css")
f.write v.css_content
f.close
end
if opt_recursive.value then
files = new Array[String]
for d in tc.option_context.rest do
- var pipe = new IProcess("find", d, "-name", "*.nit")
+ var pipe = new ProcessReader("find", d, "-name", "*.nit")
while not pipe.eof do
var l = pipe.read_line
if l == "" then break # last line
# Return result from diff between `file1` and `file2`.
private fun diff(file1, file2: String): String do
- var p = new IProcess("diff", "-u", file1, file2)
+ var p = new ProcessReader("diff", "-u", file1, file2)
var res = p.read_all
p.wait
p.close
class NitModule
super Template
- var header: nullable Streamable = null
+ var header: nullable Writable = null
# The module's name
- var name: Streamable
+ var name: Writable
# Imports from this module
- var imports = new Array[Streamable]
+ var imports = new Array[Writable]
# Main content of this module
- var content = new Array[Streamable]
+ var content = new Array[Writable]
redef fun rendering
do
module parser_nodes
import location
+import ordered_tree
# Root of the AST class-hierarchy
abstract class ANode
sys.stderr.write "{hot_location} {self.class_name}: {message}\n{hot_location.colored_line("0;32")}\n"
end
+ # Write the subtree on stdout.
+ # See `ASTDump`
+ fun dump_tree
+ do
+ var d = new ASTDump
+ d.enter_visit(self)
+ d.write_to(sys.stdout)
+ end
+
# Parent of the node in the AST
var parent: nullable ANode = null
end
end
+# A helper class to handle (print) Nit AST as an OrderedTree
+class ASTDump
+ super Visitor
+ super OrderedTree[ANode]
+
+ # Reference to the last parent in the Ordered Tree
+ # Is used to handle the initial node parent and workaround possible inconsistent `ANode::parent`
+ private var last_parent: nullable ANode = null
+
+ redef fun visit(n)
+ do
+ var p = last_parent
+ add(p, n)
+ last_parent = n
+ n.visit_all(self)
+ last_parent = p
+ end
+
+ redef fun display(n)
+ do
+ if n isa Token then
+ return "{n.class_name} \"{n.text.escape_to_c}\" @{n.location}"
+ else
+ return "{n.class_name} @{n.location}"
+ end
+ end
+end
# A sequence of nodes
# It is a specific class (instead of using a Array) to track the parent/child relation when nodes are added or removed
end
end
- ## Generate delegating makefile
+ ## Generate Application.mk
dir = "{android_project_root}/jni/"
"""
+APP_ABI := armeabi armeabi-v7a x86 mips
+APP_PLATFORM := android-{{{app_target_api}}}
+""".write_to_file "{dir}/Application.mk"
+
+ ## Generate delegating makefile
+ """
include $(call all-subdir-makefiles)
- """.write_to_file("{dir}/Android.mk")
+""".write_to_file "{dir}/Android.mk"
# Gather ldflags for Android
var ldflags = new Array[String]
LOCAL_MODULE := main
LOCAL_SRC_FILES := \\
{{{cfiles.join(" \\\n")}}}
-LOCAL_LDLIBS := {{{ldflags.join(" ")}}} libgc.a
+LOCAL_LDLIBS := {{{ldflags.join(" ")}}} $(TARGET_ARCH)/libgc.a
LOCAL_STATIC_LIBRARIES := android_native_app_glue png
include $(BUILD_SHARED_LIBRARY)
end
# Ensure that android-setup-libgc.sh has been executed
- if not "{share_dir}/libgc/lib".file_exists then
+ if not "{share_dir}/libgc/arm/lib".file_exists then
toolcontext.exec_and_check(["{share_dir}/libgc/android-setup-libgc.sh"], "Android project error")
end
# Copy GC files
- toolcontext.exec_and_check(["cp", "{share_dir}/libgc/lib/libgc.a", "{android_project_root}/libgc.a"], "Android project error")
- toolcontext.exec_and_check(["ln", "-s", "{share_dir}/libgc/include/gc/", "{android_project_root}/jni/nit_compile/gc"], "Android project error")
+ for arch in ["arm", "x86", "mips"] do
+ dir = android_project_root/arch
+ dir.mkdir
+ toolcontext.exec_and_check(["cp", "{share_dir}/libgc/{arch}/lib/libgc.a",
+ dir/"libgc.a"], "Android project error")
+ end
+
+ toolcontext.exec_and_check(["ln", "-s", "{share_dir}/libgc/arm/include/gc/",
+ "{android_project_root}/jni/nit_compile/gc"], "Android project error")
### Link to assets (for mnit and others)
# This will be accessed from `android_project_root`
"""<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">{{{app_name}}}</string>
-</resources>""".write_to_file "{dir}/res/values/strings.xml"
+</resources>""".write_to_file "{android_project_root}/res/values/strings.xml"
end
# Android libs folder
value = arg.as_id
if value == "git_revision" then
# Get Git short revision
- var proc = new IProcess("git", "rev-parse", "--short", "HEAD")
+ var proc = new ProcessReader("git", "rev-parse", "--short", "HEAD")
proc.wait
assert proc.status == 0
var lines = proc.read_all
# Is it dirty?
# If not, the return of `git diff --shortstat` is an empty line
- proc = new IProcess("git", "diff-index", "--quiet", "HEAD")
+ proc = new ProcessReader("git", "diff-index", "--quiet", "HEAD")
proc.wait
var dirty = proc.status != 0
if dirty then revision += ".d"
fun printflow
do
- var file = new OFStream.open("flow.dot")
+ var file = new FileWriter.open("flow.dot")
file.write("digraph \{\n")
for f in flows do
var s = ""
if no_file then
source = new SourceFile.from_string("", a)
else
- var f = new IFStream.open(a)
+ var f = new FileReader.open(a)
source = new SourceFile(a, f)
f.close
end
var dir = file.dirname
if dir != "" then dir.mkdir
var f
- f = new OFStream.open(file)
+ f = new FileWriter.open(file)
f.write("# GENERATED FILE\n")
f.write("# Docunits extracted from comments\n")
f.write("import {mmodule.name}\n")
f.write("end\n")
end
f.write("var a = args.first.to_i\n")
- for j in [1..i[ do
+ for j in [1..i] do
f.write("if a == {j} then run_{j}\n")
end
f.close
var res2 = sys.system("{file.to_program_name}.bin {i} >>'{file}.out1' 2>&1 </dev/null")
var msg
- f = new IFStream.open("{file}.out1")
+ f = new FileReader.open("{file}.out1")
var n2
n2 = new HTMLTag("system-err")
tc.add n2
var dir = file.dirname
if dir != "" then dir.mkdir
var f
- f = new OFStream.open(file)
+ f = new FileWriter.open(file)
f.write("# GENERATED FILE\n")
f.write("# Example extracted from a documentation\n")
f.write("import {mmodule.name}\n")
end
var msg
- f = new IFStream.open("{file}.out1")
+ f = new FileReader.open("{file}.out1")
var n2
n2 = new HTMLTag("system-err")
tc.add n2
var nodot: Array[String] = ["+", "-", "*", "/", "%", "==", "!=", "<", "<=", "<=>", ">", ">=", ">"]
# Generate subject init.
- private fun gen_init(mclassdef: MClassDef): Streamable do
+ private fun gen_init(mclassdef: MClassDef): Writable do
if mclassdef.mclass.arity == 0 then
return "\t\tvar subject: {mclassdef.name}"
end
end
# Generate call to `method` using `args`.
- private fun gen_call(method: MMethodDef, args: Array[String]): Streamable do
+ private fun gen_call(method: MMethodDef, args: Array[String]): Writable do
# Here we handle the magic of the Nit syntax, have fun :)
var name = method.name
if name == "[]" then return "subject[{args.join(", ")}]"
var include_dir = mmodule.location.file.filename.dirname
var cmd = "{nitg} --no-color '{file}.nit' -I {include_dir} -o '{file}.bin' > '{file}.out' 2>&1 </dev/null"
var res = sys.system(cmd)
- var f = new IFStream.open("{file}.out")
+ var f = new FileReader.open("{file}.out")
var msg = f.read_all
f.close
# set test case result
var test_file = test_suite.test_file
var res_name = "{test_file}_{method_name.escape_to_c}"
var res = sys.system("{test_file}.bin {method_name} > '{res_name}.out1' 2>&1 </dev/null")
- var f = new IFStream.open("{res_name}.out1")
+ var f = new FileReader.open("{res_name}.out1")
var msg = f.read_all
f.close
# set test case result
args.remove_at 0
# Is the wanted program available?
- var proc_which = new IProcess.from_a("which", [prog])
+ var proc_which = new ProcessReader.from_a("which", [prog])
proc_which.wait
var res = proc_which.status
if res != 0 then
redef class UMLModel
# Generates a UML class diagram from a `Model`
- fun generate_class_uml: Streamable do
+ fun generate_class_uml: Writable do
var tpl = new Template
tpl.add "digraph G \{\n"
tpl.add """ fontname = "Bitstream Vera Sans"
redef class Model
# Generates a UML Class diagram from the entities of a `Model`
- fun tpl_class(ctx: ToolContext, main: MModule): Streamable do
+ fun tpl_class(ctx: ToolContext, main: MModule): Writable do
var t = new Template
for i in mclasses do
if not ctx.private_gen and i.visibility != public_visibility then continue
end
redef class MEntity
- # Generates a dot-compatible `Streamable` UML Class diagram from `self`
- fun tpl_class(ctx: ToolContext, main: MModule): Streamable is abstract
+ # Generates a dot-compatible `Writable` UML Class diagram from `self`
+ fun tpl_class(ctx: ToolContext, main: MModule): Writable is abstract
end
redef class MClass
- redef fun tpl_class(ctx, main): Streamable do
+ redef fun tpl_class(ctx, main): Writable do
var t = new Template
t.add "{name} [\n label = \"\{"
if kind == abstract_kind then
#
# assert public_visibility.tpl_class == "+"
# assert private_visibility.tpl_class == "-"
- fun tpl_class: Streamable do
+ fun tpl_class: Writable do
if self == private_visibility then
return "-"
else if self == protected_visibility then
redef class UMLModel
# Generates a UML package diagram from a `Model`
- fun generate_package_uml: Streamable do
+ fun generate_package_uml: Writable do
var tpl = new Template
tpl.add "digraph G \{\n"
tpl.add """ fontname = "Bitstream Vera Sans"
redef class Model
# Returns a UML package diagram of `main`
- fun tpl_module(ctx: ToolContext, main: MModule): Streamable do
+ fun tpl_module(ctx: ToolContext, main: MModule): Writable do
return main.tpl_module(ctx, main)
end
end
redef class MEntity
# Builds a dot UML package diagram entity from `self`
- fun tpl_module(ctx: ToolContext, main: MModule): Streamable is abstract
+ fun tpl_module(ctx: ToolContext, main: MModule): Writable is abstract
end
redef class MClassDef
class A
var a: Object = get(5) is lazy
- var b: Object is noinit
- #alt1#var b2: Object = get(-4) is noinit
- var c: Object is noinit
+ var b: Object is noautoinit
+ #alt1#var b2: Object = get(-4) is noautoinit
+ var c: Object is noautoinit
var d: Object = get(2) is autoinit
#alt2#var d2: Object = get(-2) is autoinit, lazy
var e: Object = get(1)
--- /dev/null
+# 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
+
+class A
+ var i: Int
+end
+
+class B
+ autoinit b, i #alt2# autoinit foo #alt4# autoinit fail
+ super A
+ var b: Bool #alt5# var b: Bool is noinit
+ fun foo do end
+end
+
+class C
+ super A
+ var f: Float
+end
+
+class D
+ autoinit i, b, f
+ super B
+ super C
+end
+
+class E
+ noautoinit #alt6#
+ #alt6,7# autoinit
+ super A
+ var a: A
+end
+
+class F
+ #alt8#noautoinit
+end
+
+var a = new A(1)
+a.i.output
+
+var b = new B(false, 2)
+b.i.output
+b.b.output
+
+var c = new C(3, 3.3)
+c.i.output
+c.f.output
+
+var d = new D(4, true, 4.4)
+d.i.output
+d.b.output
+d.f.output
+
+var e = new E
+#alt1# e.a.i.output
import kernel
class A
- var x: Object is noinit #alt1,3# var x: Object
- var y: Object is noinit #alt2,3# var y: Object
+ var x: Object is noautoinit #alt1,3# var x: Object
+ var y: Object is noautoinit #alt2,3# var y: Object
fun work
do
if isset _x then x.output
import emscripten
-redef class IFStream
+redef class FileReader
redef fun fill_buffer
do
print "NOT YET IMPLEMENTED"
-alt/base_init_autoinit2_alt1.nit:20,30--35: Error: `noinit` attributes cannot have an initial value
+alt/base_init_autoinit2_alt1.nit:20,30--39: Error: `noautoinit` attributes cannot have an initial value
--- /dev/null
+1
+2
+false
+3
+3.300000
+4
+true
+4.400000
--- /dev/null
+Runtime error: Uninitialized attribute _a (alt/base_init_autoinit3_alt1.nit:43)
+1
+2
+false
+3
+3.300000
+4
+true
+4.400000
--- /dev/null
+alt/base_init_autoinit3_alt2.nit:22,11--13: Error: `foo` is not an autoinit method
--- /dev/null
+alt/base_init_autoinit3_alt4.nit:22,11--14: Error: unknown method `fail`
--- /dev/null
+alt/base_init_autoinit3_alt5.nit:22,11: Error: `b=` is not an autoinit method
+alt/base_init_autoinit3_alt5.nit:34,14: Error: `b=` is not an autoinit method
--- /dev/null
+alt/base_init_autoinit3_alt6.nit:40,2--41,9: Syntax error: `autoinit` expects method identifiers, use `noautoinit` to clear all autoinits.
--- /dev/null
+alt/base_init_autoinit3_alt7.nit:41,2--9: Error: `autoinit` and `noautoinit` are incompatible.
+alt/base_init_autoinit3_alt7.nit:41,2--9: Syntax error: `autoinit` expects method identifiers, use `noautoinit` to clear all autoinits.
--- /dev/null
+alt/base_init_autoinit3_alt8.nit:47,2--11: Warning: the list of autoinit is already empty.
+1
+2
+false
+3
+3.300000
+4
+true
+4.400000
-alt/base_init_noinit_alt5.nit:26,23--28: Error: `noinit` attributes cannot have an initial value
+alt/base_init_noinit_alt5.nit:26,23--28: Error: `noautoinit` attributes cannot have an initial value
--- /dev/null
+Runtime error: Uninitialized attribute _a (alt/base_init_autoinit3_alt1.nit:67)
+1
+2
+false
+3
+3.300000
+4
+true
+4.400000
var dst = "{dir}/copy.nit"
src.file_copy_to dst
-var file = new IFStream.open(dst)
+var file = new FileReader.open(dst)
printn file.read_all
file.close
# See the License for the specific language governing permissions and
# limitations under the License.
-var f = new IFStream.open("test_file_read.nit")
+var f = new FileReader.open("test_file_read.nit")
var s: String
while not f.eof do
s = f.read_line
# See the License for the specific language governing permissions and
# limitations under the License.
-var f = new IFStream.open("test_file_read.nit")
+var f = new FileReader.open("test_file_read.nit")
var s: String
while not f.eof do
s = f.read_line
# See the License for the specific language governing permissions and
# limitations under the License.
-var f = new IFStream.open("test_file_read.nit")
+var f = new FileReader.open("test_file_read.nit")
var s: String
while not f.eof do
s = f.read_line
# See the License for the specific language governing permissions and
# limitations under the License.
-var f = new IFStream.open("test_file_read.nit")
+var f = new FileReader.open("test_file_read.nit")
var s: String
while not f.eof do
s = f.read_line
# See the License for the specific language governing permissions and
# limitations under the License.
-var f = new IFStream.open("test_file_read.nit")
+var f = new FileReader.open("test_file_read.nit")
var s: String
while not f.eof do
s = f.read_line
# See the License for the specific language governing permissions and
# limitations under the License.
-var f = new IFStream.open("test_file_read.nit")
+var f = new FileReader.open("test_file_read.nit")
var s: String
while not f.eof do
s = f.read_line
# See the License for the specific language governing permissions and
# limitations under the License.
-var f = new IFStream.open("test_file_read.nit")
+var f = new FileReader.open("test_file_read.nit")
var s: String
while not f.eof do
s = f.read_line
# See the License for the specific language governing permissions and
# limitations under the License.
-var f = new IFStream.open("test_file_read.nit")
+var f = new FileReader.open("test_file_read.nit")
var s: String
while not f.eof do
s = f.read_line
AListExprs ../src/test_parser.nit:116,44
TCpar ")" ../src/test_parser.nit:116,45
ABlockExpr ../src/test_parser.nit:118,4--121,5
- AVardeclExpr ../src/test_parser.nit:118,4--31
+ AVardeclExpr ../src/test_parser.nit:118,4--33
TKwvar "var" ../src/test_parser.nit:118,4--6
TId "f" ../src/test_parser.nit:118,8
TAssign "=" ../src/test_parser.nit:118,10
- ANewExpr ../src/test_parser.nit:118,12--31
+ ANewExpr ../src/test_parser.nit:118,12--33
TKwnew "new" ../src/test_parser.nit:118,12--14
- AType ../src/test_parser.nit:118,16--23
- TClassid "IFStream" ../src/test_parser.nit:118,16--23
- TId "open" ../src/test_parser.nit:118,25--28
- AParExprs ../src/test_parser.nit:118,29--31
- TOpar "(" ../src/test_parser.nit:118,29
- ACallExpr ../src/test_parser.nit:118,30
- AImplicitSelfExpr ../src/test_parser.nit:118,30
- TId "a" ../src/test_parser.nit:118,30
- AListExprs ../src/test_parser.nit:118,30
- TCpar ")" ../src/test_parser.nit:118,31
+ AType ../src/test_parser.nit:118,16--25
+ TClassid "FileReader" ../src/test_parser.nit:118,16--25
+ TId "open" ../src/test_parser.nit:118,27--30
+ AParExprs ../src/test_parser.nit:118,31--33
+ TOpar "(" ../src/test_parser.nit:118,31
+ ACallExpr ../src/test_parser.nit:118,32
+ AImplicitSelfExpr ../src/test_parser.nit:118,32
+ TId "a" ../src/test_parser.nit:118,32
+ AListExprs ../src/test_parser.nit:118,32
+ TCpar ")" ../src/test_parser.nit:118,33
ACallAssignExpr ../src/test_parser.nit:119,4--32
AImplicitSelfExpr ../src/test_parser.nit:119,4
TId "source" ../src/test_parser.nit:119,4--9
Read token at ../src/test_parser.nit:118,8 text='f'
Read token at ../src/test_parser.nit:118,10 text='='
Read token at ../src/test_parser.nit:118,12--14 text='new'
-Read token at ../src/test_parser.nit:118,16--23 text='IFStream'
-Read token at ../src/test_parser.nit:118,24 text='.'
-Read token at ../src/test_parser.nit:118,25--28 text='open'
-Read token at ../src/test_parser.nit:118,29 text='('
-Read token at ../src/test_parser.nit:118,30 text='a'
-Read token at ../src/test_parser.nit:118,31 text=')'
-Read token at ../src/test_parser.nit:118,32--119,0 text='
+Read token at ../src/test_parser.nit:118,16--25 text='FileReader'
+Read token at ../src/test_parser.nit:118,26 text='.'
+Read token at ../src/test_parser.nit:118,27--30 text='open'
+Read token at ../src/test_parser.nit:118,31 text='('
+Read token at ../src/test_parser.nit:118,32 text='a'
+Read token at ../src/test_parser.nit:118,33 text=')'
+Read token at ../src/test_parser.nit:118,34--119,0 text='
'
Read token at ../src/test_parser.nit:119,4--9 text='source'
Read token at ../src/test_parser.nit:119,11 text='='
#alt1# tests = new Array[Serializable].with_items(a, b, c, d)
for o in tests do
- var stream = new StringOStream
+ var stream = new StringWriter
var serializer = new JsonSerializer(stream)
serializer.serialize(o)
# limitations under the License.
"out/test_directory_create.write/tmp_dir".mkdir
-var f = new OFStream.open("out/test_directory_create.write/tmp_file")
+var f = new FileWriter.open("out/test_directory_create.write/tmp_file")
f.write("test")
f.close
-f = new OFStream.open("out/test_directory_create.write/tmp_dir/tmp_file_2")
+f = new FileWriter.open("out/test_directory_create.write/tmp_dir/tmp_file_2")
f.write("other test")
f.close
print ""
-var ip = new IProcess("echo", "B hello world!")
+var ip = new ProcessReader("echo", "B hello world!")
ip.read_line.output
ip.wait
print ip.status
print ""
-var op = new OProcess.from_a("cat", null)
+var op = new ProcessWriter.from_a("cat", null)
op.write("C hello world!\n")
op.close
op.wait
print ""
-var iop = new IOProcess.from_a("cat", null)
+var iop = new ProcessDuplex.from_a("cat", null)
iop.write("D hello world!\n")
iop.read_line.output
iop.close
print ""
-var ioperr = new IOProcess.from_a("bad command", null)
+var ioperr = new ProcessDuplex.from_a("bad command", null)
ioperr.write("D hello world!\n")
ioperr.read_line.output
ioperr.close
import file
-var fd_in = new IFStream.from_fd(0)
-var fd_out = new OFStream.from_fd(1)
-var fd_err = new OFStream.from_fd(2)
+var fd_in = new FileReader.from_fd(0)
+var fd_out = new FileWriter.from_fd(1)
+var fd_err = new FileWriter.from_fd(2)
fd_out.write("Hello\n")
var dst = "{dir}/copy.nit"
src.file_copy_to dst
-var file = new IFStream.open(dst)
+var file = new FileReader.open(dst)
printn file.read_all
file.close
# See the License for the specific language governing permissions and
# limitations under the License.
-var ifs = new IFStream.open("donotcreate.bing")
+var ifs = new FileReader.open("donotcreate.bing")
var s = ifs.read_all
# See the License for the specific language governing permissions and
# limitations under the License.
-var f = new IFStream.open("test_file_read.nit")
+var f = new FileReader.open("test_file_read.nit")
var s: String
while not f.eof do
s = f.read_line
# See the License for the specific language governing permissions and
# limitations under the License.
-var f = new IFStream.open("test_file_read.nit")
+var f = new FileReader.open("test_file_read.nit")
print f.read_all
print "---"
-f = new IFStream.open("test_file_read.nit")
+f = new FileReader.open("test_file_read.nit")
print f.read_lines.join("\n")
print "---"
-f = new IFStream.open("test_file_read.nit")
+f = new FileReader.open("test_file_read.nit")
print f.each_line.to_a.join("\n")
print "---"
# See the License for the specific language governing permissions and
# limitations under the License.
-var f = new OFStream.open("out/test_file_write.write")
+var f = new FileWriter.open("out/test_file_write.write")
f.write("Quatre vingt et un : {421}\n")
f.write("Une autre ligne\nencore un")
f.write(['e', '\n'].to_s)
var filename_1 = "out/test_filterstream_tmp1.write"
var filename_2 = "out/test_filterstream_tmp2.write"
-var output_file_1 = new OFStream.open(filename_1)
-var output_file_2 = new OFStream.open(filename_2)
+var output_file_1 = new FileWriter.open(filename_1)
+var output_file_2 = new FileWriter.open(filename_2)
var stream_demux = new StreamDemux(output_file_1, output_file_2)
stream_demux.write("Hello World !!\n")
stream_demux.close
-var input_file_1 = new IFStream.open(filename_1)
-var input_file_2 = new IFStream.open(filename_2)
+var input_file_1 = new FileReader.open(filename_1)
+var input_file_2 = new FileReader.open(filename_2)
var stream_cat = new StreamCat(input_file_1,input_file_2)
import for_abuse
-var escape_f: nullable IStream = null
+var escape_f: nullable Reader = null
for f in file_open("test_for_abuse.nit") do
escape_f = f
print f.read_line
d.d = d
for o in new Array[Serializable].with_items(a, b, c, d) do
- var stream = new StringOStream
+ var stream = new StringWriter
var serializer = new JsonSerializer(stream)
serializer.serialize(o)
var p2
var p3
-p1 = new IProcess( "sleep", "0.2" )
-p2 = new IProcess( "sleep", "0.1" )
-p3 = new IProcess( "sleep", "0.4" )
+p1 = new ProcessReader( "sleep", "0.2" )
+p2 = new ProcessReader( "sleep", "0.1" )
+p3 = new ProcessReader( "sleep", "0.4" )
-var order = new Array[FStream]
+var order = new Array[FileStream]
var streams = [p1.stream_in, p2.stream_in, p3.stream_in]
while not streams.is_empty do
if s == null then continue # may have been interrupted
order.add( s )
- streams.remove( s.as(IFStream ) )
+ streams.remove( s.as(FileReader ) )
end
print order[0] == p2.stream_in