Since we plan on conforming with UTF-8, chars can no longer be of C char type, this PR changes the internal representation of a Char to become capable of holding an arbitrary Unicode code point.
Since chars become unsigned entities, and since NativeString will hold Byte values soon, its c type has been changed to unsigned char* as preparation for the migration
This is all related and necessary for #1262.
Pull-Request: #1407
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
Reviewed-by: Romain Chanoir <chanoir.romain@courrier.uqam.ca>
Reviewed-by: Jean Privat <jean@pryen.org>
end
# Return a null terminated char *
- fun to_cstring: NativeString do return flatten.to_cstring
+ fun to_cstring: NativeString is abstract
# The index of the last occurrence of an element starting from pos (in reverse order).
#
fun to_cmangle: String
do
if is_empty then return ""
- var res = new FlatBuffer
+ var res = new Buffer
var underscore = false
var start = 0
var c = chars[0]
# The exceptions are the common `\t` and `\n`.
fun escape_to_c: String
do
- var b = new FlatBuffer
+ var b = new Buffer
for i in [0..length[ do
var c = chars[i]
if c == '\n' then
# assert "ab|\{\}".escape_more_to_c("|\{\}") == "ab\\|\\\{\\\}"
fun escape_more_to_c(chars: String): String
do
- var b = new FlatBuffer
+ var b = new Buffer
for c in escape_to_c.chars do
if chars.chars.has(c) then
b.add('\\')
#
# assert "\n\"'\\\{\}0".escape_to_sh == "'\n\"'\\''\\\{\}0'"
fun escape_to_sh: String do
- var b = new FlatBuffer
+ var b = new Buffer
b.chars.add '\''
for i in [0..length[ do
var c = chars[i]
# These characters are `;`, `|`, `\`, and the non-printable ones.
# They will be rendered as `"?{hex}"`.
fun escape_to_mk: String do
- var b = new FlatBuffer
+ var b = new Buffer
for i in [0..length[ do
var c = chars[i]
if c == '$' then
# assert u.chars[0].ascii == 10 # (the ASCII value of the "new line" character)
fun unescape_nit: String
do
- var res = new FlatBuffer.with_capacity(self.length)
+ var res = new Buffer.with_cap(self.length)
var was_slash = false
for i in [0..length[ do
var c = chars[i]
# assert ".com/post?e=asdf&f=123".to_percent_encoding == ".com%2fpost%3fe%3dasdf%26f%3d123"
fun to_percent_encoding: String
do
- var buf = new FlatBuffer
+ var buf = new Buffer
for i in [0..length[ do
var c = chars[i]
# assert "invalid % usage".from_percent_encoding == "invalid ? usage"
fun from_percent_encoding: String
do
- var buf = new FlatBuffer
+ var buf = new Buffer
var i = 0
while i < length do
# SEE: <https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet#RULE_.231_-_HTML_Escape_Before_Inserting_Untrusted_Data_into_HTML_Element_Content>
fun html_escape: String
do
- var buf = new FlatBuffer
+ var buf = new Buffer
for i in [0..length[ do
var c = chars[i]
return escape_more_to_c("|\{\}<>")
end
- # Flat representation of self
- fun flatten: FlatText is abstract
-
private var hash_cache: nullable Int = null
redef fun hash
end
end
- redef fun flatten do return self
-
redef fun copy_to_native(dest, n, src_offset, dest_offset) do
items.copy_to(dest, n, src_offset, dest_offset)
end
do
if self.is_lower then return self
- var new_str = new FlatBuffer.with_capacity(self.length)
+ var new_str = new Buffer.with_cap(self.length)
var prev_is_lower = false
var prev_is_upper = false
do
if self.is_upper then return self
- var new_str = new FlatBuffer
+ var new_str = new Buffer
var is_first_char = true
var follows_us = false
fun capitalized: SELFTYPE do
if length == 0 then return self
- var buf = new FlatBuffer.with_capacity(length)
+ var buf = new Buffer.with_cap(length)
var curr = chars[0].to_upper
var prev = curr
abstract class Buffer
super Text
+ # New `Buffer` factory, will return a concrete `Buffer` type with default capacity
+ new do return new FlatBuffer
+
+ # New `Buffer` factory, returns a concrete `Buffer` with a capacity of `i`
+ new with_cap(i: Int) do return new FlatBuffer.with_capacity(i)
+
redef type SELFTYPE: Buffer is fixed
# Specific implementations MUST set this to `true` in order to invalidate caches
# Clears the buffer
#
- # var b = new FlatBuffer
+ # var b = new Buffer
# b.append "hello"
# assert not b.is_empty
# b.clear
# Adds the content of text `s` at the end of self
#
- # var b = new FlatBuffer
+ # var b = new Buffer
# b.append "hello"
# b.append "world"
# assert b == "helloworld"
# `self` is appended in such a way that `self` is repeated `r` times
#
- # var b = new FlatBuffer
+ # var b = new Buffer
# b.append "hello"
# b.times 3
# assert b == "hellohellohello"
# Reverses itself in-place
#
- # var b = new FlatBuffer
+ # var b = new Buffer
# b.append("hello")
# b.reverse
# assert b == "olleh"
# Changes each lower-case char in `self` by its upper-case variant
#
- # var b = new FlatBuffer
+ # var b = new Buffer
# b.append("Hello World!")
# b.upper
# assert b == "HELLO WORLD!"
# Changes each upper-case char in `self` by its lower-case variant
#
- # var b = new FlatBuffer
+ # var b = new Buffer
# b.append("Hello World!")
# b.lower
# assert b == "hello world!"
length = 0
end
- redef fun empty do return new FlatBuffer
+ redef fun empty do return new Buffer
redef fun enlarge(cap)
do
var r = new FlatBuffer.with_infos(r_items, len, len)
return r
else
- return new FlatBuffer
+ return new Buffer
end
end
# assert 'x'.to_s == "x"
redef fun to_s
do
- var s = new FlatBuffer.with_capacity(1)
+ var s = new Buffer.with_cap(1)
s.chars[0] = self
return s.to_s
end
# Concatenate element without separators
fun plain_to_s: String
do
- var s = new FlatBuffer
+ var s = new Buffer
for e in self do if e != null then s.append(e.to_s)
return s.to_s
end
do
if is_empty then return ""
- var s = new FlatBuffer # Result
+ var s = new Buffer # Result
# Concat first item
var i = iterator
do
if is_empty then return ""
- var s = new FlatBuffer # Result
+ var s = new Buffer # Result
# Concat first item
var i = iterator
return mdoc.cs_short_comment
end
- # Returns 1self` as a list element that can be displayed in console.
+ # Returns `self` as a list element that can be displayed in console.
+ #
+ # Displays `cs_icon`, `cs_name`, `cs_short_comment, `cs_namespace`,
+ # `cs_declaration` and `cs_location`.
fun cs_list_item: String do
var tpl = new FlatBuffer
tpl.append " {cs_visibility_color(cs_icon).bold} {cs_name.blue.bold}"
return tpl.write_to_string
end
+ # Returns `self` as a short list element that can be displayed in console.
+ # Displays `cs_icon`, `cs_name`, and `cs_short_comment.
+ fun cs_short_list_item: String do
+ var tpl = new FlatBuffer
+ tpl.append " {cs_visibility_color(cs_icon).bold} {cs_name.blue.bold}"
+ var comment = cs_short_comment
+ if comment != null then
+ tpl.append " # {comment}".green
+ end
+ return tpl.write_to_string
+ end
+
# ASCII icon to be displayed in front of the list item.
fun cs_icon: String do return "*"
# Title that can be decorated for console display.
#
# Set as `null` if you don't want to display a title.
- var cs_title: nullable String is noinit, writable
+ var cs_title: nullable String is writable, lazy do return title
# Subtitle that can be decorated for console display.
#
end
redef class IntroArticle
- redef var cs_title = null
- redef var cs_subtitle = null
-
redef fun render_body do
addn " {mentity.cs_declaration.bold}"
addn " {mentity.cs_location.gray.bold}"
end
redef class ConcernsArticle
- redef var cs_title = "Concerns"
- redef var cs_subtitle = null
-
redef fun render_body do
var w = new StringWriter
concerns.write_to(w)
super
end
end
+
+redef class MEntitiesListArticle
+ redef fun render_body do
+ for mentity in mentities do
+ addn mentity.cs_short_list_item
+ end
+ end
+end
import semantize
import doc_extract
+import doc_poset
import doc::console_templates
# Nitx handles console I/O.
# Displays the list of available commands.
fun help do
- print "\nCommands:"
- print "\tname\t\tlookup module, class and property with the corresponding 'name'"
+ print "\nCommands:\n"
+ print "\tname\t\t\tlookup module, class and property with the corresponding 'name'"
print "\tdoc: <name::space>\tdisplay the documentation page of 'namespace'"
- print "\tparam: <Type>\tlookup methods using the corresponding 'Type' as parameter"
- print "\treturn: <Type>\tlookup methods returning the corresponding 'Type'"
- print "\tnew: <Type>\tlookup methods creating new instances of 'Type'"
- print "\tcall: <name>\tlookup methods calling 'name'"
- print "\tcode: <name>\tdisplay the source code associated to the 'name' entity"
- print "\t:h\t\tdisplay this help message"
- print "\t:q\t\tquit interactive mode"
+ print "\nType lookup:"
+ print "\tparam: <Type>\t\tlookup methods using the corresponding 'Type' as parameter"
+ print "\treturn: <Type>\t\tlookup methods returning the corresponding 'Type'"
+ print "\tnew: <Type>\t\tlookup methods creating new instances of 'Type'"
+ print "\tcall: <name>\t\tlookup methods calling 'name'"
+ print "\nHierarchy lookup:"
+ print "\tparents: <Class>\tlist direct parents of 'Class'"
+ print "\tancestors: <Class>\tlist all ancestors of 'Class'"
+ print "\tchildren: <Class>\tlist direct children of 'Class'"
+ print "\tdescendants: <Class>\tlist all descendants of 'Class'"
+ print "\nCode lookup:"
+ print "\tcode: <name>\t\tdisplay the source code associated to the 'name' entity"
+ print "\n"
+ print "\t:h\t\t\tdisplay this help message"
+ print "\t:q\t\t\tquit interactive mode"
print ""
end
# Processes the query string and performs it.
fun do_query(str: String) do
- var query = parse_query(str)
- var res = query.perform(self, doc)
- var page = query.make_results(self, res)
- print page.write_to_string
- end
-
- # Returns an `NitxQuery` from a raw query string.
- fun parse_query(str: String): NitxQuery do
var query = new NitxQuery(str)
if query isa NitxCommand then
query.execute(self)
+ return
end
- return query
+ var res = query.perform(self, doc)
+ var page = query.make_results(self, res)
+ print page.write_to_string
end
end
return new CallQuery(query_string)
else if query_string.has_prefix("code:") then
return new CodeQuery(query_string)
-
+ else if query_string.has_prefix("parents:") then
+ return new ParentsQuery(query_string)
+ else if query_string.has_prefix("ancestors:") then
+ return new AncestorsQuery(query_string)
+ else if query_string.has_prefix("children:") then
+ return new ChildrenQuery(query_string)
+ else if query_string.has_prefix("descendants:") then
+ return new DescendantsQuery(query_string)
end
return new CommentQuery("comment: {query_string}")
end
end
end
+# Search in class or module hierarchy of a `MEntity`.
+#
+# It actually searches for pages about the mentity and extracts the
+# pre-calculated hierarchies by the `doc_post` phase.
+abstract class HierarchiesQuery
+ super DocQuery
+
+ redef fun make_results(nitx, results) do
+ var page = new DocPage("hierarchy", "Hierarchy")
+ for result in results do
+ if not result isa PageMatch then continue
+ var rpage = result.page
+ if not rpage isa MClassPage then continue
+ page.root.add_child build_article(rpage)
+ end
+ return page
+ end
+
+ # Build an article containing the hierarchy list depending on subclasses.
+ private fun build_article(page: MClassPage): DocArticle is abstract
+end
+
+# List all parents of a `MClass`.
+class AncestorsQuery
+ super HierarchiesQuery
+
+ redef fun build_article(page) do
+ return new MEntitiesListArticle(
+ "ancerstors",
+ "Ancestors for {page.mentity.name}",
+ page.ancestors.to_a)
+ end
+end
+
+# List direct parents of a `MClass`.
+class ParentsQuery
+ super HierarchiesQuery
+
+ redef fun build_article(page) do
+ return new MEntitiesListArticle(
+ "parents",
+ "Parents for {page.mentity.name}",
+ page.parents.to_a)
+ end
+end
+
+# List direct children of a `MClass`.
+class ChildrenQuery
+ super HierarchiesQuery
+
+ redef fun build_article(page) do
+ return new MEntitiesListArticle(
+ "children",
+ "Children for {page.mentity.name}",
+ page.children.to_a)
+ end
+end
+
+# List all descendants of a `MClass`.
+class DescendantsQuery
+ super HierarchiesQuery
+
+ redef fun build_article(page) do
+ return new MEntitiesListArticle(
+ "descendants",
+ "Descendants for {page.mentity.name}",
+ page.children.to_a)
+ end
+end
+
# A query to search source code from a file name.
class CodeQuery
super MetaQuery
new ExtractionPhase(toolcontext, doc),
new MakePagePhase(toolcontext, doc),
new ConcernsPhase(toolcontext, doc),
- new StructurePhase(toolcontext, doc): DocPhase]
+ new StructurePhase(toolcontext, doc),
+ new POSetPhase(toolcontext, doc): DocPhase]
for phase in phases do
toolcontext.info("# {phase.class_name}", 1)
end
end
+redef class AAssertExpr
+ redef fun accept_scope_visitor(v)
+ do
+ v.enter_visit(n_expr)
+ v.enter_visit_block(n_else, null)
+ end
+end
+
redef class AVarFormExpr
# The associated variable
var variable: nullable Variable
--- /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.
+
+class Foo
+ fun start do end
+ fun finish do end
+ redef fun output do 0.output
+end
+var foo = new Foo
+var maybe: Bool = true
+
+#alt1#var a = 0
+#alt1#var b = 0
+#alt1#var c = 0
+
+if maybe then
+ if maybe then var a = 1 else var a = 2
+ while maybe do
+ while false do var a = 3
+ loop
+ do
+ do var a = 4
+ with a = foo do
+ a.output
+ with b = foo do var c = 5
+ var b = 6
+ b.output
+ var c = 7
+ c.output
+ end
+
+ for a in [8] do
+ a.output
+ for b in [9] do var c = 10
+ var b = 11
+ b.output
+ var c = 12
+ c.output
+ end
+ assert maybe else
+ assert maybe else var a = 13
+ var a = 14
+ a.output
+ end
+ var a = 15
+ a.output
+ end
+ var a = 16
+ a.output
+ if maybe then break
+ end
+ var a = 17
+ a.output
+ if maybe then break
+ end
+ var a = 18
+ a.output
+else if maybe then
+ var a = 19
+ a.output
+else
+ var a = 20
+ a.output
+end
+var a = 21
+a.output
--- /dev/null
+0
+6
+7
+8
+11
+12
+15
+16
+17
+18
+21
--- /dev/null
+alt/base_scope_alt1.nit:28,20: Error: a variable named `a` already exists.
+alt/base_scope_alt1.nit:28,35: Error: a variable named `a` already exists.
+alt/base_scope_alt1.nit:30,22: Error: a variable named `a` already exists.
+alt/base_scope_alt1.nit:33,12: Error: a variable named `a` already exists.
+alt/base_scope_alt1.nit:34,10: Error: a variable named `a` already exists.
+alt/base_scope_alt1.nit:36,11: Error: a variable named `b` already exists.
+alt/base_scope_alt1.nit:36,26: Error: a variable named `c` already exists.
+alt/base_scope_alt1.nit:37,10: Error: a variable named `b` already exists.
+alt/base_scope_alt1.nit:39,10: Error: a variable named `c` already exists.
+alt/base_scope_alt1.nit:43,9: Error: a variable named `a` already exists.
+alt/base_scope_alt1.nit:45,10: Error: a variable named `b` already exists.
+alt/base_scope_alt1.nit:45,26: Error: a variable named `c` already exists.
+alt/base_scope_alt1.nit:46,10: Error: a variable named `b` already exists.
+alt/base_scope_alt1.nit:48,10: Error: a variable named `c` already exists.
+alt/base_scope_alt1.nit:52,28: Error: a variable named `a` already exists.
+alt/base_scope_alt1.nit:53,10: Error: a variable named `a` already exists.
+alt/base_scope_alt1.nit:56,9: Error: a variable named `a` already exists.
+alt/base_scope_alt1.nit:59,8: Error: a variable named `a` already exists.
+alt/base_scope_alt1.nit:63,7: Error: a variable named `a` already exists.
+alt/base_scope_alt1.nit:67,6: Error: a variable named `a` already exists.
+alt/base_scope_alt1.nit:70,6: Error: a variable named `a` already exists.
+alt/base_scope_alt1.nit:73,6: Error: a variable named `a` already exists.
+alt/base_scope_alt1.nit:76,5: Error: a variable named `a` already exists.