#
# $Id: parsedclass.icn,v 1.1 2004-02-12 17:01:53 rparlett Exp $
#
# This file is in the public domain.
#
# Author: Robert Parlett (parlett@dial.pipex.com)
#
#
# Updated: Bruce Rennie - convert all standard Unicon functions to have "::" prefix
# Date:    2020-12-28
# Updated: Bruce Rennie - define all local variables as local, to prevent problems
#                         when using the Unicon compiler -n option
# Date:    2021-01-03
#
#

package parser

link ximage

class ParsedClass : ParsedObject(superclasses,
                                 superclasses_nodes,
                                 methods,
                                 variables,
                                 initially_method)
   method add_method(n)
      ::put(methods, ParsedMethod(n, self))
   end

   method init(n)
      local supers, arglist, sc, pref, t, x, tok, locals_node

      superclasses := []
      superclasses_nodes := []
      methods := []
      variables := []
      initially_method := &null

      name := n.children[1].s
      t := n.children[2]
      if t.label == "supers" then {
         supers := t.children
         every sc := supers[1 to *supers] do {
            if ::type(sc) == "token" then {
               pref := sc.s
            } else if sc.label == "packageref" then {
               #
               # It's a packageref node
               #
               if /sc.children[1] then
                  pref := "::" || sc.children[2].s
               else
                  pref := sc.children[1].s || "::" || sc.children[2].s
            } else {
               parsing_error(sc)
               sc := &null
               pref := ""
            }
            ::put(superclasses, pref)
            ::put(superclasses_nodes, sc)
         }

      } else {
         parsing_error(t)
      }

      t := n.children[3]
      if t.label == "cparmlist" then {
         every x := t.children[1 to *t.children] do {
            if ::type(x.children[2].children[1]) == "token" then
               ::put(variables, x.children[2].children[1].s)
            else
               parsing_error(t)
         }
      } else {
         parsing_error(t)
      }
      #::write("variables:", ximage(variables))

      if n.children[5].label == "clocals" then {
         locals_node := n.children[5]
         every x := (\locals_node.children)[1 to *locals_node.children] do {
            every t := x.children[1 to *x.children] do {
               every tok := t.children[1 to * t.children] do {
                  ::put(variables, tok.children[1].s)
               }
            }
         }
      } else {
         parsing_error(n.children[5])
      }

      if n.children[6].label == "methods" then {
         every x := n.children[6].children[1 to *n.children[6].children] do {
            case x.label of {
               # "Inner" records/globals are treated as
               # top-level definitions.
               "record" : parent.add_record(x)
               "global" : parent.add_global(x)
               "method" :  add_method(x)
               "abstract" : add_method(x.children[1])
            }
         }
      } else {
         parsing_error(n.children[6])
      }
      if n.children[8].label == "initially" then {
         initially_method := ParsedInitiallyMethod(n.children[8], self)

      } else {
         parsing_error(n.children[8])
      }

   end

   method to_string()
      local s

      s := "class " || name
      every s ||:= " : " || !superclasses
      s ||:= "("
      every s ||:= !variables || ","
      if *variables > 0 then
         s[-1] := ""
      s ||:= ")"

      every s ||:= "\n" || (!methods).to_string()
      s ||:= "\n" || (\initially_method).to_string()
      return s
   end

   initially(n, p)
      self.ParsedObject.initially(n, p)
end
