001/* The type of base token classes. 002 003 Copyright (c) 1997-2018 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 027 */ 028package ptolemy.data.type; 029 030import java.lang.reflect.Modifier; 031import java.util.HashMap; 032import java.util.Map; 033 034import ptolemy.data.ActorToken; 035import ptolemy.data.BooleanToken; 036import ptolemy.data.ComplexToken; 037import ptolemy.data.DateToken; 038import ptolemy.data.DoubleToken; 039import ptolemy.data.EventToken; 040import ptolemy.data.FixToken; 041import ptolemy.data.FloatToken; 042import ptolemy.data.IntToken; 043import ptolemy.data.LongToken; 044import ptolemy.data.MatrixToken; 045import ptolemy.data.PetiteToken; 046import ptolemy.data.ScalarToken; 047import ptolemy.data.ShortToken; 048import ptolemy.data.StringToken; 049import ptolemy.data.Token; 050import ptolemy.data.UnsignedByteToken; 051import ptolemy.data.XMLToken; 052import ptolemy.graph.CPO; 053import ptolemy.kernel.util.IllegalActionException; 054 055/////////////////////////////////////////////////////////////////// 056//// BaseType 057 058/** 059 The type of base token classes. This class provides a type safe 060 enumeration of base types. 061 062 @author Yuhong Xiong, Steve Neuendorffer 063 @version $Id$ 064 @since Ptolemy II 0.4 065 @Pt.ProposedRating Red (yuhong) 066 @Pt.AcceptedRating Red 067 */ 068public abstract class BaseType implements Type { 069 /////////////////////////////////////////////////////////////////// 070 //// public methods //// 071 072 /** Return a new type which represents the type that results from 073 * adding a token of this type and a token of the given argument 074 * type. 075 * @param rightArgumentType The type to add to this type. 076 * @return A new type, or BaseType.GENERAL, if the operation does 077 * not make sense for the given types. 078 */ 079 @Override 080 public Type add(Type rightArgumentType) { 081 return TypeLattice.leastUpperBound(this, rightArgumentType); 082 } 083 084 /** Specify that the given type, with the given name, is implemented 085 * by the specified token class. Normally, an end user won't need 086 * this method, but there is a particular use that can sometimes 087 * come in handy. Occasionally it is useful for a token that subclasses a 088 * standard token to be used in place of that standard token. 089 * For example, you could create a subclass of DoubleToken called 090 * DoublePlusPlus that includes some extra fields. For that class 091 * to be acceptable to the expression language, for example as a return 092 * type from a function, then you must call this method to register that 093 * class. In this case, you call it with arguments BaseType.DOUBLE, 094 * "doublePlusPlus" (or whatever name you choose), and 095 * DoublePlusPlus.class. 096 * @param type The type. 097 * @param name The name of the type. 098 * @param theClass The implementation (token class) for the type. 099 */ 100 public static void addType(Type type, String name, Class theClass) { 101 _addType(type, name, theClass); 102 } 103 104 /** Return this, that is, return the reference to this object. 105 * @return A BaseType. 106 */ 107 @Override 108 public Object clone() { 109 return this; 110 } 111 112 /** Convert the specified token to a token having the type 113 * represented by this object. 114 * @param t A token. 115 * @return A token. 116 * @exception IllegalActionException If lossless conversion cannot 117 * be done. 118 */ 119 @Override 120 public abstract Token convert(Token t) throws IllegalActionException; 121 122 /** Return a new type which represents the type that results from 123 * dividing a token of this type and a token of the given 124 * argument type. 125 * @param rightArgumentType The type to add to this type. 126 * @return A new type, or BaseType.GENERAL, if the operation does 127 * not make sense for the given types. 128 */ 129 @Override 130 public Type divide(Type rightArgumentType) { 131 return TypeLattice.leastUpperBound(this, rightArgumentType); 132 } 133 134 /** Determine if the argument represents the same BaseType as this 135 * object. 136 * @param object Another object. 137 * @return True if the argument represents the same BaseType as 138 * this object; false otherwise. 139 */ 140 @Override 141 public boolean equals(Object object) { 142 // since BaseType is a type safe enumeration, can use == to 143 // test equality. 144 return this == object; 145 } 146 147 /** Return an instance of Type of that corresponds to tokens 148 * of a class with the given name, or null if none exists. 149 * @param className The name of the class. 150 * @return An instance of BaseType. 151 */ 152 public static Type forClassName(String className) { 153 return (Type) _classNameToType.get(className); 154 } 155 156 /** Return an instance of this class with the specified name, 157 * or null if none exists. Note that this does not recognize 158 * all the types that have symbolic names. It is better to 159 * use ptolemy.data.expr.Constants.types() to map a name 160 * to a type. 161 * @param name The name of the type. 162 * @return An instance of BaseType. 163 */ 164 public static Type forName(String name) { 165 return (Type) _nameToType.get(name); 166 } 167 168 /** Return the class for tokens that this basetype represents. 169 * @return The class for tokens that this type represents. 170 */ 171 @Override 172 public Class getTokenClass() { 173 return _tokenClass; 174 } 175 176 /** Return a perfect hash for this type. This number corresponds 177 * uniquely to a particular type, and is used to improve 178 * performance of certain operations in the TypeLattice class. 179 * All instances of a particular type (e.g. integer array) must 180 * return the same number. Types that return HASH_INVALID will 181 * not have results in TypeLattice cached. Note that it is safer 182 * to return HASH_INVALID, than to return a number that is not 183 * unique, or different number for the same type from different 184 * instances. This base class returns HASH_INVALID. 185 * @return A number greater than or equal to 0, or HASH_INVALID. 186 */ 187 @Override 188 public int getTypeHash() { 189 return Type.HASH_INVALID; 190 } 191 192 /** Return a hash code value for this object. 193 */ 194 @Override 195 public int hashCode() { 196 return super.hashCode(); 197 } 198 199 /** Return a new type which represents the type that results from 200 * moduloing a token of this type and a token of the given 201 * argument type. 202 * @param rightArgumentType The type to add to this type. 203 * @return A new type, or BaseType.GENERAL, if the operation does 204 * not make sense for the given types. 205 */ 206 @Override 207 public Type modulo(Type rightArgumentType) { 208 return TypeLattice.leastUpperBound(this, rightArgumentType); 209 } 210 211 /** Return a new type which represents the type that results from 212 * multiplying a token of this type and a token of the given 213 * argument type. 214 * @param rightArgumentType The type to add to this type. 215 * @return A new type, or BaseType.GENERAL, if the operation does 216 * not make sense for the given types. 217 */ 218 @Override 219 public Type multiply(Type rightArgumentType) { 220 return TypeLattice.leastUpperBound(this, rightArgumentType); 221 } 222 223 /** Return true if this type does not correspond to a single token 224 * class. This occurs if the type is not instantiable, or it 225 * represents either an abstract base class or an interface. 226 */ 227 @Override 228 public boolean isAbstract() { 229 if (!isInstantiable()) { 230 return true; 231 } 232 233 int mod = _tokenClass.getModifiers(); 234 235 if (Modifier.isAbstract(mod)) { 236 return true; 237 } 238 239 if (_tokenClass.isInterface()) { 240 return true; 241 } 242 return false; 243 } 244 245 /** Test if the argument type is compatible with this type. The method 246 * returns true if this type is UNKNOWN, since any type is a substitution 247 * instance of it. If this type is not UNKNOWN, this method returns true 248 * if the argument type is less than or equal to this type in the type 249 * lattice, and false otherwise. 250 * @param type An instance of Type. 251 * @return True if the argument is compatible with this type. 252 */ 253 @Override 254 public boolean isCompatible(Type type) { 255 if (this == UNKNOWN) { 256 return true; 257 } 258 259 int typeInfo = TypeLattice.compare(this, type); 260 return typeInfo == CPO.SAME || typeInfo == CPO.HIGHER; 261 } 262 263 /** Test if this Type is UNKNOWN. 264 * @return True if this Type is not UNKNOWN; false otherwise. 265 */ 266 @Override 267 public boolean isConstant() { 268 return this != UNKNOWN; 269 } 270 271 /** Determine if this type corresponds to an instantiable token 272 * classes. A BaseType is instantiable if it does not correspond 273 * to an abstract token class, or an interface, or UNKNOWN. 274 * @return True if this type is instantiable. 275 */ 276 @Override 277 public boolean isInstantiable() { 278 if (this == UNKNOWN) { 279 return false; 280 } 281 282 return true; 283 } 284 285 /** Return true if the argument is a substitution instance of this type. 286 * @param type A Type. 287 * @return True if this type is UNKNOWN; false otherwise. 288 */ 289 @Override 290 public boolean isSubstitutionInstance(Type type) { 291 return this == UNKNOWN || this == type; 292 } 293 294 /** Return the type of the multiplicative identity for elements of 295 * this type. 296 * @return A new type, or BaseType.GENERAL, if the operation does 297 * not make sense for the given types. 298 */ 299 @Override 300 public Type one() { 301 return this; 302 } 303 304 /** Return a new type which represents the type that results from 305 * subtracting a token of this type and a token of the given 306 * argument type. 307 * @param rightArgumentType The type to add to this type. 308 * @return A new type, or BaseType.GENERAL, if the operation does 309 * not make sense for the given types. 310 */ 311 @Override 312 public Type subtract(Type rightArgumentType) { 313 return TypeLattice.leastUpperBound(this, rightArgumentType); 314 } 315 316 /** Return the string representation of this type. 317 * @return A String. 318 */ 319 @Override 320 public String toString() { 321 return _name; 322 } 323 324 /** Return the type of the additive identity for elements of 325 * this type. 326 * @return A new type, or BaseType.GENERAL, if the operation does 327 * not make sense for the given types. 328 */ 329 @Override 330 public Type zero() { 331 return this; 332 } 333 334 /////////////////////////////////////////////////////////////////// 335 //// inner classes //// 336 // NOTE: It may seem strange that these inner classes are built this 337 // way instead of as anonymous classes... As anonymous classes, the 338 // fields cannot be appropriately typed, which makes type inference 339 // much more complex to find the same information. This is important 340 // to the code generator. 341 342 /** The bottom element of the data type lattice. It represents a 343 * type variable. 344 */ 345 public static class UnknownType extends BaseType { 346 private UnknownType() { 347 super(Void.TYPE, "unknown"); 348 } 349 350 @Override 351 public Token convert(Token t) throws IllegalActionException { 352 // Since any type is a substitution instance of UNKNOWN, just 353 // return the argument. 354 return t; 355 } 356 357 @Override 358 public int getTypeHash() { 359 return 0; 360 } 361 } 362 363 /** The bottom element of the data type lattice. */ 364 public static final UnknownType UNKNOWN = new UnknownType(); 365 366 /** The bottom element of the array type lattice. */ 367 public static class ArrayBottomType extends BaseType { 368 private ArrayBottomType() { 369 super(Void.TYPE, "arrayBottom"); 370 } 371 372 @Override 373 public Token convert(Token t) throws IllegalActionException { 374 // Since any type is a substitution instance of UNKNOWN, just 375 // return the argument. 376 return t; 377 } 378 } 379 380 /** The bottom element of the array type lattice. */ 381 public static final ArrayBottomType ARRAY_BOTTOM = new ArrayBottomType(); 382 383 /** The boolean data type. */ 384 public static class BooleanType extends BaseType { 385 private BooleanType() { 386 super(BooleanToken.class, "boolean"); 387 } 388 389 @Override 390 public Token convert(Token t) throws IllegalActionException { 391 return BooleanToken.convert(t); 392 } 393 394 @Override 395 public int getTypeHash() { 396 return 1; 397 } 398 } 399 400 /** The boolean data type. */ 401 public static final BooleanType BOOLEAN = new BooleanType(); 402 403 /** The boolean matrix data type. */ 404 public static final MatrixType.BooleanMatrixType BOOLEAN_MATRIX = new MatrixType.BooleanMatrixType(); 405 406 /** The unsigned byte data type. */ 407 public static class UnsignedByteType extends BaseType { 408 private UnsignedByteType() { 409 super(UnsignedByteToken.class, "unsignedByte"); 410 } 411 412 @Override 413 public Token convert(Token t) throws IllegalActionException { 414 return UnsignedByteToken.convert(t); 415 } 416 417 @Override 418 public int getTypeHash() { 419 return 2; 420 } 421 } 422 423 /** The unsigned byte data type. */ 424 public static final UnsignedByteType UNSIGNED_BYTE = new UnsignedByteType(); 425 426 /** The complex data type. */ 427 public static class ComplexType extends BaseType { 428 private ComplexType() { 429 super(ComplexToken.class, "complex"); 430 } 431 432 @Override 433 public Token convert(Token t) throws IllegalActionException { 434 return ComplexToken.convert(t); 435 } 436 437 @Override 438 public int getTypeHash() { 439 return 3; 440 } 441 } 442 443 /** The complex data type. */ 444 public static final ComplexType COMPLEX = new ComplexType(); 445 446 /** The complex matrix data type. */ 447 public static final MatrixType.ComplexMatrixType COMPLEX_MATRIX = new MatrixType.ComplexMatrixType(); 448 449 /** The float data type. */ 450 public static class FloatType extends BaseType { 451 private FloatType() { 452 super(FloatToken.class, "float"); 453 } 454 455 @Override 456 public Token convert(Token t) throws IllegalActionException { 457 return FloatToken.convert(t); 458 } 459 460 @Override 461 public int getTypeHash() { 462 return 16; 463 } 464 } 465 466 /** The float data type. */ 467 public static final FloatType FLOAT = new FloatType(); 468 469 /** The double data type. */ 470 public static class DoubleType extends BaseType { 471 private DoubleType() { 472 super(DoubleToken.class, "double"); 473 } 474 475 @Override 476 public Token convert(Token t) throws IllegalActionException { 477 return DoubleToken.convert(t); 478 } 479 480 @Override 481 public int getTypeHash() { 482 return 4; 483 } 484 } 485 486 /** The double data type. */ 487 public static final DoubleType DOUBLE = new DoubleType(); 488 489 /** The double matrix data type. */ 490 public static final MatrixType.DoubleMatrixType DOUBLE_MATRIX = new MatrixType.DoubleMatrixType(); 491 492 /** The fix data type. */ 493 public static class UnsizedFixType extends BaseType { 494 private UnsizedFixType() { 495 super(FixToken.class, "fixedpoint"); 496 } 497 498 @Override 499 public Token convert(Token t) throws IllegalActionException { 500 if (t instanceof FixToken) { 501 return t; 502 } else { 503 throw new IllegalActionException( 504 "Cannot convert token " + t + " to type fixed point."); 505 } 506 } 507 } 508 509 /** An alias for the unsized fix data type, provided for backward 510 * compatibility with the previous versions of Ptolemy. 511 */ 512 public static final UnsizedFixType FIX = new UnsizedFixType(); 513 514 /** The unsized fix data type. */ 515 public static final UnsizedFixType UNSIZED_FIX = FIX; 516 517 /** The fix data type, with a precision specified. */ 518 public static final FixType SIZED_FIX = FixType.BOTTOM; 519 520 /** The fix matrix data type. */ 521 public static final MatrixType.FixMatrixType FIX_MATRIX = new MatrixType.FixMatrixType(); 522 523 /** The short integer data type. */ 524 public static class ShortType extends BaseType { 525 private ShortType() { 526 super(ShortToken.class, "short"); 527 } 528 529 @Override 530 public Token convert(Token t) throws IllegalActionException { 531 return ShortToken.convert(t); 532 } 533 534 @Override 535 public int getTypeHash() { 536 return 15; 537 } 538 } 539 540 /** The short integer data type. */ 541 public static final ShortType SHORT = new ShortType(); 542 543 /** The integer data type. */ 544 public static class IntType extends BaseType { 545 private IntType() { 546 super(IntToken.class, "int"); 547 } 548 549 @Override 550 public Token convert(Token t) throws IllegalActionException { 551 return IntToken.convert(t); 552 } 553 554 @Override 555 public int getTypeHash() { 556 return 5; 557 } 558 } 559 560 /** The integer data type. */ 561 public static final IntType INT = new IntType(); 562 563 /** The integer matrix data type. */ 564 public static final MatrixType.IntMatrixType INT_MATRIX = new MatrixType.IntMatrixType(); 565 566 /** The long integer data type. */ 567 public static class LongType extends BaseType { 568 private LongType() { 569 super(LongToken.class, "long"); 570 } 571 572 @Override 573 public Token convert(Token t) throws IllegalActionException { 574 return LongToken.convert(t); 575 } 576 577 @Override 578 public int getTypeHash() { 579 return 6; 580 } 581 } 582 583 /** The long integer data type. */ 584 public static final LongType LONG = new LongType(); 585 586 /** The long integer matrix data type. */ 587 public static final MatrixType.LongMatrixType LONG_MATRIX = new MatrixType.LongMatrixType(); 588 589 /** The numerical data type. */ 590 // NOTE: Removed NUMERICAL from the type lattice, EAL 6/22/06. 591 /* 592 public static class NumericalType extends BaseType { 593 private NumericalType() { 594 super(Numerical.class, "numerical"); 595 } 596 597 public Token convert(Token t) throws IllegalActionException { 598 throw new IllegalActionException( 599 "Cannot convert token " 600 + t 601 + " to type numerical, because numerical is not a concrete type."); 602 } 603 604 public int getTypeHash() { 605 return 7; 606 } 607 } 608 */ 609 610 /** The numerical data type. */ 611 // NOTE: Removed NUMERICAL from the type lattice, EAL 6/22/06. 612 /* 613 public static final NumericalType NUMERICAL = new NumericalType(); 614 */ 615 616 /** The object data type. */ 617 public static final ObjectType OBJECT = new ObjectType(); 618 619 /** The actor data type. */ 620 public static final Type ACTOR = ActorToken.TYPE; 621 622 /** The XmlToken data type. */ 623 public static class XmlTokenType extends BaseType { 624 private XmlTokenType() { 625 super(XMLToken.class, "xmltoken"); 626 } 627 628 @Override 629 public Token convert(Token t) throws IllegalActionException { 630 return XMLToken.convert(t); 631 } 632 633 @Override 634 public int getTypeHash() { 635 return 8; 636 } 637 } 638 639 /** The XmlToken data type. */ 640 public static final XmlTokenType XMLTOKEN = new XmlTokenType(); 641 642 /** The scalar data type: The least upper bound of all the scalar types. */ 643 public static class ScalarType extends BaseType { 644 private ScalarType() { 645 super(ScalarToken.class, "scalar"); 646 } 647 648 @Override 649 public Token convert(Token t) throws IllegalActionException { 650 if (t instanceof ScalarToken) { 651 return t; 652 } 653 throw new IllegalActionException(Token 654 .notSupportedIncomparableConversionMessage(t, "scalar")); 655 } 656 657 @Override 658 public int getTypeHash() { 659 return 9; 660 } 661 662 // public boolean isInstantiable() { 663 // return true; 664 // } 665 } 666 667 /** The scalar data type: The least upper bound of all the scalar types. */ 668 public static final ScalarType SCALAR = new ScalarType(); 669 670 /** The matrix data type: The least upper bound of all the matrix types. */ 671 public static final MatrixType MATRIX = new MatrixType(MatrixToken.class, 672 SCALAR, "matrix"); 673 674 /** The string data type. */ 675 public static class StringType extends BaseType { 676 private StringType() { 677 super(StringToken.class, "string"); 678 } 679 680 @Override 681 public Token convert(Token t) throws IllegalActionException { 682 return StringToken.convert(t); 683 } 684 685 @Override 686 public int getTypeHash() { 687 return 10; 688 } 689 } 690 691 /** The string data type. */ 692 public static final StringType STRING = new StringType(); 693 694 /** The general data type: The top of the lattice. */ 695 public static class GeneralType extends BaseType { 696 private GeneralType() { 697 super(Token.class, "general"); 698 } 699 700 @Override 701 public Token convert(Token t) throws IllegalActionException { 702 return t; 703 } 704 705 @Override 706 public int getTypeHash() { 707 return 11; 708 } 709 } 710 711 /** The general data type: The top of the lattice. */ 712 public static final GeneralType GENERAL = new GeneralType(); 713 714 /** The event data type. */ 715 public static class EventType extends BaseType { 716 private EventType() { 717 super(EventToken.class, "event"); 718 } 719 720 @Override 721 public Token convert(Token t) throws IllegalActionException { 722 return t; 723 } 724 725 @Override 726 public int getTypeHash() { 727 return 12; 728 } 729 } 730 731 /** The event data type. */ 732 public static final EventType EVENT = new EventType(); 733 734 /** The petite data type. */ 735 public static class PetiteType extends BaseType { 736 private PetiteType() { 737 super(PetiteToken.class, "petite"); 738 } 739 740 @Override 741 public Token convert(Token t) throws IllegalActionException { 742 return PetiteToken.convert(t); 743 } 744 745 @Override 746 public int getTypeHash() { 747 return 13; 748 } 749 } 750 751 /** The petite data type. */ 752 public static final PetiteType PETITE = new PetiteType(); 753 754 /** The nil data type. */ 755 public static class NilType extends BaseType { 756 private NilType() { 757 super(Token.class, "niltype"); 758 } 759 760 @Override 761 public Token convert(Token t) throws IllegalActionException { 762 return t; 763 } 764 765 @Override 766 public int getTypeHash() { 767 return 14; 768 } 769 } 770 771 /** The nil data type. */ 772 public static final NilType NIL = new NilType(); 773 774 /** The date data type. */ 775 public static class DateType extends BaseType { 776 private DateType() { 777 super(DateToken.class, "date"); 778 } 779 780 @Override 781 public Token convert(Token t) throws IllegalActionException { 782 return DateToken.convert(t); 783 } 784 785 @Override 786 public int getTypeHash() { 787 return 16; 788 } 789 } 790 791 /** The DateToken data type. */ 792 public static final DateType DATE = new DateType(); 793 794 /////////////////////////////////////////////////////////////////// 795 //// package private method //// 796 797 /** Add entries in this class to index the given name and class to 798 * the given type. 799 * @param type The type. 800 * @param name The name of the type. 801 * @param theClass The implementation (token class) for the type. 802 */ 803 static void _addType(Type type, String name, Class theClass) { 804 // Because the private variables are below the public variables 805 // that call this initializer, 806 // it doesn't work to initialize this statically. 807 if (_nameToType == null) { 808 _nameToType = new HashMap(); 809 } 810 811 if (_classNameToType == null) { 812 _classNameToType = new HashMap(); 813 } 814 815 _nameToType.put(name, type); 816 _classNameToType.put(theClass.getName(), type); 817 } 818 819 /** Setting the type of something to RECORD allows it to take 820 * on a value that is any record with any fields. This is because 821 * a lossless conversion any such record to an empty record just 822 * returns the original record. So to force something to have a 823 * record type without specifying what fields it should have, do 824 * <pre> 825 * something.setTypeEquals(BaseType.RECORD); 826 * </pre> 827 * To allow the type to resolve to a specific record type (with 828 * particular fields), do instead 829 * <pre> 830 * something.setTypeAtMost(BaseType.RECORD); 831 * </pre> 832 * This will work for example to require a parameter to have a record 833 * value, but to allow its type to resolve to the specific record 834 * specified. 835 */ 836 static public final RecordType RECORD = RecordType.EMPTY_RECORD; 837 838 /////////////////////////////////////////////////////////////////// 839 //// private constructor //// 840 841 /** The constructor is private to make a type safe enumeration. */ 842 private BaseType(Class c, String name) { 843 _tokenClass = c; 844 _name = name; 845 _addType(this, name, c); 846 } 847 848 /////////////////////////////////////////////////////////////////// 849 //// private variables //// 850 851 /** The class of tokens with this type. */ 852 private Class _tokenClass; 853 854 /** The name of the type. */ 855 private String _name; 856 857 /** A map from type name to the type for all base types. */ 858 private static Map _nameToType; 859 860 /** A map from class name to the type for all base types. */ 861 private static Map _classNameToType; 862}