Merge: Native Types
authorJean Privat <jean@pryen.org>
Wed, 3 Jun 2015 01:58:32 +0000 (21:58 -0400)
committerJean Privat <jean@pryen.org>
Wed, 3 Jun 2015 01:58:32 +0000 (21:58 -0400)
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>

VERSION
lib/standard/string.nit
src/doc/console_templates/console_model.nit
src/doc/console_templates/console_templates.nit
src/doc/doc_phases/doc_console.nit
src/nitx.nit
src/semantize/scope.nit
tests/base_scope.nit [new file with mode: 0644]
tests/sav/base_scope.res [new file with mode: 0644]
tests/sav/base_scope_alt1.res [new file with mode: 0644]

diff --git a/VERSION b/VERSION
index 520c9c2..aed5a7d 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-v0.7.4
+v0.7.5
index 7fe5de3..95aa984 100644 (file)
@@ -127,7 +127,7 @@ abstract class Text
        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).
        #
@@ -495,7 +495,7 @@ abstract class Text
        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]
@@ -551,7 +551,7 @@ abstract class Text
        # 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
@@ -591,7 +591,7 @@ abstract class Text
        #     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('\\')
@@ -612,7 +612,7 @@ abstract class Text
        #
        #     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]
@@ -633,7 +633,7 @@ abstract class Text
        # 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
@@ -659,7 +659,7 @@ abstract class Text
        #     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]
@@ -694,7 +694,7 @@ abstract class Text
        #     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]
@@ -723,7 +723,7 @@ abstract class Text
        #     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
@@ -760,7 +760,7 @@ abstract class Text
        # 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]
@@ -838,9 +838,6 @@ abstract class Text
                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
@@ -956,8 +953,6 @@ abstract class FlatText
                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
@@ -1065,7 +1060,7 @@ abstract class String
        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
 
@@ -1113,7 +1108,7 @@ abstract class String
        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
 
@@ -1148,7 +1143,7 @@ abstract class String
        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
@@ -1546,6 +1541,12 @@ end
 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
@@ -1571,7 +1572,7 @@ abstract class Buffer
 
        # Clears the buffer
        #
-       #     var b = new FlatBuffer
+       #     var b = new Buffer
        #     b.append "hello"
        #     assert not b.is_empty
        #     b.clear
@@ -1583,7 +1584,7 @@ abstract class Buffer
 
        # 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"
@@ -1591,7 +1592,7 @@ abstract class Buffer
 
        # `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"
@@ -1599,7 +1600,7 @@ abstract class Buffer
 
        # Reverses itself in-place
        #
-       #     var b = new FlatBuffer
+       #     var b = new Buffer
        #     b.append("hello")
        #     b.reverse
        #     assert b == "olleh"
@@ -1607,7 +1608,7 @@ abstract class Buffer
 
        # 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!"
@@ -1615,7 +1616,7 @@ abstract class Buffer
 
        # 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!"
@@ -1721,7 +1722,7 @@ class FlatBuffer
                length = 0
        end
 
-       redef fun empty do return new FlatBuffer
+       redef fun empty do return new Buffer
 
        redef fun enlarge(cap)
        do
@@ -1845,7 +1846,7 @@ class FlatBuffer
                        var r = new FlatBuffer.with_infos(r_items, len, len)
                        return r
                else
-                       return new FlatBuffer
+                       return new Buffer
                end
        end
 
@@ -2204,7 +2205,7 @@ redef class Char
        #     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
@@ -2254,7 +2255,7 @@ redef class Collection[E]
        # 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
@@ -2267,7 +2268,7 @@ redef class Collection[E]
        do
                if is_empty then return ""
 
-               var s = new FlatBuffer # Result
+               var s = new Buffer # Result
 
                # Concat first item
                var i = iterator
@@ -2390,7 +2391,7 @@ redef class Map[K,V]
        do
                if is_empty then return ""
 
-               var s = new FlatBuffer # Result
+               var s = new Buffer # Result
 
                # Concat first item
                var i = iterator
index dee8a74..5d693b1 100644 (file)
@@ -94,7 +94,10 @@ redef class MEntity
                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}"
@@ -111,6 +114,18 @@ redef class MEntity
                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 "*"
 
index e94a388..6e8f03e 100644 (file)
@@ -35,7 +35,7 @@ redef class DocComposite
        # 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.
        #
@@ -87,9 +87,6 @@ redef class MEntityComposite
 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}"
@@ -104,9 +101,6 @@ redef class IntroArticle
 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)
@@ -135,3 +129,11 @@ redef class DefinitionArticle
                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
index 4c0c193..b6d08dc 100644 (file)
@@ -20,6 +20,7 @@ module doc_console
 
 import semantize
 import doc_extract
+import doc_poset
 import doc::console_templates
 
 # Nitx handles console I/O.
@@ -58,16 +59,24 @@ class Nitx
 
        # 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
 
@@ -80,19 +89,14 @@ class Nitx
 
        # 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
 
@@ -129,7 +133,14 @@ interface NitxQuery
                        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
@@ -361,6 +372,76 @@ class PageMatch
        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
index 23490a8..cf5ab95 100644 (file)
@@ -48,7 +48,8 @@ private class NitxPhase
                        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)
index 4ea5f27..a69c57a 100644 (file)
@@ -429,6 +429,14 @@ redef class AWithExpr
        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
diff --git a/tests/base_scope.nit b/tests/base_scope.nit
new file mode 100644 (file)
index 0000000..5012785
--- /dev/null
@@ -0,0 +1,77 @@
+# 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
diff --git a/tests/sav/base_scope.res b/tests/sav/base_scope.res
new file mode 100644 (file)
index 0000000..25e862a
--- /dev/null
@@ -0,0 +1,11 @@
+0
+6
+7
+8
+11
+12
+15
+16
+17
+18
+21
diff --git a/tests/sav/base_scope_alt1.res b/tests/sav/base_scope_alt1.res
new file mode 100644 (file)
index 0000000..8868091
--- /dev/null
@@ -0,0 +1,23 @@
+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.