0001: /*
0002: $Id: Types.java 2120 2005-04-12 15:05:51Z jstrachan $
0003:
0004: Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
0005:
0006: Redistribution and use of this software and associated documentation
0007: ("Software"), with or without modification, are permitted provided
0008: that the following conditions are met:
0009:
0010: 1. Redistributions of source code must retain copyright
0011: statements and notices. Redistributions must also contain a
0012: copy of this document.
0013:
0014: 2. Redistributions in binary form must reproduce the
0015: above copyright notice, this list of conditions and the
0016: following disclaimer in the documentation and/or other
0017: materials provided with the distribution.
0018:
0019: 3. The name "groovy" must not be used to endorse or promote
0020: products derived from this Software without prior written
0021: permission of The Codehaus. For written permission,
0022: please contact info@codehaus.org.
0023:
0024: 4. Products derived from this Software may not be called "groovy"
0025: nor may "groovy" appear in their names without prior written
0026: permission of The Codehaus. "groovy" is a registered
0027: trademark of The Codehaus.
0028:
0029: 5. Due credit should be given to The Codehaus -
0030: http://groovy.codehaus.org/
0031:
0032: THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
0033: ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
0034: NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
0035: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
0036: THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
0037: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
0038: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
0039: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0040: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
0041: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0042: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
0043: OF THE POSSIBILITY OF SUCH DAMAGE.
0044:
0045: */
0046:
0047: package org.codehaus.groovy.syntax;
0048:
0049: import java.util.HashMap;
0050: import java.util.Iterator;
0051: import java.util.Map;
0052:
0053: import org.codehaus.groovy.GroovyBugError;
0054:
0055: /**
0056: * Typing information for the CST system. The types here are those
0057: * used by CSTNode, Token, and Reduction.
0058: *
0059: * @author <a href="mailto:bob@werken.com">bob mcwhirter</a>
0060: * @author <a href="mailto:cpoirier@dreaming.org">Chris Poirier</a>
0061: *
0062: * @version $Id: Types.java 2120 2005-04-12 15:05:51Z jstrachan $
0063: */
0064:
0065: public class Types {
0066:
0067: //---------------------------------------------------------------------------
0068: // TYPES: NOTE THAT ORDERING AND VALUES ARE IMPORTANT TO LOCAL ROUTINES!
0069:
0070: //
0071: // SPECIAL TOKENS
0072:
0073: public static final int EOF = -1; // end of file
0074: public static final int UNKNOWN = 0; // the unknown token
0075:
0076: //
0077: // RELEVANT WHITESPACE
0078:
0079: public static final int NEWLINE = 5; // \n
0080:
0081: //
0082: // OPERATORS AND OTHER MARKERS
0083:
0084: public static final int LEFT_CURLY_BRACE = 10; // {
0085: public static final int RIGHT_CURLY_BRACE = 20; // }
0086: public static final int LEFT_SQUARE_BRACKET = 30; // [
0087: public static final int RIGHT_SQUARE_BRACKET = 40; // ]
0088: public static final int LEFT_PARENTHESIS = 50; // (
0089: public static final int RIGHT_PARENTHESIS = 60; // )
0090:
0091: public static final int DOT = 70; // .
0092: public static final int DOT_DOT = 75; // ..
0093: public static final int DOT_DOT_DOT = 77; // ...
0094:
0095: public static final int NAVIGATE = 80; // ->
0096:
0097: public static final int FIND_REGEX = 90; // =~
0098: public static final int MATCH_REGEX = 94; // ==~
0099: public static final int REGEX_PATTERN = 97; // ~
0100:
0101: public static final int EQUAL = 100; // =
0102: public static final int EQUALS = EQUAL;
0103: public static final int ASSIGN = EQUAL;
0104:
0105: public static final int COMPARE_NOT_EQUAL = 120; // !=
0106: public static final int COMPARE_IDENTICAL = 121; // ===
0107: public static final int COMPARE_NOT_IDENTICAL = 122; // !==
0108: public static final int COMPARE_EQUAL = 123; // ==
0109: public static final int COMPARE_LESS_THAN = 124; // <
0110: public static final int COMPARE_LESS_THAN_EQUAL = 125; // <=
0111: public static final int COMPARE_GREATER_THAN = 126; // >
0112: public static final int COMPARE_GREATER_THAN_EQUAL = 127; // >=
0113: public static final int COMPARE_TO = 128; // <=>
0114:
0115: public static final int NOT = 160; // !
0116: public static final int LOGICAL_OR = 162; // ||
0117: public static final int LOGICAL_AND = 164; // &&
0118:
0119: public static final int LOGICAL_OR_EQUAL = 166; // ||=
0120: public static final int LOGICAL_AND_EQUAL = 168; // &&=
0121:
0122: public static final int PLUS = 200; // +
0123: public static final int MINUS = 201; // -
0124: public static final int MULTIPLY = 202; // *
0125: public static final int DIVIDE = 203; // /
0126: public static final int INTDIV = 204; // \
0127: public static final int MOD = 205; // %
0128: public static final int STAR_STAR = 206; // **
0129: public static final int POWER = STAR_STAR; // **
0130:
0131: public static final int PLUS_EQUAL = 210; // +=
0132: public static final int MINUS_EQUAL = 211; // -=
0133: public static final int MULTIPLY_EQUAL = 212; // *=
0134: public static final int DIVIDE_EQUAL = 213; // /=
0135: public static final int INTDIV_EQUAL = 214; // \=
0136: public static final int MOD_EQUAL = 215; // %=
0137: public static final int POWER_EQUAL = 216; // **=
0138:
0139: public static final int PLUS_PLUS = 250; // ++
0140: public static final int PREFIX_PLUS_PLUS = 251; // ++
0141: public static final int POSTFIX_PLUS_PLUS = 252; // ++
0142: public static final int PREFIX_PLUS = 253; // +
0143:
0144: public static final int MINUS_MINUS = 260; // --
0145: public static final int PREFIX_MINUS_MINUS = 261; // --
0146: public static final int POSTFIX_MINUS_MINUS = 262; // --
0147: public static final int PREFIX_MINUS = 263; // - (negation)
0148:
0149: public static final int LEFT_SHIFT = 280; // <<
0150: public static final int RIGHT_SHIFT = 281; // >>
0151: public static final int RIGHT_SHIFT_UNSIGNED = 282; // >>>
0152:
0153: public static final int LEFT_SHIFT_EQUAL = 285; // <<=
0154: public static final int RIGHT_SHIFT_EQUAL = 286; // >>=
0155: public static final int RIGHT_SHIFT_UNSIGNED_EQUAL = 287; // >>>=
0156:
0157: public static final int STAR = MULTIPLY;
0158:
0159: public static final int COMMA = 300; // -
0160: public static final int COLON = 310; // :
0161: public static final int SEMICOLON = 320; // ;
0162: public static final int QUESTION = 330; // ?
0163:
0164: // TODO refactor PIPE to be BITWISE_OR
0165: public static final int PIPE = 340; // |
0166: public static final int DOUBLE_PIPE = LOGICAL_OR; // ||
0167: public static final int BITWISE_OR = PIPE; // |
0168: public static final int BITWISE_AND = 341; // &
0169: public static final int BITWISE_XOR = 342; // ^
0170:
0171: public static final int BITWISE_OR_EQUAL = 350; // |=
0172: public static final int BITWISE_AND_EQUAL = 351; // &=
0173: public static final int BITWISE_XOR_EQUAL = 352; // ^=
0174: public static final int BITWISE_NEGATION = REGEX_PATTERN; // ~
0175:
0176: //
0177: // LITERALS
0178:
0179: public static final int STRING = 400; // any bare string data
0180:
0181: public static final int IDENTIFIER = 440; // anything text and not a keyword
0182:
0183: public static final int INTEGER_NUMBER = 450; // integer
0184: public static final int DECIMAL_NUMBER = 451; // decimal
0185:
0186: //
0187: // KEYWORDS: (PRIMARILY) CLASS/METHOD DECLARATION MODIFIERS
0188:
0189: public static final int KEYWORD_PRIVATE = 500; // declaration visibility
0190: public static final int KEYWORD_PROTECTED = 501; // declaration visibility
0191: public static final int KEYWORD_PUBLIC = 502; // declaration visibility
0192:
0193: public static final int KEYWORD_ABSTRACT = 510; // method body missing
0194: public static final int KEYWORD_FINAL = 511; // declaration cannot be overridden
0195: public static final int KEYWORD_NATIVE = 512; // a native code entry point
0196: public static final int KEYWORD_TRANSIENT = 513; // property should not be persisted
0197: public static final int KEYWORD_VOLATILE = 514; // compiler should never cache property
0198:
0199: public static final int KEYWORD_SYNCHRONIZED = 520; // modifier and block type
0200: public static final int KEYWORD_STATIC = 521; // modifier and block type
0201:
0202: //
0203: // KEYWORDS: TYPE SYSTEM
0204:
0205: public static final int KEYWORD_DEF = 530; // identifies a function declaration
0206: public static final int KEYWORD_DEFMACRO = 539; // XXX br identifies a macro declaration
0207: public static final int KEYWORD_CLASS = 531; // identifies a class declaration
0208: public static final int KEYWORD_INTERFACE = 532; // identifies an interface declaration
0209: public static final int KEYWORD_MIXIN = 533; // identifies a mixin declaration
0210:
0211: public static final int KEYWORD_IMPLEMENTS = 540; // specifies the interfaces implemented by a class
0212: public static final int KEYWORD_EXTENDS = 541; // specifies the base class/interface for a new one
0213: public static final int KEYWORD_THIS = 542; // method variable points to the current instance
0214: public static final int KEYWORD_SUPER = 543; // method variable points to the base instance
0215: public static final int KEYWORD_INSTANCEOF = 544; // type comparator
0216: public static final int KEYWORD_PROPERTY = 545; // deprecated; identifies a property
0217: public static final int KEYWORD_NEW = 546; // used to create a new instance of a class
0218:
0219: public static final int KEYWORD_PACKAGE = 550; // declares the package scope
0220: public static final int KEYWORD_IMPORT = 551; // declares an external class
0221: public static final int KEYWORD_AS = 552; // used in import statements to create an alias
0222:
0223: //
0224: // KEYWORDS: CONTROL STRUCTURES
0225:
0226: public static final int KEYWORD_RETURN = 560; // returns from a closure or method
0227: public static final int KEYWORD_IF = 561; // if
0228: public static final int KEYWORD_ELSE = 562; // else
0229: public static final int KEYWORD_DO = 570; // do loop
0230: public static final int KEYWORD_WHILE = 571; // while loop
0231: public static final int KEYWORD_FOR = 572; // for loop
0232: public static final int KEYWORD_IN = 573; // for (each) loop separator
0233: public static final int KEYWORD_BREAK = 574; // exits a loop or block
0234: public static final int KEYWORD_CONTINUE = 575; // restarts a loop on the next iteration
0235: public static final int KEYWORD_SWITCH = 576; // switch block
0236: public static final int KEYWORD_CASE = 577; // item in a switch block
0237: public static final int KEYWORD_DEFAULT = 578; // catch-all item in a switch block
0238:
0239: public static final int KEYWORD_TRY = 580; // block to monitor for exceptions
0240: public static final int KEYWORD_CATCH = 581; // catch block for a particular exception
0241: public static final int KEYWORD_FINALLY = 582; // block to always execute on exit of the try
0242: public static final int KEYWORD_THROW = 583; // statement to throw an exception
0243: public static final int KEYWORD_THROWS = 584; // method modifier to declare thrown transactions
0244: public static final int KEYWORD_ASSERT = 585; // alternate throw for code invariants
0245:
0246: //
0247: // KEYWORDS: PRIMITIVE TYPES
0248:
0249: public static final int KEYWORD_VOID = 600; // void
0250: public static final int KEYWORD_BOOLEAN = 601; // boolean
0251: public static final int KEYWORD_BYTE = 602; // 1 byte integer
0252: public static final int KEYWORD_SHORT = 603; // 2 byte integer
0253: public static final int KEYWORD_INT = 604; // 4 byte integer
0254: public static final int KEYWORD_LONG = 605; // 8 byte integer
0255: public static final int KEYWORD_FLOAT = 606; // 32 bit floating point number
0256: public static final int KEYWORD_DOUBLE = 607; // 64 bit floating point number
0257: public static final int KEYWORD_CHAR = 608; // unicode character code
0258:
0259: //
0260: // KEYWORDS: SPECIAL VALUES
0261:
0262: public static final int KEYWORD_TRUE = 610; // boolean truth
0263: public static final int KEYWORD_FALSE = 611; // boolean false
0264: public static final int KEYWORD_NULL = 612; // missing instance
0265:
0266: //
0267: // KEYWORDS: RESERVED
0268:
0269: public static final int KEYWORD_CONST = 700; // reserved in java and groovy
0270: public static final int KEYWORD_GOTO = 701; // reserved in java and groovy
0271:
0272: //
0273: // SPECIAL (CALCULATED) MEANINGS
0274:
0275: public static final int SYNTH_COMPILATION_UNIT = 800; // reserved: a synthetic root for a CST
0276:
0277: public static final int SYNTH_CLASS = 801; // applied to class names
0278: public static final int SYNTH_INTERFACE = 802; // applied to interface names
0279: public static final int SYNTH_MIXIN = 803; // applied to mixin names
0280: public static final int SYNTH_METHOD = 804; // applied to method names
0281: public static final int SYNTH_PROPERTY = 805; // applied to property names
0282: public static final int SYNTH_PARAMETER_DECLARATION = 806; // applied to method/closure parameter names
0283:
0284: public static final int SYNTH_LIST = 810; // applied to "[" that marks a list
0285: public static final int SYNTH_MAP = 811; // applied to "[" that marks a map
0286: public static final int SYNTH_GSTRING = 812; // a complete GString
0287:
0288: public static final int SYNTH_METHOD_CALL = 814; // applied to the optional "(" that marks a call to a method
0289: public static final int SYNTH_CAST = 815; // applied to "(" that marks a type cast
0290: public static final int SYNTH_BLOCK = 816; // applied to "{" that marks a block
0291: public static final int SYNTH_CLOSURE = 817; // applied to "{" that marks a closure
0292: public static final int SYNTH_LABEL = 818; // applied to a statement label
0293: public static final int SYNTH_TERNARY = 819; // applied to "?" that marks a ternary expression
0294: public static final int SYNTH_TUPLE = 820; // applied to "{" that marks an array initializer
0295:
0296: public static final int SYNTH_VARIABLE_DECLARATION = 830; // applied to an identifier that specifies
0297: // the type of a variable declaration
0298:
0299: //
0300: // GSTRING TOKENS
0301:
0302: public static final int GSTRING_START = 901; // any marker tha begins a GString
0303: public static final int GSTRING_END = 902; // any matching marker that ends a GString
0304: public static final int GSTRING_EXPRESSION_START = 903; // the ${ marker that starts a GString expression
0305: public static final int GSTRING_EXPRESSION_END = 904; // the } marker that ends a GString expresssion
0306:
0307: //
0308: // TYPE CLASSES
0309:
0310: public static final int ANY = 1000; // anything
0311: public static final int NOT_EOF = 1001; // anything but EOF
0312: public static final int GENERAL_END_OF_STATEMENT = 1002; // ";", "\n", EOF
0313: public static final int ANY_END_OF_STATEMENT = 1003; // ";", "\n", EOF, "}"
0314:
0315: public static final int ASSIGNMENT_OPERATOR = 1100; // =, +=, etc.
0316: public static final int COMPARISON_OPERATOR = 1101; // ==, ===, >, <, etc.
0317: public static final int MATH_OPERATOR = 1102; // +, -, / *, %, plus the LOGICAL_OPERATORS
0318: public static final int LOGICAL_OPERATOR = 1103; // ||, &&, !
0319: public static final int RANGE_OPERATOR = 1104; // .., ...
0320: public static final int REGEX_COMPARISON_OPERATOR = 1105; // =~, etc.
0321: public static final int DEREFERENCE_OPERATOR = 1106; // ., ->
0322: public static final int BITWISE_OPERATOR = 1107; // |, &, <<, >>, >>>, ^, ~
0323:
0324: public static final int PREFIX_OPERATOR = 1200; // ++, !, etc.
0325: public static final int POSTFIX_OPERATOR = 1210; // ++, etc.
0326: public static final int INFIX_OPERATOR = 1220; // +, -, =, etc.
0327: public static final int PREFIX_OR_INFIX_OPERATOR = 1230; // +, -
0328: public static final int PURE_PREFIX_OPERATOR = 1235; // prefix +, prefix -
0329:
0330: public static final int KEYWORD = 1300; // any keyword
0331: public static final int SYMBOL = 1301; // any symbol
0332: public static final int LITERAL = 1310; // strings, numbers, identifiers
0333: public static final int NUMBER = 1320; // integers and decimals
0334: public static final int SIGN = 1325; // "+", "-"
0335: public static final int NAMED_VALUE = 1330; // true, false, null
0336: public static final int TRUTH_VALUE = 1331; // true, false
0337: public static final int PRIMITIVE_TYPE = 1340; // void, byte, short, int, etc.
0338: public static final int CREATABLE_PRIMITIVE_TYPE = 1341; // any PRIMITIVE_TYPE except void
0339: public static final int LOOP = 1350; // do, while, etc.
0340: public static final int RESERVED_KEYWORD = 1360; // const, goto, etc.
0341: public static final int KEYWORD_IDENTIFIER = 1361; // keywords that can appear as identifiers
0342: public static final int SYNTHETIC = 1370; // any of the SYNTH types
0343:
0344: public static final int TYPE_DECLARATION = 1400; // class, interface, mixin
0345: public static final int DECLARATION_MODIFIER = 1410; // public, private, abstract, etc.
0346:
0347: public static final int TYPE_NAME = 1420; // identifiers, primitive types
0348: public static final int CREATABLE_TYPE_NAME = 1430; // identifiers, primitive types except void
0349:
0350: public static final int MATCHED_CONTAINER = 1500; // (, ), [, ], {, }
0351: public static final int LEFT_OF_MATCHED_CONTAINER = 1501; // (, [, {
0352: public static final int RIGHT_OF_MATCHED_CONTAINER = 1502; // ), ], }
0353:
0354: public static final int EXPRESSION = 1900; // all of the below 1900 series
0355:
0356: public static final int OPERATOR_EXPRESSION = 1901; // "."-"<<"
0357: public static final int SYNTH_EXPRESSION = 1902; // cast, ternary, and closure expression
0358: public static final int KEYWORD_EXPRESSION = 1903; // new, this, super, instanceof, true, false, null
0359: public static final int LITERAL_EXPRESSION = 1904; // LITERAL
0360: public static final int ARRAY_EXPRESSION = 1905; // "["
0361:
0362: public static final int SIMPLE_EXPRESSION = 1910; // LITERAL, this, true, false, null
0363: public static final int COMPLEX_EXPRESSION = 1911; // SIMPLE_EXPRESSION, and various molecules
0364:
0365: //
0366: // TYPE GROUPS (OPERATIONS SUPPORT)
0367:
0368: public static final int PARAMETER_TERMINATORS = 2000; // ")", ","
0369: public static final int ARRAY_ITEM_TERMINATORS = 2001; // "]", ","
0370: public static final int TYPE_LIST_TERMINATORS = 2002; // "implements", "throws", "{", ","
0371: public static final int OPTIONAL_DATATYPE_FOLLOWERS = 2003; // identifier, "[", "."
0372:
0373: public static final int SWITCH_BLOCK_TERMINATORS = 2004; // "case", "default", "}"
0374: public static final int SWITCH_ENTRIES = 2005; // "case", "default"
0375:
0376: public static final int METHOD_CALL_STARTERS = 2006; // LITERAL, "(", "{"
0377: public static final int UNSAFE_OVER_NEWLINES = 2007; // things the expression parser should cross lines for in it doesn't have to
0378:
0379: public static final int PRECLUDES_CAST_OPERATOR = 2008; // anything that prevents (X) from being a cast
0380:
0381: //---------------------------------------------------------------------------
0382: // TYPE HIERARCHIES
0383:
0384: /**
0385: * Given two types, returns true if the second describes the first.
0386: */
0387:
0388: public static boolean ofType(int specific, int general) {
0389:
0390: if (general == specific) {
0391: return true;
0392: }
0393:
0394: switch (general) {
0395: case ANY:
0396: return true;
0397:
0398: case NOT_EOF:
0399: return specific >= UNKNOWN
0400: && specific <= SYNTH_VARIABLE_DECLARATION;
0401:
0402: case GENERAL_END_OF_STATEMENT:
0403: switch (specific) {
0404: case EOF:
0405: case NEWLINE:
0406: case SEMICOLON:
0407: return true;
0408: }
0409: break;
0410:
0411: case ANY_END_OF_STATEMENT:
0412: switch (specific) {
0413: case EOF:
0414: case NEWLINE:
0415: case SEMICOLON:
0416: case RIGHT_CURLY_BRACE:
0417: return true;
0418: }
0419: break;
0420:
0421: case ASSIGNMENT_OPERATOR:
0422: return specific == EQUAL
0423: || (specific >= PLUS_EQUAL && specific <= POWER_EQUAL)
0424: || (specific >= LOGICAL_OR_EQUAL && specific <= LOGICAL_AND_EQUAL)
0425: || (specific >= LEFT_SHIFT_EQUAL && specific <= RIGHT_SHIFT_UNSIGNED_EQUAL)
0426: || (specific >= BITWISE_OR_EQUAL && specific <= BITWISE_XOR_EQUAL);
0427:
0428: case COMPARISON_OPERATOR:
0429: return specific >= COMPARE_NOT_EQUAL
0430: && specific <= COMPARE_TO;
0431:
0432: case MATH_OPERATOR:
0433: return (specific >= PLUS && specific <= RIGHT_SHIFT_UNSIGNED)
0434: || (specific >= NOT && specific <= LOGICAL_AND)
0435: || (specific >= BITWISE_OR && specific <= BITWISE_XOR);
0436:
0437: case LOGICAL_OPERATOR:
0438: return specific >= NOT && specific <= LOGICAL_AND;
0439:
0440: case BITWISE_OPERATOR:
0441: return (specific >= BITWISE_OR && specific <= BITWISE_XOR)
0442: || specific == BITWISE_NEGATION;
0443:
0444: case RANGE_OPERATOR:
0445: return specific == DOT_DOT || specific == DOT_DOT_DOT;
0446:
0447: case REGEX_COMPARISON_OPERATOR:
0448: return specific == FIND_REGEX || specific == MATCH_REGEX;
0449:
0450: case DEREFERENCE_OPERATOR:
0451: return specific == DOT || specific == NAVIGATE;
0452:
0453: case PREFIX_OPERATOR:
0454: switch (specific) {
0455: case MINUS:
0456: case PLUS_PLUS:
0457: case MINUS_MINUS:
0458: return true;
0459: }
0460:
0461: /* FALL THROUGH */
0462:
0463: case PURE_PREFIX_OPERATOR:
0464: switch (specific) {
0465: case REGEX_PATTERN:
0466: case NOT:
0467: case PREFIX_PLUS:
0468: case PREFIX_PLUS_PLUS:
0469: case PREFIX_MINUS:
0470: case PREFIX_MINUS_MINUS:
0471: case SYNTH_CAST:
0472: return true;
0473: }
0474: break;
0475:
0476: case POSTFIX_OPERATOR:
0477: switch (specific) {
0478: case PLUS_PLUS:
0479: case POSTFIX_PLUS_PLUS:
0480: case MINUS_MINUS:
0481: case POSTFIX_MINUS_MINUS:
0482: return true;
0483: }
0484: break;
0485:
0486: case INFIX_OPERATOR:
0487: switch (specific) {
0488: case DOT:
0489: case NAVIGATE:
0490: case LOGICAL_OR:
0491: case LOGICAL_AND:
0492: case BITWISE_OR:
0493: case BITWISE_AND:
0494: case BITWISE_XOR:
0495: case LEFT_SHIFT:
0496: case RIGHT_SHIFT:
0497: case RIGHT_SHIFT_UNSIGNED:
0498: case FIND_REGEX:
0499: case MATCH_REGEX:
0500: case DOT_DOT:
0501: case DOT_DOT_DOT:
0502: case KEYWORD_INSTANCEOF:
0503: return true;
0504: }
0505:
0506: return (specific >= COMPARE_NOT_EQUAL && specific <= COMPARE_TO)
0507: || (specific >= PLUS && specific <= MOD_EQUAL)
0508: || specific == EQUAL
0509: || (specific >= PLUS_EQUAL && specific <= POWER_EQUAL)
0510: || (specific >= LOGICAL_OR_EQUAL && specific <= LOGICAL_AND_EQUAL)
0511: || (specific >= LEFT_SHIFT_EQUAL && specific <= RIGHT_SHIFT_UNSIGNED_EQUAL)
0512: || (specific >= BITWISE_OR_EQUAL && specific <= BITWISE_XOR_EQUAL);
0513:
0514: case PREFIX_OR_INFIX_OPERATOR:
0515: switch (specific) {
0516: case POWER:
0517: case PLUS:
0518: case MINUS:
0519: case PREFIX_PLUS:
0520: case PREFIX_MINUS:
0521: return true;
0522: }
0523: break;
0524:
0525: case KEYWORD:
0526: return specific >= KEYWORD_PRIVATE
0527: && specific <= KEYWORD_GOTO;
0528:
0529: case SYMBOL:
0530: return specific >= NEWLINE && specific <= PIPE;
0531:
0532: case LITERAL:
0533: return specific >= STRING && specific <= DECIMAL_NUMBER;
0534:
0535: case NUMBER:
0536: return specific == INTEGER_NUMBER
0537: || specific == DECIMAL_NUMBER;
0538:
0539: case SIGN:
0540: switch (specific) {
0541: case PLUS:
0542: case MINUS:
0543: return true;
0544: }
0545: break;
0546:
0547: case NAMED_VALUE:
0548: return specific >= KEYWORD_TRUE && specific <= KEYWORD_NULL;
0549:
0550: case TRUTH_VALUE:
0551: return specific == KEYWORD_TRUE
0552: || specific == KEYWORD_FALSE;
0553:
0554: case TYPE_NAME:
0555: if (specific == IDENTIFIER) {
0556: return true;
0557: }
0558:
0559: /* FALL THROUGH */
0560:
0561: case PRIMITIVE_TYPE:
0562: return specific >= KEYWORD_VOID && specific <= KEYWORD_CHAR;
0563:
0564: case CREATABLE_TYPE_NAME:
0565: if (specific == IDENTIFIER) {
0566: return true;
0567: }
0568:
0569: /* FALL THROUGH */
0570:
0571: case CREATABLE_PRIMITIVE_TYPE:
0572: return specific >= KEYWORD_BOOLEAN
0573: && specific <= KEYWORD_CHAR;
0574:
0575: case LOOP:
0576: switch (specific) {
0577: case KEYWORD_DO:
0578: case KEYWORD_WHILE:
0579: case KEYWORD_FOR:
0580: return true;
0581: }
0582: break;
0583:
0584: case RESERVED_KEYWORD:
0585: return specific >= KEYWORD_CONST
0586: && specific <= KEYWORD_GOTO;
0587:
0588: case KEYWORD_IDENTIFIER:
0589: switch (specific) {
0590: case KEYWORD_CLASS:
0591: case KEYWORD_INTERFACE:
0592: case KEYWORD_MIXIN:
0593: case KEYWORD_DEF:
0594: case KEYWORD_DEFMACRO:
0595: case KEYWORD_IN:
0596: case KEYWORD_PROPERTY:
0597: return true;
0598: }
0599: break;
0600:
0601: case SYNTHETIC:
0602: return specific >= SYNTH_COMPILATION_UNIT
0603: && specific <= SYNTH_VARIABLE_DECLARATION;
0604:
0605: case TYPE_DECLARATION:
0606: return specific >= KEYWORD_CLASS
0607: && specific <= KEYWORD_MIXIN;
0608:
0609: case DECLARATION_MODIFIER:
0610: return specific >= KEYWORD_PRIVATE
0611: && specific <= KEYWORD_STATIC;
0612:
0613: case MATCHED_CONTAINER:
0614: switch (specific) {
0615: case LEFT_CURLY_BRACE:
0616: case RIGHT_CURLY_BRACE:
0617: case LEFT_SQUARE_BRACKET:
0618: case RIGHT_SQUARE_BRACKET:
0619: case LEFT_PARENTHESIS:
0620: case RIGHT_PARENTHESIS:
0621: return true;
0622: }
0623: break;
0624:
0625: case LEFT_OF_MATCHED_CONTAINER:
0626: switch (specific) {
0627: case LEFT_CURLY_BRACE:
0628: case LEFT_SQUARE_BRACKET:
0629: case LEFT_PARENTHESIS:
0630: return true;
0631: }
0632: break;
0633:
0634: case RIGHT_OF_MATCHED_CONTAINER:
0635: switch (specific) {
0636: case RIGHT_CURLY_BRACE:
0637: case RIGHT_SQUARE_BRACKET:
0638: case RIGHT_PARENTHESIS:
0639: return true;
0640: }
0641: break;
0642:
0643: case PARAMETER_TERMINATORS:
0644: return specific == RIGHT_PARENTHESIS || specific == COMMA;
0645:
0646: case ARRAY_ITEM_TERMINATORS:
0647: return specific == RIGHT_SQUARE_BRACKET
0648: || specific == COMMA;
0649:
0650: case TYPE_LIST_TERMINATORS:
0651: switch (specific) {
0652: case KEYWORD_IMPLEMENTS:
0653: case KEYWORD_THROWS:
0654: case LEFT_CURLY_BRACE:
0655: case COMMA:
0656: return true;
0657: }
0658: break;
0659:
0660: case OPTIONAL_DATATYPE_FOLLOWERS:
0661: switch (specific) {
0662: case IDENTIFIER:
0663: case LEFT_SQUARE_BRACKET:
0664: case DOT:
0665: return true;
0666: }
0667: break;
0668:
0669: case SWITCH_BLOCK_TERMINATORS:
0670: if (specific == RIGHT_CURLY_BRACE) {
0671: return true;
0672: }
0673:
0674: /* FALL THROUGH */
0675:
0676: case SWITCH_ENTRIES:
0677: return specific == KEYWORD_CASE
0678: || specific == KEYWORD_DEFAULT;
0679:
0680: case METHOD_CALL_STARTERS:
0681: if (specific >= STRING && specific <= DECIMAL_NUMBER) {
0682: return true;
0683: }
0684: switch (specific) {
0685: case LEFT_PARENTHESIS:
0686: case GSTRING_START:
0687: case SYNTH_GSTRING:
0688: case KEYWORD_NEW:
0689: return true;
0690: }
0691: break;
0692:
0693: case UNSAFE_OVER_NEWLINES:
0694: if (ofType(specific, SYMBOL)) {
0695: switch (specific) {
0696: case LEFT_CURLY_BRACE:
0697: case LEFT_PARENTHESIS:
0698: case LEFT_SQUARE_BRACKET:
0699: case PLUS:
0700: case PLUS_PLUS:
0701: case MINUS:
0702: case MINUS_MINUS:
0703: case REGEX_PATTERN:
0704: case NOT:
0705: return true;
0706: }
0707:
0708: return false;
0709: }
0710:
0711: switch (specific) {
0712: case KEYWORD_INSTANCEOF:
0713: case GSTRING_EXPRESSION_START:
0714: case GSTRING_EXPRESSION_END:
0715: case GSTRING_END:
0716: return false;
0717: }
0718:
0719: return true;
0720:
0721: case PRECLUDES_CAST_OPERATOR:
0722: switch (specific) {
0723: case PLUS:
0724: case MINUS:
0725: case PREFIX_MINUS:
0726: case PREFIX_MINUS_MINUS:
0727: case PREFIX_PLUS:
0728: case PREFIX_PLUS_PLUS:
0729: case LEFT_PARENTHESIS:
0730: return false;
0731: }
0732:
0733: return !ofType(specific, COMPLEX_EXPRESSION);
0734:
0735: case OPERATOR_EXPRESSION:
0736: return specific >= DOT && specific <= RIGHT_SHIFT_UNSIGNED;
0737:
0738: case SYNTH_EXPRESSION:
0739: switch (specific) {
0740: case SYNTH_CAST:
0741: case SYNTH_CLOSURE:
0742: case SYNTH_TERNARY:
0743: return true;
0744: }
0745: break;
0746:
0747: case KEYWORD_EXPRESSION:
0748: switch (specific) {
0749: case KEYWORD_NEW:
0750: case KEYWORD_THIS:
0751: case KEYWORD_SUPER:
0752: case KEYWORD_INSTANCEOF:
0753: case KEYWORD_TRUE:
0754: case KEYWORD_FALSE:
0755: case KEYWORD_NULL:
0756: return true;
0757: }
0758: break;
0759:
0760: case LITERAL_EXPRESSION:
0761: return specific >= STRING && specific <= DECIMAL_NUMBER;
0762:
0763: case ARRAY_EXPRESSION:
0764: return specific == LEFT_SQUARE_BRACKET;
0765:
0766: case EXPRESSION:
0767: if (specific >= DOT && specific <= RIGHT_SHIFT_UNSIGNED) {
0768: return true;
0769: }
0770:
0771: if (specific >= STRING && specific <= DECIMAL_NUMBER) {
0772: return true;
0773: }
0774:
0775: switch (specific) {
0776: case SYNTH_CAST:
0777: case SYNTH_CLOSURE:
0778: case SYNTH_TERNARY:
0779: case SYNTH_GSTRING:
0780: case KEYWORD_NEW:
0781: case KEYWORD_THIS:
0782: case KEYWORD_SUPER:
0783: case KEYWORD_INSTANCEOF:
0784: case KEYWORD_TRUE:
0785: case KEYWORD_FALSE:
0786: case KEYWORD_NULL:
0787: case LEFT_SQUARE_BRACKET:
0788: return true;
0789: }
0790: break;
0791:
0792: case COMPLEX_EXPRESSION:
0793: switch (specific) {
0794: case KEYWORD_NEW:
0795: case SYNTH_METHOD_CALL:
0796: case SYNTH_GSTRING:
0797: case SYNTH_LIST:
0798: case SYNTH_MAP:
0799: case SYNTH_CLOSURE:
0800: case SYNTH_TERNARY:
0801: case SYNTH_VARIABLE_DECLARATION:
0802: return true;
0803: }
0804:
0805: /* FALL THROUGH */
0806:
0807: case SIMPLE_EXPRESSION:
0808: if (specific >= STRING && specific <= DECIMAL_NUMBER) {
0809: return true;
0810: }
0811:
0812: switch (specific) {
0813: case KEYWORD_SUPER:
0814: case KEYWORD_THIS:
0815: case KEYWORD_TRUE:
0816: case KEYWORD_FALSE:
0817: case KEYWORD_NULL:
0818: return true;
0819: }
0820:
0821: break;
0822: }
0823:
0824: return false;
0825: }
0826:
0827: //---------------------------------------------------------------------------
0828: // TYPE COERSIONS
0829:
0830: /**
0831: * Given two types, returns true if the first can be viewed as the second.
0832: * NOTE that <code>canMean()</code> is orthogonal to <code>ofType()</code>.
0833: */
0834:
0835: public static boolean canMean(int actual, int preferred) {
0836:
0837: if (actual == preferred) {
0838: return true;
0839: }
0840:
0841: switch (preferred) {
0842:
0843: case SYNTH_PARAMETER_DECLARATION:
0844: case IDENTIFIER:
0845: switch (actual) {
0846: case IDENTIFIER:
0847: case KEYWORD_DEF:
0848: case KEYWORD_DEFMACRO:
0849: case KEYWORD_CLASS:
0850: case KEYWORD_INTERFACE:
0851: case KEYWORD_MIXIN:
0852: return true;
0853: }
0854: break;
0855:
0856: case SYNTH_CLASS:
0857: case SYNTH_INTERFACE:
0858: case SYNTH_MIXIN:
0859: case SYNTH_METHOD:
0860: case SYNTH_PROPERTY:
0861: return actual == IDENTIFIER;
0862:
0863: case SYNTH_LIST:
0864: case SYNTH_MAP:
0865: return actual == LEFT_SQUARE_BRACKET;
0866:
0867: case SYNTH_CAST:
0868: return actual == LEFT_PARENTHESIS;
0869:
0870: case SYNTH_BLOCK:
0871: case SYNTH_CLOSURE:
0872: return actual == LEFT_CURLY_BRACE;
0873:
0874: case SYNTH_LABEL:
0875: return actual == COLON;
0876:
0877: case SYNTH_VARIABLE_DECLARATION:
0878: return actual == IDENTIFIER;
0879: }
0880:
0881: return false;
0882: }
0883:
0884: /**
0885: * Converts a node from a generic type to a specific prefix type.
0886: * Throws a <code>GroovyBugError</code> if the type can't be converted
0887: * and requested.
0888: */
0889:
0890: public static void makePrefix(CSTNode node, boolean throwIfInvalid) {
0891:
0892: switch (node.getMeaning()) {
0893: case PLUS:
0894: node.setMeaning(PREFIX_PLUS);
0895: break;
0896:
0897: case MINUS:
0898: node.setMeaning(PREFIX_MINUS);
0899: break;
0900:
0901: case PLUS_PLUS:
0902: node.setMeaning(PREFIX_PLUS_PLUS);
0903: break;
0904:
0905: case MINUS_MINUS:
0906: node.setMeaning(PREFIX_MINUS_MINUS);
0907: break;
0908:
0909: default:
0910: if (throwIfInvalid) {
0911: throw new GroovyBugError(
0912: "cannot convert to prefix for type ["
0913: + node.getMeaning() + "]");
0914: }
0915: }
0916:
0917: }
0918:
0919: /**
0920: * Converts a node from a generic type to a specific postfix type.
0921: * Throws a <code>GroovyBugError</code> if the type can't be converted.
0922: */
0923:
0924: public static void makePostfix(CSTNode node, boolean throwIfInvalid) {
0925:
0926: switch (node.getMeaning()) {
0927: case PLUS_PLUS:
0928: node.setMeaning(POSTFIX_PLUS_PLUS);
0929: break;
0930:
0931: case MINUS_MINUS:
0932: node.setMeaning(POSTFIX_MINUS_MINUS);
0933: break;
0934:
0935: default:
0936: if (throwIfInvalid) {
0937: throw new GroovyBugError(
0938: "cannot convert to postfix for type ["
0939: + node.getMeaning() + "]");
0940: }
0941: }
0942:
0943: }
0944:
0945: //---------------------------------------------------------------------------
0946: // OPERATOR PRECEDENCE
0947:
0948: /**
0949: * Returns the precendence of the specified operator. Non-operator's will
0950: * receive -1 or a GroovyBugError, depending on your preference.
0951: */
0952:
0953: public static int getPrecedence(int type, boolean throwIfInvalid) {
0954:
0955: switch (type) {
0956:
0957: case LEFT_PARENTHESIS:
0958: return 0;
0959:
0960: case EQUAL:
0961: case PLUS_EQUAL:
0962: case MINUS_EQUAL:
0963: case MULTIPLY_EQUAL:
0964: case DIVIDE_EQUAL:
0965: case INTDIV_EQUAL:
0966: case MOD_EQUAL:
0967: case POWER_EQUAL:
0968: case LOGICAL_OR_EQUAL:
0969: case LOGICAL_AND_EQUAL:
0970: case LEFT_SHIFT_EQUAL:
0971: case RIGHT_SHIFT_EQUAL:
0972: case RIGHT_SHIFT_UNSIGNED_EQUAL:
0973: case BITWISE_OR_EQUAL:
0974: case BITWISE_AND_EQUAL:
0975: case BITWISE_XOR_EQUAL:
0976: return 5;
0977:
0978: case QUESTION:
0979: return 10;
0980:
0981: case LOGICAL_OR:
0982: return 15;
0983:
0984: case LOGICAL_AND:
0985: return 20;
0986:
0987: case BITWISE_OR:
0988: case BITWISE_AND:
0989: case BITWISE_XOR:
0990: return 22;
0991:
0992: case COMPARE_IDENTICAL:
0993: case COMPARE_NOT_IDENTICAL:
0994: return 24;
0995:
0996: case COMPARE_NOT_EQUAL:
0997: case COMPARE_EQUAL:
0998: case COMPARE_LESS_THAN:
0999: case COMPARE_LESS_THAN_EQUAL:
1000: case COMPARE_GREATER_THAN:
1001: case COMPARE_GREATER_THAN_EQUAL:
1002: case COMPARE_TO:
1003: case FIND_REGEX:
1004: case MATCH_REGEX:
1005: case KEYWORD_INSTANCEOF:
1006: return 25;
1007:
1008: case DOT_DOT:
1009: case DOT_DOT_DOT:
1010: return 30;
1011:
1012: case LEFT_SHIFT:
1013: case RIGHT_SHIFT:
1014: case RIGHT_SHIFT_UNSIGNED:
1015: return 35;
1016:
1017: case PLUS:
1018: case MINUS:
1019: return 40;
1020:
1021: case MULTIPLY:
1022: case DIVIDE:
1023: case INTDIV:
1024: case MOD:
1025: return 45;
1026:
1027: case NOT:
1028: case REGEX_PATTERN:
1029: return 50;
1030:
1031: case SYNTH_CAST:
1032: return 55;
1033:
1034: case PLUS_PLUS:
1035: case MINUS_MINUS:
1036: case PREFIX_PLUS_PLUS:
1037: case PREFIX_MINUS_MINUS:
1038: case POSTFIX_PLUS_PLUS:
1039: case POSTFIX_MINUS_MINUS:
1040: return 65;
1041:
1042: case PREFIX_PLUS:
1043: case PREFIX_MINUS:
1044: return 70;
1045:
1046: case POWER:
1047: return 72;
1048:
1049: case SYNTH_METHOD:
1050: case LEFT_SQUARE_BRACKET:
1051: return 75;
1052:
1053: case DOT:
1054: case NAVIGATE:
1055: return 80;
1056:
1057: case KEYWORD_NEW:
1058: return 85;
1059: }
1060:
1061: if (throwIfInvalid) {
1062: throw new GroovyBugError(
1063: "precedence requested for non-operator");
1064: }
1065:
1066: return -1;
1067: }
1068:
1069: //---------------------------------------------------------------------------
1070: // TEXTS
1071:
1072: private static final Map TEXTS = new HashMap(); // symbol/keyword type -> text
1073: private static final Map LOOKUP = new HashMap(); // text -> symbol/keyword type
1074:
1075: /**
1076: * Returns the type for the specified symbol/keyword text. Returns UNKNOWN
1077: * if the text isn't found. You can filter finds on a type.
1078: */
1079:
1080: public static int lookup(String text, int filter) {
1081: int type = UNKNOWN;
1082:
1083: if (LOOKUP.containsKey(text)) {
1084: type = ((Integer) LOOKUP.get(text)).intValue();
1085: if (filter != UNKNOWN && !ofType(type, filter)) {
1086: type = UNKNOWN;
1087: }
1088: }
1089:
1090: return type;
1091: }
1092:
1093: /**
1094: * Returns the type for the specified keyword text. Returns UNKNOWN
1095: * if the text isn't found.
1096: */
1097:
1098: public static int lookupKeyword(String text) {
1099: return lookup(text, KEYWORD);
1100: }
1101:
1102: /**
1103: * Returns the type for the specified symbol text. Returns UNKNOWN
1104: * if the text isn't found.
1105: */
1106:
1107: public static int lookupSymbol(String text) {
1108: return lookup(text, SYMBOL);
1109: }
1110:
1111: /**
1112: * Returns the text for the specified type. Returns "" if the
1113: * text isn't found.
1114: */
1115:
1116: public static String getText(int type) {
1117: Integer key = new Integer(type);
1118: String text = "";
1119:
1120: if (TEXTS.containsKey(key)) {
1121: text = (String) TEXTS.get(key);
1122: }
1123:
1124: return text;
1125: }
1126:
1127: /**
1128: * Adds a element to the TEXTS and LOOKUP.
1129: */
1130:
1131: private static void addTranslation(String text, int type) {
1132: Integer key = new Integer(type);
1133:
1134: TEXTS.put(key, text);
1135: LOOKUP.put(text, key);
1136: }
1137:
1138: static {
1139:
1140: //
1141: // SYMBOLS
1142:
1143: addTranslation("\n", NEWLINE);
1144:
1145: addTranslation("{", LEFT_CURLY_BRACE);
1146: addTranslation("}", RIGHT_CURLY_BRACE);
1147: addTranslation("[", LEFT_SQUARE_BRACKET);
1148: addTranslation("]", RIGHT_SQUARE_BRACKET);
1149: addTranslation("(", LEFT_PARENTHESIS);
1150: addTranslation(")", RIGHT_PARENTHESIS);
1151:
1152: addTranslation(".", DOT);
1153: addTranslation("..", DOT_DOT);
1154: addTranslation("...", DOT_DOT_DOT);
1155:
1156: addTranslation("->", NAVIGATE);
1157:
1158: addTranslation("=~", FIND_REGEX);
1159: addTranslation("==~", MATCH_REGEX);
1160: addTranslation("~", REGEX_PATTERN);
1161:
1162: addTranslation("=", EQUAL);
1163:
1164: addTranslation("!=", COMPARE_NOT_EQUAL);
1165: addTranslation("===", COMPARE_IDENTICAL);
1166: addTranslation("!==", COMPARE_NOT_IDENTICAL);
1167: addTranslation("==", COMPARE_EQUAL);
1168: addTranslation("<", COMPARE_LESS_THAN);
1169: addTranslation("<=", COMPARE_LESS_THAN_EQUAL);
1170: addTranslation(">", COMPARE_GREATER_THAN);
1171: addTranslation(">=", COMPARE_GREATER_THAN_EQUAL);
1172: addTranslation("<=>", COMPARE_TO);
1173:
1174: addTranslation("!", NOT);
1175: addTranslation("||", LOGICAL_OR);
1176: addTranslation("&&", LOGICAL_AND);
1177:
1178: addTranslation("||=", LOGICAL_OR_EQUAL);
1179: addTranslation("&&=", LOGICAL_AND_EQUAL);
1180:
1181: addTranslation("+", PLUS);
1182: addTranslation("-", MINUS);
1183: addTranslation("*", MULTIPLY);
1184: addTranslation("/", DIVIDE);
1185: addTranslation("\\", INTDIV);
1186: addTranslation("%", MOD);
1187:
1188: addTranslation("**", POWER);
1189:
1190: addTranslation("+=", PLUS_EQUAL);
1191: addTranslation("-=", MINUS_EQUAL);
1192: addTranslation("*=", MULTIPLY_EQUAL);
1193: addTranslation("/=", DIVIDE_EQUAL);
1194: addTranslation("\\=", INTDIV_EQUAL);
1195: addTranslation("%=", MOD_EQUAL);
1196: addTranslation("**=", POWER_EQUAL);
1197:
1198: addTranslation("++", PLUS_PLUS);
1199: addTranslation("--", MINUS_MINUS);
1200:
1201: addTranslation("<<", LEFT_SHIFT);
1202: addTranslation(">>", RIGHT_SHIFT);
1203: addTranslation(">>>", RIGHT_SHIFT_UNSIGNED);
1204:
1205: addTranslation("<<=", LEFT_SHIFT_EQUAL);
1206: addTranslation(">>=", RIGHT_SHIFT_EQUAL);
1207: addTranslation(">>>=", RIGHT_SHIFT_UNSIGNED_EQUAL);
1208:
1209: addTranslation("&", BITWISE_AND);
1210: addTranslation("^", BITWISE_XOR);
1211:
1212: addTranslation("|=", BITWISE_OR_EQUAL);
1213: addTranslation("&=", BITWISE_AND_EQUAL);
1214: addTranslation("^=", BITWISE_XOR_EQUAL);
1215:
1216: addTranslation(",", COMMA);
1217: addTranslation(":", COLON);
1218: addTranslation(";", SEMICOLON);
1219: addTranslation("?", QUESTION);
1220: addTranslation("|", PIPE);
1221:
1222: addTranslation("${}", GSTRING_EXPRESSION_START);
1223:
1224: //
1225: // Keywords
1226:
1227: addTranslation("abstract", KEYWORD_ABSTRACT);
1228: addTranslation("as", KEYWORD_AS);
1229: addTranslation("assert", KEYWORD_ASSERT);
1230: addTranslation("break", KEYWORD_BREAK);
1231: addTranslation("case", KEYWORD_CASE);
1232: addTranslation("catch", KEYWORD_CATCH);
1233: addTranslation("class", KEYWORD_CLASS);
1234: addTranslation("const", KEYWORD_CONST);
1235: addTranslation("continue", KEYWORD_CONTINUE);
1236: addTranslation("def", KEYWORD_DEF);
1237: addTranslation("defmacro", KEYWORD_DEF); // xxx br defmacro
1238: addTranslation("default", KEYWORD_DEFAULT);
1239: addTranslation("do", KEYWORD_DO);
1240: addTranslation("else", KEYWORD_ELSE);
1241: addTranslation("extends", KEYWORD_EXTENDS);
1242: addTranslation("final", KEYWORD_FINAL);
1243: addTranslation("finally", KEYWORD_FINALLY);
1244: addTranslation("for", KEYWORD_FOR);
1245: addTranslation("goto", KEYWORD_GOTO);
1246: addTranslation("if", KEYWORD_IF);
1247: addTranslation("in", KEYWORD_IN);
1248: addTranslation("implements", KEYWORD_IMPLEMENTS);
1249: addTranslation("import", KEYWORD_IMPORT);
1250: addTranslation("instanceof", KEYWORD_INSTANCEOF);
1251: addTranslation("interface", KEYWORD_INTERFACE);
1252: addTranslation("mixin", KEYWORD_MIXIN);
1253: addTranslation("native", KEYWORD_NATIVE);
1254: addTranslation("new", KEYWORD_NEW);
1255: addTranslation("package", KEYWORD_PACKAGE);
1256: addTranslation("private", KEYWORD_PRIVATE);
1257: addTranslation("property", KEYWORD_PROPERTY);
1258: addTranslation("protected", KEYWORD_PROTECTED);
1259: addTranslation("public", KEYWORD_PUBLIC);
1260: addTranslation("return", KEYWORD_RETURN);
1261: addTranslation("static", KEYWORD_STATIC);
1262: addTranslation("super", KEYWORD_SUPER);
1263: addTranslation("switch", KEYWORD_SWITCH);
1264: addTranslation("synchronized", KEYWORD_SYNCHRONIZED);
1265: addTranslation("this", KEYWORD_THIS);
1266: addTranslation("throw", KEYWORD_THROW);
1267: addTranslation("throws", KEYWORD_THROWS);
1268: addTranslation("transient", KEYWORD_TRANSIENT);
1269: addTranslation("try", KEYWORD_TRY);
1270: addTranslation("volatile", KEYWORD_VOLATILE);
1271: addTranslation("while", KEYWORD_WHILE);
1272:
1273: addTranslation("true", KEYWORD_TRUE);
1274: addTranslation("false", KEYWORD_FALSE);
1275: addTranslation("null", KEYWORD_NULL);
1276:
1277: addTranslation("void", KEYWORD_VOID);
1278: addTranslation("boolean", KEYWORD_BOOLEAN);
1279: addTranslation("byte", KEYWORD_BYTE);
1280: addTranslation("int", KEYWORD_INT);
1281: addTranslation("short", KEYWORD_SHORT);
1282: addTranslation("long", KEYWORD_LONG);
1283: addTranslation("float", KEYWORD_FLOAT);
1284: addTranslation("double", KEYWORD_DOUBLE);
1285: addTranslation("char", KEYWORD_CHAR);
1286: }
1287:
1288: //---------------------------------------------------------------------------
1289: // DESCRIPTIONS
1290:
1291: private static final Map DESCRIPTIONS = new HashMap();
1292:
1293: /**
1294: * Gets the description for the specified type.
1295: */
1296:
1297: public static String getDescription(int type) {
1298: Integer typeKey = new Integer(type);
1299:
1300: if (DESCRIPTIONS.containsKey(typeKey)) {
1301: return (String) DESCRIPTIONS.get(typeKey);
1302: }
1303:
1304: return "<>";
1305: }
1306:
1307: /**
1308: * Adds a description to the set.
1309: */
1310:
1311: private static void addDescription(int type, String description) {
1312: addDescription(new Integer(type), description);
1313: }
1314:
1315: /**
1316: * Adds a description to the set.
1317: */
1318:
1319: private static void addDescription(Integer type, String description) {
1320: if (description.startsWith("<") && description.endsWith(">")) {
1321: DESCRIPTIONS.put(type, description);
1322: } else {
1323: DESCRIPTIONS.put(type, '"' + description + '"');
1324: }
1325: }
1326:
1327: static {
1328:
1329: Iterator iterator = LOOKUP.keySet().iterator();
1330: while (iterator.hasNext()) {
1331: String text = (String) iterator.next();
1332: Integer key = (Integer) LOOKUP.get(text);
1333:
1334: addDescription(key, text);
1335: }
1336:
1337: addDescription(NEWLINE, "<newline>");
1338: addDescription(PREFIX_PLUS_PLUS, "<prefix ++>");
1339: addDescription(POSTFIX_PLUS_PLUS, "<postfix ++>");
1340: addDescription(PREFIX_MINUS_MINUS, "<prefix -->");
1341: addDescription(POSTFIX_MINUS_MINUS, "<postfix -->");
1342: addDescription(PREFIX_PLUS, "<positive>");
1343: addDescription(PREFIX_MINUS, "<negative>");
1344:
1345: addDescription(STRING, "<string literal>");
1346: addDescription(IDENTIFIER, "<identifier>");
1347: addDescription(INTEGER_NUMBER, "<integer>");
1348: addDescription(DECIMAL_NUMBER, "<decimal>");
1349:
1350: addDescription(SYNTH_COMPILATION_UNIT, "<compilation unit>");
1351: addDescription(SYNTH_CLASS, "<class>");
1352: addDescription(SYNTH_INTERFACE, "<interface>");
1353: addDescription(SYNTH_MIXIN, "<mixin>");
1354: addDescription(SYNTH_METHOD, "<method>");
1355: addDescription(SYNTH_METHOD_CALL, "<method call>");
1356: addDescription(SYNTH_PROPERTY, "<property>");
1357: addDescription(SYNTH_PARAMETER_DECLARATION, "<parameter>");
1358: addDescription(SYNTH_LIST, "<list>");
1359: addDescription(SYNTH_MAP, "<map>");
1360: addDescription(SYNTH_TUPLE, "<tuple>");
1361: addDescription(SYNTH_GSTRING, "<gstring>");
1362: addDescription(SYNTH_CAST, "<cast>");
1363: addDescription(SYNTH_BLOCK, "<block>");
1364: addDescription(SYNTH_CLOSURE, "<closure>");
1365: addDescription(SYNTH_TERNARY, "<ternary>");
1366: addDescription(SYNTH_LABEL, "<label>");
1367: addDescription(SYNTH_VARIABLE_DECLARATION,
1368: "<variable declaration>");
1369:
1370: addDescription(GSTRING_START, "<start of gstring tokens>");
1371: addDescription(GSTRING_END, "<end of gstring tokens>");
1372: addDescription(GSTRING_EXPRESSION_START,
1373: "<start of gstring expression>");
1374: addDescription(GSTRING_EXPRESSION_END,
1375: "<end of gstring expression>");
1376:
1377: addDescription(ASSIGNMENT_OPERATOR, "<assignment operator>");
1378: addDescription(COMPARISON_OPERATOR, "<comparison operator>");
1379: addDescription(MATH_OPERATOR, "<math operator>");
1380: addDescription(LOGICAL_OPERATOR, "<logical operator>");
1381: addDescription(BITWISE_OPERATOR, "<bitwise operator>");
1382: addDescription(RANGE_OPERATOR, "<range operator>");
1383: addDescription(REGEX_COMPARISON_OPERATOR,
1384: "<regex comparison operator>");
1385: addDescription(DEREFERENCE_OPERATOR, "<dereference operator>");
1386: addDescription(PREFIX_OPERATOR, "<prefix operator>");
1387: addDescription(POSTFIX_OPERATOR, "<postfix operator>");
1388: addDescription(INFIX_OPERATOR, "<infix operator>");
1389: addDescription(KEYWORD, "<keyword>");
1390: addDescription(LITERAL, "<literal>");
1391: addDescription(NUMBER, "<number>");
1392: addDescription(NAMED_VALUE, "<named value>");
1393: addDescription(TRUTH_VALUE, "<truth value>");
1394: addDescription(PRIMITIVE_TYPE, "<primitive type>");
1395: addDescription(CREATABLE_PRIMITIVE_TYPE,
1396: "<creatable primitive type>");
1397: addDescription(LOOP, "<loop>");
1398: addDescription(RESERVED_KEYWORD, "<reserved keyword>");
1399: addDescription(SYNTHETIC, "<synthetic>");
1400: addDescription(TYPE_DECLARATION, "<type declaration>");
1401: addDescription(DECLARATION_MODIFIER, "<declaration modifier>");
1402: addDescription(TYPE_NAME, "<type name>");
1403: addDescription(CREATABLE_TYPE_NAME, "<creatable type name>");
1404: addDescription(MATCHED_CONTAINER, "<matched container>");
1405: addDescription(LEFT_OF_MATCHED_CONTAINER,
1406: "<left of matched container>");
1407: addDescription(RIGHT_OF_MATCHED_CONTAINER,
1408: "<right of matched container>");
1409: addDescription(SWITCH_ENTRIES, "<valid in a switch body>");
1410: }
1411:
1412: }
|