Some minor optimizations after looking at reports of valgrind.
Pull-Request: #1191
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
return default
end
- # Alias for `keys.has`
+ # Is there an item associated with `key`?
+ #
+ # var x = new HashMap[String, Int]
+ # x["four"] = 4
+ # assert x.has_key("four") == true
+ # assert x.has_key("five") == false
+ #
+ # By default it is a synonymous to `keys.has` but could be redefined with a direct implementation.
fun has_key(key: K): Bool do return self.keys.has(key)
# Get a new iterator on the map.
return c.second
end
end
+
+ redef fun has_key(key) do return couple_at(key) != null
end
# Iterator on CoupleMap
end
end
- redef fun iterator: ArrayIterator[E] do return new ArrayIterator[E](self)
+ redef fun iterator: ArrayIterator[E] do
+ var res = _free_iterator
+ if res == null then return new ArrayIterator[E](self)
+ res._index = 0
+ _free_iterator = null
+ return res
+ end
+
+ # An old iterator, free to reuse.
+ # Once an iterator is `finish`, it become reusable.
+ # Since some arrays are iterated a lot, this avoid most of the
+ # continuous allocation/garbage-collection of the needed iterators.
+ private var free_iterator: nullable ArrayIterator[E] = null
+
redef fun reverse_iterator do return new ArrayReverseIterator[E](self)
end
redef var index = 0
var array: AbstractArrayRead[E]
+
+ redef fun finish do _array._free_iterator = self
end
private class ArrayReverseIterator[E]
end
end
- redef var keys: RemovableCollection[K] = new ArrayMapKeys[K, E](self)
- redef var values: RemovableCollection[E] = new ArrayMapValues[K, E](self)
+ redef var keys: RemovableCollection[K] = new ArrayMapKeys[K, E](self) is lazy
+ redef var values: RemovableCollection[E] = new ArrayMapValues[K, E](self) is lazy
# O(1)
redef fun length do return _items.length
enlarge(0)
end
- redef var keys: RemovableCollection[K] = new HashMapKeys[K, V](self)
- redef var values: RemovableCollection[V] = new HashMapValues[K, V](self)
+ redef var keys: RemovableCollection[K] = new HashMapKeys[K, V](self) is lazy
+ redef var values: RemovableCollection[V] = new HashMapValues[K, V](self) is lazy
+ redef fun has_key(k) do return node_at(k) != null
end
# View of the keys of a HashMap
_file = new NativeFile.native_stdout
path = "/dev/stdout"
_is_writable = true
+ set_buffering_mode(256, sys.buffer_mode_line)
end
end
redef class Sys
- init do
- if stdout isa FileStream then stdout.as(FileStream).set_buffering_mode(256, buffer_mode_line)
- end
-
# Standard input
- var stdin: PollableReader = new Stdin is protected writable
+ var stdin: PollableReader = new Stdin is protected writable, lazy
# Standard output
- var stdout: Writer = new Stdout is protected writable
+ var stdout: Writer = new Stdout is protected writable, lazy
# Standard output for errors
- var stderr: Writer = new Stderr is protected writable
+ var stderr: Writer = new Stderr is protected writable, lazy
# Enumeration for buffer mode full (flushes when buffer is full)
fun buffer_mode_full: Int is extern "file_Sys_Sys_buffer_mode_full_0"
do
return is_lower or is_upper
end
+
+ # Is self a whitespace character?
+ #
+ # These correspond to the "Other" and "Separator" groups of the Unicode.
+ #
+ # In the ASCII encoding, this is those <= to space (0x20) plus delete (0x7F).
+ #
+ # assert 'A'.is_whitespace == false
+ # assert ','.is_whitespace == false
+ # assert ' '.is_whitespace == true
+ # assert '\t'.is_whitespace == true
+ fun is_whitespace: Bool
+ do
+ var i = ascii
+ return i <= 0x20 or i == 0x7F
+ end
end
# Pointer classes are used to manipulate extern C structures.
# Is there something to read.
# This function returns 'false' if there is something to read.
fun eof: Bool is abstract
+
+ # Read the next sequence of non whitespace characters.
+ #
+ # Leading whitespace characters are skipped.
+ # The first whitespace character that follows the result is consumed.
+ #
+ # An empty string is returned if the end of the file or an error is encounter.
+ #
+ # ~~~
+ # var w = new StringReader(" Hello, \n\t World!")
+ # assert w.read_word == "Hello,"
+ # assert w.read_char == '\n'.ascii
+ # assert w.read_word == "World!"
+ # assert w.read_word == ""
+ # ~~~
+ #
+ # `Char::is_whitespace` determines what is a whitespace.
+ fun read_word: String
+ do
+ var buf = new FlatBuffer
+ var c = read_nonwhitespace
+ if c > 0 then
+ buf.add(c.ascii)
+ while not eof do
+ c = read_char
+ if c < 0 then break
+ var a = c.ascii
+ if a.is_whitespace then break
+ buf.add(a)
+ end
+ end
+ var res = buf.to_s
+ return res
+ end
+
+ # Skip whitespace characters (if any) then return the following non-whitespace character.
+ #
+ # Returns the code point of the character.
+ # Return -1 on end of file or error.
+ #
+ # In fact, this method works like `read_char` except it skips whitespace.
+ #
+ # ~~~
+ # var w = new StringReader(" \nab\tc")
+ # assert w.read_nonwhitespace == 'a'.ascii
+ # assert w.read_nonwhitespace == 'b'.ascii
+ # assert w.read_nonwhitespace == 'c'.ascii
+ # assert w.read_nonwhitespace == -1
+ # ~~~
+ #
+ # `Char::is_whitespace` determines what is a whitespace.
+ fun read_nonwhitespace: Int
+ do
+ var c = -1
+ while not eof do
+ c = read_char
+ if c < 0 or not c.ascii.is_whitespace then break
+ end
+ return c
+ end
end
# Iterator returned by `Reader::each_line`.
#
# assert " \n\thello \n\t".l_trim == "hello \n\t"
#
- # A whitespace is defined as any character which ascii value is less than or equal to 32
+ # `Char::is_whitespace` determines what is a whitespace.
fun l_trim: SELFTYPE
do
var iter = self.chars.iterator
while iter.is_ok do
- if iter.item.ascii > 32 then break
+ if not iter.item.is_whitespace then break
iter.next
end
if iter.index == length then return self.empty
#
# assert " \n\thello \n\t".r_trim == " \n\thello"
#
- # A whitespace is defined as any character which ascii value is less than or equal to 32
+ # `Char::is_whitespace` determines what is a whitespace.
fun r_trim: SELFTYPE
do
var iter = self.chars.reverse_iterator
while iter.is_ok do
- if iter.item.ascii > 32 then break
+ if not iter.item.is_whitespace then break
iter.next
end
if iter.index < 0 then return self.empty
end
# Trims trailing and preceding white spaces
- # A whitespace is defined as any character which ascii value is less than or equal to 32
#
# assert " Hello World ! ".trim == "Hello World !"
# assert "\na\nb\tc\t".trim == "a\nb\tc"
+ #
+ # `Char::is_whitespace` determines what is a whitespace.
fun trim: SELFTYPE do return (self.l_trim).r_trim
+ # Is the string non-empty but only made of whitespaces?
+ #
+ # assert " \n\t ".is_whitespace == true
+ # assert " hello ".is_whitespace == false
+ # assert "".is_whitespace == false
+ #
+ # `Char::is_whitespace` determines what is a whitespace.
+ fun is_whitespace: Bool
+ do
+ if is_empty then return false
+ for c in self.chars do
+ if not c.is_whitespace then return false
+ end
+ return true
+ end
+
# Returns `self` removed from its last line terminator (if any).
#
# assert "Hello\n".chomp == "Hello"
# Indes in _items of the last item of the string
private var index_to: Int is noinit
- redef var chars: SequenceRead[Char] = new FlatStringCharView(self)
+ redef var chars: SequenceRead[Char] = new FlatStringCharView(self) is lazy
redef fun [](index)
do
super FlatText
super Buffer
- redef var chars: Sequence[Char] = new FlatBufferCharView(self)
+ redef var chars: Sequence[Char] = new FlatBufferCharView(self) is lazy
private var capacity: Int = 0
var n_kwlabel: TKwlabel is writable, noinit
# The name of the label, if any
- var n_id: nullable TId is writable
+ var n_id: nullable TId is writable, noinit
end
# Expression and statements
super AExpr
# The `self` keyword
- var n_kwself: nullable TKwself is writable
+ var n_kwself: nullable TKwself = null is writable
end
# When there is no explicit receiver, `self` is implicit
return
end
- # FIXME: THIS IS STUPID (be here to keep the old code working)
- if not mpropdef.mclassdef.is_intro then return
-
# Do we inherit for a constructor?
var skip = true
for cd in mclassdef.in_hierarchy.direct_greaters do
if not mpropdef.is_intro then
auto_super_call = true
mpropdef.has_supercall = true
+ modelbuilder.toolcontext.info("Auto-super call for {mpropdef}", 4)
return
end
var callsite = new CallSite(self, recvtype, mmodule, anchor, true, candidate, candidatedef, msignature, false)
auto_super_inits.add(callsite)
+ modelbuilder.toolcontext.info("Old-style auto-super init for {mpropdef} to {candidate.full_name}", 4)
end
# No old style? The look for new-style super constructors (called from a old style constructor)
var callsite = new CallSite(self, recvtype, mmodule, anchor, true, the_root_init_mmethod, candidatedef, msignature, false)
auto_super_inits.add(callsite)
+ modelbuilder.toolcontext.info("Auto-super init for {mpropdef} to {the_root_init_mmethod.full_name}", 4)
end
if auto_super_inits.is_empty then
modelbuilder.error(self, "Error: No constructors to call implicitely in {mpropdef}. Call one explicitely.")
--- /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 base_init
+
+redef class A
+ init
+ do
+ 'a'.output
+ end
+end
+
+redef class B
+ init
+ do
+ 'b'.output
+ end
+end
+
+redef class C
+ init
+ do
+ 'c'.output
+ end
+end
--- /dev/null
+Aa
+AaBb
+Aac
Numeric -> Int [dir=back arrowtail=open style=dashed];
Char [
- label = "{Char||+ to_i(): Int\l+ ascii(): Int\l+ to_lower(): Char\l+ to_upper(): Char\l+ is_digit(): Bool\l+ is_lower(): Bool\l+ is_upper(): Bool\l+ is_letter(): Bool\l}"
+ label = "{Char||+ to_i(): Int\l+ ascii(): Int\l+ to_lower(): Char\l+ to_upper(): Char\l+ is_digit(): Bool\l+ is_lower(): Bool\l+ is_upper(): Bool\l+ is_letter(): Bool\l+ is_whitespace(): Bool\l}"
]
Discrete -> Char [dir=back arrowtail=open style=dashed];
Numeric -> Int [dir=back arrowtail=open style=dashed];
Char [
- label = "{Char||+ to_i(): Int\l+ ascii(): Int\l+ to_lower(): Char\l+ to_upper(): Char\l+ is_digit(): Bool\l+ is_lower(): Bool\l+ is_upper(): Bool\l+ is_letter(): Bool\l}"
+ label = "{Char||+ to_i(): Int\l+ ascii(): Int\l+ to_lower(): Char\l+ to_upper(): Char\l+ is_digit(): Bool\l+ is_lower(): Bool\l+ is_upper(): Bool\l+ is_letter(): Bool\l+ is_whitespace(): Bool\l}"
]
Discrete -> Char [dir=back arrowtail=open style=dashed];
-Runtime error: Cast failed. Expected `E`, got `Bool` (../lib/standard/collection/array.nit:894)
+Runtime error: Cast failed. Expected `E`, got `Bool` (../lib/standard/collection/array.nit:909)
NativeString
N
Nit