| /* |
| * Copyright 2003-2007 the original author or authors. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.codehaus.groovy.syntax; |
| |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Map; |
| |
| import org.codehaus.groovy.GroovyBugError; |
| |
| |
| /** |
| * Typing information for the CST system. The types here are those |
| * used by CSTNode, Token, and Reduction. |
| * |
| * @author <a href="mailto:bob@werken.com">bob mcwhirter</a> |
| * @author <a href="mailto:cpoirier@dreaming.org">Chris Poirier</a> |
| * |
| * @version $Id$ |
| */ |
| |
| public class Types |
| { |
| |
| |
| //--------------------------------------------------------------------------- |
| // TYPES: NOTE THAT ORDERING AND VALUES ARE IMPORTANT TO LOCAL ROUTINES! |
| |
| |
| // |
| // SPECIAL TOKENS |
| |
| public static final int EOF = -1; // end of file |
| public static final int UNKNOWN = 0; // the unknown token |
| |
| |
| // |
| // RELEVANT WHITESPACE |
| |
| public static final int NEWLINE = 5; // \n |
| |
| |
| // |
| // OPERATORS AND OTHER MARKERS |
| |
| public static final int LEFT_CURLY_BRACE = 10; // { |
| public static final int RIGHT_CURLY_BRACE = 20; // } |
| public static final int LEFT_SQUARE_BRACKET = 30; // [ |
| public static final int RIGHT_SQUARE_BRACKET = 40; // ] |
| public static final int LEFT_PARENTHESIS = 50; // ( |
| public static final int RIGHT_PARENTHESIS = 60; // ) |
| |
| public static final int DOT = 70; // . |
| public static final int DOT_DOT = 75; // .. |
| public static final int DOT_DOT_DOT = 77; // ... |
| |
| public static final int NAVIGATE = 80; // -> |
| |
| public static final int FIND_REGEX = 90; // =~ |
| public static final int MATCH_REGEX = 94; // ==~ |
| public static final int REGEX_PATTERN = 97; // ~ |
| |
| public static final int EQUAL = 100; // = |
| public static final int EQUALS = EQUAL; |
| public static final int ASSIGN = EQUAL; |
| |
| public static final int COMPARE_NOT_EQUAL = 120; // != |
| public static final int COMPARE_IDENTICAL = 121; // === |
| public static final int COMPARE_NOT_IDENTICAL = 122; // !== |
| public static final int COMPARE_EQUAL = 123; // == |
| public static final int COMPARE_LESS_THAN = 124; // < |
| public static final int COMPARE_LESS_THAN_EQUAL = 125; // <= |
| public static final int COMPARE_GREATER_THAN = 126; // > |
| public static final int COMPARE_GREATER_THAN_EQUAL = 127; // >= |
| public static final int COMPARE_TO = 128; // <=> |
| |
| public static final int NOT = 160; // ! |
| public static final int LOGICAL_OR = 162; // || |
| public static final int LOGICAL_AND = 164; // && |
| |
| public static final int LOGICAL_OR_EQUAL = 166; // ||= |
| public static final int LOGICAL_AND_EQUAL = 168; // &&= |
| |
| public static final int PLUS = 200; // + |
| public static final int MINUS = 201; // - |
| public static final int MULTIPLY = 202; // * |
| public static final int DIVIDE = 203; // / |
| public static final int INTDIV = 204; // \ |
| public static final int MOD = 205; // % |
| public static final int STAR_STAR = 206; // ** |
| public static final int POWER = STAR_STAR; // ** |
| |
| public static final int PLUS_EQUAL = 210; // += |
| public static final int MINUS_EQUAL = 211; // -= |
| public static final int MULTIPLY_EQUAL = 212; // *= |
| public static final int DIVIDE_EQUAL = 213; // /= |
| public static final int INTDIV_EQUAL = 214; // \= |
| public static final int MOD_EQUAL = 215; // %= |
| public static final int POWER_EQUAL = 216; // **= |
| |
| public static final int PLUS_PLUS = 250; // ++ |
| public static final int PREFIX_PLUS_PLUS = 251; // ++ |
| public static final int POSTFIX_PLUS_PLUS = 252; // ++ |
| public static final int PREFIX_PLUS = 253; // + |
| |
| public static final int MINUS_MINUS = 260; // -- |
| public static final int PREFIX_MINUS_MINUS = 261; // -- |
| public static final int POSTFIX_MINUS_MINUS = 262; // -- |
| public static final int PREFIX_MINUS = 263; // - (negation) |
| |
| public static final int LEFT_SHIFT = 280; // << |
| public static final int RIGHT_SHIFT = 281; // >> |
| public static final int RIGHT_SHIFT_UNSIGNED = 282; // >>> |
| |
| public static final int LEFT_SHIFT_EQUAL = 285; // <<= |
| public static final int RIGHT_SHIFT_EQUAL = 286; // >>= |
| public static final int RIGHT_SHIFT_UNSIGNED_EQUAL = 287; // >>>= |
| |
| public static final int STAR = MULTIPLY; |
| |
| public static final int COMMA = 300; // - |
| public static final int COLON = 310; // : |
| public static final int SEMICOLON = 320; // ; |
| public static final int QUESTION = 330; // ? |
| |
| // TODO refactor PIPE to be BITWISE_OR |
| public static final int PIPE = 340; // | |
| public static final int DOUBLE_PIPE = LOGICAL_OR; // || |
| public static final int BITWISE_OR = PIPE; // | |
| public static final int BITWISE_AND = 341; // & |
| public static final int BITWISE_XOR = 342; // ^ |
| |
| public static final int BITWISE_OR_EQUAL = 350; // |= |
| public static final int BITWISE_AND_EQUAL = 351; // &= |
| public static final int BITWISE_XOR_EQUAL = 352; // ^= |
| public static final int BITWISE_NEGATION = REGEX_PATTERN; // ~ |
| |
| |
| // |
| // LITERALS |
| |
| public static final int STRING = 400; // any bare string data |
| |
| public static final int IDENTIFIER = 440; // anything text and not a keyword |
| |
| public static final int INTEGER_NUMBER = 450; // integer |
| public static final int DECIMAL_NUMBER = 451; // decimal |
| |
| |
| // |
| // KEYWORDS: (PRIMARILY) CLASS/METHOD DECLARATION MODIFIERS |
| |
| public static final int KEYWORD_PRIVATE = 500; // declaration visibility |
| public static final int KEYWORD_PROTECTED = 501; // declaration visibility |
| public static final int KEYWORD_PUBLIC = 502; // declaration visibility |
| |
| public static final int KEYWORD_ABSTRACT = 510; // method body missing |
| public static final int KEYWORD_FINAL = 511; // declaration cannot be overridden |
| public static final int KEYWORD_NATIVE = 512; // a native code entry point |
| public static final int KEYWORD_TRANSIENT = 513; // property should not be persisted |
| public static final int KEYWORD_VOLATILE = 514; // compiler should never cache property |
| |
| public static final int KEYWORD_SYNCHRONIZED = 520; // modifier and block type |
| public static final int KEYWORD_STATIC = 521; // modifier and block type |
| |
| |
| // |
| // KEYWORDS: TYPE SYSTEM |
| |
| public static final int KEYWORD_DEF = 530; // identifies a function declaration |
| public static final int KEYWORD_DEFMACRO = 539; // XXX br identifies a macro declaration |
| public static final int KEYWORD_CLASS = 531; // identifies a class declaration |
| public static final int KEYWORD_INTERFACE = 532; // identifies an interface declaration |
| public static final int KEYWORD_MIXIN = 533; // identifies a mixin declaration |
| |
| public static final int KEYWORD_IMPLEMENTS = 540; // specifies the interfaces implemented by a class |
| public static final int KEYWORD_EXTENDS = 541; // specifies the base class/interface for a new one |
| public static final int KEYWORD_THIS = 542; // method variable points to the current instance |
| public static final int KEYWORD_SUPER = 543; // method variable points to the base instance |
| public static final int KEYWORD_INSTANCEOF = 544; // type comparator |
| public static final int KEYWORD_PROPERTY = 545; // deprecated; identifies a property |
| public static final int KEYWORD_NEW = 546; // used to create a new instance of a class |
| |
| public static final int KEYWORD_PACKAGE = 550; // declares the package scope |
| public static final int KEYWORD_IMPORT = 551; // declares an external class |
| public static final int KEYWORD_AS = 552; // used in import statements to create an alias |
| |
| |
| // |
| // KEYWORDS: CONTROL STRUCTURES |
| |
| public static final int KEYWORD_RETURN = 560; // returns from a closure or method |
| public static final int KEYWORD_IF = 561; // if |
| public static final int KEYWORD_ELSE = 562; // else |
| public static final int KEYWORD_DO = 570; // do loop |
| public static final int KEYWORD_WHILE = 571; // while loop |
| public static final int KEYWORD_FOR = 572; // for loop |
| public static final int KEYWORD_IN = 573; // for (each) loop separator |
| public static final int KEYWORD_BREAK = 574; // exits a loop or block |
| public static final int KEYWORD_CONTINUE = 575; // restarts a loop on the next iteration |
| public static final int KEYWORD_SWITCH = 576; // switch block |
| public static final int KEYWORD_CASE = 577; // item in a switch block |
| public static final int KEYWORD_DEFAULT = 578; // catch-all item in a switch block |
| |
| public static final int KEYWORD_TRY = 580; // block to monitor for exceptions |
| public static final int KEYWORD_CATCH = 581; // catch block for a particular exception |
| public static final int KEYWORD_FINALLY = 582; // block to always execute on exit of the try |
| public static final int KEYWORD_THROW = 583; // statement to throw an exception |
| public static final int KEYWORD_THROWS = 584; // method modifier to declare thrown transactions |
| public static final int KEYWORD_ASSERT = 585; // alternate throw for code invariants |
| |
| |
| // |
| // KEYWORDS: PRIMITIVE TYPES |
| |
| public static final int KEYWORD_VOID = 600; // void |
| public static final int KEYWORD_BOOLEAN = 601; // boolean |
| public static final int KEYWORD_BYTE = 602; // 1 byte integer |
| public static final int KEYWORD_SHORT = 603; // 2 byte integer |
| public static final int KEYWORD_INT = 604; // 4 byte integer |
| public static final int KEYWORD_LONG = 605; // 8 byte integer |
| public static final int KEYWORD_FLOAT = 606; // 32 bit floating point number |
| public static final int KEYWORD_DOUBLE = 607; // 64 bit floating point number |
| public static final int KEYWORD_CHAR = 608; // unicode character code |
| |
| |
| // |
| // KEYWORDS: SPECIAL VALUES |
| |
| public static final int KEYWORD_TRUE = 610; // boolean truth |
| public static final int KEYWORD_FALSE = 611; // boolean false |
| public static final int KEYWORD_NULL = 612; // missing instance |
| |
| |
| // |
| // KEYWORDS: RESERVED |
| |
| public static final int KEYWORD_CONST = 700; // reserved in java and groovy |
| public static final int KEYWORD_GOTO = 701; // reserved in java and groovy |
| |
| |
| // |
| // SPECIAL (CALCULATED) MEANINGS |
| |
| public static final int SYNTH_COMPILATION_UNIT = 800; // reserved: a synthetic root for a CST |
| |
| public static final int SYNTH_CLASS = 801; // applied to class names |
| public static final int SYNTH_INTERFACE = 802; // applied to interface names |
| public static final int SYNTH_MIXIN = 803; // applied to mixin names |
| public static final int SYNTH_METHOD = 804; // applied to method names |
| public static final int SYNTH_PROPERTY = 805; // applied to property names |
| public static final int SYNTH_PARAMETER_DECLARATION = 806; // applied to method/closure parameter names |
| |
| public static final int SYNTH_LIST = 810; // applied to "[" that marks a list |
| public static final int SYNTH_MAP = 811; // applied to "[" that marks a map |
| public static final int SYNTH_GSTRING = 812; // a complete GString |
| |
| public static final int SYNTH_METHOD_CALL = 814; // applied to the optional "(" that marks a call to a method |
| public static final int SYNTH_CAST = 815; // applied to "(" that marks a type cast |
| public static final int SYNTH_BLOCK = 816; // applied to "{" that marks a block |
| public static final int SYNTH_CLOSURE = 817; // applied to "{" that marks a closure |
| public static final int SYNTH_LABEL = 818; // applied to a statement label |
| public static final int SYNTH_TERNARY = 819; // applied to "?" that marks a ternary expression |
| public static final int SYNTH_TUPLE = 820; // applied to "{" that marks an array initializer |
| |
| public static final int SYNTH_VARIABLE_DECLARATION = 830; // applied to an identifier that specifies |
| // the type of a variable declaration |
| |
| // |
| // GSTRING TOKENS |
| |
| public static final int GSTRING_START = 901; // any marker tha begins a GString |
| public static final int GSTRING_END = 902; // any matching marker that ends a GString |
| public static final int GSTRING_EXPRESSION_START = 903; // the ${ marker that starts a GString expression |
| public static final int GSTRING_EXPRESSION_END = 904; // the } marker that ends a GString expresssion |
| |
| |
| // |
| // TYPE CLASSES |
| |
| public static final int ANY = 1000; // anything |
| public static final int NOT_EOF = 1001; // anything but EOF |
| public static final int GENERAL_END_OF_STATEMENT = 1002; // ";", "\n", EOF |
| public static final int ANY_END_OF_STATEMENT = 1003; // ";", "\n", EOF, "}" |
| |
| public static final int ASSIGNMENT_OPERATOR = 1100; // =, +=, etc. |
| public static final int COMPARISON_OPERATOR = 1101; // ==, ===, >, <, etc. |
| public static final int MATH_OPERATOR = 1102; // +, -, / *, %, plus the LOGICAL_OPERATORS |
| public static final int LOGICAL_OPERATOR = 1103; // ||, &&, ! |
| public static final int RANGE_OPERATOR = 1104; // .., ... |
| public static final int REGEX_COMPARISON_OPERATOR = 1105; // =~, etc. |
| public static final int DEREFERENCE_OPERATOR = 1106; // ., -> |
| public static final int BITWISE_OPERATOR = 1107; // |, &, <<, >>, >>>, ^, ~ |
| |
| public static final int PREFIX_OPERATOR = 1200; // ++, !, etc. |
| public static final int POSTFIX_OPERATOR = 1210; // ++, etc. |
| public static final int INFIX_OPERATOR = 1220; // +, -, =, etc. |
| public static final int PREFIX_OR_INFIX_OPERATOR = 1230; // +, - |
| public static final int PURE_PREFIX_OPERATOR = 1235; // prefix +, prefix - |
| |
| public static final int KEYWORD = 1300; // any keyword |
| public static final int SYMBOL = 1301; // any symbol |
| public static final int LITERAL = 1310; // strings, numbers, identifiers |
| public static final int NUMBER = 1320; // integers and decimals |
| public static final int SIGN = 1325; // "+", "-" |
| public static final int NAMED_VALUE = 1330; // true, false, null |
| public static final int TRUTH_VALUE = 1331; // true, false |
| public static final int PRIMITIVE_TYPE = 1340; // void, byte, short, int, etc. |
| public static final int CREATABLE_PRIMITIVE_TYPE = 1341; // any PRIMITIVE_TYPE except void |
| public static final int LOOP = 1350; // do, while, etc. |
| public static final int RESERVED_KEYWORD = 1360; // const, goto, etc. |
| public static final int KEYWORD_IDENTIFIER = 1361; // keywords that can appear as identifiers |
| public static final int SYNTHETIC = 1370; // any of the SYNTH types |
| |
| public static final int TYPE_DECLARATION = 1400; // class, interface, mixin |
| public static final int DECLARATION_MODIFIER = 1410; // public, private, abstract, etc. |
| |
| public static final int TYPE_NAME = 1420; // identifiers, primitive types |
| public static final int CREATABLE_TYPE_NAME = 1430; // identifiers, primitive types except void |
| |
| public static final int MATCHED_CONTAINER = 1500; // (, ), [, ], {, } |
| public static final int LEFT_OF_MATCHED_CONTAINER = 1501; // (, [, { |
| public static final int RIGHT_OF_MATCHED_CONTAINER = 1502; // ), ], } |
| |
| public static final int EXPRESSION = 1900; // all of the below 1900 series |
| |
| public static final int OPERATOR_EXPRESSION = 1901; // "."-"<<" |
| public static final int SYNTH_EXPRESSION = 1902; // cast, ternary, and closure expression |
| public static final int KEYWORD_EXPRESSION = 1903; // new, this, super, instanceof, true, false, null |
| public static final int LITERAL_EXPRESSION = 1904; // LITERAL |
| public static final int ARRAY_EXPRESSION = 1905; // "[" |
| |
| public static final int SIMPLE_EXPRESSION = 1910; // LITERAL, this, true, false, null |
| public static final int COMPLEX_EXPRESSION = 1911; // SIMPLE_EXPRESSION, and various molecules |
| |
| |
| |
| // |
| // TYPE GROUPS (OPERATIONS SUPPORT) |
| |
| public static final int PARAMETER_TERMINATORS = 2000; // ")", "," |
| public static final int ARRAY_ITEM_TERMINATORS = 2001; // "]", "," |
| public static final int TYPE_LIST_TERMINATORS = 2002; // "implements", "throws", "{", "," |
| public static final int OPTIONAL_DATATYPE_FOLLOWERS = 2003; // identifier, "[", "." |
| |
| public static final int SWITCH_BLOCK_TERMINATORS = 2004; // "case", "default", "}" |
| public static final int SWITCH_ENTRIES = 2005; // "case", "default" |
| |
| public static final int METHOD_CALL_STARTERS = 2006; // LITERAL, "(", "{" |
| public static final int UNSAFE_OVER_NEWLINES = 2007; // things the expression parser should cross lines for in it doesn't have to |
| |
| public static final int PRECLUDES_CAST_OPERATOR = 2008; // anything that prevents (X) from being a cast |
| |
| |
| |
| |
| |
| //--------------------------------------------------------------------------- |
| // TYPE HIERARCHIES |
| |
| |
| /** |
| * Given two types, returns true if the second describes the first. |
| */ |
| |
| public static boolean ofType( int specific, int general ) |
| { |
| |
| if( general == specific ) |
| { |
| return true; |
| } |
| |
| switch( general ) |
| { |
| case ANY: |
| return true; |
| |
| case NOT_EOF: |
| return specific >= UNKNOWN && specific <= SYNTH_VARIABLE_DECLARATION; |
| |
| case GENERAL_END_OF_STATEMENT: |
| switch( specific ) |
| { |
| case EOF: |
| case NEWLINE: |
| case SEMICOLON: |
| return true; |
| } |
| break; |
| |
| case ANY_END_OF_STATEMENT: |
| switch( specific ) |
| { |
| case EOF: |
| case NEWLINE: |
| case SEMICOLON: |
| case RIGHT_CURLY_BRACE: |
| return true; |
| } |
| break; |
| |
| case ASSIGNMENT_OPERATOR: |
| return specific == EQUAL || (specific >= PLUS_EQUAL && specific <= POWER_EQUAL) || (specific >= LOGICAL_OR_EQUAL && specific <= LOGICAL_AND_EQUAL) |
| || (specific >= LEFT_SHIFT_EQUAL && specific <= RIGHT_SHIFT_UNSIGNED_EQUAL) |
| || (specific >= BITWISE_OR_EQUAL && specific <= BITWISE_XOR_EQUAL); |
| |
| case COMPARISON_OPERATOR: |
| return specific >= COMPARE_NOT_EQUAL && specific <= COMPARE_TO; |
| |
| case MATH_OPERATOR: |
| return (specific >= PLUS && specific <= RIGHT_SHIFT_UNSIGNED) || (specific >= NOT && specific <= LOGICAL_AND) |
| || (specific >= BITWISE_OR && specific <= BITWISE_XOR); |
| |
| case LOGICAL_OPERATOR: |
| return specific >= NOT && specific <= LOGICAL_AND; |
| |
| case BITWISE_OPERATOR: |
| return (specific >= BITWISE_OR && specific <= BITWISE_XOR) || specific == BITWISE_NEGATION; |
| |
| case RANGE_OPERATOR: |
| return specific == DOT_DOT || specific == DOT_DOT_DOT; |
| |
| case REGEX_COMPARISON_OPERATOR: |
| return specific == FIND_REGEX || specific == MATCH_REGEX; |
| |
| case DEREFERENCE_OPERATOR: |
| return specific == DOT || specific == NAVIGATE; |
| |
| case PREFIX_OPERATOR: |
| switch( specific ) |
| { |
| case MINUS: |
| case PLUS_PLUS: |
| case MINUS_MINUS: |
| return true; |
| } |
| |
| /* FALL THROUGH */ |
| |
| case PURE_PREFIX_OPERATOR: |
| switch( specific ) |
| { |
| case REGEX_PATTERN: |
| case NOT: |
| case PREFIX_PLUS: |
| case PREFIX_PLUS_PLUS: |
| case PREFIX_MINUS: |
| case PREFIX_MINUS_MINUS: |
| case SYNTH_CAST: |
| return true; |
| } |
| break; |
| |
| case POSTFIX_OPERATOR: |
| switch( specific ) |
| { |
| case PLUS_PLUS: |
| case POSTFIX_PLUS_PLUS: |
| case MINUS_MINUS: |
| case POSTFIX_MINUS_MINUS: |
| return true; |
| } |
| break; |
| |
| case INFIX_OPERATOR: |
| switch( specific ) |
| { |
| case DOT: |
| case NAVIGATE: |
| case LOGICAL_OR: |
| case LOGICAL_AND: |
| case BITWISE_OR: |
| case BITWISE_AND: |
| case BITWISE_XOR: |
| case LEFT_SHIFT: |
| case RIGHT_SHIFT: |
| case RIGHT_SHIFT_UNSIGNED: |
| case FIND_REGEX: |
| case MATCH_REGEX: |
| case DOT_DOT: |
| case DOT_DOT_DOT: |
| case KEYWORD_INSTANCEOF: |
| return true; |
| } |
| |
| return (specific >= COMPARE_NOT_EQUAL && specific <= COMPARE_TO) || (specific >= PLUS && specific <= MOD_EQUAL) || specific == EQUAL || (specific >= PLUS_EQUAL && specific <= POWER_EQUAL) || (specific >= LOGICAL_OR_EQUAL && specific <= LOGICAL_AND_EQUAL) |
| || (specific >= LEFT_SHIFT_EQUAL && specific <= RIGHT_SHIFT_UNSIGNED_EQUAL) || (specific >= BITWISE_OR_EQUAL && specific <= BITWISE_XOR_EQUAL); |
| |
| case PREFIX_OR_INFIX_OPERATOR: |
| switch( specific ) |
| { |
| case POWER: |
| case PLUS: |
| case MINUS: |
| case PREFIX_PLUS: |
| case PREFIX_MINUS: |
| return true; |
| } |
| break; |
| |
| |
| case KEYWORD: |
| return specific >= KEYWORD_PRIVATE && specific <= KEYWORD_GOTO; |
| |
| case SYMBOL: |
| return specific >= NEWLINE && specific <= PIPE; |
| |
| case LITERAL: |
| return specific >= STRING && specific <= DECIMAL_NUMBER; |
| |
| case NUMBER: |
| return specific == INTEGER_NUMBER || specific == DECIMAL_NUMBER; |
| |
| case SIGN: |
| switch( specific ) |
| { |
| case PLUS: |
| case MINUS: |
| return true; |
| } |
| break; |
| |
| case NAMED_VALUE: |
| return specific >= KEYWORD_TRUE && specific <= KEYWORD_NULL; |
| |
| case TRUTH_VALUE: |
| return specific == KEYWORD_TRUE || specific == KEYWORD_FALSE; |
| |
| case TYPE_NAME: |
| if( specific == IDENTIFIER ) |
| { |
| return true; |
| } |
| |
| /* FALL THROUGH */ |
| |
| case PRIMITIVE_TYPE: |
| return specific >= KEYWORD_VOID && specific <= KEYWORD_CHAR; |
| |
| case CREATABLE_TYPE_NAME: |
| if( specific == IDENTIFIER ) |
| { |
| return true; |
| } |
| |
| /* FALL THROUGH */ |
| |
| case CREATABLE_PRIMITIVE_TYPE: |
| return specific >= KEYWORD_BOOLEAN && specific <= KEYWORD_CHAR; |
| |
| case LOOP: |
| switch( specific ) |
| { |
| case KEYWORD_DO: |
| case KEYWORD_WHILE: |
| case KEYWORD_FOR: |
| return true; |
| } |
| break; |
| |
| case RESERVED_KEYWORD: |
| return specific >= KEYWORD_CONST && specific <= KEYWORD_GOTO; |
| |
| case KEYWORD_IDENTIFIER: |
| switch( specific ) |
| { |
| case KEYWORD_CLASS: |
| case KEYWORD_INTERFACE: |
| case KEYWORD_MIXIN: |
| case KEYWORD_DEF: |
| case KEYWORD_DEFMACRO: |
| case KEYWORD_IN: |
| case KEYWORD_PROPERTY: |
| return true; |
| } |
| break; |
| |
| case SYNTHETIC: |
| return specific >= SYNTH_COMPILATION_UNIT && specific <= SYNTH_VARIABLE_DECLARATION; |
| |
| case TYPE_DECLARATION: |
| return specific >= KEYWORD_CLASS && specific <= KEYWORD_MIXIN; |
| |
| case DECLARATION_MODIFIER: |
| return specific >= KEYWORD_PRIVATE && specific <= KEYWORD_STATIC; |
| |
| case MATCHED_CONTAINER: |
| switch( specific ) |
| { |
| case LEFT_CURLY_BRACE: |
| case RIGHT_CURLY_BRACE: |
| case LEFT_SQUARE_BRACKET: |
| case RIGHT_SQUARE_BRACKET: |
| case LEFT_PARENTHESIS: |
| case RIGHT_PARENTHESIS: |
| return true; |
| } |
| break; |
| |
| case LEFT_OF_MATCHED_CONTAINER: |
| switch( specific ) |
| { |
| case LEFT_CURLY_BRACE: |
| case LEFT_SQUARE_BRACKET: |
| case LEFT_PARENTHESIS: |
| return true; |
| } |
| break; |
| |
| case RIGHT_OF_MATCHED_CONTAINER: |
| switch( specific ) |
| { |
| case RIGHT_CURLY_BRACE: |
| case RIGHT_SQUARE_BRACKET: |
| case RIGHT_PARENTHESIS: |
| return true; |
| } |
| break; |
| |
| |
| case PARAMETER_TERMINATORS: |
| return specific == RIGHT_PARENTHESIS || specific == COMMA; |
| |
| case ARRAY_ITEM_TERMINATORS: |
| return specific == RIGHT_SQUARE_BRACKET || specific == COMMA; |
| |
| case TYPE_LIST_TERMINATORS: |
| switch( specific ) |
| { |
| case KEYWORD_IMPLEMENTS: |
| case KEYWORD_THROWS: |
| case LEFT_CURLY_BRACE: |
| case COMMA: |
| return true; |
| } |
| break; |
| |
| case OPTIONAL_DATATYPE_FOLLOWERS: |
| switch( specific ) |
| { |
| case IDENTIFIER: |
| case LEFT_SQUARE_BRACKET: |
| case DOT: |
| return true; |
| } |
| break; |
| |
| case SWITCH_BLOCK_TERMINATORS: |
| if( specific == RIGHT_CURLY_BRACE ) |
| { |
| return true; |
| } |
| |
| /* FALL THROUGH */ |
| |
| case SWITCH_ENTRIES: |
| return specific == KEYWORD_CASE || specific == KEYWORD_DEFAULT; |
| |
| case METHOD_CALL_STARTERS: |
| if( specific >= STRING && specific <= DECIMAL_NUMBER ) |
| { |
| return true; |
| } |
| switch( specific ) |
| { |
| case LEFT_PARENTHESIS: |
| case GSTRING_START: |
| case SYNTH_GSTRING: |
| case KEYWORD_NEW: |
| return true; |
| } |
| break; |
| |
| case UNSAFE_OVER_NEWLINES: |
| if( ofType(specific, SYMBOL) ) |
| { |
| switch( specific ) |
| { |
| case LEFT_CURLY_BRACE: |
| case LEFT_PARENTHESIS: |
| case LEFT_SQUARE_BRACKET: |
| case PLUS: |
| case PLUS_PLUS: |
| case MINUS: |
| case MINUS_MINUS: |
| case REGEX_PATTERN: |
| case NOT: |
| return true; |
| } |
| |
| return false; |
| } |
| |
| switch( specific ) |
| { |
| case KEYWORD_INSTANCEOF: |
| case GSTRING_EXPRESSION_START: |
| case GSTRING_EXPRESSION_END: |
| case GSTRING_END: |
| return false; |
| } |
| |
| return true; |
| |
| case PRECLUDES_CAST_OPERATOR: |
| switch( specific ) |
| { |
| case PLUS: |
| case MINUS: |
| case PREFIX_MINUS: |
| case PREFIX_MINUS_MINUS: |
| case PREFIX_PLUS: |
| case PREFIX_PLUS_PLUS: |
| case LEFT_PARENTHESIS: |
| return false; |
| } |
| |
| return !ofType( specific, COMPLEX_EXPRESSION ); |
| |
| |
| |
| |
| case OPERATOR_EXPRESSION: |
| return specific >= DOT && specific <= RIGHT_SHIFT_UNSIGNED; |
| |
| case SYNTH_EXPRESSION: |
| switch( specific ) |
| { |
| case SYNTH_CAST: |
| case SYNTH_CLOSURE: |
| case SYNTH_TERNARY: |
| return true; |
| } |
| break; |
| |
| case KEYWORD_EXPRESSION: |
| switch( specific ) |
| { |
| case KEYWORD_NEW: |
| case KEYWORD_THIS: |
| case KEYWORD_SUPER: |
| case KEYWORD_INSTANCEOF: |
| case KEYWORD_TRUE: |
| case KEYWORD_FALSE: |
| case KEYWORD_NULL: |
| return true; |
| } |
| break; |
| |
| case LITERAL_EXPRESSION: |
| return specific >= STRING && specific <= DECIMAL_NUMBER; |
| |
| case ARRAY_EXPRESSION: |
| return specific == LEFT_SQUARE_BRACKET; |
| |
| case EXPRESSION: |
| if( specific >= DOT && specific <= RIGHT_SHIFT_UNSIGNED ) |
| { |
| return true; |
| } |
| |
| if( specific >= STRING && specific <= DECIMAL_NUMBER ) |
| { |
| return true; |
| } |
| |
| switch( specific ) |
| { |
| case SYNTH_CAST: |
| case SYNTH_CLOSURE: |
| case SYNTH_TERNARY: |
| case SYNTH_GSTRING: |
| case KEYWORD_NEW: |
| case KEYWORD_THIS: |
| case KEYWORD_SUPER: |
| case KEYWORD_INSTANCEOF: |
| case KEYWORD_TRUE: |
| case KEYWORD_FALSE: |
| case KEYWORD_NULL: |
| case LEFT_SQUARE_BRACKET: |
| return true; |
| } |
| break; |
| |
| case COMPLEX_EXPRESSION: |
| switch( specific ) |
| { |
| case KEYWORD_NEW: |
| case SYNTH_METHOD_CALL: |
| case SYNTH_GSTRING: |
| case SYNTH_LIST: |
| case SYNTH_MAP: |
| case SYNTH_CLOSURE: |
| case SYNTH_TERNARY: |
| case SYNTH_VARIABLE_DECLARATION: |
| return true; |
| } |
| |
| /* FALL THROUGH */ |
| |
| case SIMPLE_EXPRESSION: |
| if( specific >= STRING && specific <= DECIMAL_NUMBER ) { |
| return true; |
| } |
| |
| switch( specific ) { |
| case KEYWORD_SUPER: |
| case KEYWORD_THIS: |
| case KEYWORD_TRUE: |
| case KEYWORD_FALSE: |
| case KEYWORD_NULL: |
| return true; |
| } |
| |
| break; |
| } |
| |
| return false; |
| } |
| |
| |
| |
| |
| //--------------------------------------------------------------------------- |
| // TYPE COERSIONS |
| |
| |
| /** |
| * Given two types, returns true if the first can be viewed as the second. |
| * NOTE that <code>canMean()</code> is orthogonal to <code>ofType()</code>. |
| */ |
| |
| public static boolean canMean( int actual, int preferred ) { |
| |
| if( actual == preferred ) { |
| return true; |
| } |
| |
| switch( preferred ) { |
| |
| case SYNTH_PARAMETER_DECLARATION: |
| case IDENTIFIER: |
| switch( actual ) { |
| case IDENTIFIER: |
| case KEYWORD_DEF: |
| case KEYWORD_DEFMACRO: |
| case KEYWORD_CLASS: |
| case KEYWORD_INTERFACE: |
| case KEYWORD_MIXIN: |
| return true; |
| } |
| break; |
| |
| case SYNTH_CLASS: |
| case SYNTH_INTERFACE: |
| case SYNTH_MIXIN: |
| case SYNTH_METHOD: |
| case SYNTH_PROPERTY: |
| return actual == IDENTIFIER; |
| |
| case SYNTH_LIST: |
| case SYNTH_MAP: |
| return actual == LEFT_SQUARE_BRACKET; |
| |
| case SYNTH_CAST: |
| return actual == LEFT_PARENTHESIS; |
| |
| case SYNTH_BLOCK: |
| case SYNTH_CLOSURE: |
| return actual == LEFT_CURLY_BRACE; |
| |
| case SYNTH_LABEL: |
| return actual == COLON; |
| |
| case SYNTH_VARIABLE_DECLARATION: |
| return actual == IDENTIFIER; |
| } |
| |
| return false; |
| } |
| |
| |
| |
| /** |
| * Converts a node from a generic type to a specific prefix type. |
| * Throws a <code>GroovyBugError</code> if the type can't be converted |
| * and requested. |
| */ |
| |
| public static void makePrefix( CSTNode node, boolean throwIfInvalid ) { |
| |
| switch( node.getMeaning() ) { |
| case PLUS: |
| node.setMeaning( PREFIX_PLUS ); |
| break; |
| |
| case MINUS: |
| node.setMeaning( PREFIX_MINUS ); |
| break; |
| |
| case PLUS_PLUS: |
| node.setMeaning( PREFIX_PLUS_PLUS ); |
| break; |
| |
| case MINUS_MINUS: |
| node.setMeaning( PREFIX_MINUS_MINUS ); |
| break; |
| |
| default: |
| if( throwIfInvalid ) { |
| throw new GroovyBugError( "cannot convert to prefix for type [" + node.getMeaning() + "]" ); |
| } |
| } |
| |
| } |
| |
| |
| |
| /** |
| * Converts a node from a generic type to a specific postfix type. |
| * Throws a <code>GroovyBugError</code> if the type can't be converted. |
| */ |
| |
| public static void makePostfix( CSTNode node, boolean throwIfInvalid ) { |
| |
| switch( node.getMeaning() ) { |
| case PLUS_PLUS: |
| node.setMeaning( POSTFIX_PLUS_PLUS ); |
| break; |
| |
| case MINUS_MINUS: |
| node.setMeaning( POSTFIX_MINUS_MINUS ); |
| break; |
| |
| default: |
| if( throwIfInvalid ) { |
| throw new GroovyBugError( "cannot convert to postfix for type [" + node.getMeaning() + "]" ); |
| } |
| } |
| |
| } |
| |
| |
| |
| |
| //--------------------------------------------------------------------------- |
| // OPERATOR PRECEDENCE |
| |
| |
| /** |
| * Returns the precendence of the specified operator. Non-operator's will |
| * receive -1 or a GroovyBugError, depending on your preference. |
| */ |
| |
| public static int getPrecedence( int type, boolean throwIfInvalid ) { |
| |
| switch( type ) { |
| |
| case LEFT_PARENTHESIS: |
| return 0; |
| |
| case EQUAL: |
| case PLUS_EQUAL: |
| case MINUS_EQUAL: |
| case MULTIPLY_EQUAL: |
| case DIVIDE_EQUAL: |
| case INTDIV_EQUAL: |
| case MOD_EQUAL: |
| case POWER_EQUAL: |
| case LOGICAL_OR_EQUAL: |
| case LOGICAL_AND_EQUAL: |
| case LEFT_SHIFT_EQUAL: |
| case RIGHT_SHIFT_EQUAL: |
| case RIGHT_SHIFT_UNSIGNED_EQUAL: |
| case BITWISE_OR_EQUAL: |
| case BITWISE_AND_EQUAL: |
| case BITWISE_XOR_EQUAL: |
| return 5; |
| |
| case QUESTION: |
| return 10; |
| |
| case LOGICAL_OR: |
| return 15; |
| |
| case LOGICAL_AND: |
| return 20; |
| |
| case BITWISE_OR: |
| case BITWISE_AND: |
| case BITWISE_XOR: |
| return 22; |
| |
| case COMPARE_IDENTICAL: |
| case COMPARE_NOT_IDENTICAL: |
| return 24; |
| |
| case COMPARE_NOT_EQUAL: |
| case COMPARE_EQUAL: |
| case COMPARE_LESS_THAN: |
| case COMPARE_LESS_THAN_EQUAL: |
| case COMPARE_GREATER_THAN: |
| case COMPARE_GREATER_THAN_EQUAL: |
| case COMPARE_TO: |
| case FIND_REGEX: |
| case MATCH_REGEX: |
| case KEYWORD_INSTANCEOF: |
| return 25; |
| |
| case DOT_DOT: |
| case DOT_DOT_DOT: |
| return 30; |
| |
| case LEFT_SHIFT: |
| case RIGHT_SHIFT: |
| case RIGHT_SHIFT_UNSIGNED: |
| return 35; |
| |
| case PLUS: |
| case MINUS: |
| return 40; |
| |
| case MULTIPLY: |
| case DIVIDE: |
| case INTDIV: |
| case MOD: |
| return 45; |
| |
| case NOT: |
| case REGEX_PATTERN: |
| return 50; |
| |
| case SYNTH_CAST: |
| return 55; |
| |
| case PLUS_PLUS: |
| case MINUS_MINUS: |
| case PREFIX_PLUS_PLUS: |
| case PREFIX_MINUS_MINUS: |
| case POSTFIX_PLUS_PLUS: |
| case POSTFIX_MINUS_MINUS: |
| return 65; |
| |
| case PREFIX_PLUS: |
| case PREFIX_MINUS: |
| return 70; |
| |
| case POWER: |
| return 72; |
| |
| case SYNTH_METHOD: |
| case LEFT_SQUARE_BRACKET: |
| return 75; |
| |
| case DOT: |
| case NAVIGATE: |
| return 80; |
| |
| case KEYWORD_NEW: |
| return 85; |
| } |
| |
| if( throwIfInvalid ) { |
| throw new GroovyBugError( "precedence requested for non-operator" ); |
| } |
| |
| return -1; |
| } |
| |
| |
| |
| |
| //--------------------------------------------------------------------------- |
| // TEXTS |
| |
| private static final Map TEXTS = new HashMap(); // symbol/keyword type -> text |
| private static final Map LOOKUP = new HashMap(); // text -> symbol/keyword type |
| |
| |
| /** |
| * Returns the type for the specified symbol/keyword text. Returns UNKNOWN |
| * if the text isn't found. You can filter finds on a type. |
| */ |
| |
| public static int lookup( String text, int filter ) { |
| int type = UNKNOWN; |
| |
| if( LOOKUP.containsKey(text) ) { |
| type = ((Integer)LOOKUP.get(text)).intValue(); |
| if( filter != UNKNOWN && !ofType(type, filter) ) { |
| type = UNKNOWN; |
| } |
| } |
| |
| return type; |
| } |
| |
| |
| /** |
| * Returns the type for the specified keyword text. Returns UNKNOWN |
| * if the text isn't found. |
| */ |
| |
| public static int lookupKeyword( String text ) { |
| return lookup( text, KEYWORD ); |
| } |
| |
| |
| /** |
| * Returns the type for the specified symbol text. Returns UNKNOWN |
| * if the text isn't found. |
| */ |
| |
| public static int lookupSymbol( String text ) { |
| return lookup( text, SYMBOL ); |
| } |
| |
| |
| /** |
| * Returns the text for the specified type. Returns "" if the |
| * text isn't found. |
| */ |
| |
| public static String getText( int type ) { |
| Integer key = new Integer( type ); |
| String text = ""; |
| |
| if( TEXTS.containsKey(key) ) { |
| text = (String)TEXTS.get( key ); |
| } |
| |
| return text; |
| } |
| |
| |
| /** |
| * Adds a element to the TEXTS and LOOKUP. |
| */ |
| |
| private static void addTranslation( String text, int type ) { |
| Integer key = new Integer( type ); |
| |
| TEXTS.put( key, text ); |
| LOOKUP.put( text, key ); |
| } |
| |
| |
| static { |
| |
| // |
| // SYMBOLS |
| |
| addTranslation( "\n" , NEWLINE ); |
| |
| addTranslation( "{" , LEFT_CURLY_BRACE ); |
| addTranslation( "}" , RIGHT_CURLY_BRACE ); |
| addTranslation( "[" , LEFT_SQUARE_BRACKET ); |
| addTranslation( "]" , RIGHT_SQUARE_BRACKET ); |
| addTranslation( "(" , LEFT_PARENTHESIS ); |
| addTranslation( ")" , RIGHT_PARENTHESIS ); |
| |
| addTranslation( "." , DOT ); |
| addTranslation( ".." , DOT_DOT ); |
| addTranslation( "..." , DOT_DOT_DOT ); |
| |
| addTranslation( "->" , NAVIGATE ); |
| |
| addTranslation( "=~" , FIND_REGEX ); |
| addTranslation( "==~" , MATCH_REGEX ); |
| addTranslation( "~" , REGEX_PATTERN ); |
| |
| addTranslation( "=" , EQUAL ); |
| |
| addTranslation( "!=" , COMPARE_NOT_EQUAL ); |
| addTranslation( "===" , COMPARE_IDENTICAL ); |
| addTranslation( "!==" , COMPARE_NOT_IDENTICAL ); |
| addTranslation( "==" , COMPARE_EQUAL ); |
| addTranslation( "<" , COMPARE_LESS_THAN ); |
| addTranslation( "<=" , COMPARE_LESS_THAN_EQUAL ); |
| addTranslation( ">" , COMPARE_GREATER_THAN ); |
| addTranslation( ">=" , COMPARE_GREATER_THAN_EQUAL ); |
| addTranslation( "<=>" , COMPARE_TO ); |
| |
| addTranslation( "!" , NOT ); |
| addTranslation( "||" , LOGICAL_OR ); |
| addTranslation( "&&" , LOGICAL_AND ); |
| |
| addTranslation( "||=" , LOGICAL_OR_EQUAL ); |
| addTranslation( "&&=" , LOGICAL_AND_EQUAL ); |
| |
| addTranslation( "+" , PLUS ); |
| addTranslation( "-" , MINUS ); |
| addTranslation( "*" , MULTIPLY ); |
| addTranslation( "/" , DIVIDE ); |
| addTranslation( "\\" , INTDIV ); |
| addTranslation( "%" , MOD ); |
| |
| addTranslation( "**" , POWER ); |
| |
| addTranslation( "+=" , PLUS_EQUAL ); |
| addTranslation( "-=" , MINUS_EQUAL ); |
| addTranslation( "*=" , MULTIPLY_EQUAL ); |
| addTranslation( "/=" , DIVIDE_EQUAL ); |
| addTranslation( "\\=" , INTDIV_EQUAL ); |
| addTranslation( "%=" , MOD_EQUAL ); |
| addTranslation( "**=" , POWER_EQUAL ); |
| |
| addTranslation( "++" , PLUS_PLUS ); |
| addTranslation( "--" , MINUS_MINUS ); |
| |
| addTranslation( "<<" , LEFT_SHIFT ); |
| addTranslation( ">>" , RIGHT_SHIFT ); |
| addTranslation( ">>>" , RIGHT_SHIFT_UNSIGNED ); |
| |
| addTranslation( "<<=" , LEFT_SHIFT_EQUAL ); |
| addTranslation( ">>=" , RIGHT_SHIFT_EQUAL ); |
| addTranslation( ">>>=" , RIGHT_SHIFT_UNSIGNED_EQUAL ); |
| |
| addTranslation( "&" , BITWISE_AND ); |
| addTranslation( "^" , BITWISE_XOR ); |
| |
| addTranslation( "|=" , BITWISE_OR_EQUAL ); |
| addTranslation( "&=" , BITWISE_AND_EQUAL ); |
| addTranslation( "^=" , BITWISE_XOR_EQUAL ); |
| |
| addTranslation( "," , COMMA ); |
| addTranslation( ":" , COLON ); |
| addTranslation( ";" , SEMICOLON ); |
| addTranslation( "?" , QUESTION ); |
| addTranslation( "|" , PIPE ); |
| |
| addTranslation( "${}" , GSTRING_EXPRESSION_START ); |
| |
| |
| // |
| // Keywords |
| |
| addTranslation( "abstract" , KEYWORD_ABSTRACT ); |
| addTranslation( "as" , KEYWORD_AS ); |
| addTranslation( "assert" , KEYWORD_ASSERT ); |
| addTranslation( "break" , KEYWORD_BREAK ); |
| addTranslation( "case" , KEYWORD_CASE ); |
| addTranslation( "catch" , KEYWORD_CATCH ); |
| addTranslation( "class" , KEYWORD_CLASS ); |
| addTranslation( "const" , KEYWORD_CONST ); |
| addTranslation( "continue" , KEYWORD_CONTINUE ); |
| addTranslation( "def" , KEYWORD_DEF ); |
| addTranslation( "defmacro" , KEYWORD_DEF ); // xxx br defmacro |
| addTranslation( "default" , KEYWORD_DEFAULT ); |
| addTranslation( "do" , KEYWORD_DO ); |
| addTranslation( "else" , KEYWORD_ELSE ); |
| addTranslation( "extends" , KEYWORD_EXTENDS ); |
| addTranslation( "final" , KEYWORD_FINAL ); |
| addTranslation( "finally" , KEYWORD_FINALLY ); |
| addTranslation( "for" , KEYWORD_FOR ); |
| addTranslation( "goto" , KEYWORD_GOTO ); |
| addTranslation( "if" , KEYWORD_IF ); |
| addTranslation( "in" , KEYWORD_IN ); |
| addTranslation( "implements" , KEYWORD_IMPLEMENTS ); |
| addTranslation( "import" , KEYWORD_IMPORT ); |
| addTranslation( "instanceof" , KEYWORD_INSTANCEOF ); |
| addTranslation( "interface" , KEYWORD_INTERFACE ); |
| addTranslation( "mixin" , KEYWORD_MIXIN ); |
| addTranslation( "native" , KEYWORD_NATIVE ); |
| addTranslation( "new" , KEYWORD_NEW ); |
| addTranslation( "package" , KEYWORD_PACKAGE ); |
| addTranslation( "private" , KEYWORD_PRIVATE ); |
| addTranslation( "property" , KEYWORD_PROPERTY ); |
| addTranslation( "protected" , KEYWORD_PROTECTED ); |
| addTranslation( "public" , KEYWORD_PUBLIC ); |
| addTranslation( "return" , KEYWORD_RETURN ); |
| addTranslation( "static" , KEYWORD_STATIC ); |
| addTranslation( "super" , KEYWORD_SUPER ); |
| addTranslation( "switch" , KEYWORD_SWITCH ); |
| addTranslation( "synchronized", KEYWORD_SYNCHRONIZED ); |
| addTranslation( "this" , KEYWORD_THIS ); |
| addTranslation( "throw" , KEYWORD_THROW ); |
| addTranslation( "throws" , KEYWORD_THROWS ); |
| addTranslation( "transient" , KEYWORD_TRANSIENT ); |
| addTranslation( "try" , KEYWORD_TRY ); |
| addTranslation( "volatile" , KEYWORD_VOLATILE ); |
| addTranslation( "while" , KEYWORD_WHILE ); |
| |
| addTranslation( "true" , KEYWORD_TRUE ); |
| addTranslation( "false" , KEYWORD_FALSE ); |
| addTranslation( "null" , KEYWORD_NULL ); |
| |
| addTranslation( "void" , KEYWORD_VOID ); |
| addTranslation( "boolean" , KEYWORD_BOOLEAN ); |
| addTranslation( "byte" , KEYWORD_BYTE ); |
| addTranslation( "int" , KEYWORD_INT ); |
| addTranslation( "short" , KEYWORD_SHORT ); |
| addTranslation( "long" , KEYWORD_LONG ); |
| addTranslation( "float" , KEYWORD_FLOAT ); |
| addTranslation( "double" , KEYWORD_DOUBLE ); |
| addTranslation( "char" , KEYWORD_CHAR ); |
| } |
| |
| |
| |
| |
| //--------------------------------------------------------------------------- |
| // DESCRIPTIONS |
| |
| |
| private static final Map DESCRIPTIONS = new HashMap(); |
| |
| |
| /** |
| * Gets the description for the specified type. |
| */ |
| |
| public static String getDescription( int type ) { |
| Integer typeKey = new Integer(type); |
| |
| if (DESCRIPTIONS.containsKey(typeKey)) { |
| return (String)DESCRIPTIONS.get(typeKey); |
| } |
| |
| return "<>"; |
| } |
| |
| |
| /** |
| * Adds a description to the set. |
| */ |
| |
| private static void addDescription(int type, String description) { |
| addDescription(new Integer(type), description); |
| } |
| |
| |
| /** |
| * Adds a description to the set. |
| */ |
| |
| private static void addDescription(Integer type, String description) { |
| if (description.startsWith("<") && description.endsWith(">")) { |
| DESCRIPTIONS.put(type, description); |
| } |
| else { |
| DESCRIPTIONS.put(type, '"' + description + '"'); |
| } |
| } |
| |
| |
| static { |
| |
| Iterator iterator = LOOKUP.keySet().iterator(); |
| while( iterator.hasNext() ) |
| { |
| String text = (String)iterator.next(); |
| Integer key = (Integer)LOOKUP.get(text); |
| |
| addDescription( key, text ); |
| } |
| |
| addDescription( NEWLINE , "<newline>" ); |
| addDescription( PREFIX_PLUS_PLUS , "<prefix ++>" ); |
| addDescription( POSTFIX_PLUS_PLUS , "<postfix ++>" ); |
| addDescription( PREFIX_MINUS_MINUS , "<prefix -->" ); |
| addDescription( POSTFIX_MINUS_MINUS , "<postfix -->" ); |
| addDescription( PREFIX_PLUS , "<positive>" ); |
| addDescription( PREFIX_MINUS , "<negative>" ); |
| |
| addDescription( STRING , "<string literal>" ); |
| addDescription( IDENTIFIER , "<identifier>" ); |
| addDescription( INTEGER_NUMBER , "<integer>" ); |
| addDescription( DECIMAL_NUMBER , "<decimal>" ); |
| |
| addDescription( SYNTH_COMPILATION_UNIT , "<compilation unit>" ); |
| addDescription( SYNTH_CLASS , "<class>" ); |
| addDescription( SYNTH_INTERFACE , "<interface>" ); |
| addDescription( SYNTH_MIXIN , "<mixin>" ); |
| addDescription( SYNTH_METHOD , "<method>" ); |
| addDescription( SYNTH_METHOD_CALL , "<method call>" ); |
| addDescription( SYNTH_PROPERTY , "<property>" ); |
| addDescription( SYNTH_PARAMETER_DECLARATION , "<parameter>" ); |
| addDescription( SYNTH_LIST , "<list>" ); |
| addDescription( SYNTH_MAP , "<map>" ); |
| addDescription( SYNTH_TUPLE , "<tuple>" ); |
| addDescription( SYNTH_GSTRING , "<gstring>" ); |
| addDescription( SYNTH_CAST , "<cast>" ); |
| addDescription( SYNTH_BLOCK , "<block>" ); |
| addDescription( SYNTH_CLOSURE , "<closure>" ); |
| addDescription( SYNTH_TERNARY , "<ternary>" ); |
| addDescription( SYNTH_LABEL , "<label>" ); |
| addDescription( SYNTH_VARIABLE_DECLARATION , "<variable declaration>" ); |
| |
| addDescription( GSTRING_START , "<start of gstring tokens>" ); |
| addDescription( GSTRING_END , "<end of gstring tokens>" ); |
| addDescription( GSTRING_EXPRESSION_START , "<start of gstring expression>"); |
| addDescription( GSTRING_EXPRESSION_END , "<end of gstring expression>" ); |
| |
| addDescription( ASSIGNMENT_OPERATOR , "<assignment operator>" ); |
| addDescription( COMPARISON_OPERATOR , "<comparison operator>" ); |
| addDescription( MATH_OPERATOR , "<math operator>" ); |
| addDescription( LOGICAL_OPERATOR , "<logical operator>" ); |
| addDescription( BITWISE_OPERATOR , "<bitwise operator>" ); |
| addDescription( RANGE_OPERATOR , "<range operator>" ); |
| addDescription( REGEX_COMPARISON_OPERATOR , "<regex comparison operator>" ); |
| addDescription( DEREFERENCE_OPERATOR , "<dereference operator>" ); |
| addDescription( PREFIX_OPERATOR , "<prefix operator>" ); |
| addDescription( POSTFIX_OPERATOR , "<postfix operator>" ); |
| addDescription( INFIX_OPERATOR , "<infix operator>" ); |
| addDescription( KEYWORD , "<keyword>" ); |
| addDescription( LITERAL , "<literal>" ); |
| addDescription( NUMBER , "<number>" ); |
| addDescription( NAMED_VALUE , "<named value>" ); |
| addDescription( TRUTH_VALUE , "<truth value>" ); |
| addDescription( PRIMITIVE_TYPE , "<primitive type>" ); |
| addDescription( CREATABLE_PRIMITIVE_TYPE , "<creatable primitive type>" ); |
| addDescription( LOOP , "<loop>" ); |
| addDescription( RESERVED_KEYWORD , "<reserved keyword>" ); |
| addDescription( SYNTHETIC , "<synthetic>" ); |
| addDescription( TYPE_DECLARATION , "<type declaration>" ); |
| addDescription( DECLARATION_MODIFIER , "<declaration modifier>" ); |
| addDescription( TYPE_NAME , "<type name>" ); |
| addDescription( CREATABLE_TYPE_NAME , "<creatable type name>" ); |
| addDescription( MATCHED_CONTAINER , "<matched container>" ); |
| addDescription( LEFT_OF_MATCHED_CONTAINER , "<left of matched container>" ); |
| addDescription( RIGHT_OF_MATCHED_CONTAINER , "<right of matched container>" ); |
| addDescription( SWITCH_ENTRIES , "<valid in a switch body>" ); |
| } |
| |
| } |