View Javadoc

    1   /*
    2    $Id: Types.java,v 1.5 2004/07/10 03:31:44 bran Exp $
    3
    4    Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
    5
    6    Redistribution and use of this software and associated documentation
    7    ("Software"), with or without modification, are permitted provided
    8    that the following conditions are met:
    9
    10   1. Redistributions of source code must retain copyright
    11      statements and notices.  Redistributions must also contain a
    12      copy of this document.
    13
    14   2. Redistributions in binary form must reproduce the
    15      above copyright notice, this list of conditions and the
    16      following disclaimer in the documentation and/or other
    17      materials provided with the distribution.
    18
    19   3. The name "groovy" must not be used to endorse or promote
    20      products derived from this Software without prior written
    21      permission of The Codehaus.  For written permission,
    22      please contact info@codehaus.org.
    23
    24   4. Products derived from this Software may not be called "groovy"
    25      nor may "groovy" appear in their names without prior written
    26      permission of The Codehaus. "groovy" is a registered
    27      trademark of The Codehaus.
    28
    29   5. Due credit should be given to The Codehaus -
    30      http://groovy.codehaus.org/
    31
    32   THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
    33   ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
    34   NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
    35   FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
    36   THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
    37   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    38   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    39   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    40   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    41   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    42   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
    43   OF THE POSSIBILITY OF SUCH DAMAGE.
    44
    45   */
    46
    47  package org.codehaus.groovy.syntax;
    48
    49  import java.util.HashMap;
    50  import java.util.Iterator;
    51  import java.util.Map;
    52
    53  import org.codehaus.groovy.GroovyBugError;
    54
    55
    56  /***
    57   *  Typing information for the CST system.  The types here are those
    58   *  used by CSTNode, Token, and Reduction.
    59   *
    60   *  @author <a href="mailto:bob@werken.com">bob mcwhirter</a>
    61   *  @author <a href="mailto:cpoirier@dreaming.org">Chris Poirier</a>
    62   *
    63   *  @version $Id: Types.java,v 1.5 2004/07/10 03:31:44 bran Exp $
    64   */
    65
    66  public class Types
    67  {
    68
    69
    70    //---------------------------------------------------------------------------
    71    // TYPES: NOTE THAT ORDERING AND VALUES ARE IMPORTANT TO LOCAL ROUTINES!
    72
    73
    74      //
    75      // SPECIAL TOKENS
    76
    77      public static final int EOF                         = -1;    // end of file
    78      public static final int UNKNOWN                     = 0;     // the unknown token
    79
    80
    81      //
    82      // RELEVANT WHITESPACE
    83
    84      public static final int NEWLINE                     = 5;     // \n
    85
    86
    87      //
    88      // OPERATORS AND OTHER MARKERS
    89
    90      public static final int LEFT_CURLY_BRACE            = 10;    // {
    91      public static final int RIGHT_CURLY_BRACE           = 20;    // }
    92      public static final int LEFT_SQUARE_BRACKET         = 30;    // [
    93      public static final int RIGHT_SQUARE_BRACKET        = 40;    // ]
    94      public static final int LEFT_PARENTHESIS            = 50;    // (
    95      public static final int RIGHT_PARENTHESIS           = 60;    // )
    96
    97      public static final int DOT                         = 70;    // .
    98      public static final int DOT_DOT                     = 75;    // ..
    99      public static final int DOT_DOT_DOT                 = 77;    // ...
    100
    101     public static final int NAVIGATE                    = 80;    // ->
    102
    103     public static final int FIND_REGEX                  = 90;    // =~
    104     public static final int MATCH_REGEX                 = 94;    // ==~
    105     public static final int REGEX_PATTERN               = 97;    // ~
    106
    107     public static final int EQUAL                       = 100;   // =
    108     public static final int EQUALS                      = EQUAL;
    109     public static final int ASSIGN                      = EQUAL;
    110
    111     public static final int COMPARE_NOT_EQUAL           = 120;   // !=
    112     public static final int COMPARE_IDENTICAL           = 121;   // ===
    113     public static final int COMPARE_NOT_IDENTICAL       = 122;   // !==
    114     public static final int COMPARE_EQUAL               = 123;   // ==
    115     public static final int COMPARE_LESS_THAN           = 124;   // <
    116     public static final int COMPARE_LESS_THAN_EQUAL     = 125;   // <=
    117     public static final int COMPARE_GREATER_THAN        = 126;   // >
    118     public static final int COMPARE_GREATER_THAN_EQUAL  = 127;   // >=
    119     public static final int COMPARE_TO                  = 128;   // <=>
    120
    121     public static final int NOT                         = 160;   // !
    122     public static final int LOGICAL_OR                  = 162;   // ||
    123     public static final int LOGICAL_AND                 = 164;   // &&
    124
    125     public static final int LOGICAL_OR_EQUAL            = 166;   // ||=
    126     public static final int LOGICAL_AND_EQUAL           = 168;   // &&=
    127
    128     public static final int PLUS                        = 200;   // +
    129     public static final int MINUS                       = 201;   // -
    130     public static final int MULTIPLY                    = 202;   // *
    131     public static final int DIVIDE                      = 203;   // /
    132     public static final int INTDIV                      = 204;   // \
    133     public static final int MOD                         = 205;   // %
    134
    135     public static final int PLUS_EQUAL                  = 210;   // +=
    136     public static final int MINUS_EQUAL                 = 211;   // -=
    137     public static final int MULTIPLY_EQUAL              = 212;   // *=
    138     public static final int DIVIDE_EQUAL                = 213;   // /=
    139     public static final int INTDIV_EQUAL                = 214;   // \=
    140     public static final int MOD_EQUAL                   = 215;   // %=
    141
    142     public static final int PLUS_PLUS                   = 250;   // ++
    143     public static final int PREFIX_PLUS_PLUS            = 251;   // ++
    144     public static final int POSTFIX_PLUS_PLUS           = 252;   // ++
    145     public static final int PREFIX_PLUS                 = 253;   // +
    146
    147     public static final int MINUS_MINUS                 = 260;   // --
    148     public static final int PREFIX_MINUS_MINUS          = 261;   // --
    149     public static final int POSTFIX_MINUS_MINUS         = 262;   // --
    150     public static final int PREFIX_MINUS                = 263;   // - (negation)
    151
    152     public static final int LEFT_SHIFT                  = 280;   // <<
    153     public static final int RIGHT_SHIFT                 = 281;   // >>
    154     public static final int RIGHT_SHIFT_UNSIGNED        = 282;   // >>>
    155
    156     public static final int STAR                        = MULTIPLY;
    157
    158     public static final int COMMA                       = 300;   // -
    159     public static final int COLON                       = 310;   // :
    160     public static final int SEMICOLON                   = 320;   // ;
    161     public static final int QUESTION                    = 330;   // ?
    162     public static final int PIPE                        = 340;   // |
    163     public static final int DOUBLE_PIPE                 = LOGICAL_OR;
    164
    165
    166     //
    167     // LITERALS
    168
    169     public static final int STRING                      = 400;   // any bare string data
    170
    171     public static final int IDENTIFIER                  = 440;   // anything text and not a keyword
    172
    173     public static final int INTEGER_NUMBER              = 450;   // integer
    174     public static final int DECIMAL_NUMBER              = 451;   // decimal
    175
    176
    177     //
    178     // KEYWORDS: (PRIMARILY) CLASS/METHOD DECLARATION MODIFIERS
    179
    180     public static final int KEYWORD_PRIVATE             = 500;   // declaration visibility
    181     public static final int KEYWORD_PROTECTED           = 501;   // declaration visibility
    182     public static final int KEYWORD_PUBLIC              = 502;   // declaration visibility
    183
    184     public static final int KEYWORD_ABSTRACT            = 510;   // method body missing
    185     public static final int KEYWORD_FINAL               = 511;   // declaration cannot be overridden
    186     public static final int KEYWORD_NATIVE              = 512;   // a native code entry point
    187     public static final int KEYWORD_TRANSIENT           = 513;   // property should not be persisted
    188     public static final int KEYWORD_VOLATILE            = 514;   // compiler should never cache property
    189
    190     public static final int KEYWORD_SYNCHRONIZED        = 520;   // modifier and block type
    191     public static final int KEYWORD_STATIC              = 521;   // modifier and block type
    192
    193
    194     //
    195     // KEYWORDS: TYPE SYSTEM
    196
    197     public static final int KEYWORD_DEF                 = 530;   // identifies a function declaration
    198     public static final int KEYWORD_DEFMACRO            = 539;   // XXX br identifies a macro declaration
    199     public static final int KEYWORD_CLASS               = 531;   // identifies a class declaration
    200     public static final int KEYWORD_INTERFACE           = 532;   // identifies an interface declaration
    201     public static final int KEYWORD_MIXIN               = 533;   // identifies a mixin declaration
    202
    203     public static final int KEYWORD_IMPLEMENTS          = 540;   // specifies the interfaces implemented by a class
    204     public static final int KEYWORD_EXTENDS             = 541;   // specifies the base class/interface for a new one
    205     public static final int KEYWORD_THIS                = 542;   // method variable points to the current instance
    206     public static final int KEYWORD_SUPER               = 543;   // method variable points to the base instance
    207     public static final int KEYWORD_INSTANCEOF          = 544;   // type comparator
    208     public static final int KEYWORD_PROPERTY            = 545;   // deprecated; identifies a property
    209     public static final int KEYWORD_NEW                 = 546;   // used to create a new instance of a class
    210
    211     public static final int KEYWORD_PACKAGE             = 550;   // declares the package scope
    212     public static final int KEYWORD_IMPORT              = 551;   // declares an external class
    213     public static final int KEYWORD_AS                  = 552;   // used in import statements to create an alias
    214
    215
    216     //
    217     // KEYWORDS: CONTROL STRUCTURES
    218
    219     public static final int KEYWORD_RETURN              = 560;   // returns from a closure or method
    220     public static final int KEYWORD_IF                  = 561;   // if
    221     public static final int KEYWORD_ELSE                = 562;   // else
    222     public static final int KEYWORD_DO                  = 570;   // do loop
    223     public static final int KEYWORD_WHILE               = 571;   // while loop
    224     public static final int KEYWORD_FOR                 = 572;   // for loop
    225     public static final int KEYWORD_IN                  = 573;   // for (each) loop separator
    226     public static final int KEYWORD_BREAK               = 574;   // exits a loop or block
    227     public static final int KEYWORD_CONTINUE            = 575;   // restarts a loop on the next iteration
    228     public static final int KEYWORD_SWITCH              = 576;   // switch block
    229     public static final int KEYWORD_CASE                = 577;   // item in a switch block
    230     public static final int KEYWORD_DEFAULT             = 578;   // catch-all item in a switch block
    231
    232     public static final int KEYWORD_TRY                 = 580;   // block to monitor for exceptions
    233     public static final int KEYWORD_CATCH               = 581;   // catch block for a particular exception
    234     public static final int KEYWORD_FINALLY             = 582;   // block to always execute on exit of the try
    235     public static final int KEYWORD_THROW               = 583;   // statement to throw an exception
    236     public static final int KEYWORD_THROWS              = 584;   // method modifier to declare thrown transactions
    237     public static final int KEYWORD_ASSERT              = 585;   // alternate throw for code invariants
    238
    239
    240     //
    241     // KEYWORDS: PRIMITIVE TYPES
    242
    243     public static final int KEYWORD_VOID                = 600;   // void
    244     public static final int KEYWORD_BOOLEAN             = 601;   // boolean
    245     public static final int KEYWORD_BYTE                = 602;   // 1 byte integer
    246     public static final int KEYWORD_SHORT               = 603;   // 2 byte integer
    247     public static final int KEYWORD_INT                 = 604;   // 4 byte integer
    248     public static final int KEYWORD_LONG                = 605;   // 8 byte integer
    249     public static final int KEYWORD_FLOAT               = 606;   // 32 bit floating point number
    250     public static final int KEYWORD_DOUBLE              = 607;   // 64 bit floating point number
    251     public static final int KEYWORD_CHAR                = 608;   // unicode character code
    252
    253
    254     //
    255     // KEYWORDS: SPECIAL VALUES
    256
    257     public static final int KEYWORD_TRUE                = 610;   // boolean truth
    258     public static final int KEYWORD_FALSE               = 611;   // boolean false
    259     public static final int KEYWORD_NULL                = 612;   // missing instance
    260
    261
    262     //
    263     // KEYWORDS: RESERVED
    264
    265     public static final int KEYWORD_CONST               = 700;   // reserved in java and groovy
    266     public static final int KEYWORD_GOTO                = 701;   // reserved in java and groovy
    267
    268
    269     //
    270     // SPECIAL (CALCULATED) MEANINGS
    271
    272     public static final int SYNTH_COMPILATION_UNIT      = 800;   // reserved: a synthetic root for a CST
    273
    274     public static final int SYNTH_CLASS                 = 801;   // applied to class names
    275     public static final int SYNTH_INTERFACE             = 802;   // applied to interface names
    276     public static final int SYNTH_MIXIN                 = 803;   // applied to mixin names
    277     public static final int SYNTH_METHOD                = 804;   // applied to method names
    278     public static final int SYNTH_PROPERTY              = 805;   // applied to property names
    279     public static final int SYNTH_PARAMETER_DECLARATION = 806;   // applied to method/closure parameter names
    280
    281     public static final int SYNTH_LIST                  = 810;   // applied to "[" that marks a list
    282     public static final int SYNTH_MAP                   = 811;   // applied to "[" that marks a map
    283     public static final int SYNTH_GSTRING               = 812;   // a complete GString
    284
    285     public static final int SYNTH_METHOD_CALL           = 814;   // applied to the optional "(" that marks a call to a method
    286     public static final int SYNTH_CAST                  = 815;   // applied to "(" that marks a type cast
    287     public static final int SYNTH_BLOCK                 = 816;   // applied to "{" that marks a block
    288     public static final int SYNTH_CLOSURE               = 817;   // applied to "{" that marks a closure
    289     public static final int SYNTH_LABEL                 = 818;   // applied to a statement label
    290     public static final int SYNTH_TERNARY               = 819;   // applied to "?" that marks a ternary expression
    291     public static final int SYNTH_TUPLE                 = 820;   // applied to "{" that marks an array initializer
    292
    293     public static final int SYNTH_VARIABLE_DECLARATION  = 830;   // applied to an identifier that specifies
    294                                                                  // the type of a variable declaration
    295
    296     //
    297     // GSTRING TOKENS
    298
    299     public static final int GSTRING_START               = 901;   // any marker tha begins a GString
    300     public static final int GSTRING_END                 = 902;   // any matching marker that ends a GString
    301     public static final int GSTRING_EXPRESSION_START    = 903;   // the ${ marker that starts a GString expression
    302     public static final int GSTRING_EXPRESSION_END      = 904;   // the } marker that ends a GString expresssion
    303
    304
    305     //
    306     // TYPE CLASSES
    307
    308     public static final int ANY                         = 1000;  // anything
    309     public static final int NOT_EOF                     = 1001;  // anything but EOF
    310     public static final int GENERAL_END_OF_STATEMENT    = 1002;  // ";", "\n", EOF
    311     public static final int ANY_END_OF_STATEMENT        = 1003;  // ";", "\n", EOF, "}"
    312
    313     public static final int ASSIGNMENT_OPERATOR         = 1100;  // =, +=, etc.
    314     public static final int COMPARISON_OPERATOR         = 1101;  // ==, ===, >, <, etc.
    315     public static final int MATH_OPERATOR               = 1102;  // +, -, / *, %, plus the LOGICAL_OPERATORS
    316     public static final int LOGICAL_OPERATOR            = 1103;  // ||, &&, !
    317     public static final int RANGE_OPERATOR              = 1104;  // .., ...
    318     public static final int REGEX_COMPARISON_OPERATOR   = 1105;  // =~, etc.
    319     public static final int DEREFERENCE_OPERATOR        = 1106;  // ., ->
    320
    321     public static final int PREFIX_OPERATOR             = 1200;  // ++, !, etc.
    322     public static final int POSTFIX_OPERATOR            = 1210;  // ++, etc.
    323     public static final int INFIX_OPERATOR              = 1220;  // +, -, =, etc.
    324     public static final int PREFIX_OR_INFIX_OPERATOR    = 1230;  // +, -
    325     public static final int PURE_PREFIX_OPERATOR        = 1235;  // prefix +, prefix -
    326
    327     public static final int KEYWORD                     = 1300;  // any keyword
    328     public static final int SYMBOL                      = 1301;  // any symbol
    329     public static final int LITERAL                     = 1310;  // strings, numbers, identifiers
    330     public static final int NUMBER                      = 1320;  // integers and decimals
    331     public static final int SIGN                        = 1325;  // "+", "-"
    332     public static final int NAMED_VALUE                 = 1330;  // true, false, null
    333     public static final int TRUTH_VALUE                 = 1331;  // true, false
    334     public static final int PRIMITIVE_TYPE              = 1340;  // void, byte, short, int, etc.
    335     public static final int CREATABLE_PRIMITIVE_TYPE    = 1341;  // any PRIMITIVE_TYPE except void
    336     public static final int LOOP                        = 1350;  // do, while, etc.
    337     public static final int RESERVED_KEYWORD            = 1360;  // const, goto, etc.
    338     public static final int KEYWORD_IDENTIFIER          = 1361;  // keywords that can appear as identifiers
    339     public static final int SYNTHETIC                   = 1370;  // any of the SYNTH types
    340
    341     public static final int TYPE_DECLARATION            = 1400;  // class, interface, mixin
    342     public static final int DECLARATION_MODIFIER        = 1410;  // public, private, abstract, etc.
    343
    344     public static final int TYPE_NAME                   = 1420;  // identifiers, primitive types
    345     public static final int CREATABLE_TYPE_NAME         = 1430;  // identifiers, primitive types except void
    346
    347     public static final int MATCHED_CONTAINER           = 1500;  // (, ), [, ], {, }
    348     public static final int LEFT_OF_MATCHED_CONTAINER   = 1501;  // (, [, {
    349     public static final int RIGHT_OF_MATCHED_CONTAINER  = 1502;  // ), ], }
    350
    351     public static final int EXPRESSION                  = 1900;  // all of the below 1900 series
    352
    353     public static final int OPERATOR_EXPRESSION         = 1901;  // "."-"<<"
    354     public static final int SYNTH_EXPRESSION            = 1902;  // cast, ternary, and closure expression
    355     public static final int KEYWORD_EXPRESSION          = 1903;  // new, this, super, instanceof, true, false, null
    356     public static final int LITERAL_EXPRESSION          = 1904;  // LITERAL
    357     public static final int ARRAY_EXPRESSION            = 1905;  // "["
    358
    359     public static final int SIMPLE_EXPRESSION           = 1910;  // LITERAL, this, true, false, null
    360     public static final int COMPLEX_EXPRESSION          = 1911;  // SIMPLE_EXPRESSION, and various molecules
    361
    362
    363
    364     //
    365     // TYPE GROUPS (OPERATIONS SUPPORT)
    366
    367     public static final int PARAMETER_TERMINATORS       = 2000;  // ")", ","
    368     public static final int ARRAY_ITEM_TERMINATORS      = 2001;  // "]", ","
    369     public static final int TYPE_LIST_TERMINATORS       = 2002;  // "implements", "throws", "{", ","
    370     public static final int OPTIONAL_DATATYPE_FOLLOWERS = 2003;  // identifier, "[", "."
    371
    372     public static final int SWITCH_BLOCK_TERMINATORS    = 2004;  // "case", "default", "}"
    373     public static final int SWITCH_ENTRIES              = 2005;  // "case", "default"
    374
    375     public static final int METHOD_CALL_STARTERS        = 2006;  // LITERAL, "(", "{"
    376     public static final int UNSAFE_OVER_NEWLINES        = 2007;  // things the expression parser should cross lines for in it doesn't have to
    377
    378     public static final int PRECLUDES_CAST_OPERATOR     = 2008;  // anything that prevents (X) from being a cast
    379
    380
    381
    382
    383
    384   //---------------------------------------------------------------------------
    385   // TYPE HIERARCHIES
    386
    387
    388    /***
    389     *  Given two types, returns true if the second describes the first.
    390     */
    391
    392     public static boolean ofType( int specific, int general )
    393     {
    394
    395         if( general == specific )
    396         {
    397             return true;
    398         }
    399
    400         switch( general )
    401         {
    402             case ANY:
    403                 return true;
    404
    405             case NOT_EOF:
    406                 return specific >= UNKNOWN && specific <= SYNTH_VARIABLE_DECLARATION;
    407
    408             case GENERAL_END_OF_STATEMENT:
    409                 switch( specific )
    410                 {
    411                     case EOF:
    412                     case NEWLINE:
    413                     case SEMICOLON:
    414                         return true;
    415                 }
    416                 break;
    417
    418             case ANY_END_OF_STATEMENT:
    419                 switch( specific )
    420                 {
    421                     case EOF:
    422                     case NEWLINE:
    423                     case SEMICOLON:
    424                     case RIGHT_CURLY_BRACE:
    425                         return true;
    426                 }
    427                 break;
    428
    429             case ASSIGNMENT_OPERATOR:
    430                 return specific == EQUAL || (specific >= PLUS_EQUAL && specific <= MOD_EQUAL) || (specific >= LOGICAL_OR_EQUAL && specific <= LOGICAL_AND_EQUAL);
    431
    432             case COMPARISON_OPERATOR:
    433                 return specific >= COMPARE_NOT_EQUAL && specific <= COMPARE_TO;
    434
    435             case MATH_OPERATOR:
    436                 return (specific >= PLUS && specific <= RIGHT_SHIFT_UNSIGNED) || (specific >= NOT && specific <= LOGICAL_AND);
    437
    438             case LOGICAL_OPERATOR:
    439                 return specific >= NOT && specific <= LOGICAL_AND;
    440
    441             case RANGE_OPERATOR:
    442                 return specific == DOT_DOT || specific == DOT_DOT_DOT;
    443
    444             case REGEX_COMPARISON_OPERATOR:
    445                 return specific == FIND_REGEX || specific == MATCH_REGEX;
    446
    447             case DEREFERENCE_OPERATOR:
    448                 return specific == DOT || specific == NAVIGATE;
    449
    450             case PREFIX_OPERATOR:
    451                 switch( specific )
    452                 {
    453                     case MINUS:
    454                     case PLUS_PLUS:
    455                     case MINUS_MINUS:
    456                         return true;
    457                 }
    458
    459                 /* FALL THROUGH */
    460
    461             case PURE_PREFIX_OPERATOR:
    462                 switch( specific )
    463                 {
    464                     case REGEX_PATTERN:
    465                     case NOT:
    466                     case PREFIX_PLUS:
    467                     case PREFIX_PLUS_PLUS:
    468                     case PREFIX_MINUS:
    469                     case PREFIX_MINUS_MINUS:
    470                     case SYNTH_CAST:
    471                         return true;
    472                 }
    473                 break;
    474
    475             case POSTFIX_OPERATOR:
    476                 switch( specific )
    477                 {
    478                     case PLUS_PLUS:
    479                     case POSTFIX_PLUS_PLUS:
    480                     case MINUS_MINUS:
    481                     case POSTFIX_MINUS_MINUS:
    482                         return true;
    483                 }
    484                 break;
    485
    486             case INFIX_OPERATOR:
    487                 switch( specific )
    488                 {
    489                     case DOT:
    490                     case NAVIGATE:
    491                     case LOGICAL_OR:
    492                     case LOGICAL_AND:
    493                     case LEFT_SHIFT:
    494                     case RIGHT_SHIFT:
    495                     case RIGHT_SHIFT_UNSIGNED:
    496                     case FIND_REGEX:
    497                     case MATCH_REGEX:
    498                     case DOT_DOT:
    499                     case DOT_DOT_DOT:
    500                     case KEYWORD_INSTANCEOF:
    501                         return true;
    502                 }
    503
    504                 return (specific >= COMPARE_NOT_EQUAL && specific <= COMPARE_TO) || (specific >= PLUS && specific <= MOD_EQUAL) || specific == EQUAL || (specific >= PLUS_EQUAL && specific <= MOD_EQUAL) || (specific >= LOGICAL_OR_EQUAL && specific <= LOGICAL_AND_EQUAL);
    505
    506             case PREFIX_OR_INFIX_OPERATOR:
    507                 switch( specific )
    508                 {
    509                     case PLUS:
    510                     case MINUS:
    511                     case PREFIX_PLUS:
    512                     case PREFIX_MINUS:
    513                         return true;
    514                 }
    515                 break;
    516
    517
    518             case KEYWORD:
    519                 return specific >= KEYWORD_PRIVATE && specific <= KEYWORD_GOTO;
    520
    521             case SYMBOL:
    522                 return specific >= NEWLINE && specific <= PIPE;
    523
    524             case LITERAL:
    525                 return specific >= STRING && specific <= DECIMAL_NUMBER;
    526
    527             case NUMBER:
    528                 return specific == INTEGER_NUMBER || specific == DECIMAL_NUMBER;
    529
    530             case SIGN:
    531                 switch( specific )
    532                 {
    533                     case PLUS:
    534                     case MINUS:
    535                         return true;
    536                 }
    537                 break;
    538
    539             case NAMED_VALUE:
    540                 return specific >= KEYWORD_TRUE && specific <= KEYWORD_NULL;
    541
    542             case TRUTH_VALUE:
    543                 return specific == KEYWORD_TRUE || specific == KEYWORD_FALSE;
    544
    545             case TYPE_NAME:
    546                 if( specific == IDENTIFIER )
    547                 {
    548                     return true;
    549                 }
    550
    551                 /* FALL THROUGH */
    552
    553             case PRIMITIVE_TYPE:
    554                 return specific >= KEYWORD_VOID && specific <= KEYWORD_CHAR;
    555
    556             case CREATABLE_TYPE_NAME:
    557                 if( specific == IDENTIFIER )
    558                 {
    559                     return true;
    560                 }
    561
    562                 /* FALL THROUGH */
    563
    564             case CREATABLE_PRIMITIVE_TYPE:
    565                 return specific >= KEYWORD_BOOLEAN && specific <= KEYWORD_CHAR;
    566
    567             case LOOP:
    568                 switch( specific )
    569                 {
    570                     case KEYWORD_DO:
    571                     case KEYWORD_WHILE:
    572                     case KEYWORD_FOR:
    573                         return true;
    574                 }
    575                 break;
    576
    577             case RESERVED_KEYWORD:
    578                 return specific >= KEYWORD_CONST && specific <= KEYWORD_GOTO;
    579
    580             case KEYWORD_IDENTIFIER:
    581                 switch( specific )
    582                 {
    583                     case KEYWORD_CLASS:
    584                     case KEYWORD_INTERFACE:
    585                     case KEYWORD_MIXIN:
    586                     case KEYWORD_DEF:
    587                     case KEYWORD_DEFMACRO:
    588                     case KEYWORD_IN:
    589                     case KEYWORD_PROPERTY:
    590                         return true;
    591                 }
    592                 break;
    593
    594             case SYNTHETIC:
    595                 return specific >= SYNTH_COMPILATION_UNIT && specific <= SYNTH_VARIABLE_DECLARATION;
    596
    597             case TYPE_DECLARATION:
    598                 return specific >= KEYWORD_CLASS && specific <= KEYWORD_MIXIN;
    599
    600             case DECLARATION_MODIFIER:
    601                 return specific >= KEYWORD_PRIVATE && specific <= KEYWORD_STATIC;
    602
    603             case MATCHED_CONTAINER:
    604                 switch( specific )
    605                 {
    606                     case LEFT_CURLY_BRACE:
    607                     case RIGHT_CURLY_BRACE:
    608                     case LEFT_SQUARE_BRACKET:
    609                     case RIGHT_SQUARE_BRACKET:
    610                     case LEFT_PARENTHESIS:
    611                     case RIGHT_PARENTHESIS:
    612                         return true;
    613                 }
    614                 break;
    615
    616             case LEFT_OF_MATCHED_CONTAINER:
    617                 switch( specific )
    618                 {
    619                     case LEFT_CURLY_BRACE:
    620                     case LEFT_SQUARE_BRACKET:
    621                     case LEFT_PARENTHESIS:
    622                         return true;
    623                 }
    624                 break;
    625
    626             case RIGHT_OF_MATCHED_CONTAINER:
    627                 switch( specific )
    628                 {
    629                     case RIGHT_CURLY_BRACE:
    630                     case RIGHT_SQUARE_BRACKET:
    631                     case RIGHT_PARENTHESIS:
    632                         return true;
    633                 }
    634                 break;
    635
    636
    637             case PARAMETER_TERMINATORS:
    638                 return specific == RIGHT_PARENTHESIS || specific == COMMA;
    639
    640             case ARRAY_ITEM_TERMINATORS:
    641                 return specific == RIGHT_SQUARE_BRACKET || specific == COMMA;
    642
    643             case TYPE_LIST_TERMINATORS:
    644                 switch( specific )
    645                 {
    646                     case KEYWORD_IMPLEMENTS:
    647                     case KEYWORD_THROWS:
    648                     case LEFT_CURLY_BRACE:
    649                     case COMMA:
    650                         return true;
    651                 }
    652                 break;
    653
    654             case OPTIONAL_DATATYPE_FOLLOWERS:
    655                 switch( specific )
    656                 {
    657                     case IDENTIFIER:
    658                     case LEFT_SQUARE_BRACKET:
    659                     case DOT:
    660                         return true;
    661                 }
    662                 break;
    663
    664             case SWITCH_BLOCK_TERMINATORS:
    665                 if( specific == RIGHT_CURLY_BRACE )
    666                 {
    667                     return true;
    668                 }
    669
    670                 /* FALL THROUGH */
    671
    672             case SWITCH_ENTRIES:
    673                 return specific == KEYWORD_CASE || specific == KEYWORD_DEFAULT;
    674
    675             case METHOD_CALL_STARTERS:
    676                 if( specific >= STRING && specific <= DECIMAL_NUMBER )
    677                 {
    678                     return true;
    679                 }
    680                 switch( specific )
    681 				{
    682                 	case LEFT_PARENTHESIS:
    683                     case GSTRING_START:
    684                     case SYNTH_GSTRING:
    685                     case KEYWORD_NEW:
    686                     	return true;
    687                 }
    688                 break;
    689
    690             case UNSAFE_OVER_NEWLINES:
    691                 if( ofType(specific, SYMBOL) )
    692                 {
    693                     switch( specific )
    694                     {
    695                         case LEFT_CURLY_BRACE:
    696                         case LEFT_PARENTHESIS:
    697                         case LEFT_SQUARE_BRACKET:
    698                         case PLUS:
    699                         case PLUS_PLUS:
    700                         case MINUS:
    701                         case MINUS_MINUS:
    702                         case REGEX_PATTERN:
    703                         case NOT:
    704                             return true;
    705                     }
    706
    707                     return false;
    708                 }
    709
    710                 switch( specific )
    711                 {
    712                     case KEYWORD_INSTANCEOF:
    713                     case GSTRING_EXPRESSION_START:
    714                     case GSTRING_EXPRESSION_END:
    715                     case GSTRING_END:
    716                         return false;
    717                 }
    718
    719                 return true;
    720
    721             case PRECLUDES_CAST_OPERATOR:
    722                 switch( specific )
    723                 {
    724                     case PLUS:
    725                     case MINUS:
    726                     case PREFIX_MINUS:
    727                     case PREFIX_MINUS_MINUS:
    728                     case PREFIX_PLUS:
    729                     case PREFIX_PLUS_PLUS:
    730                     case LEFT_PARENTHESIS:
    731                         return false;
    732                 }
    733
    734                 return !ofType( specific, COMPLEX_EXPRESSION );
    735
    736
    737
    738
    739             case OPERATOR_EXPRESSION:
    740                 return specific >= DOT && specific <= RIGHT_SHIFT_UNSIGNED;
    741
    742             case SYNTH_EXPRESSION:
    743                 switch( specific )
    744                 {
    745                     case SYNTH_CAST:
    746                     case SYNTH_CLOSURE:
    747                     case SYNTH_TERNARY:
    748                         return true;
    749                 }
    750                 break;
    751
    752             case KEYWORD_EXPRESSION:
    753                 switch( specific )
    754                 {
    755                     case KEYWORD_NEW:
    756                     case KEYWORD_THIS:
    757                     case KEYWORD_SUPER:
    758                     case KEYWORD_INSTANCEOF:
    759                     case KEYWORD_TRUE:
    760                     case KEYWORD_FALSE:
    761                     case KEYWORD_NULL:
    762                         return true;
    763                 }
    764                 break;
    765
    766             case LITERAL_EXPRESSION:
    767                 return specific >= STRING && specific <= DECIMAL_NUMBER;
    768
    769             case ARRAY_EXPRESSION:
    770                 return specific == LEFT_SQUARE_BRACKET;
    771
    772             case EXPRESSION:
    773                 if( specific >= DOT && specific <= RIGHT_SHIFT_UNSIGNED )
    774                 {
    775                     return true;
    776                 }
    777
    778                 if( specific >= STRING && specific <= DECIMAL_NUMBER )
    779                 {
    780                     return true;
    781                 }
    782
    783                 switch( specific )
    784                 {
    785                     case SYNTH_CAST:
    786                     case SYNTH_CLOSURE:
    787                     case SYNTH_TERNARY:
    788                     case SYNTH_GSTRING:
    789                     case KEYWORD_NEW:
    790                     case KEYWORD_THIS:
    791                     case KEYWORD_SUPER:
    792                     case KEYWORD_INSTANCEOF:
    793                     case KEYWORD_TRUE:
    794                     case KEYWORD_FALSE:
    795                     case KEYWORD_NULL:
    796                     case LEFT_SQUARE_BRACKET:
    797                         return true;
    798                 }
    799                 break;
    800
    801             case COMPLEX_EXPRESSION:
    802                 switch( specific )
    803                 {
    804                     case KEYWORD_NEW:
    805                     case SYNTH_METHOD_CALL:
    806                     case SYNTH_GSTRING:
    807                     case SYNTH_LIST:
    808                     case SYNTH_MAP:
    809                     case SYNTH_CLOSURE:
    810                     case SYNTH_TERNARY:
    811                     case SYNTH_VARIABLE_DECLARATION:
    812                         return true;
    813                 }
    814
    815                 /* FALL THROUGH */
    816
    817             case SIMPLE_EXPRESSION:
    818                 if( specific >= STRING && specific <= DECIMAL_NUMBER ) {
    819                     return true;
    820                 }
    821
    822                 switch( specific ) {
    823                     case KEYWORD_SUPER:
    824                     case KEYWORD_THIS:
    825                     case KEYWORD_TRUE:
    826                     case KEYWORD_FALSE:
    827                     case KEYWORD_NULL:
    828                         return true;
    829                 }
    830
    831                 break;
    832         }
    833
    834         return false;
    835     }
    836
    837
    838
    839
    840   //---------------------------------------------------------------------------
    841   // TYPE COERSIONS
    842
    843
    844    /***
    845     *  Given two types, returns true if the first can be viewed as the second.
    846     *  NOTE that <code>canMean()</code> is orthogonal to <code>ofType()</code>.
    847     */
    848
    849     public static boolean canMean( int actual, int preferred ) {
    850
    851         if( actual == preferred ) {
    852             return true;
    853         }
    854
    855         switch( preferred ) {
    856
    857             case SYNTH_PARAMETER_DECLARATION:
    858             case IDENTIFIER:
    859                 switch( actual ) {
    860                     case IDENTIFIER:
    861                     case KEYWORD_DEF:
    862                     case KEYWORD_DEFMACRO:
    863                     case KEYWORD_CLASS:
    864                     case KEYWORD_INTERFACE:
    865                     case KEYWORD_MIXIN:
    866                         return true;
    867                 }
    868                 break;
    869
    870             case SYNTH_CLASS:
    871             case SYNTH_INTERFACE:
    872             case SYNTH_MIXIN:
    873             case SYNTH_METHOD:
    874             case SYNTH_PROPERTY:
    875                 return actual == IDENTIFIER;
    876
    877             case SYNTH_LIST:
    878             case SYNTH_MAP:
    879                 return actual == LEFT_SQUARE_BRACKET;
    880
    881             case SYNTH_CAST:
    882                 return actual == LEFT_PARENTHESIS;
    883
    884             case SYNTH_BLOCK:
    885             case SYNTH_CLOSURE:
    886                 return actual == LEFT_CURLY_BRACE;
    887
    888             case SYNTH_LABEL:
    889                 return actual == COLON;
    890
    891             case SYNTH_VARIABLE_DECLARATION:
    892                 return actual == IDENTIFIER;
    893         }
    894
    895         return false;
    896     }
    897
    898
    899
    900    /***
    901     *  Converts a node from a generic type to a specific prefix type.
    902     *  Throws a <code>GroovyBugError</code> if the type can't be converted
    903     *  and requested.
    904     */
    905
    906     public static void makePrefix( CSTNode node, boolean throwIfInvalid ) {
    907
    908         switch( node.getMeaning() ) {
    909             case PLUS:
    910                 node.setMeaning( PREFIX_PLUS );
    911                 break;
    912
    913             case MINUS:
    914                 node.setMeaning( PREFIX_MINUS );
    915                 break;
    916
    917             case PLUS_PLUS:
    918                 node.setMeaning( PREFIX_PLUS_PLUS );
    919                 break;
    920
    921             case MINUS_MINUS:
    922                 node.setMeaning( PREFIX_MINUS_MINUS );
    923                 break;
    924
    925             default:
    926                 if( throwIfInvalid ) {
    927                     throw new GroovyBugError( "cannot convert to prefix for type [" + node.getMeaning() + "]" );
    928                 }
    929         }
    930
    931     }
    932
    933
    934
    935    /***
    936     *  Converts a node from a generic type to a specific postfix type.
    937     *  Throws a <code>GroovyBugError</code> if the type can't be converted.
    938     */
    939
    940     public static void makePostfix( CSTNode node, boolean throwIfInvalid ) {
    941
    942         switch( node.getMeaning() ) {
    943             case PLUS_PLUS:
    944                 node.setMeaning( POSTFIX_PLUS_PLUS );
    945                 break;
    946
    947             case MINUS_MINUS:
    948                 node.setMeaning( POSTFIX_MINUS_MINUS );
    949                 break;
    950
    951             default:
    952                 if( throwIfInvalid ) {
    953                     throw new GroovyBugError( "cannot convert to postfix for type [" + node.getMeaning() + "]" );
    954                 }
    955         }
    956
    957     }
    958
    959
    960
    961
    962   //---------------------------------------------------------------------------
    963   // OPERATOR PRECEDENCE
    964
    965
    966    /***
    967     *  Returns the precendence of the specified operator.  Non-operator's will
    968     *  receive -1 or a GroovyBugError, depending on your preference.
    969     */
    970
    971     public static int getPrecedence( int type, boolean throwIfInvalid ) {
    972
    973         switch( type ) {
    974
    975             case LEFT_PARENTHESIS:
    976                 return 0;
    977
    978             case EQUAL:
    979             case PLUS_EQUAL:
    980             case MINUS_EQUAL:
    981             case MULTIPLY_EQUAL:
    982             case DIVIDE_EQUAL:
    983             case INTDIV_EQUAL:
    984             case MOD_EQUAL:
    985             case LOGICAL_OR_EQUAL:
    986             case LOGICAL_AND_EQUAL:
    987                 return 5;
    988
    989             case QUESTION:
    990                 return 10;
    991
    992             case LOGICAL_OR:
    993                 return 15;
    994
    995             case LOGICAL_AND:
    996                 return 20;
    997
    998             case COMPARE_IDENTICAL:
    999             case COMPARE_NOT_IDENTICAL:
    1000                 return 24;
    1001
    1002             case COMPARE_NOT_EQUAL:
    1003             case COMPARE_EQUAL:
    1004             case COMPARE_LESS_THAN:
    1005             case COMPARE_LESS_THAN_EQUAL:
    1006             case COMPARE_GREATER_THAN:
    1007             case COMPARE_GREATER_THAN_EQUAL:
    1008             case COMPARE_TO:
    1009             case FIND_REGEX:
    1010             case MATCH_REGEX:
    1011             case KEYWORD_INSTANCEOF:
    1012                 return 25;
    1013
    1014             case DOT_DOT:
    1015             case DOT_DOT_DOT:
    1016                 return 30;
    1017
    1018             case LEFT_SHIFT:
    1019             case RIGHT_SHIFT:
    1020             case RIGHT_SHIFT_UNSIGNED:
    1021                 return 35;
    1022
    1023             case PLUS:
    1024             case MINUS:
    1025                 return 40;
    1026
    1027             case MULTIPLY:
    1028             case DIVIDE:
    1029             case INTDIV:
    1030             case MOD:
    1031                 return 45;
    1032
    1033             case NOT:
    1034             case REGEX_PATTERN:
    1035                 return 50;
    1036
    1037             case SYNTH_CAST:
    1038                 return 55;
    1039
    1040             case PLUS_PLUS:
    1041             case MINUS_MINUS:
    1042             case PREFIX_PLUS_PLUS:
    1043             case PREFIX_MINUS_MINUS:
    1044             case POSTFIX_PLUS_PLUS:
    1045             case POSTFIX_MINUS_MINUS:
    1046                 return 65;
    1047
    1048             case PREFIX_PLUS:
    1049             case PREFIX_MINUS:
    1050                 return 70;
    1051
    1052             case SYNTH_METHOD:
    1053             case LEFT_SQUARE_BRACKET:
    1054                 return 75;
    1055
    1056             case DOT:
    1057             case NAVIGATE:
    1058                 return 80;
    1059
    1060             case KEYWORD_NEW:
    1061                 return 85;
    1062         }
    1063
    1064         if( throwIfInvalid ) {
    1065             throw new GroovyBugError( "precedence requested for non-operator" );
    1066         }
    1067
    1068         return -1;
    1069     }
    1070
    1071
    1072
    1073
    1074   //---------------------------------------------------------------------------
    1075   // TEXTS
    1076
    1077     private static final Map TEXTS  = new HashMap();  // symbol/keyword type -> text
    1078     private static final Map LOOKUP = new HashMap();  // text -> symbol/keyword type
    1079
    1080
    1081    /***
    1082     *  Returns the type for the specified symbol/keyword text.  Returns UNKNOWN
    1083     *  if the text isn't found.  You can filter finds on a type.
    1084     */
    1085
    1086     public static int lookup( String text, int filter ) {
    1087         int type = UNKNOWN;
    1088
    1089         if( LOOKUP.containsKey(text) ) {
    1090             type = ((Integer)LOOKUP.get(text)).intValue();
    1091             if( filter != UNKNOWN && !ofType(type, filter) ) {
    1092                 type = UNKNOWN;
    1093             }
    1094         }
    1095
    1096         return type;
    1097     }
    1098
    1099
    1100    /***
    1101     *  Returns the type for the specified keyword text.  Returns UNKNOWN
    1102     *  if the text isn't found.
    1103     */
    1104
    1105     public static int lookupKeyword( String text ) {
    1106         return lookup( text, KEYWORD );
    1107     }
    1108
    1109
    1110    /***
    1111     *  Returns the type for the specified symbol text.  Returns UNKNOWN
    1112     *  if the text isn't found.
    1113     */
    1114
    1115     public static int lookupSymbol( String text ) {
    1116         return lookup( text, SYMBOL );
    1117     }
    1118
    1119
    1120    /***
    1121     *  Returns the text for the specified type.  Returns "" if the
    1122     *  text isn't found.
    1123     */
    1124
    1125     public static String getText( int type ) {
    1126         Integer key = new Integer( type );
    1127         String text = "";
    1128
    1129         if( TEXTS.containsKey(key) ) {
    1130             text = (String)TEXTS.get( key );
    1131         }
    1132
    1133         return text;
    1134     }
    1135
    1136
    1137    /***
    1138     *  Adds a element to the TEXTS and LOOKUP.
    1139     */
    1140
    1141     private static void addTranslation( String text, int type ) {
    1142         Integer key = new Integer( type );
    1143
    1144         TEXTS.put( key, text );
    1145         LOOKUP.put( text, key );
    1146     }
    1147
    1148
    1149     static {
    1150
    1151         //
    1152         // SYMBOLS
    1153
    1154         addTranslation( "\n"          , NEWLINE                     );
    1155
    1156         addTranslation( "{"           , LEFT_CURLY_BRACE            );
    1157         addTranslation( "}"           , RIGHT_CURLY_BRACE           );
    1158         addTranslation( "["           , LEFT_SQUARE_BRACKET         );
    1159         addTranslation( "]"           , RIGHT_SQUARE_BRACKET        );
    1160         addTranslation( "("           , LEFT_PARENTHESIS            );
    1161         addTranslation( ")"           , RIGHT_PARENTHESIS           );
    1162
    1163         addTranslation( "."           , DOT                         );
    1164         addTranslation( ".."          , DOT_DOT                     );
    1165         addTranslation( "..."         , DOT_DOT_DOT                 );
    1166
    1167         addTranslation( "->"          , NAVIGATE                    );
    1168
    1169         addTranslation( "=~"          , FIND_REGEX                  );
    1170         addTranslation( "==~"         , MATCH_REGEX                 );
    1171         addTranslation( "~"           , REGEX_PATTERN               );
    1172
    1173         addTranslation( "="           , EQUAL                       );
    1174
    1175         addTranslation( "!="          , COMPARE_NOT_EQUAL           );
    1176         addTranslation( "==="         , COMPARE_IDENTICAL           );
    1177         addTranslation( "!=="         , COMPARE_NOT_IDENTICAL       );
    1178         addTranslation( "=="          , COMPARE_EQUAL               );
    1179         addTranslation( "<"           , COMPARE_LESS_THAN           );
    1180         addTranslation( "<="          , COMPARE_LESS_THAN_EQUAL     );
    1181         addTranslation( ">"           , COMPARE_GREATER_THAN        );
    1182         addTranslation( ">="          , COMPARE_GREATER_THAN_EQUAL  );
    1183         addTranslation( "<=>"         , COMPARE_TO                  );
    1184
    1185         addTranslation( "!"           , NOT                         );
    1186         addTranslation( "||"          , LOGICAL_OR                  );
    1187         addTranslation( "&&"          , LOGICAL_AND                 );
    1188
    1189         addTranslation( "||="         , LOGICAL_OR_EQUAL            );
    1190         addTranslation( "&&="         , LOGICAL_AND_EQUAL           );
    1191
    1192         addTranslation( "+"           , PLUS                        );
    1193         addTranslation( "-"           , MINUS                       );
    1194         addTranslation( "*"           , MULTIPLY                    );
    1195         addTranslation( "/"           , DIVIDE                      );
    1196         addTranslation( "//"          , INTDIV                      );
    1197         addTranslation( "%"           , MOD                         );
    1198
    1199         addTranslation( "+="          , PLUS_EQUAL                  );
    1200         addTranslation( "-="          , MINUS_EQUAL                 );
    1201         addTranslation( "*="          , MULTIPLY_EQUAL              );
    1202         addTranslation( "/="          , DIVIDE_EQUAL                );
    1203         addTranslation( "//="         , INTDIV_EQUAL                );
    1204         addTranslation( "%="          , MOD_EQUAL                   );
    1205
    1206         addTranslation( "++"          , PLUS_PLUS                   );
    1207         addTranslation( "--"          , MINUS_MINUS                 );
    1208
    1209         addTranslation( "<<"          , LEFT_SHIFT                  );
    1210         addTranslation( ">>"          , RIGHT_SHIFT                 );
    1211         addTranslation( ">>>"         , RIGHT_SHIFT_UNSIGNED        );
    1212
    1213         addTranslation( ","           , COMMA                       );
    1214         addTranslation( ":"           , COLON                       );
    1215         addTranslation( ";"           , SEMICOLON                   );
    1216         addTranslation( "?"           , QUESTION                    );
    1217         addTranslation( "|"           , PIPE                        );
    1218
    1219         addTranslation( "${}"         , GSTRING_EXPRESSION_START    );
    1220
    1221
    1222         //
    1223         // Keywords
    1224
    1225         addTranslation( "abstract"    , KEYWORD_ABSTRACT            );
    1226         addTranslation( "as"          , KEYWORD_AS                  );
    1227         addTranslation( "assert"      , KEYWORD_ASSERT              );
    1228         addTranslation( "break"       , KEYWORD_BREAK               );
    1229         addTranslation( "case"        , KEYWORD_CASE                );
    1230         addTranslation( "catch"       , KEYWORD_CATCH               );
    1231         addTranslation( "class"       , KEYWORD_CLASS               );
    1232         addTranslation( "const"       , KEYWORD_CONST               );
    1233         addTranslation( "continue"    , KEYWORD_CONTINUE            );
    1234         addTranslation( "def"         , KEYWORD_DEF                 );
    1235         addTranslation( "defmacro"    , KEYWORD_DEF                 ); // xxx br defmacro
    1236         addTranslation( "default"     , KEYWORD_DEFAULT             );
    1237         addTranslation( "do"          , KEYWORD_DO                  );
    1238         addTranslation( "else"        , KEYWORD_ELSE                );
    1239         addTranslation( "extends"     , KEYWORD_EXTENDS             );
    1240         addTranslation( "final"       , KEYWORD_FINAL               );
    1241         addTranslation( "finally"     , KEYWORD_FINALLY             );
    1242         addTranslation( "for"         , KEYWORD_FOR                 );
    1243         addTranslation( "goto"        , KEYWORD_GOTO                );
    1244         addTranslation( "if"          , KEYWORD_IF                  );
    1245         addTranslation( "in"          , KEYWORD_IN                  );
    1246         addTranslation( "implements"  , KEYWORD_IMPLEMENTS          );
    1247         addTranslation( "import"      , KEYWORD_IMPORT              );
    1248         addTranslation( "instanceof"  , KEYWORD_INSTANCEOF          );
    1249         addTranslation( "interface"   , KEYWORD_INTERFACE           );
    1250         addTranslation( "mixin"       , KEYWORD_MIXIN               );
    1251         addTranslation( "native"      , KEYWORD_NATIVE              );
    1252         addTranslation( "new"         , KEYWORD_NEW                 );
    1253         addTranslation( "package"     , KEYWORD_PACKAGE             );
    1254         addTranslation( "private"     , KEYWORD_PRIVATE             );
    1255         addTranslation( "property"    , KEYWORD_PROPERTY            );
    1256         addTranslation( "protected"   , KEYWORD_PROTECTED           );
    1257         addTranslation( "public"      , KEYWORD_PUBLIC              );
    1258         addTranslation( "return"      , KEYWORD_RETURN              );
    1259         addTranslation( "static"      , KEYWORD_STATIC              );
    1260         addTranslation( "super"       , KEYWORD_SUPER               );
    1261         addTranslation( "switch"      , KEYWORD_SWITCH              );
    1262         addTranslation( "synchronized", KEYWORD_SYNCHRONIZED        );
    1263         addTranslation( "this"        , KEYWORD_THIS                );
    1264         addTranslation( "throw"       , KEYWORD_THROW               );
    1265         addTranslation( "throws"      , KEYWORD_THROWS              );
    1266         addTranslation( "transient"   , KEYWORD_TRANSIENT           );
    1267         addTranslation( "try"         , KEYWORD_TRY                 );
    1268         addTranslation( "volatile"    , KEYWORD_VOLATILE            );
    1269         addTranslation( "while"       , KEYWORD_WHILE               );
    1270
    1271         addTranslation( "true"        , KEYWORD_TRUE                );
    1272         addTranslation( "false"       , KEYWORD_FALSE               );
    1273         addTranslation( "null"        , KEYWORD_NULL                );
    1274
    1275         addTranslation( "void"        , KEYWORD_VOID                );
    1276         addTranslation( "boolean"     , KEYWORD_BOOLEAN             );
    1277         addTranslation( "byte"        , KEYWORD_BYTE                );
    1278         addTranslation( "int"         , KEYWORD_INT                 );
    1279         addTranslation( "short"       , KEYWORD_SHORT               );
    1280         addTranslation( "long"        , KEYWORD_LONG                );
    1281         addTranslation( "float"       , KEYWORD_FLOAT               );
    1282         addTranslation( "double"      , KEYWORD_DOUBLE              );
    1283         addTranslation( "char"        , KEYWORD_CHAR                );
    1284     }
    1285
    1286
    1287
    1288
    1289   //---------------------------------------------------------------------------
    1290   // DESCRIPTIONS
    1291
    1292
    1293     private static final Map DESCRIPTIONS = new HashMap();
    1294
    1295
    1296    /***
    1297     *  Gets the description for the specified type.
    1298     */
    1299
    1300     public static String getDescription( int type ) {
    1301         Integer typeKey = new Integer(type);
    1302
    1303         if (DESCRIPTIONS.containsKey(typeKey)) {
    1304             return (String)DESCRIPTIONS.get(typeKey);
    1305         }
    1306
    1307         return "<>";
    1308     }
    1309
    1310
    1311    /***
    1312     *  Adds a description to the set.
    1313     */
    1314
    1315     private static void addDescription(int type, String description) {
    1316         addDescription(new Integer(type), description);
    1317     }
    1318
    1319
    1320    /***
    1321     *  Adds a description to the set.
    1322     */
    1323
    1324     private static void addDescription(Integer type, String description) {
    1325         if (description.startsWith("<") && description.endsWith(">")) {
    1326             DESCRIPTIONS.put(type, description);
    1327         }
    1328         else {
    1329             DESCRIPTIONS.put(type, '"' + description + '"');
    1330         }
    1331     }
    1332
    1333
    1334     static {
    1335
    1336         Iterator iterator = LOOKUP.keySet().iterator();
    1337         while( iterator.hasNext() )
    1338         {
    1339             String text = (String)iterator.next();
    1340             Integer key = (Integer)LOOKUP.get(text);
    1341
    1342             addDescription( key, text );
    1343         }
    1344
    1345         addDescription( NEWLINE                     , "<newline>"        );
    1346         addDescription( PREFIX_PLUS_PLUS            , "<prefix ++>"      );
    1347         addDescription( POSTFIX_PLUS_PLUS           , "<postfix ++>"     );
    1348         addDescription( PREFIX_MINUS_MINUS          , "<prefix -->"      );
    1349         addDescription( POSTFIX_MINUS_MINUS         , "<postfix -->"     );
    1350         addDescription( PREFIX_PLUS                 , "<positive>"       );
    1351         addDescription( PREFIX_MINUS                , "<negative>"       );
    1352
    1353         addDescription( STRING                      , "<string literal>" );
    1354         addDescription( IDENTIFIER                  , "<identifier>"     );
    1355         addDescription( INTEGER_NUMBER              , "<integer>"        );
    1356         addDescription( DECIMAL_NUMBER              , "<decimal>"        );
    1357
    1358         addDescription( SYNTH_COMPILATION_UNIT      , "<compilation unit>" );
    1359         addDescription( SYNTH_CLASS                 , "<class>"          );
    1360         addDescription( SYNTH_INTERFACE             , "<interface>"      );
    1361         addDescription( SYNTH_MIXIN                 , "<mixin>"          );
    1362         addDescription( SYNTH_METHOD                , "<method>"         );
    1363         addDescription( SYNTH_METHOD_CALL           , "<method call>"    );
    1364         addDescription( SYNTH_PROPERTY              , "<property>"       );
    1365         addDescription( SYNTH_PARAMETER_DECLARATION , "<parameter>"      );
    1366         addDescription( SYNTH_LIST                  , "<list>"           );
    1367         addDescription( SYNTH_MAP                   , "<map>"            );
    1368         addDescription( SYNTH_TUPLE                 , "<tuple>"          );
    1369         addDescription( SYNTH_GSTRING               , "<gstring>"        );
    1370         addDescription( SYNTH_CAST                  , "<cast>"           );
    1371         addDescription( SYNTH_BLOCK                 , "<block>"          );
    1372         addDescription( SYNTH_CLOSURE               , "<closure>"        );
    1373         addDescription( SYNTH_TERNARY               , "<ternary>"        );
    1374         addDescription( SYNTH_LABEL                 , "<label>"          );
    1375         addDescription( SYNTH_VARIABLE_DECLARATION  , "<variable declaration>"       );
    1376
    1377         addDescription( GSTRING_START               , "<start of gstring tokens>"    );
    1378         addDescription( GSTRING_END                 , "<end of gstring tokens>"      );
    1379         addDescription( GSTRING_EXPRESSION_START    , "<start of gstring expression>");
    1380         addDescription( GSTRING_EXPRESSION_END      , "<end of gstring expression>"  );
    1381
    1382         addDescription( ASSIGNMENT_OPERATOR         , "<assignment operator>"        );
    1383         addDescription( COMPARISON_OPERATOR         , "<comparison operator>"        );
    1384         addDescription( MATH_OPERATOR               , "<math operator>"              );
    1385         addDescription( LOGICAL_OPERATOR            , "<logical operator>"           );
    1386         addDescription( RANGE_OPERATOR              , "<range operator>"             );
    1387         addDescription( REGEX_COMPARISON_OPERATOR   , "<regex comparison operator>"  );
    1388         addDescription( DEREFERENCE_OPERATOR        , "<dereference operator>"       );
    1389         addDescription( PREFIX_OPERATOR             , "<prefix operator>"            );
    1390         addDescription( POSTFIX_OPERATOR            , "<postfix operator>"           );
    1391         addDescription( INFIX_OPERATOR              , "<infix operator>"             );
    1392         addDescription( KEYWORD                     , "<keyword>"                    );
    1393         addDescription( LITERAL                     , "<literal>"                    );
    1394         addDescription( NUMBER                      , "<number>"                     );
    1395         addDescription( NAMED_VALUE                 , "<named value>"                );
    1396         addDescription( TRUTH_VALUE                 , "<truth value>"                );
    1397         addDescription( PRIMITIVE_TYPE              , "<primitive type>"             );
    1398         addDescription( CREATABLE_PRIMITIVE_TYPE    , "<creatable primitive type>"   );
    1399         addDescription( LOOP                        , "<loop>"                       );
    1400         addDescription( RESERVED_KEYWORD            , "<reserved keyword>"           );
    1401         addDescription( SYNTHETIC                   , "<synthetic>"                  );
    1402         addDescription( TYPE_DECLARATION            , "<type declaration>"           );
    1403         addDescription( DECLARATION_MODIFIER        , "<declaration modifier>"       );
    1404         addDescription( TYPE_NAME                   , "<type name>"                  );
    1405         addDescription( CREATABLE_TYPE_NAME         , "<creatable type name>"        );
    1406         addDescription( MATCHED_CONTAINER           , "<matched container>"          );
    1407         addDescription( LEFT_OF_MATCHED_CONTAINER   , "<left of matched container>"  );
    1408         addDescription( RIGHT_OF_MATCHED_CONTAINER  , "<right of matched container>" );
    1409         addDescription( SWITCH_ENTRIES              , "<valid in a switch body>"     );
    1410     }
    1411
    1412 }