File: model/abstraction.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: TmDoc#7
  module: Model
  module: Abstraction#9
  class: Store#11
inherits from
  Abstract ( TmStd::Lsm::Product )
  module: Path#15
  class: Abstract#17
includes
  Equalable ( TmStd::Lsm::Collection::Sequence )
  Comparable ( TmStd::Lsm::Collection::Sequence )
inherits from
  Abstract ( TmStd::Lsm::Collection::Sequence )
has properties
method: initialize / 1 #22
method: join / 1 #29
method: to_s / 1 #38
method: __path_separator_string__ #49
  class: Absolute#62
inherits from
  Abstract ( TmDoc::Model::Abstraction::Path )
has properties
class method: new_root #63
method: + / 1 #68
method: to_s / 1 #77
  class: SetOfPath#88
inherits from
  Abstract ( TmStd::Lsm::Collection::Set )
has properties
constant: LSM_ELEMENT_CLASS #89
  class: Relative#94
inherits from
  Abstract ( TmDoc::Model::Abstraction::Path )
has properties
method: to_absolute #95
method: + / 1 #104
method: __absolute_path_class__ #113
  module: Subject#128
  class: GenericSubject#130
includes
  Comparable ( Builtin-Module )
inherits from
  Abstract ( TmStd::Lsm::Product )
has properties
method: == / 1 #134
method: eql? / 1 #141
method: hash #146
method: freeze_equality! #151
method: <=> / 1 #156
  class: SeqOfGenericSubject#163
inherits from
  Abstract ( TmStd::Lsm::Collection::Sequence )
has properties
constant: LSM_ELEMENT_CLASS #164
  class: SetOfGenericSubject#169
inherits from
  Abstract ( TmStd::Lsm::Collection::Set )
has properties
constant: LSM_ELEMENT_CLASS #170
  class: PhysicalSubject#175
inherits from
  GenericSubject ( TmDoc::Model::Abstraction::Subject )
has properties
attribute: name [R] #176
attribute: seq_num [R] #176
attribute: hash [R] #177
method: initialize / 2 #180
method: eql? / 1 #194
method: freeze_equality! #201
method: <=> / 1 #206
method: to_s / 1 #219
method: print / 1 #228
  class: SetOfPhysicalSubject#244
inherits from
  SetOfGenericSubject ( TmDoc::Model::Abstraction::Subject )
has properties
constant: LSM_ELEMENT_CLASS #245
  class: LogicalSubject#250
inherits from
  GenericSubject ( TmDoc::Model::Abstraction::Subject )
has properties
attribute: location [R] #251
attribute: above_path [R] #252
attribute: name [R] #253
attribute: seq_num [R] #254
attribute: hash [R] #255
method: initialize / 4 #258
method: to_s / 2 #288
method: print / 1 #310
method: path #343
method: eql? / 1 #354
method: freeze_equality! #366
method: <=> / 1 #371
method: compare_by_name / 1 #398
class method: __compare__ / 2 #426
  class: SetOfLogicalSubject#447
inherits from
  SetOfGenericSubject ( TmDoc::Model::Abstraction::Subject )
has properties
constant: LSM_ELEMENT_CLASS #448
  class: SeqOfLogicalSubject#453
inherits from
  SeqOfGenericSubject ( TmDoc::Model::Abstraction::Subject )
has properties
constant: LSM_ELEMENT_CLASS #454
  class: Location#461
includes
  Comparable ( Builtin-Module )
inherits from
  Abstract ( TmStd::Lsm::Product )
has properties
attribute: a_file [R] #464
attribute: line_num [R] #464
attribute: hash [R] #465
method: initialize / 2 #468
method: to_s #482
method: file_name #489
method: eql? / 1 #496
method: freeze_equality! #505
method: <=> / 1 #510
  class: SetOfLocation#527
inherits from
  Abstract ( TmStd::Lsm::Collection::Set )
has properties
constant: LSM_ELEMENT_CLASS #528
  class: GenericDocument#533
inherits from
  Abstract ( TmStd::Lsm::Product )
  class: SeqOfGenericDocument#537
inherits from
  Abstract ( TmStd::Lsm::Collection::Sequence )
has properties
constant: LSM_ELEMENT_CLASS #538

Code

   1  # $Id: abstraction.rb,v 1.13 2011/12/13 23:54:06 machan Exp $
   2 
   3  require 'tmdoc/tmstd'
   4  require 'tmdoc/constant'
   5 
   6 
   7  module TmDoc
   8 
   9  module Model::Abstraction
  10 
  11  class Store < TmStd::Lsm::Product::Abstract; end
  12 
  13 
  14 
  15  module Path
  16 
  17  class Abstract < TmStd::Lsm::Collection::Sequence::Abstract
  18      include TmStd::Lsm::Collection::Sequence::Equalable
  19      include TmStd::Lsm::Collection::Sequence::Comparable
  20 
  21 
  22      def initialize(elements = [])
  23          ASSERT.kind_of __path_separator_string__, String
  24 
  25          super
  26      end
  27 
  28 
  29      def join(sep = __path_separator_string__)
  30          ASSERT.kind_of sep, String
  31 
  32          str = super(sep)
  33 
  34          ASSERT.kind_of str, String
  35      end
  36 
  37 
  38      def to_s(sep = __path_separator_string__)
  39          ASSERT.kind_of sep, String
  40 
  41          str = self.join(sep)
  42 
  43          ASSERT.kind_of str, String
  44      end
  45 
  46 
  47  private
  48 
  49      def __path_separator_string__
  50          begin
  51              sep = self.class.const_get('PATH_SEPARATOR_STRING')
  52          rescue NameError
  53              raise SubclassResponsibility
  54          end
  55 
  56          ASSERT.kind_of sep, String
  57      end
  58  end
  59 
  60 
  61 
  62  class Absolute < Abstract
  63      def Absolute.new_root
  64          self.new([])
  65      end
  66 
  67 
  68      def +(other)
  69          ASSERT.kind_of other, Relative
  70 
  71          path = super
  72 
  73          ASSERT.kind_of path, Absolute
  74      end
  75 
  76 
  77      def to_s(sep = __path_separator_string__)
  78          ASSERT.kind_of sep, String
  79 
  80          str = sep + super
  81 
  82          ASSERT.kind_of str, String
  83      end
  84  end
  85 
  86 
  87 
  88  class SetOfPath < TmStd::Lsm::Collection::Set::Abstract
  89      LSM_ELEMENT_CLASS = Absolute
  90  end
  91 
  92 
  93 
  94  class Relative < Abstract
  95      def to_absolute
  96          klass = __absolute_path_class__
  97 
  98          ASSERT.subclass_of klass, Absolute
  99 
 100          klass.new(self.to_a)
 101      end
 102 
 103 
 104      def +(other)
 105          ASSERT.kind_of other, Relative
 106 
 107          super
 108      end
 109 
 110 
 111  private
 112 
 113      def __absolute_path_class__
 114          begin
 115              klass = self.class.const_get('ABSOLUTE_PATH_CLASS')
 116          rescue NameError
 117              raise Exception::SubclassResponsibility
 118          end
 119 
 120          ASSERT.subclass_of klass, Abstract
 121      end
 122  end
 123 
 124  end # TmDoc::Model::Abstraction::Path
 125 
 126 
 127 
 128  module Subject
 129 
 130  class GenericSubject < TmStd::Lsm::Product::Abstract
 131      include Comparable
 132 
 133 
 134      def ==(other)
 135          result = self.eql? other
 136 
 137          ASSERT.boolean result
 138      end
 139 
 140 
 141      def eql?(other)
 142          raise Exception::SubclassResponsibility
 143      end
 144 
 145 
 146      def hash
 147          raise Exception::SubclassResponsibility
 148      end
 149 
 150 
 151      def freeze_equality!
 152          raise Exception::SubclassResponsibility
 153      end
 154 
 155 
 156      def <=>(other)
 157          raise Exception::SubclassResponsibility
 158      end
 159  end
 160 
 161 
 162 
 163  class SeqOfGenericSubject < TmStd::Lsm::Collection::Sequence::Abstract
 164      LSM_ELEMENT_CLASS = GenericSubject
 165  end
 166 
 167 
 168 
 169  class SetOfGenericSubject < TmStd::Lsm::Collection::Set::Abstract
 170      LSM_ELEMENT_CLASS = GenericSubject
 171  end
 172 
 173 
 174 
 175  class PhysicalSubject < GenericSubject
 176      attr_reader :name, :seq_num
 177      attr_reader :hash
 178 
 179 
 180      def initialize(name, seq_num)
 181          ASSERT.kind_of name,    String
 182          ASSERT.kind_of seq_num, Integer
 183 
 184          @name       = name
 185          @seq_num    = seq_num
 186 
 187          @name.freeze
 188          @seq_num.freeze
 189 
 190          @hash = format("%s %d", @name, @seq_num).hash
 191      end
 192 
 193 
 194      def eql?(other)
 195          result = self.name == other.name && self.seq_num == other.seq_num
 196 
 197          ASSERT.boolean result
 198      end
 199 
 200 
 201      def freeze_equality!
 202          nil     # Nop, already frozen.
 203      end
 204 
 205 
 206      def <=>(other)
 207          result_of_seq_num = self.seq_num <=> other.seq_num
 208 
 209          result =    if result_of_seq_num == 0
 210                          self.name <=> other.name
 211                      else
 212                          result_of_seq_num
 213                      end
 214 
 215          ASSERT.kind_of result, Integer
 216      end
 217 
 218 
 219      def to_s(label)
 220          ASSERT.kind_of label, String
 221 
 222          str = format "%s[#%d]: %s", label, self.seq_num, self.name
 223 
 224          ASSERT.kind_of str, String
 225      end
 226 
 227 
 228      def print(indent)
 229          ASSERT.kind_of indent,  Integer
 230 
 231          is  = "\t" * indent
 232 
 233          LOG::Debug.log(
 234              "%s---- %s[#%d]: %s ----",
 235              is, self.class.to_s, self.seq_num, self.name
 236          )
 237 
 238          nil
 239      end
 240  end
 241 
 242 
 243 
 244  class SetOfPhysicalSubject < SetOfGenericSubject
 245      LSM_ELEMENT_CLASS = PhysicalSubject
 246  end
 247 
 248 
 249 
 250  class LogicalSubject < GenericSubject
 251      attr_reader :location,
 252                  :above_path,
 253                  :name,
 254                  :seq_num
 255      attr_reader :hash
 256 
 257 
 258      def initialize(
 259          location = nil, above_path = nil,   name = nil,     seq_num = nil
 260      )
 261          ASSERT.opt_kind_of location,    Model::Abstraction::Location
 262          ASSERT.opt_kind_of above_path,  Model::Abstraction::Path::Absolute
 263          ASSERT.opt_kind_of name,        String
 264          ASSERT.opt_kind_of seq_num,     Integer
 265 
 266          super()
 267 
 268          @above_path = above_path
 269          @name       = name
 270          @location   = location
 271          @seq_num    = if seq_num then seq_num else 0 end
 272 
 273          @above_path.freeze_equality!    if @above_path
 274          @name.freeze                    if @name
 275          @location.freeze_equality!      if @location
 276          @seq_num.freeze                 if @seq_num
 277 
 278          @hash = format(
 279              "%s %s %s %s",
 280              if @above_path  then @above_path    else '-' end,
 281              if @name        then @name          else '-' end,
 282              if @location    then @location.to_s else '-' end,
 283              if @seq_num     then @seq_num.to_s  else '-' end
 284          ).hash
 285      end
 286 
 287 
 288      def to_s(label, opt_str = nil)
 289          ASSERT.kind_of      label,      String
 290          ASSERT.opt_kind_of  opt_str,    String
 291 
 292          str = format("%s %s%s%s", 
 293              label,
 294 
 295              self.above_path.to_s,
 296 
 297              if opt_str then ' ' + opt_str else '' end,
 298 
 299              if self.location
 300                  ' -- ' + self.location.to_s
 301              else
 302                  ''
 303              end
 304          )
 305 
 306          ASSERT.kind_of str, String
 307      end
 308 
 309 
 310      def print(indent)
 311          ASSERT.kind_of indent,  Integer
 312 
 313          is  = "\t" * indent
 314 
 315          LOG::Debug.log(
 316              "%s---- %s%s%s ----",
 317 
 318              is,
 319 
 320              if self.name then self.name else '' end,
 321 
 322              if self.seq_num && self.seq_num != 0
 323                  format " [#%d]", self.seq_num
 324              else
 325                  ''
 326              end,
 327 
 328              format(": %s", self.class.to_s)
 329          )
 330 
 331          if self.location
 332              LOG::Debug.log "%slocation: %s", is, self.location.to_s
 333          end
 334 
 335          if self.above_path
 336              LOG::Debug.log "%sabove_path: %s", is, self.above_path.to_s
 337          end
 338 
 339          nil
 340      end
 341 
 342 
 343      def path
 344          unless self.name
 345              raise Exception::SubclassResponsibility
 346          end
 347 
 348          path = self.above_path << self.name
 349 
 350          ASSERT.kind_of path, Model::Abstraction::Path::Absolute
 351      end
 352 
 353 
 354      def eql?(other)
 355          result =
 356              if LogicalSubject >= other.class then true else false end &&
 357              self.above_path == other.above_path &&
 358              self.name       == other.name &&
 359              self.location   == other.location &&
 360              self.seq_num    == other.seq_num
 361 
 362          ASSERT.boolean result
 363      end
 364 
 365 
 366      def freeze_equality!
 367          nil     # Nop, already frozen
 368      end
 369 
 370 
 371      def <=>(other)
 372          ASSERT.kind_of other, LogicalSubject
 373 
 374          location_result =
 375                  LogicalSubject.__compare__ self.location, other.location
 376          if location_result != 0
 377              return location_result
 378          end
 379 
 380          seq_num_result =
 381                  LogicalSubject.__compare__ self.seq_num, other.seq_num
 382          if seq_num_result != 0
 383              return seq_num_result
 384          end
 385 
 386          above_path_result =
 387              LogicalSubject.__compare__ self.above_path, other.above_path
 388          if above_path_result != 0
 389              return above_path_result
 390          end
 391 
 392          name_result = LogicalSubject.__compare__ self.name, other.name
 393 
 394          ASSERT.kind_of name_result, Integer
 395      end
 396 
 397 
 398      def compare_by_name(other)
 399          ASSERT.kind_of other, LogicalSubject
 400 
 401          name_result = LogicalSubject.__compare__ self.name, other.name
 402          if name_result != 0
 403              return name_result
 404          end
 405 
 406          above_path_result = LogicalSubject.__compare__(
 407              self.above_path, other.above_path
 408          )
 409          if above_path_result != 0
 410              return above_path_result
 411          end
 412 
 413          location_result =
 414                  LogicalSubject.__compare__ self.location, other.location
 415          if location_result != 0
 416              return location_result
 417          end
 418 
 419          seq_num_result =
 420                  LogicalSubject.__compare__ self.seq_num, other.seq_num
 421 
 422          ASSERT.kind_of seq_num_result, Integer
 423      end
 424 
 425 
 426      def self.__compare__(self_obj, other_obj)
 427          result =    if self_obj
 428                          if other_obj
 429                              self_obj <=> other_obj
 430                          else
 431                              1
 432                          end
 433                      else
 434                          if other_obj
 435                              -1
 436                          else
 437                              0
 438                          end
 439                      end
 440 
 441          ASSERT.kind_of result, Integer
 442      end
 443  end
 444 
 445 
 446 
 447  class SetOfLogicalSubject < SetOfGenericSubject
 448      LSM_ELEMENT_CLASS = LogicalSubject
 449  end
 450 
 451 
 452 
 453  class SeqOfLogicalSubject < SeqOfGenericSubject
 454      LSM_ELEMENT_CLASS = LogicalSubject
 455  end
 456 
 457  end # TmDoc::Model::Abstraction::Subject
 458 
 459 
 460 
 461  class Location < TmStd::Lsm::Product::Abstract
 462      include     Comparable
 463 
 464      attr_reader :a_file, :line_num
 465      attr_reader :hash
 466 
 467 
 468      def initialize(a_file, line_num)
 469          ASSERT.kind_of a_file,      Subject::PhysicalSubject
 470          ASSERT.kind_of line_num,    Integer
 471 
 472          @a_file     = a_file
 473          @line_num   = line_num
 474 
 475          @a_file.freeze_equality!
 476          @line_num.freeze
 477 
 478          @hash = format("#%s#%d", self.a_file.to_s, self.line_num).hash
 479      end
 480 
 481 
 482      def to_s
 483          str = format "#%d in '%s'", self.line_num, self.a_file.to_s
 484 
 485          ASSERT.kind_of str, String
 486      end
 487 
 488 
 489      def file_name
 490          str = self.a_file.name
 491 
 492          ASSERT.kind_of str, String
 493      end
 494 
 495 
 496      def eql?(other)
 497          result =    if Location >= other.class then true else false end &&
 498                      self.a_file     == other.a_file &&
 499                      self.line_num   == other.line_num
 500 
 501          ASSERT.boolean result
 502      end
 503 
 504 
 505      def freeze_equality!
 506          nil     # Nop, already frozen.
 507      end
 508 
 509 
 510      def <=>(other)
 511          ASSERT.kind_of other, Location
 512 
 513          result_file = self.a_file <=> other.a_file
 514 
 515          result =    if result_file == 0
 516                          self.line_num <=> other.line_num
 517                      else
 518                          result_file
 519                      end
 520 
 521          ASSERT.kind_of result, Integer
 522      end
 523  end
 524 
 525 
 526 
 527  class SetOfLocation < TmStd::Lsm::Collection::Set::Abstract
 528      LSM_ELEMENT_CLASS = Location
 529  end
 530 
 531 
 532 
 533  class GenericDocument < TmStd::Lsm::Product::Abstract; end
 534 
 535 
 536 
 537  class SeqOfGenericDocument < TmStd::Lsm::Collection::Sequence::Abstract
 538      LSM_ELEMENT_CLASS = GenericDocument
 539  end
 540 
 541  end # TmDoc::Model::Abstraction
 542 
 543  end # TmDoc