diff --git a/Site-org.codehaus.groovy.eclipse/site.xml b/Site-org.codehaus.groovy.eclipse/site.xml index 22c2d131c1..0544a237ac 100644 --- a/Site-org.codehaus.groovy.eclipse/site.xml +++ b/Site-org.codehaus.groovy.eclipse/site.xml @@ -51,7 +51,7 @@ - + diff --git a/base-test/org.eclipse.jdt.groovy.core.tests.builder/lib/spock-core-1.1-groovy-2.4.jar b/base-test/org.eclipse.jdt.groovy.core.tests.builder/lib/spock-core-1.1-groovy-2.4.jar deleted file mode 100644 index eb889a3067..0000000000 Binary files a/base-test/org.eclipse.jdt.groovy.core.tests.builder/lib/spock-core-1.1-groovy-2.4.jar and /dev/null differ diff --git a/base-test/org.eclipse.jdt.groovy.core.tests.builder/lib/spock-core-1.2-groovy-2.4.jar b/base-test/org.eclipse.jdt.groovy.core.tests.builder/lib/spock-core-1.2-groovy-2.4.jar new file mode 100644 index 0000000000..c84e919c3c Binary files /dev/null and b/base-test/org.eclipse.jdt.groovy.core.tests.builder/lib/spock-core-1.2-groovy-2.4.jar differ diff --git a/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/builder/BasicGroovyBuildTests.java b/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/builder/BasicGroovyBuildTests.java index f1224f3b4b..ffae13a295 100644 --- a/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/builder/BasicGroovyBuildTests.java +++ b/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/builder/BasicGroovyBuildTests.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.junit.Assume.assumeFalse; import java.io.File; import java.util.Arrays; @@ -1684,7 +1685,7 @@ public void testAnnotationCollectorMultiProject() throws Exception { fullBuild(); expectingNoProblems(); - if (!isAtLeastGroovy(25) || isAtLeastGroovy(26)) { + if (!isAtLeastGroovy(25)) { expectingCompiledClasses("com.demo.MyAnnotation", "com.demo.Widget"); } else { expectingCompiledClasses("com.demo.MyAnnotation", "com.demo.MyAnnotation$CollectorHelper", "com.demo.Widget"); @@ -1725,7 +1726,7 @@ public void testAnnotationCollectorIncremental() throws Exception { incrementalBuild(paths[0]); expectingNoProblems(); - if (!isAtLeastGroovy(25) || isAtLeastGroovy(26)) { + if (!isAtLeastGroovy(25)) { expectingCompiledClasses("Book", "Length", "NotNull", "ISBN"); } else { expectingCompiledClasses("Book", "Length", "NotNull", "ISBN", "ISBN$CollectorHelper"); @@ -1825,27 +1826,28 @@ public void testClosureIncremental() throws Exception { executeClass(paths[0], "Launch", "12345678", ""); } - /** Verify the processing in ASTTransformationCollectorCodeVisitor - to check it finds everything it expects. */ @Test public void testSpock_GRE558() throws Exception { + assumeFalse(isAtLeastGroovy(30)); // TODO: Remove when spock-core supports Groovy 3 + IPath[] paths = createSimpleProject("Project", true); - env.addJar(paths[0], "lib/spock-core-1.1-groovy-2.4.jar"); + env.addJar(paths[0], "lib/spock-core-1.2-groovy-2.4.jar"); env.addEntry(paths[0], JavaCore.newContainerEntry(new Path("org.eclipse.jdt.junit.JUNIT_CONTAINER/4"))); env.addGroovyClass(paths[1], "", "MyTest", "import org.junit.runner.RunWith\n" + - "import spock.lang.Specification \n" + - "\n" + - "class MyTest extends Specification {\n" + - "//deleting extends Specification is sufficient to remove all 3 errors,\n" + - "//necessary to remove model.SpecMetadata\n" + - "\n" + - "def aField; //delete line to remove the model.FieldMetadata error.\n" + + "import spock.lang.Specification\n" + "\n" + - "def noSuchLuck() { expect: //delete line to remove model.FeatureMetadata error. \n" + - " println hello }\n" + - "public static void main(String[] argv) { print 'success';}\n" + - "}"); + "final class MyTest extends Specification {\n" + + " def aField\n" + + " def aMethod() {\n" + + " expect:\n" + + " println 'hello'\n" + + " }\n" + + " static void main(String[] argv) {\n" + + " print 'success'\n" + + " }\n" + + "}\n"); incrementalBuild(paths[0]); expectingNoProblems(); @@ -1860,8 +1862,10 @@ public void testSpock_GRE558() throws Exception { */ @Test public void testSpock_GRE605_1() throws Exception { + assumeFalse(isAtLeastGroovy(30)); // TODO: Remove when spock-core supports Groovy 3 + IPath[] paths = createSimpleProject("Project", true); - env.addJar(paths[0], "lib/spock-core-1.1-groovy-2.4.jar"); + env.addJar(paths[0], "lib/spock-core-1.2-groovy-2.4.jar"); env.addEntry(paths[0], JavaCore.newContainerEntry(new Path("org.eclipse.jdt.junit.JUNIT_CONTAINER/4"))); env.addGroovyClass(paths[1], "", "FoobarSpec", @@ -1924,8 +1928,10 @@ public void testSpock_GRE605_1() throws Exception { */ @Test public void testSpock_GRE605_2() throws Exception { + assumeFalse(isAtLeastGroovy(30)); // TODO: Remove when spock-core supports Groovy 3 + IPath[] paths = createSimpleProject("Project", true); - env.addJar(paths[0], "lib/spock-core-1.1-groovy-2.4.jar"); + env.addJar(paths[0], "lib/spock-core-1.2-groovy-2.4.jar"); env.addEntry(paths[0], JavaCore.newContainerEntry(new Path("org.eclipse.jdt.junit.JUNIT_CONTAINER/4"))); env.addGroovyClass(paths[1], "", "FoobarSpec", diff --git a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/basic/GroovyCompilerTestSuite.java b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/basic/GroovyCompilerTestSuite.java index f79455a314..a60590583e 100644 --- a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/basic/GroovyCompilerTestSuite.java +++ b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/basic/GroovyCompilerTestSuite.java @@ -124,7 +124,7 @@ protected String[] getDefaultClassPaths() { System.arraycopy(cps, 0, newcps, 0, cps.length); String[] ivyVersions = {"2.5.0", "2.4.0"}; - String[] groovyVersions = {"2.6.0-indy", "2.5.5-indy", "2.4.16"}; + String[] groovyVersions = {"3.0.0-indy", "2.5.5-indy", "2.4.16"}; try { URL groovyJar = null; for (String groovyVer : groovyVersions) { diff --git a/base/org.codehaus.groovy.eclipse.compilerResolver/src/org/codehaus/groovy/frameworkadapter/util/SpecifiedVersion.java b/base/org.codehaus.groovy.eclipse.compilerResolver/src/org/codehaus/groovy/frameworkadapter/util/SpecifiedVersion.java index 5821b56458..6431837545 100644 --- a/base/org.codehaus.groovy.eclipse.compilerResolver/src/org/codehaus/groovy/frameworkadapter/util/SpecifiedVersion.java +++ b/base/org.codehaus.groovy.eclipse.compilerResolver/src/org/codehaus/groovy/frameworkadapter/util/SpecifiedVersion.java @@ -29,6 +29,7 @@ public enum SpecifiedVersion { _24(2, 4, "24"), _25(2, 5, "25"), _26(2, 6, "26"), + _30(3, 0, "30"), DONT_CARE(0, 0, "-1"), UNSPECIFIED(0, 0, "0"); @@ -106,6 +107,11 @@ public static SpecifiedVersion parseVersion(String jarName) { return _26; } break; + case 3: + switch (minor) { + case 0: + return _30; + } } } catch (NumberFormatException e) { // can ignore just return unspecified @@ -152,6 +158,9 @@ public static SpecifiedVersion findVersionFromString(String compilerLevel) { if ("26".equals(compilerLevel) || "2.6".equals(compilerLevel)) { return _26; } + if ("30".equals(compilerLevel) || "3.0".equals(compilerLevel)) { + return _30; + } if ("0".equals(compilerLevel)) { return UNSPECIFIED; } @@ -160,7 +169,7 @@ public static SpecifiedVersion findVersionFromString(String compilerLevel) { } System.out.println("Invalid Groovy compiler level specified: " + compilerLevel + "\n" + - "Must be one of 16, 1.6, 17, 1.7, 18, 1.8, 19, 1.9, 20, 2.0, 21, 2.1, 22, 2.2, 23, 2.3, 24, 2.4, 25, 2.5, 26 or 2.6"); + "Must be one of 16, 1.6, 17, 1.7, 18, 1.8, 19, 1.9, 20, 2.0, 21, 2.1, 22, 2.2, 23, 2.3, 24, 2.4, 25, 2.5, 26, 2.6, 30 or 3.0"); return UNSPECIFIED; } @@ -194,6 +203,11 @@ public static SpecifiedVersion findVersion(Version ver) { case 6: return _26; } + case 3: + switch (ver.getMinor()) { + case 0: + return _30; + } } return UNSPECIFIED; } diff --git a/base/org.codehaus.groovy26/META-INF/MANIFEST.MF b/base/org.codehaus.groovy26/META-INF/MANIFEST.MF deleted file mode 100644 index c436171988..0000000000 --- a/base/org.codehaus.groovy26/META-INF/MANIFEST.MF +++ /dev/null @@ -1,111 +0,0 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-SymbolicName: org.codehaus.groovy -Automatic-Module-Name: org.codehaus.groovy -Bundle-Name: Groovy Runtime -Bundle-Vendor: Pivotal Software, Inc. -Bundle-Version: 2.6.0.qualifier -Bundle-ClassPath: eclipse-trace.jar, - groovy-eclipse.jar, - lib/ivy-2.4.0.jar, - lib/groovy-2.6.0-indy.jar, - lib/groovy-test-2.6.0-indy.jar -Export-Package: groovy.beans;version="2.6.0", - groovy.cli;version="2.6.0", - groovy.grape;version="2.6.0", - groovy.inspect;version="2.6.0", - groovy.io;version="2.6.0", - groovy.lang;version="2.6.0", - groovy.lang.groovydoc;version="2.6.0", - groovy.mock.interceptor;version="2.6.0", - groovy.security;version="2.6.0", - groovy.test;version="2.6.0", - groovy.time;version="2.6.0", - groovy.transform;version="2.6.0", - groovy.transform.builder;version="2.6.0", - groovy.transform.options;version="2.6.0", - groovy.transform.stc;version="2.6.0", - groovy.ui;version="2.6.0", - groovy.util;version="2.6.0", - groovy.util.logging;version="2.6.0", - groovy.xml;version="2.6.0", - groovyjarjarantlr;x-internal:=true, - groovyjarjarasm.asm;x-internal:=true, - org.apache.groovy.ast.tools;version="2.6.0", - org.apache.groovy.internal.metaclass;version="2.6.0", - org.apache.groovy.internal.util;version="2.6.0", - org.apache.groovy.io;version="2.6.0", - org.apache.groovy.lang.annotation;version="2.6.0", - org.apache.groovy.metaclass;version="2.6.0", - org.apache.groovy.parser;version="2.6.0", - org.apache.groovy.parser.antlr4;version="2.6.0", - org.apache.groovy.parser.antlr4.util;version="2.6.0", - org.apache.groovy.plugin;version="2.6.0", - org.apache.groovy.util;version="2.6.0", - org.apache.groovy.util.concurrentlinkedhashmap;version="2.6.0", - org.codehaus.greclipse;x-internal:=true, - org.codehaus.groovy;version="2.6.0", - org.codehaus.groovy.activator, - org.codehaus.groovy.antlr;version="2.6.0", - org.codehaus.groovy.antlr.java;version="2.6.0", - org.codehaus.groovy.antlr.parser;version="2.6.0", - org.codehaus.groovy.antlr.treewalker;version="2.6.0", - org.codehaus.groovy.ast;version="2.6.0", - org.codehaus.groovy.ast.builder;version="2.6.0", - org.codehaus.groovy.ast.decompiled;version="2.6.0", - org.codehaus.groovy.ast.expr;version="2.6.0", - org.codehaus.groovy.ast.stmt;version="2.6.0", - org.codehaus.groovy.ast.tools;version="2.6.0", - org.codehaus.groovy.classgen;version="2.6.0", - org.codehaus.groovy.classgen.asm;version="2.6.0", - org.codehaus.groovy.classgen.asm.indy;version="2.6.0", - org.codehaus.groovy.classgen.asm.indy.sc;version="2.6.0", - org.codehaus.groovy.classgen.asm.sc;version="2.6.0", - org.codehaus.groovy.classgen.asm.util;version="2.6.0", - org.codehaus.groovy.control;version="2.6.0", - org.codehaus.groovy.control.customizers;version="2.6.0", - org.codehaus.groovy.control.customizers.builder;version="2.6.0", - org.codehaus.groovy.control.io;version="2.6.0", - org.codehaus.groovy.control.messages;version="2.6.0", - org.codehaus.groovy.eclipse, - org.codehaus.groovy.plugin;version="2.6.0", - org.codehaus.groovy.reflection;version="2.6.0", - org.codehaus.groovy.reflection.android;version="2.6.0", - org.codehaus.groovy.reflection.stdclasses;version="2.6.0", - org.codehaus.groovy.reflection.v7;version="2.6.0", - org.codehaus.groovy.runtime;version="2.6.0", - org.codehaus.groovy.runtime.callsite;version="2.6.0", - org.codehaus.groovy.runtime.dgmimpl;version="2.6.0", - org.codehaus.groovy.runtime.dgmimpl.arrays;version="2.6.0", - org.codehaus.groovy.runtime.m12n;version="2.6.0", - org.codehaus.groovy.runtime.memoize;version="2.6.0", - org.codehaus.groovy.runtime.metaclass;version="2.6.0", - org.codehaus.groovy.runtime.powerassert;version="2.6.0", - org.codehaus.groovy.runtime.typehandling;version="2.6.0", - org.codehaus.groovy.runtime.wrappers;version="2.6.0", - org.codehaus.groovy.syntax;version="2.6.0", - org.codehaus.groovy.tools;version="2.6.0", - org.codehaus.groovy.tools.ast;version="2.6.0", - org.codehaus.groovy.tools.gse;version="2.6.0", - org.codehaus.groovy.tools.javac;version="2.6.0", - org.codehaus.groovy.tools.shell;version="2.6.0", - org.codehaus.groovy.tools.shell.util;version="2.6.0", - org.codehaus.groovy.transform;version="2.6.0", - org.codehaus.groovy.transform.sc;version="2.6.0", - org.codehaus.groovy.transform.sc.transformers;version="2.6.0", - org.codehaus.groovy.transform.stc;version="2.6.0", - org.codehaus.groovy.transform.tailrec;version="2.6.0", - org.codehaus.groovy.transform.trait;version="2.6.0", - org.codehaus.groovy.util;version="2.6.0", - org.codehaus.groovy.vmplugin;version="2.6.0", - org.codehaus.groovy.vmplugin.v5;version="2.6.0", - org.codehaus.groovy.vmplugin.v6;version="2.6.0", - org.codehaus.groovy.vmplugin.v7;version="2.6.0", - org.codehaus.groovy.vmplugin.v8;version="2.6.0" -Require-Bundle: org.eclipse.core.runtime, - org.apache.ant;resolution:=optional, - org.junit;resolution:=optional -Bundle-ActivationPolicy: lazy -Bundle-Activator: org.codehaus.groovy.activator.GroovyActivator -Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Eclipse-BundleShape: dir diff --git a/base/org.codehaus.groovy26/VERSION b/base/org.codehaus.groovy26/VERSION deleted file mode 100644 index 4b25615cf0..0000000000 --- a/base/org.codehaus.groovy26/VERSION +++ /dev/null @@ -1,3 +0,0 @@ -2018-02-26: GROOVY_2_6_0_SNAPSHOT -2018-03-06: GROOVY_2_6_0_ALPHA_3 -2018-06-26: GROOVY_2_6_0_ALPHA_4 diff --git a/base/org.codehaus.groovy26/lib/groovy-2.6.0-javadoc.jar b/base/org.codehaus.groovy26/lib/groovy-2.6.0-javadoc.jar deleted file mode 100644 index 73bbd43d35..0000000000 Binary files a/base/org.codehaus.groovy26/lib/groovy-2.6.0-javadoc.jar and /dev/null differ diff --git a/base/org.codehaus.groovy26/lib/groovy-test-2.6.0-indy.jar b/base/org.codehaus.groovy26/lib/groovy-test-2.6.0-indy.jar deleted file mode 100644 index d57a67affb..0000000000 Binary files a/base/org.codehaus.groovy26/lib/groovy-test-2.6.0-indy.jar and /dev/null differ diff --git a/base/org.codehaus.groovy26/lib/groovy-test-2.6.0-javadoc.jar b/base/org.codehaus.groovy26/lib/groovy-test-2.6.0-javadoc.jar deleted file mode 100644 index 98b9ff97d1..0000000000 Binary files a/base/org.codehaus.groovy26/lib/groovy-test-2.6.0-javadoc.jar and /dev/null differ diff --git a/base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/GroovyLexer.java b/base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/GroovyLexer.java deleted file mode 100644 index 492cb1ff17..0000000000 --- a/base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/GroovyLexer.java +++ /dev/null @@ -1,1362 +0,0 @@ -// Generated from GroovyLexer.g4 by ANTLR 4.7 -package org.apache.groovy.parser.antlr4; - - import static org.apache.groovy.parser.antlr4.SemanticPredicates.*; - import org.codehaus.groovy.ast.Comment; - import java.util.*; - -import groovyjarjarantlr4.v4.runtime.Lexer; -import groovyjarjarantlr4.v4.runtime.CharStream; -import groovyjarjarantlr4.v4.runtime.Token; -import groovyjarjarantlr4.v4.runtime.TokenStream; -import groovyjarjarantlr4.v4.runtime.*; -import groovyjarjarantlr4.v4.runtime.atn.*; -import groovyjarjarantlr4.v4.runtime.dfa.DFA; -import groovyjarjarantlr4.v4.runtime.misc.*; - -public class GroovyLexer extends AbstractLexer { - public static final int - StringLiteral=1, GStringBegin=2, GStringEnd=3, GStringPart=4, GStringPathPart=5, - RollBackOne=6, AS=7, DEF=8, IN=9, TRAIT=10, THREADSAFE=11, VAR=12, BuiltInPrimitiveType=13, - ABSTRACT=14, ASSERT=15, BREAK=16, CASE=17, CATCH=18, CLASS=19, CONST=20, - CONTINUE=21, DEFAULT=22, DO=23, ELSE=24, ENUM=25, EXTENDS=26, FINAL=27, - FINALLY=28, FOR=29, IF=30, GOTO=31, IMPLEMENTS=32, IMPORT=33, INSTANCEOF=34, - INTERFACE=35, NATIVE=36, NEW=37, PACKAGE=38, PRIVATE=39, PROTECTED=40, - PUBLIC=41, RETURN=42, STATIC=43, STRICTFP=44, SUPER=45, SWITCH=46, SYNCHRONIZED=47, - THIS=48, THROW=49, THROWS=50, TRANSIENT=51, TRY=52, VOID=53, VOLATILE=54, - WHILE=55, IntegerLiteral=56, FloatingPointLiteral=57, BooleanLiteral=58, - NullLiteral=59, RANGE_INCLUSIVE=60, RANGE_EXCLUSIVE=61, SPREAD_DOT=62, - SAFE_DOT=63, SAFE_CHAIN_DOT=64, ELVIS=65, METHOD_POINTER=66, METHOD_REFERENCE=67, - REGEX_FIND=68, REGEX_MATCH=69, POWER=70, POWER_ASSIGN=71, SPACESHIP=72, - IDENTICAL=73, NOT_IDENTICAL=74, ARROW=75, NOT_INSTANCEOF=76, NOT_IN=77, - LPAREN=78, RPAREN=79, LBRACE=80, RBRACE=81, LBRACK=82, RBRACK=83, SEMI=84, - COMMA=85, DOT=86, ASSIGN=87, GT=88, LT=89, NOT=90, BITNOT=91, QUESTION=92, - COLON=93, EQUAL=94, LE=95, GE=96, NOTEQUAL=97, AND=98, OR=99, INC=100, - DEC=101, ADD=102, SUB=103, MUL=104, DIV=105, BITAND=106, BITOR=107, XOR=108, - MOD=109, ADD_ASSIGN=110, SUB_ASSIGN=111, MUL_ASSIGN=112, DIV_ASSIGN=113, - AND_ASSIGN=114, OR_ASSIGN=115, XOR_ASSIGN=116, MOD_ASSIGN=117, LSHIFT_ASSIGN=118, - RSHIFT_ASSIGN=119, URSHIFT_ASSIGN=120, ELVIS_ASSIGN=121, CapitalizedIdentifier=122, - Identifier=123, AT=124, ELLIPSIS=125, WS=126, NL=127, SH_COMMENT=128, - UNEXPECTED_CHAR=129; - public static final int - DQ_GSTRING_MODE=1, TDQ_GSTRING_MODE=2, SLASHY_GSTRING_MODE=3, DOLLAR_SLASHY_GSTRING_MODE=4, - GSTRING_TYPE_SELECTOR_MODE=5, GSTRING_PATH_MODE=6; - public static String[] channelNames = { - "DEFAULT_TOKEN_CHANNEL", "HIDDEN" - }; - - public static String[] modeNames = { - "DEFAULT_MODE", "DQ_GSTRING_MODE", "TDQ_GSTRING_MODE", "SLASHY_GSTRING_MODE", - "DOLLAR_SLASHY_GSTRING_MODE", "GSTRING_TYPE_SELECTOR_MODE", "GSTRING_PATH_MODE" - }; - - public static final String[] ruleNames = { - "StringLiteral", "GStringBegin", "TdqGStringBegin", "SlashyGStringBegin", - "DollarSlashyGStringBegin", "GStringEnd", "GStringPart", "GStringCharacter", - "TdqGStringEnd", "TdqGStringPart", "TdqGStringCharacter", "SlashyGStringEnd", - "SlashyGStringPart", "SlashyGStringCharacter", "DollarSlashyGStringEnd", - "DollarSlashyGStringPart", "DollarSlashyGStringCharacter", "GStringLBrace", - "GStringIdentifier", "GStringPathPart", "RollBackOne", "DqStringCharacter", - "SqStringCharacter", "TdqStringCharacter", "TsqStringCharacter", "SlashyStringCharacter", - "DollarSlashyStringCharacter", "AS", "DEF", "IN", "TRAIT", "THREADSAFE", - "VAR", "BuiltInPrimitiveType", "ABSTRACT", "ASSERT", "BOOLEAN", "BREAK", - "BYTE", "CASE", "CATCH", "CHAR", "CLASS", "CONST", "CONTINUE", "DEFAULT", - "DO", "DOUBLE", "ELSE", "ENUM", "EXTENDS", "FINAL", "FINALLY", "FLOAT", - "FOR", "IF", "GOTO", "IMPLEMENTS", "IMPORT", "INSTANCEOF", "INT", "INTERFACE", - "LONG", "NATIVE", "NEW", "PACKAGE", "PRIVATE", "PROTECTED", "PUBLIC", - "RETURN", "SHORT", "STATIC", "STRICTFP", "SUPER", "SWITCH", "SYNCHRONIZED", - "THIS", "THROW", "THROWS", "TRANSIENT", "TRY", "VOID", "VOLATILE", "WHILE", - "IntegerLiteral", "Zero", "DecimalIntegerLiteral", "HexIntegerLiteral", - "OctalIntegerLiteral", "BinaryIntegerLiteral", "IntegerTypeSuffix", "DecimalNumeral", - "Digits", "Digit", "NonZeroDigit", "DigitOrUnderscore", "Underscores", - "Underscore", "HexNumeral", "HexDigits", "HexDigit", "HexDigitOrUnderscore", - "OctalNumeral", "OctalDigits", "OctalDigit", "OctalDigitOrUnderscore", - "BinaryNumeral", "BinaryDigits", "BinaryDigit", "BinaryDigitOrUnderscore", - "FloatingPointLiteral", "DecimalFloatingPointLiteral", "ExponentPart", - "ExponentIndicator", "SignedInteger", "Sign", "FloatTypeSuffix", "HexadecimalFloatingPointLiteral", - "HexSignificand", "BinaryExponent", "BinaryExponentIndicator", "Dot", - "BooleanLiteral", "EscapeSequence", "OctalEscape", "UnicodeEscape", "ZeroToThree", - "DollarEscape", "LineEscape", "SlashEscape", "Backslash", "Slash", "Dollar", - "GStringQuotationMark", "SqStringQuotationMark", "TdqStringQuotationMark", - "TsqStringQuotationMark", "DollarSlashyGStringQuotationMarkBegin", "DollarSlashyGStringQuotationMarkEnd", - "DollarSlashEscape", "DollarDollarEscape", "NullLiteral", "RANGE_INCLUSIVE", - "RANGE_EXCLUSIVE", "SPREAD_DOT", "SAFE_DOT", "SAFE_CHAIN_DOT", "ELVIS", - "METHOD_POINTER", "METHOD_REFERENCE", "REGEX_FIND", "REGEX_MATCH", "POWER", - "POWER_ASSIGN", "SPACESHIP", "IDENTICAL", "NOT_IDENTICAL", "ARROW", "NOT_INSTANCEOF", - "NOT_IN", "LPAREN", "RPAREN", "LBRACE", "RBRACE", "LBRACK", "RBRACK", - "SEMI", "COMMA", "DOT", "ASSIGN", "GT", "LT", "NOT", "BITNOT", "QUESTION", - "COLON", "EQUAL", "LE", "GE", "NOTEQUAL", "AND", "OR", "INC", "DEC", "ADD", - "SUB", "MUL", "DIV", "BITAND", "BITOR", "XOR", "MOD", "ADD_ASSIGN", "SUB_ASSIGN", - "MUL_ASSIGN", "DIV_ASSIGN", "AND_ASSIGN", "OR_ASSIGN", "XOR_ASSIGN", "MOD_ASSIGN", - "LSHIFT_ASSIGN", "RSHIFT_ASSIGN", "URSHIFT_ASSIGN", "ELVIS_ASSIGN", "CapitalizedIdentifier", - "Identifier", "IdentifierInGString", "JavaLetterInGString", "JavaLetterOrDigitInGString", - "JavaLetter", "JavaLetterOrDigit", "AT", "ELLIPSIS", "WS", "NL", "ML_COMMENT", - "SL_COMMENT", "SH_COMMENT", "UNEXPECTED_CHAR" - }; - - private static final String[] _LITERAL_NAMES = { - null, null, null, null, null, null, null, "'as'", "'def'", "'in'", "'trait'", - "'threadsafe'", "'var'", null, "'abstract'", "'assert'", "'break'", "'case'", - "'catch'", "'class'", "'const'", "'continue'", "'default'", "'do'", "'else'", - "'enum'", "'extends'", "'final'", "'finally'", "'for'", "'if'", "'goto'", - "'implements'", "'import'", "'instanceof'", "'interface'", "'native'", - "'new'", "'package'", "'private'", "'protected'", "'public'", "'return'", - "'static'", "'strictfp'", "'super'", "'switch'", "'synchronized'", "'this'", - "'throw'", "'throws'", "'transient'", "'try'", "'void'", "'volatile'", - "'while'", null, null, null, "'null'", "'..'", "'..<'", "'*.'", "'?.'", - "'??.'", "'?:'", "'.&'", "'::'", "'=~'", "'==~'", "'**'", "'**='", "'<=>'", - "'==='", "'!=='", "'->'", "'!instanceof'", "'!in'", null, null, null, - null, null, null, "';'", "','", null, "'='", "'>'", "'<'", "'!'", "'~'", - "'?'", "':'", "'=='", "'<='", "'>='", "'!='", "'&&'", "'||'", "'++'", - "'--'", "'+'", "'-'", "'*'", null, "'&'", "'|'", "'^'", "'%'", "'+='", - "'-='", "'*='", "'/='", "'&='", "'|='", "'^='", "'%='", "'<<='", "'>>='", - "'>>>='", "'?='", null, null, "'@'", "'...'" - }; - private static final String[] _SYMBOLIC_NAMES = { - null, "StringLiteral", "GStringBegin", "GStringEnd", "GStringPart", "GStringPathPart", - "RollBackOne", "AS", "DEF", "IN", "TRAIT", "THREADSAFE", "VAR", "BuiltInPrimitiveType", - "ABSTRACT", "ASSERT", "BREAK", "CASE", "CATCH", "CLASS", "CONST", "CONTINUE", - "DEFAULT", "DO", "ELSE", "ENUM", "EXTENDS", "FINAL", "FINALLY", "FOR", - "IF", "GOTO", "IMPLEMENTS", "IMPORT", "INSTANCEOF", "INTERFACE", "NATIVE", - "NEW", "PACKAGE", "PRIVATE", "PROTECTED", "PUBLIC", "RETURN", "STATIC", - "STRICTFP", "SUPER", "SWITCH", "SYNCHRONIZED", "THIS", "THROW", "THROWS", - "TRANSIENT", "TRY", "VOID", "VOLATILE", "WHILE", "IntegerLiteral", "FloatingPointLiteral", - "BooleanLiteral", "NullLiteral", "RANGE_INCLUSIVE", "RANGE_EXCLUSIVE", - "SPREAD_DOT", "SAFE_DOT", "SAFE_CHAIN_DOT", "ELVIS", "METHOD_POINTER", - "METHOD_REFERENCE", "REGEX_FIND", "REGEX_MATCH", "POWER", "POWER_ASSIGN", - "SPACESHIP", "IDENTICAL", "NOT_IDENTICAL", "ARROW", "NOT_INSTANCEOF", - "NOT_IN", "LPAREN", "RPAREN", "LBRACE", "RBRACE", "LBRACK", "RBRACK", - "SEMI", "COMMA", "DOT", "ASSIGN", "GT", "LT", "NOT", "BITNOT", "QUESTION", - "COLON", "EQUAL", "LE", "GE", "NOTEQUAL", "AND", "OR", "INC", "DEC", "ADD", - "SUB", "MUL", "DIV", "BITAND", "BITOR", "XOR", "MOD", "ADD_ASSIGN", "SUB_ASSIGN", - "MUL_ASSIGN", "DIV_ASSIGN", "AND_ASSIGN", "OR_ASSIGN", "XOR_ASSIGN", "MOD_ASSIGN", - "LSHIFT_ASSIGN", "RSHIFT_ASSIGN", "URSHIFT_ASSIGN", "ELVIS_ASSIGN", "CapitalizedIdentifier", - "Identifier", "AT", "ELLIPSIS", "WS", "NL", "SH_COMMENT", "UNEXPECTED_CHAR" - }; - public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); - - /** - * @deprecated Use {@link #VOCABULARY} instead. - */ - @Deprecated - public static final String[] tokenNames; - static { - tokenNames = new String[_SYMBOLIC_NAMES.length]; - for (int i = 0; i < tokenNames.length; i++) { - tokenNames[i] = VOCABULARY.getLiteralName(i); - if (tokenNames[i] == null) { - tokenNames[i] = VOCABULARY.getSymbolicName(i); - } - - if (tokenNames[i] == null) { - tokenNames[i] = ""; - } - } - } - - @Override - @Deprecated - public String[] getTokenNames() { - return tokenNames; - } - - @Override - @NotNull - public Vocabulary getVocabulary() { - return VOCABULARY; - } - - - private long tokenIndex = 0; - private int lastTokenType = 0; - private int invalidDigitCount = 0; - - /** - * Record the index and token type of the current token while emitting tokens. - */ - @Override - public void emit(Token token) { - this.tokenIndex++; - - int tokenType = token.getType(); - if (Token.DEFAULT_CHANNEL == token.getChannel()) { - this.lastTokenType = tokenType; - } - - if (RollBackOne == tokenType) { - this.rollbackOneChar(); - } - - super.emit(token); - } - - private static final Set REGEX_CHECK_SET = - Collections.unmodifiableSet( - new HashSet<>(Arrays.asList(Identifier, CapitalizedIdentifier, NullLiteral, BooleanLiteral, THIS, RPAREN, RBRACK, RBRACE, IntegerLiteral, FloatingPointLiteral, StringLiteral, GStringEnd, INC, DEC))); - private boolean isRegexAllowed() { - if (REGEX_CHECK_SET.contains(this.lastTokenType)) { - return false; - } - - return true; - } - - /** - * just a hook, which will be overrided by GroovyLangLexer - */ - protected void rollbackOneChar() {} - - private static class Paren { - private String text; - private int lastTokenType; - private int line; - private int column; - - public Paren(String text, int lastTokenType, int line, int column) { - this.text = text; - this.lastTokenType = lastTokenType; - this.line = line; - this.column = column; - } - - public String getText() { - return this.text; - } - - public int getLastTokenType() { - return this.lastTokenType; - } - - public int getLine() { - return line; - } - - public int getColumn() { - return column; - } - - @Override - public int hashCode() { - return (int) (text.hashCode() * line + column); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof Paren)) { - return false; - } - - Paren other = (Paren) obj; - - return this.text.equals(other.text) && (this.line == other.line && this.column == other.column); - } - } - - /* GRECLIPSE edit - private static final Map PAREN_MAP = Collections.unmodifiableMap(new HashMap() { - { - put("(", ")"); - put("[", "]"); - put("{", "}"); - } - }); - */ - private static final Map PAREN_MAP = org.apache.groovy.util.Maps.of( - "(", ")", - "[", "]", - "{", "}" - ); - // GRECLIPSE end - - private final Deque parenStack = new ArrayDeque<>(32); - private void enterParen() { - parenStack.push(new Paren(getText(), this.lastTokenType, getLine(), getCharPositionInLine())); - } - private void exitParen() { - Paren paren = parenStack.peek(); - String text = getText(); - - require(null != paren, "Too many '" + text + "'"); - require(text.equals(PAREN_MAP.get(paren.getText())), - "'" + paren.getText() + "'" + new PositionInfo(paren.getLine(), paren.getColumn()) + " can not match '" + text + "'", -1); - - parenStack.pop(); - } - private boolean isInsideParens() { - Paren paren = parenStack.peek(); - - // We just care about "(" and "[", inside which the new lines will be ignored. - // Notice: the new lines between "{" and "}" can not be ignored. - if (null == paren) { - return false; - } - return ("(".equals(paren.getText()) && TRY != paren.getLastTokenType()) // we don't treat try-paren(i.e. try (....)) as parenthesis - || "[".equals(paren.getText()); - } - private void ignoreTokenInsideParens() { - if (!this.isInsideParens()) { - return; - } - - this.setChannel(Token.HIDDEN_CHANNEL); - } - private void ignoreMultiLineCommentConditionally() { - if (!this.isInsideParens() && isFollowedByWhiteSpaces(_input)) { - return; - } - - this.setChannel(Token.HIDDEN_CHANNEL); - } - - @Override - public int getSyntaxErrorSource() { - return GroovySyntaxError.LEXER; - } - - @Override - public int getErrorLine() { - return getLine(); - } - - @Override - public int getErrorColumn() { - return getCharPositionInLine() + 1; - } - - // GRECLIPSE add - private void addComment(int type) { - String text = _input.getText(Interval.of(_tokenStartCharIndex, getCharIndex() - 1)); - Comment comment; - if (type == 0) { - comment = Comment.makeMultiLineComment( _tokenStartLine, _tokenStartCharPositionInLine + 1, getLine(), getCharPositionInLine() + 1, text); - } else { - comment = Comment.makeSingleLineComment(_tokenStartLine, _tokenStartCharPositionInLine + 1, getLine(), getCharPositionInLine() + 1, text); - } - comments.add(comment); - } - public List getComments() { return comments; } - private final List comments = new ArrayList<>(); - // GRECLIPSE end - - - public GroovyLexer(CharStream input) { - super(input); - _interp = new LexerATNSimulator(this,_ATN); - validateInputStream(_ATN, input); - } - - @Override - public String getGrammarFileName() { return "GroovyLexer.g4"; } - - @Override - public String[] getRuleNames() { return ruleNames; } - - @Override - public String getSerializedATN() { return _serializedATN; } - - @Override - @NotNull - public String[] getChannelNames() { return channelNames; } - - @Override - @NotNull - public String[] getModeNames() { return modeNames; } - - @Override - public void action(RuleContext _localctx, int ruleIndex, int actionIndex) { - switch (ruleIndex) { - case 17: - GStringLBrace_action(_localctx, actionIndex); - break; - - case 20: - RollBackOne_action(_localctx, actionIndex); - break; - - case 84: - IntegerLiteral_action(_localctx, actionIndex); - break; - - case 110: - FloatingPointLiteral_action(_localctx, actionIndex); - break; - - case 160: - LPAREN_action(_localctx, actionIndex); - break; - - case 161: - RPAREN_action(_localctx, actionIndex); - break; - - case 162: - LBRACE_action(_localctx, actionIndex); - break; - - case 163: - RBRACE_action(_localctx, actionIndex); - break; - - case 164: - LBRACK_action(_localctx, actionIndex); - break; - - case 165: - RBRACK_action(_localctx, actionIndex); - break; - - case 214: - NL_action(_localctx, actionIndex); - break; - - case 215: - ML_COMMENT_action(_localctx, actionIndex); - break; - - case 216: - SL_COMMENT_action(_localctx, actionIndex); - break; - - case 217: - SH_COMMENT_action(_localctx, actionIndex); - break; - } - } - private void GStringLBrace_action(RuleContext _localctx, int actionIndex) { - switch (actionIndex) { - case 0: - this.enterParen(); - break; - } - } - private void RollBackOne_action(RuleContext _localctx, int actionIndex) { - switch (actionIndex) { - case 1: - - // a trick to handle GStrings followed by EOF properly - if (EOF == _input.LA(1) && ('"' == _input.LA(-1) || '/' == _input.LA(-1))) { - setType(GStringEnd); - } else { - setChannel(HIDDEN); - } - - break; - } - } - private void IntegerLiteral_action(RuleContext _localctx, int actionIndex) { - switch (actionIndex) { - case 2: - require(false, "Number ending with underscores is invalid", -1, true); - break; - - case 3: - invalidDigitCount++; - break; - - case 4: - require(false, "Invalid octal number", -(invalidDigitCount + 1), true); - break; - } - } - private void FloatingPointLiteral_action(RuleContext _localctx, int actionIndex) { - switch (actionIndex) { - case 5: - require(false, "Number ending with underscores is invalid", -1, true); - break; - } - } - private void LPAREN_action(RuleContext _localctx, int actionIndex) { - switch (actionIndex) { - case 6: - this.enterParen(); - break; - } - } - private void RPAREN_action(RuleContext _localctx, int actionIndex) { - switch (actionIndex) { - case 7: - this.exitParen(); - break; - } - } - private void LBRACE_action(RuleContext _localctx, int actionIndex) { - switch (actionIndex) { - case 8: - this.enterParen(); - break; - } - } - private void RBRACE_action(RuleContext _localctx, int actionIndex) { - switch (actionIndex) { - case 9: - this.exitParen(); - break; - } - } - private void LBRACK_action(RuleContext _localctx, int actionIndex) { - switch (actionIndex) { - case 10: - this.enterParen(); - break; - } - } - private void RBRACK_action(RuleContext _localctx, int actionIndex) { - switch (actionIndex) { - case 11: - this.exitParen(); - break; - } - } - private void NL_action(RuleContext _localctx, int actionIndex) { - switch (actionIndex) { - case 12: - this.ignoreTokenInsideParens(); - break; - } - } - private void ML_COMMENT_action(RuleContext _localctx, int actionIndex) { - switch (actionIndex) { - case 13: - addComment(0); ignoreMultiLineCommentConditionally(); - break; - } - } - private void SL_COMMENT_action(RuleContext _localctx, int actionIndex) { - switch (actionIndex) { - case 14: - addComment(1); ignoreTokenInsideParens(); - break; - } - } - private void SH_COMMENT_action(RuleContext _localctx, int actionIndex) { - switch (actionIndex) { - case 15: - require(0 == this.tokenIndex, "Shebang comment should appear at the first line", -2, true); - break; - } - } - @Override - public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { - switch (ruleIndex) { - case 0: - return StringLiteral_sempred(_localctx, predIndex); - - case 3: - return SlashyGStringBegin_sempred(_localctx, predIndex); - - case 4: - return DollarSlashyGStringBegin_sempred(_localctx, predIndex); - - case 12: - return SlashyGStringPart_sempred(_localctx, predIndex); - - case 15: - return DollarSlashyGStringPart_sempred(_localctx, predIndex); - - case 23: - return TdqStringCharacter_sempred(_localctx, predIndex); - - case 24: - return TsqStringCharacter_sempred(_localctx, predIndex); - - case 25: - return SlashyStringCharacter_sempred(_localctx, predIndex); - - case 26: - return DollarSlashyStringCharacter_sempred(_localctx, predIndex); - - case 158: - return NOT_INSTANCEOF_sempred(_localctx, predIndex); - - case 159: - return NOT_IN_sempred(_localctx, predIndex); - - case 207: - return JavaLetterInGString_sempred(_localctx, predIndex); - - case 208: - return JavaLetterOrDigitInGString_sempred(_localctx, predIndex); - - case 209: - return JavaLetter_sempred(_localctx, predIndex); - - case 210: - return JavaLetterOrDigit_sempred(_localctx, predIndex); - } - return true; - } - private boolean StringLiteral_sempred(RuleContext _localctx, int predIndex) { - switch (predIndex) { - case 0: - return this.isRegexAllowed() && _input.LA(1) != '*' ; - } - return true; - } - private boolean SlashyGStringBegin_sempred(RuleContext _localctx, int predIndex) { - switch (predIndex) { - case 1: - return this.isRegexAllowed() && _input.LA(1) != '*' ; - - case 2: - return isFollowedByJavaLetterInGString(_input) ; - } - return true; - } - private boolean DollarSlashyGStringBegin_sempred(RuleContext _localctx, int predIndex) { - switch (predIndex) { - case 3: - return isFollowedByJavaLetterInGString(_input) ; - } - return true; - } - private boolean SlashyGStringPart_sempred(RuleContext _localctx, int predIndex) { - switch (predIndex) { - case 4: - return isFollowedByJavaLetterInGString(_input) ; - } - return true; - } - private boolean DollarSlashyGStringPart_sempred(RuleContext _localctx, int predIndex) { - switch (predIndex) { - case 5: - return isFollowedByJavaLetterInGString(_input) ; - } - return true; - } - private boolean TdqStringCharacter_sempred(RuleContext _localctx, int predIndex) { - switch (predIndex) { - case 6: - return _input.LA(1) != '"' || _input.LA(2) != '"' || _input.LA(3) == '"' && (_input.LA(4) != '"' || _input.LA(5) != '"') ; - } - return true; - } - private boolean TsqStringCharacter_sempred(RuleContext _localctx, int predIndex) { - switch (predIndex) { - case 7: - return _input.LA(1) != '\'' || _input.LA(2) != '\'' || _input.LA(3) == '\'' && (_input.LA(4) != '\'' || _input.LA(5) != '\'') ; - } - return true; - } - private boolean SlashyStringCharacter_sempred(RuleContext _localctx, int predIndex) { - switch (predIndex) { - case 8: - return !isFollowedByJavaLetterInGString(_input) ; - } - return true; - } - private boolean DollarSlashyStringCharacter_sempred(RuleContext _localctx, int predIndex) { - switch (predIndex) { - case 9: - return _input.LA(1) != '$' ; - - case 10: - return !isFollowedByJavaLetterInGString(_input) ; - } - return true; - } - private boolean NOT_INSTANCEOF_sempred(RuleContext _localctx, int predIndex) { - switch (predIndex) { - case 11: - return isFollowedBy(_input, ' ', '\t', '\r', '\n') ; - } - return true; - } - private boolean NOT_IN_sempred(RuleContext _localctx, int predIndex) { - switch (predIndex) { - case 12: - return isFollowedBy(_input, ' ', '\t', '\r', '\n', '[', '(', '{') ; - } - return true; - } - private boolean JavaLetterInGString_sempred(RuleContext _localctx, int predIndex) { - switch (predIndex) { - case 13: - return Character.isJavaIdentifierStart(_input.LA(-1)); - - case 14: - return Character.isJavaIdentifierStart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1))); - } - return true; - } - private boolean JavaLetterOrDigitInGString_sempred(RuleContext _localctx, int predIndex) { - switch (predIndex) { - case 15: - return Character.isJavaIdentifierPart(_input.LA(-1)); - - case 16: - return Character.isJavaIdentifierPart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1))); - } - return true; - } - private boolean JavaLetter_sempred(RuleContext _localctx, int predIndex) { - switch (predIndex) { - case 17: - return Character.isJavaIdentifierStart(_input.LA(-1)); - - case 18: - return Character.isJavaIdentifierStart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1))); - } - return true; - } - private boolean JavaLetterOrDigit_sempred(RuleContext _localctx, int predIndex) { - switch (predIndex) { - case 19: - return Character.isJavaIdentifierPart(_input.LA(-1)); - - case 20: - return Character.isJavaIdentifierPart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1))); - } - return true; - } - - public static final String _serializedATN = - "\3\uc91d\ucaba\u058d\uafba\u4f53\u0607\uea8b\uc241\2\u0083\u0698\b\1\b"+ - "\1\b\1\b\1\b\1\b\1\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7"+ - "\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17"+ - "\4\20\t\20\4\21\t\21\4\22\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26"+ - "\4\27\t\27\4\30\t\30\4\31\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35"+ - "\4\36\t\36\4\37\t\37\4 \t \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t"+ - "\'\4(\t(\4)\t)\4*\t*\4+\t+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61"+ - "\4\62\t\62\4\63\t\63\4\64\t\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49"+ - "\t9\4:\t:\4;\t;\4<\t<\4=\t=\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD"+ - "\4E\tE\4F\tF\4G\tG\4H\tH\4I\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P"+ - "\tP\4Q\tQ\4R\tR\4S\tS\4T\tT\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t["+ - "\4\\\t\\\4]\t]\4^\t^\4_\t_\4`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4"+ - "g\tg\4h\th\4i\ti\4j\tj\4k\tk\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\t"+ - "r\4s\ts\4t\tt\4u\tu\4v\tv\4w\tw\4x\tx\4y\ty\4z\tz\4{\t{\4|\t|\4}\t}\4"+ - "~\t~\4\177\t\177\4\u0080\t\u0080\4\u0081\t\u0081\4\u0082\t\u0082\4\u0083"+ - "\t\u0083\4\u0084\t\u0084\4\u0085\t\u0085\4\u0086\t\u0086\4\u0087\t\u0087"+ - "\4\u0088\t\u0088\4\u0089\t\u0089\4\u008a\t\u008a\4\u008b\t\u008b\4\u008c"+ - "\t\u008c\4\u008d\t\u008d\4\u008e\t\u008e\4\u008f\t\u008f\4\u0090\t\u0090"+ - "\4\u0091\t\u0091\4\u0092\t\u0092\4\u0093\t\u0093\4\u0094\t\u0094\4\u0095"+ - "\t\u0095\4\u0096\t\u0096\4\u0097\t\u0097\4\u0098\t\u0098\4\u0099\t\u0099"+ - "\4\u009a\t\u009a\4\u009b\t\u009b\4\u009c\t\u009c\4\u009d\t\u009d\4\u009e"+ - "\t\u009e\4\u009f\t\u009f\4\u00a0\t\u00a0\4\u00a1\t\u00a1\4\u00a2\t\u00a2"+ - "\4\u00a3\t\u00a3\4\u00a4\t\u00a4\4\u00a5\t\u00a5\4\u00a6\t\u00a6\4\u00a7"+ - "\t\u00a7\4\u00a8\t\u00a8\4\u00a9\t\u00a9\4\u00aa\t\u00aa\4\u00ab\t\u00ab"+ - "\4\u00ac\t\u00ac\4\u00ad\t\u00ad\4\u00ae\t\u00ae\4\u00af\t\u00af\4\u00b0"+ - "\t\u00b0\4\u00b1\t\u00b1\4\u00b2\t\u00b2\4\u00b3\t\u00b3\4\u00b4\t\u00b4"+ - "\4\u00b5\t\u00b5\4\u00b6\t\u00b6\4\u00b7\t\u00b7\4\u00b8\t\u00b8\4\u00b9"+ - "\t\u00b9\4\u00ba\t\u00ba\4\u00bb\t\u00bb\4\u00bc\t\u00bc\4\u00bd\t\u00bd"+ - "\4\u00be\t\u00be\4\u00bf\t\u00bf\4\u00c0\t\u00c0\4\u00c1\t\u00c1\4\u00c2"+ - "\t\u00c2\4\u00c3\t\u00c3\4\u00c4\t\u00c4\4\u00c5\t\u00c5\4\u00c6\t\u00c6"+ - "\4\u00c7\t\u00c7\4\u00c8\t\u00c8\4\u00c9\t\u00c9\4\u00ca\t\u00ca\4\u00cb"+ - "\t\u00cb\4\u00cc\t\u00cc\4\u00cd\t\u00cd\4\u00ce\t\u00ce\4\u00cf\t\u00cf"+ - "\4\u00d0\t\u00d0\4\u00d1\t\u00d1\4\u00d2\t\u00d2\4\u00d3\t\u00d3\4\u00d4"+ - "\t\u00d4\4\u00d5\t\u00d5\4\u00d6\t\u00d6\4\u00d7\t\u00d7\4\u00d8\t\u00d8"+ - "\4\u00d9\t\u00d9\4\u00da\t\u00da\4\u00db\t\u00db\4\u00dc\t\u00dc\3\2\3"+ - "\2\7\2\u01c2\n\2\f\2\16\2\u01c5\13\2\3\2\3\2\3\2\3\2\7\2\u01cb\n\2\f\2"+ - "\16\2\u01ce\13\2\3\2\3\2\3\2\3\2\3\2\6\2\u01d5\n\2\r\2\16\2\u01d6\3\2"+ - "\3\2\3\2\3\2\7\2\u01dd\n\2\f\2\16\2\u01e0\13\2\3\2\3\2\3\2\3\2\7\2\u01e6"+ - "\n\2\f\2\16\2\u01e9\13\2\3\2\3\2\3\2\3\2\6\2\u01ef\n\2\r\2\16\2\u01f0"+ - "\3\2\3\2\5\2\u01f5\n\2\3\3\3\3\7\3\u01f9\n\3\f\3\16\3\u01fc\13\3\3\3\3"+ - "\3\3\3\3\3\3\3\3\4\3\4\7\4\u0205\n\4\f\4\16\4\u0208\13\4\3\4\3\4\3\4\3"+ - "\4\3\4\3\4\3\5\3\5\3\5\7\5\u0213\n\5\f\5\16\5\u0216\13\5\3\5\3\5\3\5\3"+ - "\5\3\5\3\5\3\5\3\6\3\6\7\6\u0221\n\6\f\6\16\6\u0224\13\6\3\6\3\6\3\6\3"+ - "\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\n\3\n"+ - "\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\r\5\r\u0248\n"+ - "\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3"+ - "\17\3\20\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3"+ - "\22\3\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3"+ - "\24\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26\3\27\3\27\5\27\u027f\n\27"+ - "\3\30\3\30\5\30\u0283\n\30\3\31\3\31\3\31\3\31\3\31\5\31\u028a\n\31\3"+ - "\32\3\32\3\32\3\32\3\32\5\32\u0291\n\32\3\33\3\33\3\33\3\33\3\33\5\33"+ - "\u0298\n\33\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\5\34\u02a4"+ - "\n\34\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\37\3\37\3\37\3 \3 \3 \3 \3"+ - " \3 \3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3\"\3\"\3\"\3\"\3#\3#\3#\3#\3#\3"+ - "#\3#\3#\5#\u02cd\n#\3$\3$\3$\3$\3$\3$\3$\3$\3$\3%\3%\3%\3%\3%\3%\3%\3"+ - "&\3&\3&\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3\'\3\'\3(\3(\3(\3(\3(\3)\3)\3"+ - ")\3)\3)\3*\3*\3*\3*\3*\3*\3+\3+\3+\3+\3+\3,\3,\3,\3,\3,\3,\3-\3-\3-\3"+ - "-\3-\3-\3.\3.\3.\3.\3.\3.\3.\3.\3.\3/\3/\3/\3/\3/\3/\3/\3/\3\60\3\60\3"+ - "\60\3\61\3\61\3\61\3\61\3\61\3\61\3\61\3\62\3\62\3\62\3\62\3\62\3\63\3"+ - "\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64\3\64\3\64\3\64\3\64\3\65\3\65\3"+ - "\65\3\65\3\65\3\65\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\67\3\67\3"+ - "\67\3\67\3\67\3\67\38\38\38\38\39\39\39\3:\3:\3:\3:\3:\3;\3;\3;\3;\3;"+ - "\3;\3;\3;\3;\3;\3;\3<\3<\3<\3<\3<\3<\3<\3=\3=\3=\3=\3=\3=\3=\3=\3=\3="+ - "\3=\3>\3>\3>\3>\3?\3?\3?\3?\3?\3?\3?\3?\3?\3?\3@\3@\3@\3@\3@\3A\3A\3A"+ - "\3A\3A\3A\3A\3B\3B\3B\3B\3C\3C\3C\3C\3C\3C\3C\3C\3D\3D\3D\3D\3D\3D\3D"+ - "\3D\3E\3E\3E\3E\3E\3E\3E\3E\3E\3E\3F\3F\3F\3F\3F\3F\3F\3G\3G\3G\3G\3G"+ - "\3G\3G\3H\3H\3H\3H\3H\3H\3I\3I\3I\3I\3I\3I\3I\3J\3J\3J\3J\3J\3J\3J\3J"+ - "\3J\3K\3K\3K\3K\3K\3K\3L\3L\3L\3L\3L\3L\3L\3M\3M\3M\3M\3M\3M\3M\3M\3M"+ - "\3M\3M\3M\3M\3N\3N\3N\3N\3N\3O\3O\3O\3O\3O\3O\3P\3P\3P\3P\3P\3P\3P\3Q"+ - "\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3S\3S\3S\3S\3S\3T\3T\3T\3T\3T"+ - "\3T\3T\3T\3T\3U\3U\3U\3U\3U\3U\3V\3V\3V\3V\5V\u0426\nV\3V\3V\3V\5V\u042b"+ - "\nV\3V\3V\3V\6V\u0430\nV\rV\16V\u0431\3V\3V\5V\u0436\nV\5V\u0438\nV\3"+ - "W\3W\3X\3X\5X\u043e\nX\3Y\3Y\5Y\u0442\nY\3Z\3Z\5Z\u0446\nZ\3[\3[\5[\u044a"+ - "\n[\3\\\3\\\3]\3]\3]\5]\u0451\n]\3]\3]\3]\5]\u0456\n]\5]\u0458\n]\3^\3"+ - "^\7^\u045c\n^\f^\16^\u045f\13^\3^\5^\u0462\n^\3_\3_\5_\u0466\n_\3`\3`"+ - "\3a\3a\5a\u046c\na\3b\6b\u046f\nb\rb\16b\u0470\3c\3c\3d\3d\3d\3d\3e\3"+ - "e\7e\u047b\ne\fe\16e\u047e\13e\3e\5e\u0481\ne\3f\3f\3g\3g\5g\u0487\ng"+ - "\3h\3h\5h\u048b\nh\3h\3h\3i\3i\7i\u0491\ni\fi\16i\u0494\13i\3i\5i\u0497"+ - "\ni\3j\3j\3k\3k\5k\u049d\nk\3l\3l\3l\3l\3m\3m\7m\u04a5\nm\fm\16m\u04a8"+ - "\13m\3m\5m\u04ab\nm\3n\3n\3o\3o\5o\u04b1\no\3p\3p\5p\u04b5\np\3p\3p\3"+ - "p\5p\u04ba\np\3q\3q\3q\3q\5q\u04c0\nq\3q\5q\u04c3\nq\3q\3q\3q\5q\u04c8"+ - "\nq\3q\3q\3q\5q\u04cd\nq\3r\3r\3r\3s\3s\3t\5t\u04d5\nt\3t\3t\3u\3u\3v"+ - "\3v\3w\3w\3w\5w\u04e0\nw\3x\3x\5x\u04e4\nx\3x\3x\3x\5x\u04e9\nx\3x\3x"+ - "\3x\5x\u04ee\nx\3y\3y\3y\3z\3z\3{\3{\3|\3|\3|\3|\3|\3|\3|\3|\3|\5|\u0500"+ - "\n|\3}\3}\3}\3}\3}\3}\3}\5}\u0509\n}\3~\3~\3~\3~\3~\3~\3~\3~\3~\3~\3~"+ - "\3~\5~\u0517\n~\3\177\3\177\3\177\3\177\3\177\3\177\3\177\3\u0080\3\u0080"+ - "\3\u0081\3\u0081\3\u0081\3\u0082\3\u0082\5\u0082\u0527\n\u0082\3\u0082"+ - "\3\u0082\3\u0083\3\u0083\3\u0083\3\u0084\3\u0084\3\u0085\3\u0085\3\u0086"+ - "\3\u0086\3\u0087\3\u0087\3\u0088\3\u0088\3\u0089\3\u0089\3\u0089\3\u0089"+ - "\3\u008a\3\u008a\3\u008a\3\u008a\3\u008b\3\u008b\3\u008b\3\u008c\3\u008c"+ - "\3\u008c\3\u008d\3\u008d\3\u008d\3\u008d\3\u008e\3\u008e\3\u008e\3\u008f"+ - "\3\u008f\3\u008f\3\u008f\3\u008f\3\u0090\3\u0090\3\u0090\3\u0091\3\u0091"+ - "\3\u0091\3\u0091\3\u0092\3\u0092\3\u0092\3\u0093\3\u0093\3\u0093\3\u0094"+ - "\3\u0094\3\u0094\3\u0094\3\u0095\3\u0095\3\u0095\3\u0096\3\u0096\3\u0096"+ - "\3\u0097\3\u0097\3\u0097\3\u0098\3\u0098\3\u0098\3\u0099\3\u0099\3\u0099"+ - "\3\u0099\3\u009a\3\u009a\3\u009a\3\u009b\3\u009b\3\u009b\3\u009b\3\u009c"+ - "\3\u009c\3\u009c\3\u009c\3\u009d\3\u009d\3\u009d\3\u009d\3\u009e\3\u009e"+ - "\3\u009e\3\u009e\3\u009f\3\u009f\3\u009f\3\u00a0\3\u00a0\3\u00a0\3\u00a0"+ - "\3\u00a0\3\u00a0\3\u00a0\3\u00a0\3\u00a0\3\u00a0\3\u00a0\3\u00a0\3\u00a0"+ - "\3\u00a0\3\u00a1\3\u00a1\3\u00a1\3\u00a1\3\u00a1\3\u00a1\3\u00a2\3\u00a2"+ - "\3\u00a2\3\u00a2\3\u00a2\3\u00a3\3\u00a3\3\u00a3\3\u00a3\3\u00a3\3\u00a4"+ - "\3\u00a4\3\u00a4\3\u00a4\3\u00a4\3\u00a5\3\u00a5\3\u00a5\3\u00a5\3\u00a5"+ - "\3\u00a6\3\u00a6\3\u00a6\3\u00a6\3\u00a6\3\u00a7\3\u00a7\3\u00a7\3\u00a7"+ - "\3\u00a7\3\u00a8\3\u00a8\3\u00a9\3\u00a9\3\u00aa\3\u00aa\3\u00ab\3\u00ab"+ - "\3\u00ac\3\u00ac\3\u00ad\3\u00ad\3\u00ae\3\u00ae\3\u00af\3\u00af\3\u00b0"+ - "\3\u00b0\3\u00b1\3\u00b1\3\u00b2\3\u00b2\3\u00b2\3\u00b3\3\u00b3\3\u00b3"+ - "\3\u00b4\3\u00b4\3\u00b4\3\u00b5\3\u00b5\3\u00b5\3\u00b6\3\u00b6\3\u00b6"+ - "\3\u00b7\3\u00b7\3\u00b7\3\u00b8\3\u00b8\3\u00b8\3\u00b9\3\u00b9\3\u00b9"+ - "\3\u00ba\3\u00ba\3\u00bb\3\u00bb\3\u00bc\3\u00bc\3\u00bd\3\u00bd\3\u00be"+ - "\3\u00be\3\u00bf\3\u00bf\3\u00c0\3\u00c0\3\u00c1\3\u00c1\3\u00c2\3\u00c2"+ - "\3\u00c2\3\u00c3\3\u00c3\3\u00c3\3\u00c4\3\u00c4\3\u00c4\3\u00c5\3\u00c5"+ - "\3\u00c5\3\u00c6\3\u00c6\3\u00c6\3\u00c7\3\u00c7\3\u00c7\3\u00c8\3\u00c8"+ - "\3\u00c8\3\u00c9\3\u00c9\3\u00c9\3\u00ca\3\u00ca\3\u00ca\3\u00ca\3\u00cb"+ - "\3\u00cb\3\u00cb\3\u00cb\3\u00cc\3\u00cc\3\u00cc\3\u00cc\3\u00cc\3\u00cd"+ - "\3\u00cd\3\u00cd\3\u00ce\3\u00ce\7\u00ce\u0621\n\u00ce\f\u00ce\16\u00ce"+ - "\u0624\13\u00ce\3\u00cf\3\u00cf\7\u00cf\u0628\n\u00cf\f\u00cf\16\u00cf"+ - "\u062b\13\u00cf\3\u00d0\3\u00d0\7\u00d0\u062f\n\u00d0\f\u00d0\16\u00d0"+ - "\u0632\13\u00d0\3\u00d1\3\u00d1\3\u00d1\3\u00d1\3\u00d1\3\u00d1\5\u00d1"+ - "\u063a\n\u00d1\3\u00d2\3\u00d2\3\u00d2\3\u00d2\3\u00d2\3\u00d2\5\u00d2"+ - "\u0642\n\u00d2\3\u00d3\3\u00d3\3\u00d3\3\u00d3\3\u00d3\3\u00d3\5\u00d3"+ - "\u064a\n\u00d3\3\u00d4\3\u00d4\3\u00d4\3\u00d4\3\u00d4\3\u00d4\5\u00d4"+ - "\u0652\n\u00d4\3\u00d5\3\u00d5\3\u00d6\3\u00d6\3\u00d6\3\u00d6\3\u00d7"+ - "\6\u00d7\u065b\n\u00d7\r\u00d7\16\u00d7\u065c\3\u00d7\6\u00d7\u0660\n"+ - "\u00d7\r\u00d7\16\u00d7\u0661\5\u00d7\u0664\n\u00d7\3\u00d7\3\u00d7\3"+ - "\u00d8\5\u00d8\u0669\n\u00d8\3\u00d8\3\u00d8\3\u00d8\3\u00d9\3\u00d9\3"+ - "\u00d9\3\u00d9\7\u00d9\u0672\n\u00d9\f\u00d9\16\u00d9\u0675\13\u00d9\3"+ - "\u00d9\3\u00d9\3\u00d9\3\u00d9\3\u00d9\3\u00d9\3\u00d9\3\u00da\3\u00da"+ - "\3\u00da\3\u00da\7\u00da\u0682\n\u00da\f\u00da\16\u00da\u0685\13\u00da"+ - "\3\u00da\3\u00da\3\u00da\3\u00da\3\u00db\3\u00db\3\u00db\3\u00db\3\u00db"+ - "\7\u00db\u0690\n\u00db\f\u00db\16\u00db\u0693\13\u00db\3\u00db\3\u00db"+ - "\3\u00dc\3\u00dc\3\u0673\2\2\u00dd\t\2\3\13\2\4\r\2\2\17\2\2\21\2\2\23"+ - "\2\5\25\2\6\27\2\2\31\2\2\33\2\2\35\2\2\37\2\2!\2\2#\2\2%\2\2\'\2\2)\2"+ - "\2+\2\2-\2\2/\2\7\61\2\b\63\2\2\65\2\2\67\2\29\2\2;\2\2=\2\2?\2\tA\2\n"+ - "C\2\13E\2\fG\2\rI\2\16K\2\17M\2\20O\2\21Q\2\2S\2\22U\2\2W\2\23Y\2\24["+ - "\2\2]\2\25_\2\26a\2\27c\2\30e\2\31g\2\2i\2\32k\2\33m\2\34o\2\35q\2\36"+ - "s\2\2u\2\37w\2 y\2!{\2\"}\2#\177\2$\u0081\2\2\u0083\2%\u0085\2\2\u0087"+ - "\2&\u0089\2\'\u008b\2(\u008d\2)\u008f\2*\u0091\2+\u0093\2,\u0095\2\2\u0097"+ - "\2-\u0099\2.\u009b\2/\u009d\2\60\u009f\2\61\u00a1\2\62\u00a3\2\63\u00a5"+ - "\2\64\u00a7\2\65\u00a9\2\66\u00ab\2\67\u00ad\28\u00af\29\u00b1\2:\u00b3"+ - "\2\2\u00b5\2\2\u00b7\2\2\u00b9\2\2\u00bb\2\2\u00bd\2\2\u00bf\2\2\u00c1"+ - "\2\2\u00c3\2\2\u00c5\2\2\u00c7\2\2\u00c9\2\2\u00cb\2\2\u00cd\2\2\u00cf"+ - "\2\2\u00d1\2\2\u00d3\2\2\u00d5\2\2\u00d7\2\2\u00d9\2\2\u00db\2\2\u00dd"+ - "\2\2\u00df\2\2\u00e1\2\2\u00e3\2\2\u00e5\2;\u00e7\2\2\u00e9\2\2\u00eb"+ - "\2\2\u00ed\2\2\u00ef\2\2\u00f1\2\2\u00f3\2\2\u00f5\2\2\u00f7\2\2\u00f9"+ - "\2\2\u00fb\2\2\u00fd\2<\u00ff\2\2\u0101\2\2\u0103\2\2\u0105\2\2\u0107"+ - "\2\2\u0109\2\2\u010b\2\2\u010d\2\2\u010f\2\2\u0111\2\2\u0113\2\2\u0115"+ - "\2\2\u0117\2\2\u0119\2\2\u011b\2\2\u011d\2\2\u011f\2\2\u0121\2\2\u0123"+ - "\2=\u0125\2>\u0127\2?\u0129\2@\u012b\2A\u012d\2B\u012f\2C\u0131\2D\u0133"+ - "\2E\u0135\2F\u0137\2G\u0139\2H\u013b\2I\u013d\2J\u013f\2K\u0141\2L\u0143"+ - "\2M\u0145\2N\u0147\2O\u0149\2P\u014b\2Q\u014d\2R\u014f\2S\u0151\2T\u0153"+ - "\2U\u0155\2V\u0157\2W\u0159\2X\u015b\2Y\u015d\2Z\u015f\2[\u0161\2\\\u0163"+ - "\2]\u0165\2^\u0167\2_\u0169\2`\u016b\2a\u016d\2b\u016f\2c\u0171\2d\u0173"+ - "\2e\u0175\2f\u0177\2g\u0179\2h\u017b\2i\u017d\2j\u017f\2k\u0181\2l\u0183"+ - "\2m\u0185\2n\u0187\2o\u0189\2p\u018b\2q\u018d\2r\u018f\2s\u0191\2t\u0193"+ - "\2u\u0195\2v\u0197\2w\u0199\2x\u019b\2y\u019d\2z\u019f\2{\u01a1\2|\u01a3"+ - "\2}\u01a5\2\2\u01a7\2\2\u01a9\2\2\u01ab\2\2\u01ad\2\2\u01af\2~\u01b1\2"+ - "\177\u01b3\2\u0080\u01b5\2\u0081\u01b7\2\2\u01b9\2\2\u01bb\2\u0082\u01bd"+ - "\2\u0083\t\2\3\4\5\6\7\b\35\5\2$$&&^^\4\2))^^\5\2\2\2&&\61\61\3\2\62;"+ - "\b\2IIKKNNiikknn\3\2\63;\4\2ZZzz\5\2\62;CHch\3\2\629\4\2DDdd\3\2\62\63"+ - "\4\2GGgg\4\2--//\6\2FFHIffhi\4\2RRrr\n\2$$))^^ddhhppttvv\3\2\62\65\3\2"+ - "C\\\5\2C\\aac|\4\2\2\u0081\ud802\udc01\3\2\ud802\udc01\3\2\udc02\ue001"+ - "\6\2\62;C\\aac|\6\2&&C\\aac|\7\2&&\62;C\\aac|\5\2\13\13\16\16\"\"\5\2"+ - "\f\f\17\17\1\1\2\u06af\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2"+ - "\2\2\21\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2"+ - "\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2S\3\2\2\2\2W\3\2\2\2\2Y"+ - "\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2i\3\2"+ - "\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2"+ - "\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3\2\2\2\2\u0083\3\2\2\2\2\u0087"+ - "\3\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2"+ - "\2\2\u0091\3\2\2\2\2\u0093\3\2\2\2\2\u0097\3\2\2\2\2\u0099\3\2\2\2\2\u009b"+ - "\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2"+ - "\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad"+ - "\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00e5\3\2\2\2\2\u00fd\3\2\2"+ - "\2\2\u0123\3\2\2\2\2\u0125\3\2\2\2\2\u0127\3\2\2\2\2\u0129\3\2\2\2\2\u012b"+ - "\3\2\2\2\2\u012d\3\2\2\2\2\u012f\3\2\2\2\2\u0131\3\2\2\2\2\u0133\3\2\2"+ - "\2\2\u0135\3\2\2\2\2\u0137\3\2\2\2\2\u0139\3\2\2\2\2\u013b\3\2\2\2\2\u013d"+ - "\3\2\2\2\2\u013f\3\2\2\2\2\u0141\3\2\2\2\2\u0143\3\2\2\2\2\u0145\3\2\2"+ - "\2\2\u0147\3\2\2\2\2\u0149\3\2\2\2\2\u014b\3\2\2\2\2\u014d\3\2\2\2\2\u014f"+ - "\3\2\2\2\2\u0151\3\2\2\2\2\u0153\3\2\2\2\2\u0155\3\2\2\2\2\u0157\3\2\2"+ - "\2\2\u0159\3\2\2\2\2\u015b\3\2\2\2\2\u015d\3\2\2\2\2\u015f\3\2\2\2\2\u0161"+ - "\3\2\2\2\2\u0163\3\2\2\2\2\u0165\3\2\2\2\2\u0167\3\2\2\2\2\u0169\3\2\2"+ - "\2\2\u016b\3\2\2\2\2\u016d\3\2\2\2\2\u016f\3\2\2\2\2\u0171\3\2\2\2\2\u0173"+ - "\3\2\2\2\2\u0175\3\2\2\2\2\u0177\3\2\2\2\2\u0179\3\2\2\2\2\u017b\3\2\2"+ - "\2\2\u017d\3\2\2\2\2\u017f\3\2\2\2\2\u0181\3\2\2\2\2\u0183\3\2\2\2\2\u0185"+ - "\3\2\2\2\2\u0187\3\2\2\2\2\u0189\3\2\2\2\2\u018b\3\2\2\2\2\u018d\3\2\2"+ - "\2\2\u018f\3\2\2\2\2\u0191\3\2\2\2\2\u0193\3\2\2\2\2\u0195\3\2\2\2\2\u0197"+ - "\3\2\2\2\2\u0199\3\2\2\2\2\u019b\3\2\2\2\2\u019d\3\2\2\2\2\u019f\3\2\2"+ - "\2\2\u01a1\3\2\2\2\2\u01a3\3\2\2\2\2\u01af\3\2\2\2\2\u01b1\3\2\2\2\2\u01b3"+ - "\3\2\2\2\2\u01b5\3\2\2\2\2\u01b7\3\2\2\2\2\u01b9\3\2\2\2\2\u01bb\3\2\2"+ - "\2\2\u01bd\3\2\2\2\3\23\3\2\2\2\3\25\3\2\2\2\3\27\3\2\2\2\4\31\3\2\2\2"+ - "\4\33\3\2\2\2\4\35\3\2\2\2\5\37\3\2\2\2\5!\3\2\2\2\5#\3\2\2\2\6%\3\2\2"+ - "\2\6\'\3\2\2\2\6)\3\2\2\2\7+\3\2\2\2\7-\3\2\2\2\b/\3\2\2\2\b\61\3\2\2"+ - "\2\t\u01f4\3\2\2\2\13\u01f6\3\2\2\2\r\u0202\3\2\2\2\17\u020f\3\2\2\2\21"+ - "\u021e\3\2\2\2\23\u022c\3\2\2\2\25\u0230\3\2\2\2\27\u0234\3\2\2\2\31\u0238"+ - "\3\2\2\2\33\u023d\3\2\2\2\35\u0242\3\2\2\2\37\u0247\3\2\2\2!\u024e\3\2"+ - "\2\2#\u0254\3\2\2\2%\u0258\3\2\2\2\'\u025d\3\2\2\2)\u0263\3\2\2\2+\u0267"+ - "\3\2\2\2-\u026e\3\2\2\2/\u0274\3\2\2\2\61\u0277\3\2\2\2\63\u027e\3\2\2"+ - "\2\65\u0282\3\2\2\2\67\u0289\3\2\2\29\u0290\3\2\2\2;\u0297\3\2\2\2=\u02a3"+ - "\3\2\2\2?\u02a5\3\2\2\2A\u02a8\3\2\2\2C\u02ac\3\2\2\2E\u02af\3\2\2\2G"+ - "\u02b5\3\2\2\2I\u02c0\3\2\2\2K\u02cc\3\2\2\2M\u02ce\3\2\2\2O\u02d7\3\2"+ - "\2\2Q\u02de\3\2\2\2S\u02e6\3\2\2\2U\u02ec\3\2\2\2W\u02f1\3\2\2\2Y\u02f6"+ - "\3\2\2\2[\u02fc\3\2\2\2]\u0301\3\2\2\2_\u0307\3\2\2\2a\u030d\3\2\2\2c"+ - "\u0316\3\2\2\2e\u031e\3\2\2\2g\u0321\3\2\2\2i\u0328\3\2\2\2k\u032d\3\2"+ - "\2\2m\u0332\3\2\2\2o\u033a\3\2\2\2q\u0340\3\2\2\2s\u0348\3\2\2\2u\u034e"+ - "\3\2\2\2w\u0352\3\2\2\2y\u0355\3\2\2\2{\u035a\3\2\2\2}\u0365\3\2\2\2\177"+ - "\u036c\3\2\2\2\u0081\u0377\3\2\2\2\u0083\u037b\3\2\2\2\u0085\u0385\3\2"+ - "\2\2\u0087\u038a\3\2\2\2\u0089\u0391\3\2\2\2\u008b\u0395\3\2\2\2\u008d"+ - "\u039d\3\2\2\2\u008f\u03a5\3\2\2\2\u0091\u03af\3\2\2\2\u0093\u03b6\3\2"+ - "\2\2\u0095\u03bd\3\2\2\2\u0097\u03c3\3\2\2\2\u0099\u03ca\3\2\2\2\u009b"+ - "\u03d3\3\2\2\2\u009d\u03d9\3\2\2\2\u009f\u03e0\3\2\2\2\u00a1\u03ed\3\2"+ - "\2\2\u00a3\u03f2\3\2\2\2\u00a5\u03f8\3\2\2\2\u00a7\u03ff\3\2\2\2\u00a9"+ - "\u0409\3\2\2\2\u00ab\u040d\3\2\2\2\u00ad\u0412\3\2\2\2\u00af\u041b\3\2"+ - "\2\2\u00b1\u0437\3\2\2\2\u00b3\u0439\3\2\2\2\u00b5\u043b\3\2\2\2\u00b7"+ - "\u043f\3\2\2\2\u00b9\u0443\3\2\2\2\u00bb\u0447\3\2\2\2\u00bd\u044b\3\2"+ - "\2\2\u00bf\u0457\3\2\2\2\u00c1\u0459\3\2\2\2\u00c3\u0465\3\2\2\2\u00c5"+ - "\u0467\3\2\2\2\u00c7\u046b\3\2\2\2\u00c9\u046e\3\2\2\2\u00cb\u0472\3\2"+ - "\2\2\u00cd\u0474\3\2\2\2\u00cf\u0478\3\2\2\2\u00d1\u0482\3\2\2\2\u00d3"+ - "\u0486\3\2\2\2\u00d5\u0488\3\2\2\2\u00d7\u048e\3\2\2\2\u00d9\u0498\3\2"+ - "\2\2\u00db\u049c\3\2\2\2\u00dd\u049e\3\2\2\2\u00df\u04a2\3\2\2\2\u00e1"+ - "\u04ac\3\2\2\2\u00e3\u04b0\3\2\2\2\u00e5\u04b4\3\2\2\2\u00e7\u04cc\3\2"+ - "\2\2\u00e9\u04ce\3\2\2\2\u00eb\u04d1\3\2\2\2\u00ed\u04d4\3\2\2\2\u00ef"+ - "\u04d8\3\2\2\2\u00f1\u04da\3\2\2\2\u00f3\u04dc\3\2\2\2\u00f5\u04ed\3\2"+ - "\2\2\u00f7\u04ef\3\2\2\2\u00f9\u04f2\3\2\2\2\u00fb\u04f4\3\2\2\2\u00fd"+ - "\u04ff\3\2\2\2\u00ff\u0508\3\2\2\2\u0101\u0516\3\2\2\2\u0103\u0518\3\2"+ - "\2\2\u0105\u051f\3\2\2\2\u0107\u0521\3\2\2\2\u0109\u0524\3\2\2\2\u010b"+ - "\u052a\3\2\2\2\u010d\u052d\3\2\2\2\u010f\u052f\3\2\2\2\u0111\u0531\3\2"+ - "\2\2\u0113\u0533\3\2\2\2\u0115\u0535\3\2\2\2\u0117\u0537\3\2\2\2\u0119"+ - "\u053b\3\2\2\2\u011b\u053f\3\2\2\2\u011d\u0542\3\2\2\2\u011f\u0545\3\2"+ - "\2\2\u0121\u0549\3\2\2\2\u0123\u054c\3\2\2\2\u0125\u0551\3\2\2\2\u0127"+ - "\u0554\3\2\2\2\u0129\u0558\3\2\2\2\u012b\u055b\3\2\2\2\u012d\u055e\3\2"+ - "\2\2\u012f\u0562\3\2\2\2\u0131\u0565\3\2\2\2\u0133\u0568\3\2\2\2\u0135"+ - "\u056b\3\2\2\2\u0137\u056e\3\2\2\2\u0139\u0572\3\2\2\2\u013b\u0575\3\2"+ - "\2\2\u013d\u0579\3\2\2\2\u013f\u057d\3\2\2\2\u0141\u0581\3\2\2\2\u0143"+ - "\u0585\3\2\2\2\u0145\u0588\3\2\2\2\u0147\u0596\3\2\2\2\u0149\u059c\3\2"+ - "\2\2\u014b\u05a1\3\2\2\2\u014d\u05a6\3\2\2\2\u014f\u05ab\3\2\2\2\u0151"+ - "\u05b0\3\2\2\2\u0153\u05b5\3\2\2\2\u0155\u05ba\3\2\2\2\u0157\u05bc\3\2"+ - "\2\2\u0159\u05be\3\2\2\2\u015b\u05c0\3\2\2\2\u015d\u05c2\3\2\2\2\u015f"+ - "\u05c4\3\2\2\2\u0161\u05c6\3\2\2\2\u0163\u05c8\3\2\2\2\u0165\u05ca\3\2"+ - "\2\2\u0167\u05cc\3\2\2\2\u0169\u05ce\3\2\2\2\u016b\u05d1\3\2\2\2\u016d"+ - "\u05d4\3\2\2\2\u016f\u05d7\3\2\2\2\u0171\u05da\3\2\2\2\u0173\u05dd\3\2"+ - "\2\2\u0175\u05e0\3\2\2\2\u0177\u05e3\3\2\2\2\u0179\u05e6\3\2\2\2\u017b"+ - "\u05e8\3\2\2\2\u017d\u05ea\3\2\2\2\u017f\u05ec\3\2\2\2\u0181\u05ee\3\2"+ - "\2\2\u0183\u05f0\3\2\2\2\u0185\u05f2\3\2\2\2\u0187\u05f4\3\2\2\2\u0189"+ - "\u05f6\3\2\2\2\u018b\u05f9\3\2\2\2\u018d\u05fc\3\2\2\2\u018f\u05ff\3\2"+ - "\2\2\u0191\u0602\3\2\2\2\u0193\u0605\3\2\2\2\u0195\u0608\3\2\2\2\u0197"+ - "\u060b\3\2\2\2\u0199\u060e\3\2\2\2\u019b\u0612\3\2\2\2\u019d\u0616\3\2"+ - "\2\2\u019f\u061b\3\2\2\2\u01a1\u061e\3\2\2\2\u01a3\u0625\3\2\2\2\u01a5"+ - "\u062c\3\2\2\2\u01a7\u0639\3\2\2\2\u01a9\u0641\3\2\2\2\u01ab\u0649\3\2"+ - "\2\2\u01ad\u0651\3\2\2\2\u01af\u0653\3\2\2\2\u01b1\u0655\3\2\2\2\u01b3"+ - "\u0663\3\2\2\2\u01b5\u0668\3\2\2\2\u01b7\u066d\3\2\2\2\u01b9\u067d\3\2"+ - "\2\2\u01bb\u068a\3\2\2\2\u01bd\u0696\3\2\2\2\u01bf\u01c3\5\u0113\u0087"+ - "\2\u01c0\u01c2\5\63\27\2\u01c1\u01c0\3\2\2\2\u01c2\u01c5\3\2\2\2\u01c3"+ - "\u01c1\3\2\2\2\u01c3\u01c4\3\2\2\2\u01c4\u01c6\3\2\2\2\u01c5\u01c3\3\2"+ - "\2\2\u01c6\u01c7\5\u0113\u0087\2\u01c7\u01f5\3\2\2\2\u01c8\u01cc\5\u0115"+ - "\u0088\2\u01c9\u01cb\5\65\30\2\u01ca\u01c9\3\2\2\2\u01cb\u01ce\3\2\2\2"+ - "\u01cc\u01ca\3\2\2\2\u01cc\u01cd\3\2\2\2\u01cd\u01cf\3\2\2\2\u01ce\u01cc"+ - "\3\2\2\2\u01cf\u01d0\5\u0115\u0088\2\u01d0\u01f5\3\2\2\2\u01d1\u01d2\5"+ - "\u010f\u0085\2\u01d2\u01d4\6\2\2\2\u01d3\u01d5\5;\33\2\u01d4\u01d3\3\2"+ - "\2\2\u01d5\u01d6\3\2\2\2\u01d6\u01d4\3\2\2\2\u01d6\u01d7\3\2\2\2\u01d7"+ - "\u01d8\3\2\2\2\u01d8\u01d9\5\u010f\u0085\2\u01d9\u01f5\3\2\2\2\u01da\u01de"+ - "\5\u0117\u0089\2\u01db\u01dd\5\67\31\2\u01dc\u01db\3\2\2\2\u01dd\u01e0"+ - "\3\2\2\2\u01de\u01dc\3\2\2\2\u01de\u01df\3\2\2\2\u01df\u01e1\3\2\2\2\u01e0"+ - "\u01de\3\2\2\2\u01e1\u01e2\5\u0117\u0089\2\u01e2\u01f5\3\2\2\2\u01e3\u01e7"+ - "\5\u0119\u008a\2\u01e4\u01e6\59\32\2\u01e5\u01e4\3\2\2\2\u01e6\u01e9\3"+ - "\2\2\2\u01e7\u01e5\3\2\2\2\u01e7\u01e8\3\2\2\2\u01e8\u01ea\3\2\2\2\u01e9"+ - "\u01e7\3\2\2\2\u01ea\u01eb\5\u0119\u008a\2\u01eb\u01f5\3\2\2\2\u01ec\u01ee"+ - "\5\u011b\u008b\2\u01ed\u01ef\5=\34\2\u01ee\u01ed\3\2\2\2\u01ef\u01f0\3"+ - "\2\2\2\u01f0\u01ee\3\2\2\2\u01f0\u01f1\3\2\2\2\u01f1\u01f2\3\2\2\2\u01f2"+ - "\u01f3\5\u011d\u008c\2\u01f3\u01f5\3\2\2\2\u01f4\u01bf\3\2\2\2\u01f4\u01c8"+ - "\3\2\2\2\u01f4\u01d1\3\2\2\2\u01f4\u01da\3\2\2\2\u01f4\u01e3\3\2\2\2\u01f4"+ - "\u01ec\3\2\2\2\u01f5\n\3\2\2\2\u01f6\u01fa\5\u0113\u0087\2\u01f7\u01f9"+ - "\5\63\27\2\u01f8\u01f7\3\2\2\2\u01f9\u01fc\3\2\2\2\u01fa\u01f8\3\2\2\2"+ - "\u01fa\u01fb\3\2\2\2\u01fb\u01fd\3\2\2\2\u01fc\u01fa\3\2\2\2\u01fd\u01fe"+ - "\5\u0111\u0086\2\u01fe\u01ff\3\2\2\2\u01ff\u0200\b\3\2\2\u0200\u0201\b"+ - "\3\3\2\u0201\f\3\2\2\2\u0202\u0206\5\u0117\u0089\2\u0203\u0205\5\67\31"+ - "\2\u0204\u0203\3\2\2\2\u0205\u0208\3\2\2\2\u0206\u0204\3\2\2\2\u0206\u0207"+ - "\3\2\2\2\u0207\u0209\3\2\2\2\u0208\u0206\3\2\2\2\u0209\u020a\5\u0111\u0086"+ - "\2\u020a\u020b\3\2\2\2\u020b\u020c\b\4\4\2\u020c\u020d\b\4\5\2\u020d\u020e"+ - "\b\4\3\2\u020e\16\3\2\2\2\u020f\u0210\5\u010f\u0085\2\u0210\u0214\6\5"+ - "\3\2\u0211\u0213\5;\33\2\u0212\u0211\3\2\2\2\u0213\u0216\3\2\2\2\u0214"+ - "\u0212\3\2\2\2\u0214\u0215\3\2\2\2\u0215\u0217\3\2\2\2\u0216\u0214\3\2"+ - "\2\2\u0217\u0218\5\u0111\u0086\2\u0218\u0219\6\5\4\2\u0219\u021a\3\2\2"+ - "\2\u021a\u021b\b\5\4\2\u021b\u021c\b\5\6\2\u021c\u021d\b\5\3\2\u021d\20"+ - "\3\2\2\2\u021e\u0222\5\u011b\u008b\2\u021f\u0221\5=\34\2\u0220\u021f\3"+ - "\2\2\2\u0221\u0224\3\2\2\2\u0222\u0220\3\2\2\2\u0222\u0223\3\2\2\2\u0223"+ - "\u0225\3\2\2\2\u0224\u0222\3\2\2\2\u0225\u0226\5\u0111\u0086\2\u0226\u0227"+ - "\6\6\5\2\u0227\u0228\3\2\2\2\u0228\u0229\b\6\4\2\u0229\u022a\b\6\7\2\u022a"+ - "\u022b\b\6\3\2\u022b\22\3\2\2\2\u022c\u022d\5\u0113\u0087\2\u022d\u022e"+ - "\3\2\2\2\u022e\u022f\b\7\b\2\u022f\24\3\2\2\2\u0230\u0231\5\u0111\u0086"+ - "\2\u0231\u0232\3\2\2\2\u0232\u0233\b\b\3\2\u0233\26\3\2\2\2\u0234\u0235"+ - "\5\63\27\2\u0235\u0236\3\2\2\2\u0236\u0237\b\t\t\2\u0237\30\3\2\2\2\u0238"+ - "\u0239\5\u0117\u0089\2\u0239\u023a\3\2\2\2\u023a\u023b\b\n\n\2\u023b\u023c"+ - "\b\n\b\2\u023c\32\3\2\2\2\u023d\u023e\5\u0111\u0086\2\u023e\u023f\3\2"+ - "\2\2\u023f\u0240\b\13\13\2\u0240\u0241\b\13\3\2\u0241\34\3\2\2\2\u0242"+ - "\u0243\5\67\31\2\u0243\u0244\3\2\2\2\u0244\u0245\b\f\t\2\u0245\36\3\2"+ - "\2\2\u0246\u0248\5\u0111\u0086\2\u0247\u0246\3\2\2\2\u0247\u0248\3\2\2"+ - "\2\u0248\u0249\3\2\2\2\u0249\u024a\5\u010f\u0085\2\u024a\u024b\3\2\2\2"+ - "\u024b\u024c\b\r\n\2\u024c\u024d\b\r\b\2\u024d \3\2\2\2\u024e\u024f\5"+ - "\u0111\u0086\2\u024f\u0250\6\16\6\2\u0250\u0251\3\2\2\2\u0251\u0252\b"+ - "\16\13\2\u0252\u0253\b\16\3\2\u0253\"\3\2\2\2\u0254\u0255\5;\33\2\u0255"+ - "\u0256\3\2\2\2\u0256\u0257\b\17\t\2\u0257$\3\2\2\2\u0258\u0259\5\u011d"+ - "\u008c\2\u0259\u025a\3\2\2\2\u025a\u025b\b\20\n\2\u025b\u025c\b\20\b\2"+ - "\u025c&\3\2\2\2\u025d\u025e\5\u0111\u0086\2\u025e\u025f\6\21\7\2\u025f"+ - "\u0260\3\2\2\2\u0260\u0261\b\21\13\2\u0261\u0262\b\21\3\2\u0262(\3\2\2"+ - "\2\u0263\u0264\5=\34\2\u0264\u0265\3\2\2\2\u0265\u0266\b\22\t\2\u0266"+ - "*\3\2\2\2\u0267\u0268\7}\2\2\u0268\u0269\b\23\f\2\u0269\u026a\3\2\2\2"+ - "\u026a\u026b\b\23\r\2\u026b\u026c\b\23\b\2\u026c\u026d\b\23\16\2\u026d"+ - ",\3\2\2\2\u026e\u026f\5\u01a5\u00d0\2\u026f\u0270\3\2\2\2\u0270\u0271"+ - "\b\24\17\2\u0271\u0272\b\24\b\2\u0272\u0273\b\24\20\2\u0273.\3\2\2\2\u0274"+ - "\u0275\5\u00fb{\2\u0275\u0276\5\u01a5\u00d0\2\u0276\60\3\2\2\2\u0277\u0278"+ - "\13\2\2\2\u0278\u0279\b\26\21\2\u0279\u027a\3\2\2\2\u027a\u027b\b\26\b"+ - "\2\u027b\62\3\2\2\2\u027c\u027f\n\2\2\2\u027d\u027f\5\u00ff}\2\u027e\u027c"+ - "\3\2\2\2\u027e\u027d\3\2\2\2\u027f\64\3\2\2\2\u0280\u0283\n\3\2\2\u0281"+ - "\u0283\5\u00ff}\2\u0282\u0280\3\2\2\2\u0282\u0281\3\2\2\2\u0283\66\3\2"+ - "\2\2\u0284\u028a\n\2\2\2\u0285\u0286\5\u0113\u0087\2\u0286\u0287\6\31"+ - "\b\2\u0287\u028a\3\2\2\2\u0288\u028a\5\u00ff}\2\u0289\u0284\3\2\2\2\u0289"+ - "\u0285\3\2\2\2\u0289\u0288\3\2\2\2\u028a8\3\2\2\2\u028b\u0291\n\3\2\2"+ - "\u028c\u028d\5\u0115\u0088\2\u028d\u028e\6\32\t\2\u028e\u0291\3\2\2\2"+ - "\u028f\u0291\5\u00ff}\2\u0290\u028b\3\2\2\2\u0290\u028c\3\2\2\2\u0290"+ - "\u028f\3\2\2\2\u0291:\3\2\2\2\u0292\u0298\5\u010b\u0083\2\u0293\u0294"+ - "\5\u0111\u0086\2\u0294\u0295\6\33\n\2\u0295\u0298\3\2\2\2\u0296\u0298"+ - "\n\4\2\2\u0297\u0292\3\2\2\2\u0297\u0293\3\2\2\2\u0297\u0296\3\2\2\2\u0298"+ - "<\3\2\2\2\u0299\u02a4\5\u010b\u0083\2\u029a\u02a4\5\u011f\u008d\2\u029b"+ - "\u02a4\5\u0121\u008e\2\u029c\u029d\5\u010f\u0085\2\u029d\u029e\6\34\13"+ - "\2\u029e\u02a4\3\2\2\2\u029f\u02a0\5\u0111\u0086\2\u02a0\u02a1\6\34\f"+ - "\2\u02a1\u02a4\3\2\2\2\u02a2\u02a4\n\4\2\2\u02a3\u0299\3\2\2\2\u02a3\u029a"+ - "\3\2\2\2\u02a3\u029b\3\2\2\2\u02a3\u029c\3\2\2\2\u02a3\u029f\3\2\2\2\u02a3"+ - "\u02a2\3\2\2\2\u02a4>\3\2\2\2\u02a5\u02a6\7c\2\2\u02a6\u02a7\7u\2\2\u02a7"+ - "@\3\2\2\2\u02a8\u02a9\7f\2\2\u02a9\u02aa\7g\2\2\u02aa\u02ab\7h\2\2\u02ab"+ - "B\3\2\2\2\u02ac\u02ad\7k\2\2\u02ad\u02ae\7p\2\2\u02aeD\3\2\2\2\u02af\u02b0"+ - "\7v\2\2\u02b0\u02b1\7t\2\2\u02b1\u02b2\7c\2\2\u02b2\u02b3\7k\2\2\u02b3"+ - "\u02b4\7v\2\2\u02b4F\3\2\2\2\u02b5\u02b6\7v\2\2\u02b6\u02b7\7j\2\2\u02b7"+ - "\u02b8\7t\2\2\u02b8\u02b9\7g\2\2\u02b9\u02ba\7c\2\2\u02ba\u02bb\7f\2\2"+ - "\u02bb\u02bc\7u\2\2\u02bc\u02bd\7c\2\2\u02bd\u02be\7h\2\2\u02be\u02bf"+ - "\7g\2\2\u02bfH\3\2\2\2\u02c0\u02c1\7x\2\2\u02c1\u02c2\7c\2\2\u02c2\u02c3"+ - "\7t\2\2\u02c3J\3\2\2\2\u02c4\u02cd\5Q&\2\u02c5\u02cd\5[+\2\u02c6\u02cd"+ - "\5U(\2\u02c7\u02cd\5\u0095H\2\u02c8\u02cd\5\u0081>\2\u02c9\u02cd\5\u0085"+ - "@\2\u02ca\u02cd\5s\67\2\u02cb\u02cd\5g\61\2\u02cc\u02c4\3\2\2\2\u02cc"+ - "\u02c5\3\2\2\2\u02cc\u02c6\3\2\2\2\u02cc\u02c7\3\2\2\2\u02cc\u02c8\3\2"+ - "\2\2\u02cc\u02c9\3\2\2\2\u02cc\u02ca\3\2\2\2\u02cc\u02cb\3\2\2\2\u02cd"+ - "L\3\2\2\2\u02ce\u02cf\7c\2\2\u02cf\u02d0\7d\2\2\u02d0\u02d1\7u\2\2\u02d1"+ - "\u02d2\7v\2\2\u02d2\u02d3\7t\2\2\u02d3\u02d4\7c\2\2\u02d4\u02d5\7e\2\2"+ - "\u02d5\u02d6\7v\2\2\u02d6N\3\2\2\2\u02d7\u02d8\7c\2\2\u02d8\u02d9\7u\2"+ - "\2\u02d9\u02da\7u\2\2\u02da\u02db\7g\2\2\u02db\u02dc\7t\2\2\u02dc\u02dd"+ - "\7v\2\2\u02ddP\3\2\2\2\u02de\u02df\7d\2\2\u02df\u02e0\7q\2\2\u02e0\u02e1"+ - "\7q\2\2\u02e1\u02e2\7n\2\2\u02e2\u02e3\7g\2\2\u02e3\u02e4\7c\2\2\u02e4"+ - "\u02e5\7p\2\2\u02e5R\3\2\2\2\u02e6\u02e7\7d\2\2\u02e7\u02e8\7t\2\2\u02e8"+ - "\u02e9\7g\2\2\u02e9\u02ea\7c\2\2\u02ea\u02eb\7m\2\2\u02ebT\3\2\2\2\u02ec"+ - "\u02ed\7d\2\2\u02ed\u02ee\7{\2\2\u02ee\u02ef\7v\2\2\u02ef\u02f0\7g\2\2"+ - "\u02f0V\3\2\2\2\u02f1\u02f2\7e\2\2\u02f2\u02f3\7c\2\2\u02f3\u02f4\7u\2"+ - "\2\u02f4\u02f5\7g\2\2\u02f5X\3\2\2\2\u02f6\u02f7\7e\2\2\u02f7\u02f8\7"+ - "c\2\2\u02f8\u02f9\7v\2\2\u02f9\u02fa\7e\2\2\u02fa\u02fb\7j\2\2\u02fbZ"+ - "\3\2\2\2\u02fc\u02fd\7e\2\2\u02fd\u02fe\7j\2\2\u02fe\u02ff\7c\2\2\u02ff"+ - "\u0300\7t\2\2\u0300\\\3\2\2\2\u0301\u0302\7e\2\2\u0302\u0303\7n\2\2\u0303"+ - "\u0304\7c\2\2\u0304\u0305\7u\2\2\u0305\u0306\7u\2\2\u0306^\3\2\2\2\u0307"+ - "\u0308\7e\2\2\u0308\u0309\7q\2\2\u0309\u030a\7p\2\2\u030a\u030b\7u\2\2"+ - "\u030b\u030c\7v\2\2\u030c`\3\2\2\2\u030d\u030e\7e\2\2\u030e\u030f\7q\2"+ - "\2\u030f\u0310\7p\2\2\u0310\u0311\7v\2\2\u0311\u0312\7k\2\2\u0312\u0313"+ - "\7p\2\2\u0313\u0314\7w\2\2\u0314\u0315\7g\2\2\u0315b\3\2\2\2\u0316\u0317"+ - "\7f\2\2\u0317\u0318\7g\2\2\u0318\u0319\7h\2\2\u0319\u031a\7c\2\2\u031a"+ - "\u031b\7w\2\2\u031b\u031c\7n\2\2\u031c\u031d\7v\2\2\u031dd\3\2\2\2\u031e"+ - "\u031f\7f\2\2\u031f\u0320\7q\2\2\u0320f\3\2\2\2\u0321\u0322\7f\2\2\u0322"+ - "\u0323\7q\2\2\u0323\u0324\7w\2\2\u0324\u0325\7d\2\2\u0325\u0326\7n\2\2"+ - "\u0326\u0327\7g\2\2\u0327h\3\2\2\2\u0328\u0329\7g\2\2\u0329\u032a\7n\2"+ - "\2\u032a\u032b\7u\2\2\u032b\u032c\7g\2\2\u032cj\3\2\2\2\u032d\u032e\7"+ - "g\2\2\u032e\u032f\7p\2\2\u032f\u0330\7w\2\2\u0330\u0331\7o\2\2\u0331l"+ - "\3\2\2\2\u0332\u0333\7g\2\2\u0333\u0334\7z\2\2\u0334\u0335\7v\2\2\u0335"+ - "\u0336\7g\2\2\u0336\u0337\7p\2\2\u0337\u0338\7f\2\2\u0338\u0339\7u\2\2"+ - "\u0339n\3\2\2\2\u033a\u033b\7h\2\2\u033b\u033c\7k\2\2\u033c\u033d\7p\2"+ - "\2\u033d\u033e\7c\2\2\u033e\u033f\7n\2\2\u033fp\3\2\2\2\u0340\u0341\7"+ - "h\2\2\u0341\u0342\7k\2\2\u0342\u0343\7p\2\2\u0343\u0344\7c\2\2\u0344\u0345"+ - "\7n\2\2\u0345\u0346\7n\2\2\u0346\u0347\7{\2\2\u0347r\3\2\2\2\u0348\u0349"+ - "\7h\2\2\u0349\u034a\7n\2\2\u034a\u034b\7q\2\2\u034b\u034c\7c\2\2\u034c"+ - "\u034d\7v\2\2\u034dt\3\2\2\2\u034e\u034f\7h\2\2\u034f\u0350\7q\2\2\u0350"+ - "\u0351\7t\2\2\u0351v\3\2\2\2\u0352\u0353\7k\2\2\u0353\u0354\7h\2\2\u0354"+ - "x\3\2\2\2\u0355\u0356\7i\2\2\u0356\u0357\7q\2\2\u0357\u0358\7v\2\2\u0358"+ - "\u0359\7q\2\2\u0359z\3\2\2\2\u035a\u035b\7k\2\2\u035b\u035c\7o\2\2\u035c"+ - "\u035d\7r\2\2\u035d\u035e\7n\2\2\u035e\u035f\7g\2\2\u035f\u0360\7o\2\2"+ - "\u0360\u0361\7g\2\2\u0361\u0362\7p\2\2\u0362\u0363\7v\2\2\u0363\u0364"+ - "\7u\2\2\u0364|\3\2\2\2\u0365\u0366\7k\2\2\u0366\u0367\7o\2\2\u0367\u0368"+ - "\7r\2\2\u0368\u0369\7q\2\2\u0369\u036a\7t\2\2\u036a\u036b\7v\2\2\u036b"+ - "~\3\2\2\2\u036c\u036d\7k\2\2\u036d\u036e\7p\2\2\u036e\u036f\7u\2\2\u036f"+ - "\u0370\7v\2\2\u0370\u0371\7c\2\2\u0371\u0372\7p\2\2\u0372\u0373\7e\2\2"+ - "\u0373\u0374\7g\2\2\u0374\u0375\7q\2\2\u0375\u0376\7h\2\2\u0376\u0080"+ - "\3\2\2\2\u0377\u0378\7k\2\2\u0378\u0379\7p\2\2\u0379\u037a\7v\2\2\u037a"+ - "\u0082\3\2\2\2\u037b\u037c\7k\2\2\u037c\u037d\7p\2\2\u037d\u037e\7v\2"+ - "\2\u037e\u037f\7g\2\2\u037f\u0380\7t\2\2\u0380\u0381\7h\2\2\u0381\u0382"+ - "\7c\2\2\u0382\u0383\7e\2\2\u0383\u0384\7g\2\2\u0384\u0084\3\2\2\2\u0385"+ - "\u0386\7n\2\2\u0386\u0387\7q\2\2\u0387\u0388\7p\2\2\u0388\u0389\7i\2\2"+ - "\u0389\u0086\3\2\2\2\u038a\u038b\7p\2\2\u038b\u038c\7c\2\2\u038c\u038d"+ - "\7v\2\2\u038d\u038e\7k\2\2\u038e\u038f\7x\2\2\u038f\u0390\7g\2\2\u0390"+ - "\u0088\3\2\2\2\u0391\u0392\7p\2\2\u0392\u0393\7g\2\2\u0393\u0394\7y\2"+ - "\2\u0394\u008a\3\2\2\2\u0395\u0396\7r\2\2\u0396\u0397\7c\2\2\u0397\u0398"+ - "\7e\2\2\u0398\u0399\7m\2\2\u0399\u039a\7c\2\2\u039a\u039b\7i\2\2\u039b"+ - "\u039c\7g\2\2\u039c\u008c\3\2\2\2\u039d\u039e\7r\2\2\u039e\u039f\7t\2"+ - "\2\u039f\u03a0\7k\2\2\u03a0\u03a1\7x\2\2\u03a1\u03a2\7c\2\2\u03a2\u03a3"+ - "\7v\2\2\u03a3\u03a4\7g\2\2\u03a4\u008e\3\2\2\2\u03a5\u03a6\7r\2\2\u03a6"+ - "\u03a7\7t\2\2\u03a7\u03a8\7q\2\2\u03a8\u03a9\7v\2\2\u03a9\u03aa\7g\2\2"+ - "\u03aa\u03ab\7e\2\2\u03ab\u03ac\7v\2\2\u03ac\u03ad\7g\2\2\u03ad\u03ae"+ - "\7f\2\2\u03ae\u0090\3\2\2\2\u03af\u03b0\7r\2\2\u03b0\u03b1\7w\2\2\u03b1"+ - "\u03b2\7d\2\2\u03b2\u03b3\7n\2\2\u03b3\u03b4\7k\2\2\u03b4\u03b5\7e\2\2"+ - "\u03b5\u0092\3\2\2\2\u03b6\u03b7\7t\2\2\u03b7\u03b8\7g\2\2\u03b8\u03b9"+ - "\7v\2\2\u03b9\u03ba\7w\2\2\u03ba\u03bb\7t\2\2\u03bb\u03bc\7p\2\2\u03bc"+ - "\u0094\3\2\2\2\u03bd\u03be\7u\2\2\u03be\u03bf\7j\2\2\u03bf\u03c0\7q\2"+ - "\2\u03c0\u03c1\7t\2\2\u03c1\u03c2\7v\2\2\u03c2\u0096\3\2\2\2\u03c3\u03c4"+ - "\7u\2\2\u03c4\u03c5\7v\2\2\u03c5\u03c6\7c\2\2\u03c6\u03c7\7v\2\2\u03c7"+ - "\u03c8\7k\2\2\u03c8\u03c9\7e\2\2\u03c9\u0098\3\2\2\2\u03ca\u03cb\7u\2"+ - "\2\u03cb\u03cc\7v\2\2\u03cc\u03cd\7t\2\2\u03cd\u03ce\7k\2\2\u03ce\u03cf"+ - "\7e\2\2\u03cf\u03d0\7v\2\2\u03d0\u03d1\7h\2\2\u03d1\u03d2\7r\2\2\u03d2"+ - "\u009a\3\2\2\2\u03d3\u03d4\7u\2\2\u03d4\u03d5\7w\2\2\u03d5\u03d6\7r\2"+ - "\2\u03d6\u03d7\7g\2\2\u03d7\u03d8\7t\2\2\u03d8\u009c\3\2\2\2\u03d9\u03da"+ - "\7u\2\2\u03da\u03db\7y\2\2\u03db\u03dc\7k\2\2\u03dc\u03dd\7v\2\2\u03dd"+ - "\u03de\7e\2\2\u03de\u03df\7j\2\2\u03df\u009e\3\2\2\2\u03e0\u03e1\7u\2"+ - "\2\u03e1\u03e2\7{\2\2\u03e2\u03e3\7p\2\2\u03e3\u03e4\7e\2\2\u03e4\u03e5"+ - "\7j\2\2\u03e5\u03e6\7t\2\2\u03e6\u03e7\7q\2\2\u03e7\u03e8\7p\2\2\u03e8"+ - "\u03e9\7k\2\2\u03e9\u03ea\7|\2\2\u03ea\u03eb\7g\2\2\u03eb\u03ec\7f\2\2"+ - "\u03ec\u00a0\3\2\2\2\u03ed\u03ee\7v\2\2\u03ee\u03ef\7j\2\2\u03ef\u03f0"+ - "\7k\2\2\u03f0\u03f1\7u\2\2\u03f1\u00a2\3\2\2\2\u03f2\u03f3\7v\2\2\u03f3"+ - "\u03f4\7j\2\2\u03f4\u03f5\7t\2\2\u03f5\u03f6\7q\2\2\u03f6\u03f7\7y\2\2"+ - "\u03f7\u00a4\3\2\2\2\u03f8\u03f9\7v\2\2\u03f9\u03fa\7j\2\2\u03fa\u03fb"+ - "\7t\2\2\u03fb\u03fc\7q\2\2\u03fc\u03fd\7y\2\2\u03fd\u03fe\7u\2\2\u03fe"+ - "\u00a6\3\2\2\2\u03ff\u0400\7v\2\2\u0400\u0401\7t\2\2\u0401\u0402\7c\2"+ - "\2\u0402\u0403\7p\2\2\u0403\u0404\7u\2\2\u0404\u0405\7k\2\2\u0405\u0406"+ - "\7g\2\2\u0406\u0407\7p\2\2\u0407\u0408\7v\2\2\u0408\u00a8\3\2\2\2\u0409"+ - "\u040a\7v\2\2\u040a\u040b\7t\2\2\u040b\u040c\7{\2\2\u040c\u00aa\3\2\2"+ - "\2\u040d\u040e\7x\2\2\u040e\u040f\7q\2\2\u040f\u0410\7k\2\2\u0410\u0411"+ - "\7f\2\2\u0411\u00ac\3\2\2\2\u0412\u0413\7x\2\2\u0413\u0414\7q\2\2\u0414"+ - "\u0415\7n\2\2\u0415\u0416\7c\2\2\u0416\u0417\7v\2\2\u0417\u0418\7k\2\2"+ - "\u0418\u0419\7n\2\2\u0419\u041a\7g\2\2\u041a\u00ae\3\2\2\2\u041b\u041c"+ - "\7y\2\2\u041c\u041d\7j\2\2\u041d\u041e\7k\2\2\u041e\u041f\7n\2\2\u041f"+ - "\u0420\7g\2\2\u0420\u00b0\3\2\2\2\u0421\u0426\5\u00b5X\2\u0422\u0426\5"+ - "\u00b7Y\2\u0423\u0426\5\u00b9Z\2\u0424\u0426\5\u00bb[\2\u0425\u0421\3"+ - "\2\2\2\u0425\u0422\3\2\2\2\u0425\u0423\3\2\2\2\u0425\u0424\3\2\2\2\u0426"+ - "\u042a\3\2\2\2\u0427\u0428\5\u00cbc\2\u0428\u0429\bV\22\2\u0429\u042b"+ - "\3\2\2\2\u042a\u0427\3\2\2\2\u042a\u042b\3\2\2\2\u042b\u0438\3\2\2\2\u042c"+ - "\u042f\5\u00b3W\2\u042d\u042e\t\5\2\2\u042e\u0430\bV\23\2\u042f\u042d"+ - "\3\2\2\2\u0430\u0431\3\2\2\2\u0431\u042f\3\2\2\2\u0431\u0432\3\2\2\2\u0432"+ - "\u0433\3\2\2\2\u0433\u0435\bV\24\2\u0434\u0436\5\u00bd\\\2\u0435\u0434"+ - "\3\2\2\2\u0435\u0436\3\2\2\2\u0436\u0438\3\2\2\2\u0437\u0425\3\2\2\2\u0437"+ - "\u042c\3\2\2\2\u0438\u00b2\3\2\2\2\u0439\u043a\7\62\2\2\u043a\u00b4\3"+ - "\2\2\2\u043b\u043d\5\u00bf]\2\u043c\u043e\5\u00bd\\\2\u043d\u043c\3\2"+ - "\2\2\u043d\u043e\3\2\2\2\u043e\u00b6\3\2\2\2\u043f\u0441\5\u00cdd\2\u0440"+ - "\u0442\5\u00bd\\\2\u0441\u0440\3\2\2\2\u0441\u0442\3\2\2\2\u0442\u00b8"+ - "\3\2\2\2\u0443\u0445\5\u00d5h\2\u0444\u0446\5\u00bd\\\2\u0445\u0444\3"+ - "\2\2\2\u0445\u0446\3\2\2\2\u0446\u00ba\3\2\2\2\u0447\u0449\5\u00ddl\2"+ - "\u0448\u044a\5\u00bd\\\2\u0449\u0448\3\2\2\2\u0449\u044a\3\2\2\2\u044a"+ - "\u00bc\3\2\2\2\u044b\u044c\t\6\2\2\u044c\u00be\3\2\2\2\u044d\u0458\5\u00b3"+ - "W\2\u044e\u0455\5\u00c5`\2\u044f\u0451\5\u00c1^\2\u0450\u044f\3\2\2\2"+ - "\u0450\u0451\3\2\2\2\u0451\u0456\3\2\2\2\u0452\u0453\5\u00c9b\2\u0453"+ - "\u0454\5\u00c1^\2\u0454\u0456\3\2\2\2\u0455\u0450\3\2\2\2\u0455\u0452"+ - "\3\2\2\2\u0456\u0458\3\2\2\2\u0457\u044d\3\2\2\2\u0457\u044e\3\2\2\2\u0458"+ - "\u00c0\3\2\2\2\u0459\u0461\5\u00c3_\2\u045a\u045c\5\u00c7a\2\u045b\u045a"+ - "\3\2\2\2\u045c\u045f\3\2\2\2\u045d\u045b\3\2\2\2\u045d\u045e\3\2\2\2\u045e"+ - "\u0460\3\2\2\2\u045f\u045d\3\2\2\2\u0460\u0462\5\u00c3_\2\u0461\u045d"+ - "\3\2\2\2\u0461\u0462\3\2\2\2\u0462\u00c2\3\2\2\2\u0463\u0466\5\u00b3W"+ - "\2\u0464\u0466\5\u00c5`\2\u0465\u0463\3\2\2\2\u0465\u0464\3\2\2\2\u0466"+ - "\u00c4\3\2\2\2\u0467\u0468\t\7\2\2\u0468\u00c6\3\2\2\2\u0469\u046c\5\u00c3"+ - "_\2\u046a\u046c\5\u00cbc\2\u046b\u0469\3\2\2\2\u046b\u046a\3\2\2\2\u046c"+ - "\u00c8\3\2\2\2\u046d\u046f\5\u00cbc\2\u046e\u046d\3\2\2\2\u046f\u0470"+ - "\3\2\2\2\u0470\u046e\3\2\2\2\u0470\u0471\3\2\2\2\u0471\u00ca\3\2\2\2\u0472"+ - "\u0473\7a\2\2\u0473\u00cc\3\2\2\2\u0474\u0475\5\u00b3W\2\u0475\u0476\t"+ - "\b\2\2\u0476\u0477\5\u00cfe\2\u0477\u00ce\3\2\2\2\u0478\u0480\5\u00d1"+ - "f\2\u0479\u047b\5\u00d3g\2\u047a\u0479\3\2\2\2\u047b\u047e\3\2\2\2\u047c"+ - "\u047a\3\2\2\2\u047c\u047d\3\2\2\2\u047d\u047f\3\2\2\2\u047e\u047c\3\2"+ - "\2\2\u047f\u0481\5\u00d1f\2\u0480\u047c\3\2\2\2\u0480\u0481\3\2\2\2\u0481"+ - "\u00d0\3\2\2\2\u0482\u0483\t\t\2\2\u0483\u00d2\3\2\2\2\u0484\u0487\5\u00d1"+ - "f\2\u0485\u0487\5\u00cbc\2\u0486\u0484\3\2\2\2\u0486\u0485\3\2\2\2\u0487"+ - "\u00d4\3\2\2\2\u0488\u048a\5\u00b3W\2\u0489\u048b\5\u00c9b\2\u048a\u0489"+ - "\3\2\2\2\u048a\u048b\3\2\2\2\u048b\u048c\3\2\2\2\u048c\u048d\5\u00d7i"+ - "\2\u048d\u00d6\3\2\2\2\u048e\u0496\5\u00d9j\2\u048f\u0491\5\u00dbk\2\u0490"+ - "\u048f\3\2\2\2\u0491\u0494\3\2\2\2\u0492\u0490\3\2\2\2\u0492\u0493\3\2"+ - "\2\2\u0493\u0495\3\2\2\2\u0494\u0492\3\2\2\2\u0495\u0497\5\u00d9j\2\u0496"+ - "\u0492\3\2\2\2\u0496\u0497\3\2\2\2\u0497\u00d8\3\2\2\2\u0498\u0499\t\n"+ - "\2\2\u0499\u00da\3\2\2\2\u049a\u049d\5\u00d9j\2\u049b\u049d\5\u00cbc\2"+ - "\u049c\u049a\3\2\2\2\u049c\u049b\3\2\2\2\u049d\u00dc\3\2\2\2\u049e\u049f"+ - "\5\u00b3W\2\u049f\u04a0\t\13\2\2\u04a0\u04a1\5\u00dfm\2\u04a1\u00de\3"+ - "\2\2\2\u04a2\u04aa\5\u00e1n\2\u04a3\u04a5\5\u00e3o\2\u04a4\u04a3\3\2\2"+ - "\2\u04a5\u04a8\3\2\2\2\u04a6\u04a4\3\2\2\2\u04a6\u04a7\3\2\2\2\u04a7\u04a9"+ - "\3\2\2\2\u04a8\u04a6\3\2\2\2\u04a9\u04ab\5\u00e1n\2\u04aa\u04a6\3\2\2"+ - "\2\u04aa\u04ab\3\2\2\2\u04ab\u00e0\3\2\2\2\u04ac\u04ad\t\f\2\2\u04ad\u00e2"+ - "\3\2\2\2\u04ae\u04b1\5\u00e1n\2\u04af\u04b1\5\u00cbc\2\u04b0\u04ae\3\2"+ - "\2\2\u04b0\u04af\3\2\2\2\u04b1\u00e4\3\2\2\2\u04b2\u04b5\5\u00e7q\2\u04b3"+ - "\u04b5\5\u00f3w\2\u04b4\u04b2\3\2\2\2\u04b4\u04b3\3\2\2\2\u04b5\u04b9"+ - "\3\2\2\2\u04b6\u04b7\5\u00cbc\2\u04b7\u04b8\bp\25\2\u04b8\u04ba\3\2\2"+ - "\2\u04b9\u04b6\3\2\2\2\u04b9\u04ba\3\2\2\2\u04ba\u00e6\3\2\2\2\u04bb\u04bc"+ - "\5\u00c1^\2\u04bc\u04bd\5\u00fb{\2\u04bd\u04bf\5\u00c1^\2\u04be\u04c0"+ - "\5\u00e9r\2\u04bf\u04be\3\2\2\2\u04bf\u04c0\3\2\2\2\u04c0\u04c2\3\2\2"+ - "\2\u04c1\u04c3\5\u00f1v\2\u04c2\u04c1\3\2\2\2\u04c2\u04c3\3\2\2\2\u04c3"+ - "\u04cd\3\2\2\2\u04c4\u04c5\5\u00c1^\2\u04c5\u04c7\5\u00e9r\2\u04c6\u04c8"+ - "\5\u00f1v\2\u04c7\u04c6\3\2\2\2\u04c7\u04c8\3\2\2\2\u04c8\u04cd\3\2\2"+ - "\2\u04c9\u04ca\5\u00c1^\2\u04ca\u04cb\5\u00f1v\2\u04cb\u04cd\3\2\2\2\u04cc"+ - "\u04bb\3\2\2\2\u04cc\u04c4\3\2\2\2\u04cc\u04c9\3\2\2\2\u04cd\u00e8\3\2"+ - "\2\2\u04ce\u04cf\5\u00ebs\2\u04cf\u04d0\5\u00edt\2\u04d0\u00ea\3\2\2\2"+ - "\u04d1\u04d2\t\r\2\2\u04d2\u00ec\3\2\2\2\u04d3\u04d5\5\u00efu\2\u04d4"+ - "\u04d3\3\2\2\2\u04d4\u04d5\3\2\2\2\u04d5\u04d6\3\2\2\2\u04d6\u04d7\5\u00c1"+ - "^\2\u04d7\u00ee\3\2\2\2\u04d8\u04d9\t\16\2\2\u04d9\u00f0\3\2\2\2\u04da"+ - "\u04db\t\17\2\2\u04db\u00f2\3\2\2\2\u04dc\u04dd\5\u00f5x\2\u04dd\u04df"+ - "\5\u00f7y\2\u04de\u04e0\5\u00f1v\2\u04df\u04de\3\2\2\2\u04df\u04e0\3\2"+ - "\2\2\u04e0\u00f4\3\2\2\2\u04e1\u04e3\5\u00cdd\2\u04e2\u04e4\5\u00fb{\2"+ - "\u04e3\u04e2\3\2\2\2\u04e3\u04e4\3\2\2\2\u04e4\u04ee\3\2\2\2\u04e5\u04e6"+ - "\5\u00b3W\2\u04e6\u04e8\t\b\2\2\u04e7\u04e9\5\u00cfe\2\u04e8\u04e7\3\2"+ - "\2\2\u04e8\u04e9\3\2\2\2\u04e9\u04ea\3\2\2\2\u04ea\u04eb\5\u00fb{\2\u04eb"+ - "\u04ec\5\u00cfe\2\u04ec\u04ee\3\2\2\2\u04ed\u04e1\3\2\2\2\u04ed\u04e5"+ - "\3\2\2\2\u04ee\u00f6\3\2\2\2\u04ef\u04f0\5\u00f9z\2\u04f0\u04f1\5\u00ed"+ - "t\2\u04f1\u00f8\3\2\2\2\u04f2\u04f3\t\20\2\2\u04f3\u00fa\3\2\2\2\u04f4"+ - "\u04f5\7\60\2\2\u04f5\u00fc\3\2\2\2\u04f6\u04f7\7v\2\2\u04f7\u04f8\7t"+ - "\2\2\u04f8\u04f9\7w\2\2\u04f9\u0500\7g\2\2\u04fa\u04fb\7h\2\2\u04fb\u04fc"+ - "\7c\2\2\u04fc\u04fd\7n\2\2\u04fd\u04fe\7u\2\2\u04fe\u0500\7g\2\2\u04ff"+ - "\u04f6\3\2\2\2\u04ff\u04fa\3\2\2\2\u0500\u00fe\3\2\2\2\u0501\u0502\5\u010d"+ - "\u0084\2\u0502\u0503\t\21\2\2\u0503\u0509\3\2\2\2\u0504\u0509\5\u0101"+ - "~\2\u0505\u0509\5\u0103\177\2\u0506\u0509\5\u0107\u0081\2\u0507\u0509"+ - "\5\u0109\u0082\2\u0508\u0501\3\2\2\2\u0508\u0504\3\2\2\2\u0508\u0505\3"+ - "\2\2\2\u0508\u0506\3\2\2\2\u0508\u0507\3\2\2\2\u0509\u0100\3\2\2\2\u050a"+ - "\u050b\5\u010d\u0084\2\u050b\u050c\5\u00d9j\2\u050c\u0517\3\2\2\2\u050d"+ - "\u050e\5\u010d\u0084\2\u050e\u050f\5\u00d9j\2\u050f\u0510\5\u00d9j\2\u0510"+ - "\u0517\3\2\2\2\u0511\u0512\5\u010d\u0084\2\u0512\u0513\5\u0105\u0080\2"+ - "\u0513\u0514\5\u00d9j\2\u0514\u0515\5\u00d9j\2\u0515\u0517\3\2\2\2\u0516"+ - "\u050a\3\2\2\2\u0516\u050d\3\2\2\2\u0516\u0511\3\2\2\2\u0517\u0102\3\2"+ - "\2\2\u0518\u0519\5\u010d\u0084\2\u0519\u051a\7w\2\2\u051a\u051b\5\u00d1"+ - "f\2\u051b\u051c\5\u00d1f\2\u051c\u051d\5\u00d1f\2\u051d\u051e\5\u00d1"+ - "f\2\u051e\u0104\3\2\2\2\u051f\u0520\t\22\2\2\u0520\u0106\3\2\2\2\u0521"+ - "\u0522\5\u010d\u0084\2\u0522\u0523\5\u0111\u0086\2\u0523\u0108\3\2\2\2"+ - "\u0524\u0526\5\u010d\u0084\2\u0525\u0527\7\17\2\2\u0526\u0525\3\2\2\2"+ - "\u0526\u0527\3\2\2\2\u0527\u0528\3\2\2\2\u0528\u0529\7\f\2\2\u0529\u010a"+ - "\3\2\2\2\u052a\u052b\5\u010d\u0084\2\u052b\u052c\5\u010f\u0085\2\u052c"+ - "\u010c\3\2\2\2\u052d\u052e\7^\2\2\u052e\u010e\3\2\2\2\u052f\u0530\7\61"+ - "\2\2\u0530\u0110\3\2\2\2\u0531\u0532\7&\2\2\u0532\u0112\3\2\2\2\u0533"+ - "\u0534\7$\2\2\u0534\u0114\3\2\2\2\u0535\u0536\7)\2\2\u0536\u0116\3\2\2"+ - "\2\u0537\u0538\7$\2\2\u0538\u0539\7$\2\2\u0539\u053a\7$\2\2\u053a\u0118"+ - "\3\2\2\2\u053b\u053c\7)\2\2\u053c\u053d\7)\2\2\u053d\u053e\7)\2\2\u053e"+ - "\u011a\3\2\2\2\u053f\u0540\7&\2\2\u0540\u0541\7\61\2\2\u0541\u011c\3\2"+ - "\2\2\u0542\u0543\7\61\2\2\u0543\u0544\7&\2\2\u0544\u011e\3\2\2\2\u0545"+ - "\u0546\7&\2\2\u0546\u0547\7\61\2\2\u0547\u0548\7&\2\2\u0548\u0120\3\2"+ - "\2\2\u0549\u054a\7&\2\2\u054a\u054b\7&\2\2\u054b\u0122\3\2\2\2\u054c\u054d"+ - "\7p\2\2\u054d\u054e\7w\2\2\u054e\u054f\7n\2\2\u054f\u0550\7n\2\2\u0550"+ - "\u0124\3\2\2\2\u0551\u0552\7\60\2\2\u0552\u0553\7\60\2\2\u0553\u0126\3"+ - "\2\2\2\u0554\u0555\7\60\2\2\u0555\u0556\7\60\2\2\u0556\u0557\7>\2\2\u0557"+ - "\u0128\3\2\2\2\u0558\u0559\7,\2\2\u0559\u055a\7\60\2\2\u055a\u012a\3\2"+ - "\2\2\u055b\u055c\7A\2\2\u055c\u055d\7\60\2\2\u055d\u012c\3\2\2\2\u055e"+ - "\u055f\7A\2\2\u055f\u0560\7A\2\2\u0560\u0561\7\60\2\2\u0561\u012e\3\2"+ - "\2\2\u0562\u0563\7A\2\2\u0563\u0564\7<\2\2\u0564\u0130\3\2\2\2\u0565\u0566"+ - "\7\60\2\2\u0566\u0567\7(\2\2\u0567\u0132\3\2\2\2\u0568\u0569\7<\2\2\u0569"+ - "\u056a\7<\2\2\u056a\u0134\3\2\2\2\u056b\u056c\7?\2\2\u056c\u056d\7\u0080"+ - "\2\2\u056d\u0136\3\2\2\2\u056e\u056f\7?\2\2\u056f\u0570\7?\2\2\u0570\u0571"+ - "\7\u0080\2\2\u0571\u0138\3\2\2\2\u0572\u0573\7,\2\2\u0573\u0574\7,\2\2"+ - "\u0574\u013a\3\2\2\2\u0575\u0576\7,\2\2\u0576\u0577\7,\2\2\u0577\u0578"+ - "\7?\2\2\u0578\u013c\3\2\2\2\u0579\u057a\7>\2\2\u057a\u057b\7?\2\2\u057b"+ - "\u057c\7@\2\2\u057c\u013e\3\2\2\2\u057d\u057e\7?\2\2\u057e\u057f\7?\2"+ - "\2\u057f\u0580\7?\2\2\u0580\u0140\3\2\2\2\u0581\u0582\7#\2\2\u0582\u0583"+ - "\7?\2\2\u0583\u0584\7?\2\2\u0584\u0142\3\2\2\2\u0585\u0586\7/\2\2\u0586"+ - "\u0587\7@\2\2\u0587\u0144\3\2\2\2\u0588\u0589\7#\2\2\u0589\u058a\7k\2"+ - "\2\u058a\u058b\7p\2\2\u058b\u058c\7u\2\2\u058c\u058d\7v\2\2\u058d\u058e"+ - "\7c\2\2\u058e\u058f\7p\2\2\u058f\u0590\7e\2\2\u0590\u0591\7g\2\2\u0591"+ - "\u0592\7q\2\2\u0592\u0593\7h\2\2\u0593\u0594\3\2\2\2\u0594\u0595\6\u00a0"+ - "\r\2\u0595\u0146\3\2\2\2\u0596\u0597\7#\2\2\u0597\u0598\7k\2\2\u0598\u0599"+ - "\7p\2\2\u0599\u059a\3\2\2\2\u059a\u059b\6\u00a1\16\2\u059b\u0148\3\2\2"+ - "\2\u059c\u059d\7*\2\2\u059d\u059e\b\u00a2\26\2\u059e\u059f\3\2\2\2\u059f"+ - "\u05a0\b\u00a2\16\2\u05a0\u014a\3\2\2\2\u05a1\u05a2\7+\2\2\u05a2\u05a3"+ - "\b\u00a3\27\2\u05a3\u05a4\3\2\2\2\u05a4\u05a5\b\u00a3\b\2\u05a5\u014c"+ - "\3\2\2\2\u05a6\u05a7\7}\2\2\u05a7\u05a8\b\u00a4\30\2\u05a8\u05a9\3\2\2"+ - "\2\u05a9\u05aa\b\u00a4\16\2\u05aa\u014e\3\2\2\2\u05ab\u05ac\7\177\2\2"+ - "\u05ac\u05ad\b\u00a5\31\2\u05ad\u05ae\3\2\2\2\u05ae\u05af\b\u00a5\b\2"+ - "\u05af\u0150\3\2\2\2\u05b0\u05b1\7]\2\2\u05b1\u05b2\b\u00a6\32\2\u05b2"+ - "\u05b3\3\2\2\2\u05b3\u05b4\b\u00a6\16\2\u05b4\u0152\3\2\2\2\u05b5\u05b6"+ - "\7_\2\2\u05b6\u05b7\b\u00a7\33\2\u05b7\u05b8\3\2\2\2\u05b8\u05b9\b\u00a7"+ - "\b\2\u05b9\u0154\3\2\2\2\u05ba\u05bb\7=\2\2\u05bb\u0156\3\2\2\2\u05bc"+ - "\u05bd\7.\2\2\u05bd\u0158\3\2\2\2\u05be\u05bf\5\u00fb{\2\u05bf\u015a\3"+ - "\2\2\2\u05c0\u05c1\7?\2\2\u05c1\u015c\3\2\2\2\u05c2\u05c3\7@\2\2\u05c3"+ - "\u015e\3\2\2\2\u05c4\u05c5\7>\2\2\u05c5\u0160\3\2\2\2\u05c6\u05c7\7#\2"+ - "\2\u05c7\u0162\3\2\2\2\u05c8\u05c9\7\u0080\2\2\u05c9\u0164\3\2\2\2\u05ca"+ - "\u05cb\7A\2\2\u05cb\u0166\3\2\2\2\u05cc\u05cd\7<\2\2\u05cd\u0168\3\2\2"+ - "\2\u05ce\u05cf\7?\2\2\u05cf\u05d0\7?\2\2\u05d0\u016a\3\2\2\2\u05d1\u05d2"+ - "\7>\2\2\u05d2\u05d3\7?\2\2\u05d3\u016c\3\2\2\2\u05d4\u05d5\7@\2\2\u05d5"+ - "\u05d6\7?\2\2\u05d6\u016e\3\2\2\2\u05d7\u05d8\7#\2\2\u05d8\u05d9\7?\2"+ - "\2\u05d9\u0170\3\2\2\2\u05da\u05db\7(\2\2\u05db\u05dc\7(\2\2\u05dc\u0172"+ - "\3\2\2\2\u05dd\u05de\7~\2\2\u05de\u05df\7~\2\2\u05df\u0174\3\2\2\2\u05e0"+ - "\u05e1\7-\2\2\u05e1\u05e2\7-\2\2\u05e2\u0176\3\2\2\2\u05e3\u05e4\7/\2"+ - "\2\u05e4\u05e5\7/\2\2\u05e5\u0178\3\2\2\2\u05e6\u05e7\7-\2\2\u05e7\u017a"+ - "\3\2\2\2\u05e8\u05e9\7/\2\2\u05e9\u017c\3\2\2\2\u05ea\u05eb\7,\2\2\u05eb"+ - "\u017e\3\2\2\2\u05ec\u05ed\5\u010f\u0085\2\u05ed\u0180\3\2\2\2\u05ee\u05ef"+ - "\7(\2\2\u05ef\u0182\3\2\2\2\u05f0\u05f1\7~\2\2\u05f1\u0184\3\2\2\2\u05f2"+ - "\u05f3\7`\2\2\u05f3\u0186\3\2\2\2\u05f4\u05f5\7\'\2\2\u05f5\u0188\3\2"+ - "\2\2\u05f6\u05f7\7-\2\2\u05f7\u05f8\7?\2\2\u05f8\u018a\3\2\2\2\u05f9\u05fa"+ - "\7/\2\2\u05fa\u05fb\7?\2\2\u05fb\u018c\3\2\2\2\u05fc\u05fd\7,\2\2\u05fd"+ - "\u05fe\7?\2\2\u05fe\u018e\3\2\2\2\u05ff\u0600\7\61\2\2\u0600\u0601\7?"+ - "\2\2\u0601\u0190\3\2\2\2\u0602\u0603\7(\2\2\u0603\u0604\7?\2\2\u0604\u0192"+ - "\3\2\2\2\u0605\u0606\7~\2\2\u0606\u0607\7?\2\2\u0607\u0194\3\2\2\2\u0608"+ - "\u0609\7`\2\2\u0609\u060a\7?\2\2\u060a\u0196\3\2\2\2\u060b\u060c\7\'\2"+ - "\2\u060c\u060d\7?\2\2\u060d\u0198\3\2\2\2\u060e\u060f\7>\2\2\u060f\u0610"+ - "\7>\2\2\u0610\u0611\7?\2\2\u0611\u019a\3\2\2\2\u0612\u0613\7@\2\2\u0613"+ - "\u0614\7@\2\2\u0614\u0615\7?\2\2\u0615\u019c\3\2\2\2\u0616\u0617\7@\2"+ - "\2\u0617\u0618\7@\2\2\u0618\u0619\7@\2\2\u0619\u061a\7?\2\2\u061a\u019e"+ - "\3\2\2\2\u061b\u061c\7A\2\2\u061c\u061d\7?\2\2\u061d\u01a0\3\2\2\2\u061e"+ - "\u0622\t\23\2\2\u061f\u0621\5\u01ad\u00d4\2\u0620\u061f\3\2\2\2\u0621"+ - "\u0624\3\2\2\2\u0622\u0620\3\2\2\2\u0622\u0623\3\2\2\2\u0623\u01a2\3\2"+ - "\2\2\u0624\u0622\3\2\2\2\u0625\u0629\5\u01ab\u00d3\2\u0626\u0628\5\u01ad"+ - "\u00d4\2\u0627\u0626\3\2\2\2\u0628\u062b\3\2\2\2\u0629\u0627\3\2\2\2\u0629"+ - "\u062a\3\2\2\2\u062a\u01a4\3\2\2\2\u062b\u0629\3\2\2\2\u062c\u0630\5\u01a7"+ - "\u00d1\2\u062d\u062f\5\u01a9\u00d2\2\u062e\u062d\3\2\2\2\u062f\u0632\3"+ - "\2\2\2\u0630\u062e\3\2\2\2\u0630\u0631\3\2\2\2\u0631\u01a6\3\2\2\2\u0632"+ - "\u0630\3\2\2\2\u0633\u063a\t\24\2\2\u0634\u0635\n\25\2\2\u0635\u063a\6"+ - "\u00d1\17\2\u0636\u0637\t\26\2\2\u0637\u0638\t\27\2\2\u0638\u063a\6\u00d1"+ - "\20\2\u0639\u0633\3\2\2\2\u0639\u0634\3\2\2\2\u0639\u0636\3\2\2\2\u063a"+ - "\u01a8\3\2\2\2\u063b\u0642\t\30\2\2\u063c\u063d\n\25\2\2\u063d\u0642\6"+ - "\u00d2\21\2\u063e\u063f\t\26\2\2\u063f\u0640\t\27\2\2\u0640\u0642\6\u00d2"+ - "\22\2\u0641\u063b\3\2\2\2\u0641\u063c\3\2\2\2\u0641\u063e\3\2\2\2\u0642"+ - "\u01aa\3\2\2\2\u0643\u064a\t\31\2\2\u0644\u0645\n\25\2\2\u0645\u064a\6"+ - "\u00d3\23\2\u0646\u0647\t\26\2\2\u0647\u0648\t\27\2\2\u0648\u064a\6\u00d3"+ - "\24\2\u0649\u0643\3\2\2\2\u0649\u0644\3\2\2\2\u0649\u0646\3\2\2\2\u064a"+ - "\u01ac\3\2\2\2\u064b\u0652\t\32\2\2\u064c\u064d\n\25\2\2\u064d\u0652\6"+ - "\u00d4\25\2\u064e\u064f\t\26\2\2\u064f\u0650\t\27\2\2\u0650\u0652\6\u00d4"+ - "\26\2\u0651\u064b\3\2\2\2\u0651\u064c\3\2\2\2\u0651\u064e\3\2\2\2\u0652"+ - "\u01ae\3\2\2\2\u0653\u0654\7B\2\2\u0654\u01b0\3\2\2\2\u0655\u0656\7\60"+ - "\2\2\u0656\u0657\7\60\2\2\u0657\u0658\7\60\2\2\u0658\u01b2\3\2\2\2\u0659"+ - "\u065b\t\33\2\2\u065a\u0659\3\2\2\2\u065b\u065c\3\2\2\2\u065c\u065a\3"+ - "\2\2\2\u065c\u065d\3\2\2\2\u065d\u0664\3\2\2\2\u065e\u0660\5\u0109\u0082"+ - "\2\u065f\u065e\3\2\2\2\u0660\u0661\3\2\2\2\u0661\u065f\3\2\2\2\u0661\u0662"+ - "\3\2\2\2\u0662\u0664\3\2\2\2\u0663\u065a\3\2\2\2\u0663\u065f\3\2\2\2\u0664"+ - "\u0665\3\2\2\2\u0665\u0666\b\u00d7\34\2\u0666\u01b4\3\2\2\2\u0667\u0669"+ - "\7\17\2\2\u0668\u0667\3\2\2\2\u0668\u0669\3\2\2\2\u0669\u066a\3\2\2\2"+ - "\u066a\u066b\7\f\2\2\u066b\u066c\b\u00d8\35\2\u066c\u01b6\3\2\2\2\u066d"+ - "\u066e\7\61\2\2\u066e\u066f\7,\2\2\u066f\u0673\3\2\2\2\u0670\u0672\13"+ - "\2\2\2\u0671\u0670\3\2\2\2\u0672\u0675\3\2\2\2\u0673\u0674\3\2\2\2\u0673"+ - "\u0671\3\2\2\2\u0674\u0676\3\2\2\2\u0675\u0673\3\2\2\2\u0676\u0677\7,"+ - "\2\2\u0677\u0678\7\61\2\2\u0678\u0679\3\2\2\2\u0679\u067a\b\u00d9\36\2"+ - "\u067a\u067b\3\2\2\2\u067b\u067c\b\u00d9\37\2\u067c\u01b8\3\2\2\2\u067d"+ - "\u067e\7\61\2\2\u067e\u067f\7\61\2\2\u067f\u0683\3\2\2\2\u0680\u0682\n"+ - "\34\2\2\u0681\u0680\3\2\2\2\u0682\u0685\3\2\2\2\u0683\u0681\3\2\2\2\u0683"+ - "\u0684\3\2\2\2\u0684\u0686\3\2\2\2\u0685\u0683\3\2\2\2\u0686\u0687\b\u00da"+ - " \2\u0687\u0688\3\2\2\2\u0688\u0689\b\u00da\37\2\u0689\u01ba\3\2\2\2\u068a"+ - "\u068b\7%\2\2\u068b\u068c\7#\2\2\u068c\u068d\3\2\2\2\u068d\u0691\b\u00db"+ - "!\2\u068e\u0690\n\34\2\2\u068f\u068e\3\2\2\2\u0690\u0693\3\2\2\2\u0691"+ - "\u068f\3\2\2\2\u0691\u0692\3\2\2\2\u0692\u0694\3\2\2\2\u0693\u0691\3\2"+ - "\2\2\u0694\u0695\b\u00db\34\2\u0695\u01bc\3\2\2\2\u0696\u0697\13\2\2\2"+ - "\u0697\u01be\3\2\2\2T\2\3\4\5\6\7\b\u01c3\u01cc\u01d6\u01de\u01e7\u01f0"+ - "\u01f4\u01fa\u0206\u0214\u0222\u0247\u027e\u0282\u0289\u0290\u0297\u02a3"+ - "\u02cc\u0425\u042a\u0431\u0435\u0437\u043d\u0441\u0445\u0449\u0450\u0455"+ - "\u0457\u045d\u0461\u0465\u046b\u0470\u047c\u0480\u0486\u048a\u0492\u0496"+ - "\u049c\u04a6\u04aa\u04b0\u04b4\u04b9\u04bf\u04c2\u04c7\u04cc\u04d4\u04df"+ - "\u04e3\u04e8\u04ed\u04ff\u0508\u0516\u0526\u0622\u0629\u0630\u0639\u0641"+ - "\u0649\u0651\u065c\u0661\u0663\u0668\u0673\u0683\u0691\"\7\3\2\7\7\2\t"+ - "\4\2\7\4\2\7\5\2\7\6\2\6\2\2\5\2\2\t\5\2\t\6\2\3\23\2\tR\2\7\2\2\t}\2"+ - "\7\b\2\3\26\3\3V\4\3V\5\3V\6\3p\7\3\u00a2\b\3\u00a3\t\3\u00a4\n\3\u00a5"+ - "\13\3\u00a6\f\3\u00a7\r\b\2\2\3\u00d8\16\3\u00d9\17\t\u0081\2\3\u00da"+ - "\20\3\u00db\21"; - public static final ATN _ATN = - new ATNDeserializer().deserialize(_serializedATN.toCharArray()); - static { - } -} \ No newline at end of file diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/CodeVisitorSupport.java b/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/CodeVisitorSupport.java deleted file mode 100644 index 3ae2fd1e8e..0000000000 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/CodeVisitorSupport.java +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.ast; - -import org.codehaus.groovy.ast.expr.ArgumentListExpression; -import org.codehaus.groovy.ast.expr.ArrayExpression; -import org.codehaus.groovy.ast.expr.AttributeExpression; -import org.codehaus.groovy.ast.expr.BinaryExpression; -import org.codehaus.groovy.ast.expr.BitwiseNegationExpression; -import org.codehaus.groovy.ast.expr.BooleanExpression; -import org.codehaus.groovy.ast.expr.CastExpression; -import org.codehaus.groovy.ast.expr.ClassExpression; -import org.codehaus.groovy.ast.expr.ClosureExpression; -import org.codehaus.groovy.ast.expr.ClosureListExpression; -import org.codehaus.groovy.ast.expr.ConstantExpression; -import org.codehaus.groovy.ast.expr.ConstructorCallExpression; -import org.codehaus.groovy.ast.expr.DeclarationExpression; -import org.codehaus.groovy.ast.expr.ElvisOperatorExpression; -import org.codehaus.groovy.ast.expr.Expression; -import org.codehaus.groovy.ast.expr.FieldExpression; -import org.codehaus.groovy.ast.expr.GStringExpression; -import org.codehaus.groovy.ast.expr.LambdaExpression; -import org.codehaus.groovy.ast.expr.ListExpression; -import org.codehaus.groovy.ast.expr.MapEntryExpression; -import org.codehaus.groovy.ast.expr.MapExpression; -import org.codehaus.groovy.ast.expr.MethodCallExpression; -import org.codehaus.groovy.ast.expr.MethodPointerExpression; -import org.codehaus.groovy.ast.expr.NotExpression; -import org.codehaus.groovy.ast.expr.PostfixExpression; -import org.codehaus.groovy.ast.expr.PrefixExpression; -import org.codehaus.groovy.ast.expr.PropertyExpression; -import org.codehaus.groovy.ast.expr.RangeExpression; -import org.codehaus.groovy.ast.expr.SpreadExpression; -import org.codehaus.groovy.ast.expr.SpreadMapExpression; -import org.codehaus.groovy.ast.expr.StaticMethodCallExpression; -import org.codehaus.groovy.ast.expr.TernaryExpression; -import org.codehaus.groovy.ast.expr.TupleExpression; -import org.codehaus.groovy.ast.expr.UnaryMinusExpression; -import org.codehaus.groovy.ast.expr.UnaryPlusExpression; -import org.codehaus.groovy.ast.expr.VariableExpression; -import org.codehaus.groovy.ast.stmt.AssertStatement; -import org.codehaus.groovy.ast.stmt.BlockStatement; -import org.codehaus.groovy.ast.stmt.BreakStatement; -import org.codehaus.groovy.ast.stmt.CaseStatement; -import org.codehaus.groovy.ast.stmt.CatchStatement; -import org.codehaus.groovy.ast.stmt.ContinueStatement; -import org.codehaus.groovy.ast.stmt.DoWhileStatement; -import org.codehaus.groovy.ast.stmt.EmptyStatement; -import org.codehaus.groovy.ast.stmt.ExpressionStatement; -import org.codehaus.groovy.ast.stmt.ForStatement; -import org.codehaus.groovy.ast.stmt.IfStatement; -import org.codehaus.groovy.ast.stmt.ReturnStatement; -import org.codehaus.groovy.ast.stmt.Statement; -import org.codehaus.groovy.ast.stmt.SwitchStatement; -import org.codehaus.groovy.ast.stmt.SynchronizedStatement; -import org.codehaus.groovy.ast.stmt.ThrowStatement; -import org.codehaus.groovy.ast.stmt.TryCatchStatement; -import org.codehaus.groovy.ast.stmt.WhileStatement; -import org.codehaus.groovy.classgen.BytecodeExpression; - -import java.util.List; - -/** - * Abstract base class for any GroovyCodeVisitor which by default - * just walks the code and expression tree - * - * @author James Strachan - */ -public abstract class CodeVisitorSupport implements GroovyCodeVisitor { - - public void visitBlockStatement(BlockStatement block) { - for (Statement statement : block.getStatements()) { - statement.visit(this); - } - } - - public void visitForLoop(ForStatement forLoop) { - forLoop.getCollectionExpression().visit(this); - forLoop.getLoopBlock().visit(this); - } - - public void visitWhileLoop(WhileStatement loop) { - loop.getBooleanExpression().visit(this); - loop.getLoopBlock().visit(this); - } - - public void visitDoWhileLoop(DoWhileStatement loop) { - loop.getLoopBlock().visit(this); - loop.getBooleanExpression().visit(this); - } - - public void visitIfElse(IfStatement ifElse) { - ifElse.getBooleanExpression().visit(this); - ifElse.getIfBlock().visit(this); - - Statement elseBlock = ifElse.getElseBlock(); - if (elseBlock instanceof EmptyStatement) { - // dispatching to EmptyStatement will not call back visitor, - // must call our visitEmptyStatement explicitly - visitEmptyStatement((EmptyStatement) elseBlock); - } else { - elseBlock.visit(this); - } - } - - public void visitExpressionStatement(ExpressionStatement statement) { - statement.getExpression().visit(this); - } - - public void visitReturnStatement(ReturnStatement statement) { - statement.getExpression().visit(this); - } - - public void visitAssertStatement(AssertStatement statement) { - statement.getBooleanExpression().visit(this); - statement.getMessageExpression().visit(this); - } - - public void visitTryCatchFinally(TryCatchStatement statement) { - statement.getTryStatement().visit(this); - for (CatchStatement catchStatement : statement.getCatchStatements()) { - catchStatement.visit(this); - } - Statement finallyStatement = statement.getFinallyStatement(); - if (finallyStatement instanceof EmptyStatement) { - // dispatching to EmptyStatement will not call back visitor, - // must call our visitEmptyStatement explicitly - visitEmptyStatement((EmptyStatement) finallyStatement); - } else { - finallyStatement.visit(this); - } - } - - protected void visitEmptyStatement(EmptyStatement statement) { - // noop - } - - public void visitSwitch(SwitchStatement statement) { - statement.getExpression().visit(this); - for (CaseStatement caseStatement : statement.getCaseStatements()) { - caseStatement.visit(this); - } - statement.getDefaultStatement().visit(this); - } - - public void visitCaseStatement(CaseStatement statement) { - statement.getExpression().visit(this); - statement.getCode().visit(this); - } - - public void visitBreakStatement(BreakStatement statement) { - } - - public void visitContinueStatement(ContinueStatement statement) { - } - - public void visitSynchronizedStatement(SynchronizedStatement statement) { - statement.getExpression().visit(this); - statement.getCode().visit(this); - } - - public void visitThrowStatement(ThrowStatement statement) { - statement.getExpression().visit(this); - } - - public void visitMethodCallExpression(MethodCallExpression call) { - call.getObjectExpression().visit(this); - call.getMethod().visit(this); - call.getArguments().visit(this); - } - - public void visitStaticMethodCallExpression(StaticMethodCallExpression call) { - call.getArguments().visit(this); - } - - public void visitConstructorCallExpression(ConstructorCallExpression call) { - call.getArguments().visit(this); - } - - public void visitBinaryExpression(BinaryExpression expression) { - expression.getLeftExpression().visit(this); - expression.getRightExpression().visit(this); - } - - public void visitTernaryExpression(TernaryExpression expression) { - expression.getBooleanExpression().visit(this); - expression.getTrueExpression().visit(this); - expression.getFalseExpression().visit(this); - } - - public void visitShortTernaryExpression(ElvisOperatorExpression expression) { - visitTernaryExpression(expression); - } - - public void visitPostfixExpression(PostfixExpression expression) { - expression.getExpression().visit(this); - } - - public void visitPrefixExpression(PrefixExpression expression) { - expression.getExpression().visit(this); - } - - public void visitBooleanExpression(BooleanExpression expression) { - expression.getExpression().visit(this); - } - - public void visitNotExpression(NotExpression expression) { - expression.getExpression().visit(this); - } - - public void visitClosureExpression(ClosureExpression expression) { - expression.getCode().visit(this); - } - - public void visitLambdaExpression(LambdaExpression expression) { - visitClosureExpression(expression); - } - - public void visitTupleExpression(TupleExpression expression) { - visitListOfExpressions(expression.getExpressions()); - } - - public void visitListExpression(ListExpression expression) { - visitListOfExpressions(expression.getExpressions()); - } - - public void visitArrayExpression(ArrayExpression expression) { - visitListOfExpressions(expression.getExpressions()); - visitListOfExpressions(expression.getSizeExpression()); - } - - public void visitMapExpression(MapExpression expression) { - visitListOfExpressions(expression.getMapEntryExpressions()); - - } - - public void visitMapEntryExpression(MapEntryExpression expression) { - expression.getKeyExpression().visit(this); - expression.getValueExpression().visit(this); - - } - - public void visitRangeExpression(RangeExpression expression) { - expression.getFrom().visit(this); - expression.getTo().visit(this); - } - - public void visitSpreadExpression(SpreadExpression expression) { - expression.getExpression().visit(this); - } - - public void visitSpreadMapExpression(SpreadMapExpression expression) { - expression.getExpression().visit(this); - } - - public void visitMethodPointerExpression(MethodPointerExpression expression) { - expression.getExpression().visit(this); - expression.getMethodName().visit(this); - } - - public void visitUnaryMinusExpression(UnaryMinusExpression expression) { - expression.getExpression().visit(this); - } - - public void visitUnaryPlusExpression(UnaryPlusExpression expression) { - expression.getExpression().visit(this); - } - - public void visitBitwiseNegationExpression(BitwiseNegationExpression expression) { - expression.getExpression().visit(this); - } - - public void visitCastExpression(CastExpression expression) { - expression.getExpression().visit(this); - } - - public void visitConstantExpression(ConstantExpression expression) { - } - - public void visitClassExpression(ClassExpression expression) { - } - - public void visitVariableExpression(VariableExpression expression) { - } - - public void visitDeclarationExpression(DeclarationExpression expression) { - visitBinaryExpression(expression); - } - - public void visitPropertyExpression(PropertyExpression expression) { - expression.getObjectExpression().visit(this); - expression.getProperty().visit(this); - } - - public void visitAttributeExpression(AttributeExpression expression) { - expression.getObjectExpression().visit(this); - expression.getProperty().visit(this); - } - - public void visitFieldExpression(FieldExpression expression) { - } - - public void visitGStringExpression(GStringExpression expression) { - visitListOfExpressions(expression.getStrings()); - visitListOfExpressions(expression.getValues()); - } - - protected void visitListOfExpressions(List list) { - if (list == null) return; - for (Expression expression : list) { - // GRECLIPSE edit - //if (expression instanceof SpreadExpression) { - // Expression spread = ((SpreadExpression) expression).getExpression(); - // spread.visit(this); - //} else { - expression.visit(this); - //} - // GRECLIPSE end - } - } - - public void visitCatchStatement(CatchStatement statement) { - statement.getCode().visit(this); - } - - public void visitArgumentlistExpression(ArgumentListExpression ale) { - visitTupleExpression(ale); - } - - public void visitClosureListExpression(ClosureListExpression cle) { - visitListOfExpressions(cle.getExpressions()); - } - - public void visitBytecodeExpression(BytecodeExpression cle) { - } -} diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java deleted file mode 100644 index 056f9d7b83..0000000000 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java +++ /dev/null @@ -1,2497 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.transform.stc; - -import org.codehaus.groovy.GroovyBugError; -import org.codehaus.groovy.ast.ClassHelper; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.GenericsType; -import org.codehaus.groovy.ast.MethodNode; -import org.codehaus.groovy.ast.Parameter; -import org.codehaus.groovy.ast.Variable; -import org.codehaus.groovy.ast.expr.ArgumentListExpression; -import org.codehaus.groovy.ast.expr.ArrayExpression; -import org.codehaus.groovy.ast.expr.BinaryExpression; -import org.codehaus.groovy.ast.expr.ClosureExpression; -import org.codehaus.groovy.ast.expr.ConstantExpression; -import org.codehaus.groovy.ast.expr.Expression; -import org.codehaus.groovy.ast.expr.ListExpression; -import org.codehaus.groovy.ast.expr.MapExpression; -import org.codehaus.groovy.ast.expr.VariableExpression; -import org.codehaus.groovy.ast.stmt.ReturnStatement; -import org.codehaus.groovy.ast.tools.GenericsUtils; -import org.codehaus.groovy.ast.tools.ParameterUtils; -import org.codehaus.groovy.ast.tools.WideningCategories; -import org.codehaus.groovy.control.CompilationUnit; -import org.codehaus.groovy.control.CompilerConfiguration; -import org.codehaus.groovy.control.Phases; -import org.codehaus.groovy.runtime.DefaultGroovyMethods; -import org.codehaus.groovy.runtime.DefaultGroovyStaticMethods; -import org.codehaus.groovy.runtime.m12n.ExtensionModule; -import org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner; -import org.codehaus.groovy.runtime.m12n.MetaInfExtensionModule; -import org.codehaus.groovy.runtime.memoize.ConcurrentCommonCache; -import org.codehaus.groovy.runtime.memoize.EvictableCache; -import org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl; -import org.codehaus.groovy.tools.GroovyClass; -import org.codehaus.groovy.transform.trait.Traits; -import org.codehaus.groovy.vmplugin.VMPluginFactory; -import groovyjarjarasm.asm.Opcodes; - -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.TreeSet; -import java.util.UUID; -import java.util.WeakHashMap; -import java.util.regex.Matcher; - -import static java.lang.Math.min; -import static org.codehaus.groovy.ast.ClassHelper.BigDecimal_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.BigInteger_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.Boolean_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.Byte_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.CLASS_Type; -import static org.codehaus.groovy.ast.ClassHelper.CLOSURE_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.Character_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.Double_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.Enum_Type; -import static org.codehaus.groovy.ast.ClassHelper.Float_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.GROOVY_OBJECT_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.GSTRING_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.Integer_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.Long_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.OBJECT_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.STRING_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.Short_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.VOID_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.boolean_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.byte_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.char_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.double_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.float_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.getUnwrapper; -import static org.codehaus.groovy.ast.ClassHelper.getWrapper; -import static org.codehaus.groovy.ast.ClassHelper.int_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.isNumberType; -import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveType; -import static org.codehaus.groovy.ast.ClassHelper.isSAMType; -import static org.codehaus.groovy.ast.ClassHelper.long_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.make; -import static org.codehaus.groovy.ast.ClassHelper.makeWithoutCaching; -import static org.codehaus.groovy.ast.ClassHelper.short_TYPE; -import static org.codehaus.groovy.ast.ClassHelper.void_WRAPPER_TYPE; -import static org.codehaus.groovy.ast.tools.GenericsUtils.getSuperClass; -import static org.codehaus.groovy.syntax.Types.ASSIGN; -import static org.codehaus.groovy.syntax.Types.BITWISE_AND; -import static org.codehaus.groovy.syntax.Types.BITWISE_AND_EQUAL; -import static org.codehaus.groovy.syntax.Types.BITWISE_OR; -import static org.codehaus.groovy.syntax.Types.BITWISE_OR_EQUAL; -import static org.codehaus.groovy.syntax.Types.BITWISE_XOR; -import static org.codehaus.groovy.syntax.Types.BITWISE_XOR_EQUAL; -import static org.codehaus.groovy.syntax.Types.COMPARE_EQUAL; -import static org.codehaus.groovy.syntax.Types.COMPARE_GREATER_THAN; -import static org.codehaus.groovy.syntax.Types.COMPARE_GREATER_THAN_EQUAL; -import static org.codehaus.groovy.syntax.Types.COMPARE_IDENTICAL; -import static org.codehaus.groovy.syntax.Types.COMPARE_LESS_THAN; -import static org.codehaus.groovy.syntax.Types.COMPARE_LESS_THAN_EQUAL; -import static org.codehaus.groovy.syntax.Types.COMPARE_NOT_EQUAL; -import static org.codehaus.groovy.syntax.Types.COMPARE_NOT_IDENTICAL; -import static org.codehaus.groovy.syntax.Types.COMPARE_NOT_IN; -import static org.codehaus.groovy.syntax.Types.COMPARE_NOT_INSTANCEOF; -import static org.codehaus.groovy.syntax.Types.COMPARE_TO; -import static org.codehaus.groovy.syntax.Types.DIVIDE; -import static org.codehaus.groovy.syntax.Types.DIVIDE_EQUAL; -import static org.codehaus.groovy.syntax.Types.INTDIV; -import static org.codehaus.groovy.syntax.Types.INTDIV_EQUAL; -import static org.codehaus.groovy.syntax.Types.KEYWORD_IN; -import static org.codehaus.groovy.syntax.Types.KEYWORD_INSTANCEOF; -import static org.codehaus.groovy.syntax.Types.LEFT_SHIFT; -import static org.codehaus.groovy.syntax.Types.LEFT_SHIFT_EQUAL; -import static org.codehaus.groovy.syntax.Types.LEFT_SQUARE_BRACKET; -import static org.codehaus.groovy.syntax.Types.LOGICAL_AND; -import static org.codehaus.groovy.syntax.Types.LOGICAL_AND_EQUAL; -import static org.codehaus.groovy.syntax.Types.LOGICAL_OR; -import static org.codehaus.groovy.syntax.Types.LOGICAL_OR_EQUAL; -import static org.codehaus.groovy.syntax.Types.MATCH_REGEX; -import static org.codehaus.groovy.syntax.Types.MINUS; -import static org.codehaus.groovy.syntax.Types.MINUS_EQUAL; -import static org.codehaus.groovy.syntax.Types.MOD; -import static org.codehaus.groovy.syntax.Types.MOD_EQUAL; -import static org.codehaus.groovy.syntax.Types.MULTIPLY; -import static org.codehaus.groovy.syntax.Types.MULTIPLY_EQUAL; -import static org.codehaus.groovy.syntax.Types.PLUS; -import static org.codehaus.groovy.syntax.Types.PLUS_EQUAL; -import static org.codehaus.groovy.syntax.Types.POWER; -import static org.codehaus.groovy.syntax.Types.POWER_EQUAL; -import static org.codehaus.groovy.syntax.Types.RIGHT_SHIFT; -import static org.codehaus.groovy.syntax.Types.RIGHT_SHIFT_EQUAL; -import static org.codehaus.groovy.syntax.Types.RIGHT_SHIFT_UNSIGNED; -import static org.codehaus.groovy.syntax.Types.RIGHT_SHIFT_UNSIGNED_EQUAL; - -/** - * Static support methods for {@link StaticTypeCheckingVisitor}. - */ -public abstract class StaticTypeCheckingSupport { - protected static final ClassNode - Collection_TYPE = makeWithoutCaching(Collection.class); - protected static final ClassNode Deprecated_TYPE = makeWithoutCaching(Deprecated.class); - protected static final ClassNode Matcher_TYPE = makeWithoutCaching(Matcher.class); - protected static final ClassNode ArrayList_TYPE = makeWithoutCaching(ArrayList.class); - protected static final ExtensionMethodCache EXTENSION_METHOD_CACHE = new ExtensionMethodCache(); - protected static final Map NUMBER_TYPES = Collections.unmodifiableMap( - new HashMap() { - private static final long serialVersionUID = 8841951852732042766L; - - { - put(byte_TYPE, 0); - put(Byte_TYPE, 0); - put(short_TYPE, 1); - put(Short_TYPE, 1); - put(int_TYPE, 2); - put(Integer_TYPE, 2); - put(Long_TYPE, 3); - put(long_TYPE, 3); - put(float_TYPE, 4); - put(Float_TYPE, 4); - put(double_TYPE, 5); - put(Double_TYPE, 5); - } - }); - - protected static final Map NUMBER_OPS = Collections.unmodifiableMap( - new HashMap() { - private static final long serialVersionUID = 6951856193525808411L; - - { - put("plus", PLUS); - put("minus", MINUS); - put("multiply", MULTIPLY); - put("div", DIVIDE); - put("or", BITWISE_OR); - put("and", BITWISE_AND); - put("xor", BITWISE_XOR); - put("mod", MOD); - put("intdiv", INTDIV); - put("leftShift", LEFT_SHIFT); - put("rightShift", RIGHT_SHIFT); - put("rightShiftUnsigned", RIGHT_SHIFT_UNSIGNED); - } - }); - - protected static final ClassNode GSTRING_STRING_CLASSNODE = WideningCategories.lowestUpperBound( - STRING_TYPE, - GSTRING_TYPE - ); - - /** - * This is for internal use only. When an argument method is null, we cannot determine its type, so - * we use this one as a wildcard. - */ - protected static final ClassNode UNKNOWN_PARAMETER_TYPE = make(""); - - /** - * This comparator is used when we return the list of methods from DGM which name correspond to a given - * name. As we also lookup for DGM methods of superclasses or interfaces, it may be possible to find - * two methods which have the same name and the same arguments. In that case, we should not add the method - * from superclass or interface otherwise the system won't be able to select the correct method, resulting - * in an ambiguous method selection for similar methods. - */ - protected static final Comparator DGM_METHOD_NODE_COMPARATOR = new Comparator() { - public int compare(final MethodNode o1, final MethodNode o2) { - if (o1.getName().equals(o2.getName())) { - Parameter[] o1ps = o1.getParameters(); - Parameter[] o2ps = o2.getParameters(); - if (o1ps.length == o2ps.length) { - boolean allEqual = true; - for (int i = 0; i < o1ps.length && allEqual; i++) { - allEqual = o1ps[i].getType().equals(o2ps[i].getType()); - } - if (allEqual) { - if (o1 instanceof ExtensionMethodNode && o2 instanceof ExtensionMethodNode) { - return compare(((ExtensionMethodNode) o1).getExtensionMethodNode(), ((ExtensionMethodNode) o2).getExtensionMethodNode()); - } - return 0; - } - } else { - return o1ps.length - o2ps.length; - } - } - return 1; - } - }; - - /** - * Returns true for expressions of the form x[...] - * - * @param expression an expression - * @return true for array access expressions - */ - protected static boolean isArrayAccessExpression(Expression expression) { - return expression instanceof BinaryExpression && isArrayOp(((BinaryExpression) expression).getOperation().getType()); - } - - /** - * Called on method call checks in order to determine if a method call corresponds to the - * idiomatic o.with { ... } structure - * - * @param name name of the method called - * @param callArguments arguments of the method - * @return true if the name is "with" and arguments consist of a single closure - */ - public static boolean isWithCall(final String name, final Expression callArguments) { - boolean isWithCall = "with".equals(name) && callArguments instanceof ArgumentListExpression; - if (isWithCall) { - ArgumentListExpression argList = (ArgumentListExpression) callArguments; - List expressions = argList.getExpressions(); - isWithCall = expressions.size() == 1 && expressions.get(0) instanceof ClosureExpression; - } - return isWithCall; - } - - /** - * Given a variable expression, returns the ultimately accessed variable. - * - * @param ve a variable expression - * @return the target variable - */ - protected static Variable findTargetVariable(VariableExpression ve) { - final Variable accessedVariable = ve.getAccessedVariable() != null ? ve.getAccessedVariable() : ve; - if (accessedVariable != ve) { - if (accessedVariable instanceof VariableExpression) - return findTargetVariable((VariableExpression) accessedVariable); - } - return accessedVariable; - } - - - /** - * @deprecated Use {@link #findDGMMethodsForClassNode(ClassLoader, ClassNode, String)} instead - */ - @Deprecated - protected static Set findDGMMethodsForClassNode(ClassNode clazz, String name) { - return findDGMMethodsForClassNode(MetaClassRegistryImpl.class.getClassLoader(), clazz, name); - } - - protected static Set findDGMMethodsForClassNode(final ClassLoader loader, ClassNode clazz, String name) { - TreeSet accumulator = new TreeSet(DGM_METHOD_NODE_COMPARATOR); - findDGMMethodsForClassNode(loader, clazz, name, accumulator); - return accumulator; - } - - - /** - * @deprecated Use {@link #findDGMMethodsForClassNode(ClassLoader, ClassNode, String, TreeSet)} instead - */ - @Deprecated - protected static void findDGMMethodsForClassNode(ClassNode clazz, String name, TreeSet accumulator) { - findDGMMethodsForClassNode(MetaClassRegistryImpl.class.getClassLoader(), clazz, name, accumulator); - } - - protected static void findDGMMethodsForClassNode(final ClassLoader loader, ClassNode clazz, String name, TreeSet accumulator) { - List fromDGM = EXTENSION_METHOD_CACHE.getExtensionMethods(loader).get(clazz.getName()); - if (fromDGM != null) { - for (MethodNode node : fromDGM) { - if (node.getName().equals(name)) accumulator.add(node); - } - } - for (ClassNode node : clazz.getInterfaces()) { - findDGMMethodsForClassNode(loader, node, name, accumulator); - } - if (clazz.isArray()) { - ClassNode componentClass = clazz.getComponentType(); - if (!componentClass.equals(OBJECT_TYPE) && !isPrimitiveType(componentClass)) { - if (componentClass.isInterface()) { - findDGMMethodsForClassNode(loader, OBJECT_TYPE.makeArray(), name, accumulator); - } else { - findDGMMethodsForClassNode(loader, componentClass.getSuperClass().makeArray(), name, accumulator); - } - } - } - if (clazz.getSuperClass() != null) { - findDGMMethodsForClassNode(loader, clazz.getSuperClass(), name, accumulator); - } else if (!clazz.equals(OBJECT_TYPE)) { - findDGMMethodsForClassNode(loader, OBJECT_TYPE, name, accumulator); - } - } - - /** - * Checks that arguments and parameter types match. - * - * @param params method parameters - * @param args type arguments - * @return -1 if arguments do not match, 0 if arguments are of the exact type and >0 when one or more argument is - * not of the exact type but still match - */ - public static int allParametersAndArgumentsMatch(Parameter[] params, ClassNode[] args) { - if (params == null) { - params = Parameter.EMPTY_ARRAY; - } - int dist = 0; - if (args.length < params.length) return -1; - // we already know there are at least params.length elements in both arrays - for (int i = 0; i < params.length; i++) { - ClassNode paramType = params[i].getType(); - ClassNode argType = args[i]; - if (!isAssignableTo(argType, paramType)) return -1; - else { - if (!paramType.equals(argType)) dist += getDistance(argType, paramType); - } - } - return dist; - } - - /** - * Checks that arguments and parameter types match, expecting that the number of parameters is strictly greater - * than the number of arguments, allowing possible inclusion of default parameters. - * - * @param params method parameters - * @param args type arguments - * @return -1 if arguments do not match, 0 if arguments are of the exact type and >0 when one or more argument is - * not of the exact type but still match - */ - static int allParametersAndArgumentsMatchWithDefaultParams(Parameter[] params, ClassNode[] args) { - int dist = 0; - ClassNode ptype = null; - // we already know the lengths are equal - for (int i = 0, j = 0; i < params.length; i++) { - Parameter param = params[i]; - ClassNode paramType = param.getType(); - ClassNode arg = j >= args.length ? null : args[j]; - if (arg == null || !isAssignableTo(arg, paramType)) { - if (!param.hasInitialExpression() && (ptype == null || !ptype.equals(paramType))) { - return -1; // no default value - } - // a default value exists, we can skip this param - ptype = null; - } else { - j++; - if (!paramType.equals(arg)) dist += getDistance(arg, paramType); - if (param.hasInitialExpression()) { - ptype = arg; - } else { - ptype = null; - } - } - } - return dist; - } - - /** - * Checks that excess arguments match the vararg signature parameter. - * - * @param params - * @param args - * @return -1 if no match, 0 if all arguments matches the vararg type and >0 if one or more vararg argument is - * assignable to the vararg type, but still not an exact match - */ - static int excessArgumentsMatchesVargsParameter(Parameter[] params, ClassNode[] args) { - // we already know parameter length is bigger zero and last is a vargs - // the excess arguments are all put in an array for the vargs call - // so check against the component type - int dist = 0; - ClassNode vargsBase = params[params.length - 1].getType().getComponentType(); - for (int i = params.length; i < args.length; i++) { - if (!isAssignableTo(args[i], vargsBase)) return -1; - else dist += getClassDistance(vargsBase, args[i]); - } - return dist; - } - - /** - * Checks if the last argument matches the vararg type. - * - * @param params - * @param args - * @return -1 if no match, 0 if the last argument is exactly the vararg type and 1 if of an assignable type - */ - static int lastArgMatchesVarg(Parameter[] params, ClassNode... args) { - if (!isVargs(params)) return -1; - // case length ==0 handled already - // we have now two cases, - // the argument is wrapped in the vargs array or - // the argument is an array that can be used for the vargs part directly - // we test only the wrapping part, since the non wrapping is done already - ClassNode lastParamType = params[params.length - 1].getType(); - ClassNode ptype = lastParamType.getComponentType(); - ClassNode arg = args[args.length - 1]; - if (isNumberType(ptype) && isNumberType(arg) && !ptype.equals(arg)) return -1; - return isAssignableTo(arg, ptype) ? min(getDistance(arg, lastParamType), getDistance(arg, ptype)) : -1; - } - - /** - * Checks if a class node is assignable to another. This is used for example in - * assignment checks where you want to verify that the assignment is valid. - * - * @param type - * @param toBeAssignedTo - * @return true if the class node is assignable to the other class node, false otherwise - */ - static boolean isAssignableTo(ClassNode type, ClassNode toBeAssignedTo) { - if (UNKNOWN_PARAMETER_TYPE == type) return true; - if (type == toBeAssignedTo) return true; - if (toBeAssignedTo.redirect() == STRING_TYPE && type.redirect() == GSTRING_TYPE) { - return true; - } - if (isPrimitiveType(toBeAssignedTo)) toBeAssignedTo = getWrapper(toBeAssignedTo); - if (isPrimitiveType(type)) type = getWrapper(type); - if (NUMBER_TYPES.containsKey(type.redirect()) && NUMBER_TYPES.containsKey(toBeAssignedTo.redirect())) { - return NUMBER_TYPES.get(type.redirect()) <= NUMBER_TYPES.get(toBeAssignedTo.redirect()); - } - if (type.isArray() && toBeAssignedTo.isArray()) { - return isAssignableTo(type.getComponentType(), toBeAssignedTo.getComponentType()); - } - if (type.isDerivedFrom(GSTRING_TYPE) && STRING_TYPE.equals(toBeAssignedTo)) { - return true; - } - if (toBeAssignedTo.isDerivedFrom(GSTRING_TYPE) && STRING_TYPE.equals(type)) { - return true; - } - if (implementsInterfaceOrIsSubclassOf(type, toBeAssignedTo)) { - if (OBJECT_TYPE.equals(toBeAssignedTo)) return true; - if (toBeAssignedTo.isUsingGenerics()) { - // perform additional check on generics - // ? extends toBeAssignedTo - GenericsType gt = GenericsUtils.buildWildcardType(toBeAssignedTo); - return gt.isCompatibleWith(type); - } - return true; - } - - //SAM check - if (type.isDerivedFrom(CLOSURE_TYPE) && isSAMType(toBeAssignedTo)) { - return true; - } - - return false; - } - - static boolean isVargs(Parameter[] params) { - if (params.length == 0) return false; - if (params[params.length - 1].getType().isArray()) return true; - return false; - } - - public static boolean isCompareToBoolean(int op) { - return op == COMPARE_GREATER_THAN || - op == COMPARE_GREATER_THAN_EQUAL || - op == COMPARE_LESS_THAN || - op == COMPARE_LESS_THAN_EQUAL; - } - - static boolean isArrayOp(int op) { - return op == LEFT_SQUARE_BRACKET; - } - - static boolean isBoolIntrinsicOp(int op) { - return op == LOGICAL_AND || op == LOGICAL_OR || op == COMPARE_NOT_IDENTICAL || op == COMPARE_IDENTICAL || - op == MATCH_REGEX || op == KEYWORD_INSTANCEOF || op == COMPARE_NOT_INSTANCEOF; - } - - static boolean isPowerOperator(int op) { - return op == POWER || op == POWER_EQUAL; - } - - static String getOperationName(int op) { - switch (op) { - case COMPARE_EQUAL: - case COMPARE_NOT_EQUAL: - // this is only correct in this context here, normally - // we would have to compile against compareTo if available - // but since we don't compile here, this one is enough - return "equals"; - - case COMPARE_TO: - case COMPARE_GREATER_THAN: - case COMPARE_GREATER_THAN_EQUAL: - case COMPARE_LESS_THAN: - case COMPARE_LESS_THAN_EQUAL: - return "compareTo"; - - case BITWISE_AND: - case BITWISE_AND_EQUAL: - return "and"; - - case BITWISE_OR: - case BITWISE_OR_EQUAL: - return "or"; - - case BITWISE_XOR: - case BITWISE_XOR_EQUAL: - return "xor"; - - case PLUS: - case PLUS_EQUAL: - return "plus"; - - case MINUS: - case MINUS_EQUAL: - return "minus"; - - case MULTIPLY: - case MULTIPLY_EQUAL: - return "multiply"; - - case DIVIDE: - case DIVIDE_EQUAL: - return "div"; - - case INTDIV: - case INTDIV_EQUAL: - return "intdiv"; - - case MOD: - case MOD_EQUAL: - return "mod"; - - case POWER: - case POWER_EQUAL: - return "power"; - - case LEFT_SHIFT: - case LEFT_SHIFT_EQUAL: - return "leftShift"; - - case RIGHT_SHIFT: - case RIGHT_SHIFT_EQUAL: - return "rightShift"; - - case RIGHT_SHIFT_UNSIGNED: - case RIGHT_SHIFT_UNSIGNED_EQUAL: - return "rightShiftUnsigned"; - - case KEYWORD_IN: - return "isCase"; - - case COMPARE_NOT_IN: - return "isNotCase"; - - default: - return null; - } - } - - static boolean isShiftOperation(String name) { - return "leftShift".equals(name) || "rightShift".equals(name) || "rightShiftUnsigned".equals(name); - } - - /** - * Returns true for operations that are of the class, that given a common type class for left and right, the - * operation "left op right" will have a result in the same type class In Groovy on numbers that is +,-,* as well as - * their variants with equals. - */ - static boolean isOperationInGroup(int op) { - switch (op) { - case PLUS: - case PLUS_EQUAL: - case MINUS: - case MINUS_EQUAL: - case MULTIPLY: - case MULTIPLY_EQUAL: - return true; - default: - return false; - } - } - - static boolean isBitOperator(int op) { - switch (op) { - case BITWISE_OR_EQUAL: - case BITWISE_OR: - case BITWISE_AND_EQUAL: - case BITWISE_AND: - case BITWISE_XOR_EQUAL: - case BITWISE_XOR: - return true; - default: - return false; - } - } - - public static boolean isAssignment(int op) { - switch (op) { - case ASSIGN: - case LOGICAL_OR_EQUAL: - case LOGICAL_AND_EQUAL: - case PLUS_EQUAL: - case MINUS_EQUAL: - case MULTIPLY_EQUAL: - case DIVIDE_EQUAL: - case INTDIV_EQUAL: - case MOD_EQUAL: - case POWER_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 true; - default: - return false; - } - } - - /** - * Returns true or false depending on whether the right classnode can be assigned to the left classnode. This method - * should not add errors by itself: we let the caller decide what to do if an incompatible assignment is found. - * - * @param left the class to be assigned to - * @param right the assignee class - * @return false if types are incompatible - */ - public static boolean checkCompatibleAssignmentTypes(ClassNode left, ClassNode right) { - return checkCompatibleAssignmentTypes(left, right, null); - } - - public static boolean checkCompatibleAssignmentTypes(ClassNode left, ClassNode right, Expression rightExpression) { - return checkCompatibleAssignmentTypes(left, right, rightExpression, true); - } - - public static boolean checkCompatibleAssignmentTypes(ClassNode left, ClassNode right, Expression rightExpression, boolean allowConstructorCoercion) { - ClassNode leftRedirect = left.redirect(); - ClassNode rightRedirect = right.redirect(); - if (leftRedirect == rightRedirect) return true; - - if (leftRedirect.isArray() && rightRedirect.isArray()) { - return checkCompatibleAssignmentTypes(leftRedirect.getComponentType(), rightRedirect.getComponentType(), rightExpression, false); - } - - if (right == VOID_TYPE || right == void_WRAPPER_TYPE) { - return left == VOID_TYPE || left == void_WRAPPER_TYPE; - } - - if ((isNumberType(rightRedirect) || WideningCategories.isNumberCategory(rightRedirect))) { - if (BigDecimal_TYPE == leftRedirect) { - // any number can be assigned to a big decimal - return true; - } - if (BigInteger_TYPE == leftRedirect) { - return WideningCategories.isBigIntCategory(getUnwrapper(rightRedirect)) || - rightRedirect.isDerivedFrom(BigInteger_TYPE); - } - } - - // if rightExpression is null and leftExpression is not a primitive type, it's ok - boolean rightExpressionIsNull = rightExpression instanceof ConstantExpression && ((ConstantExpression) rightExpression).getValue() == null; - if (rightExpressionIsNull && !isPrimitiveType(left)) { - return true; - } - - // on an assignment everything that can be done by a GroovyCast is allowed - - // anything can be assigned to an Object, String, Boolean - // or Class typed variable - if (isWildcardLeftHandSide(leftRedirect) - && !(boolean_TYPE.equals(left) && rightExpressionIsNull)) return true; - - // char as left expression - if (leftRedirect == char_TYPE && rightRedirect == STRING_TYPE) { - if (rightExpression instanceof ConstantExpression) { - String value = rightExpression.getText(); - return value.length() == 1; - } - } - if (leftRedirect == Character_TYPE && (rightRedirect == STRING_TYPE || rightExpressionIsNull)) { - return rightExpressionIsNull || (rightExpression instanceof ConstantExpression && rightExpression.getText().length() == 1); - } - - // if left is Enum and right is String or GString we do valueOf - if (leftRedirect.isDerivedFrom(Enum_Type) && - (rightRedirect == GSTRING_TYPE || rightRedirect == STRING_TYPE)) { - return true; - } - - // if right is array, map or collection we try invoking the - // constructor - if (allowConstructorCoercion && isGroovyConstructorCompatible(rightExpression)) { - //TODO: in case of the array we could maybe make a partial check - if (leftRedirect.isArray() && rightRedirect.isArray()) { - return checkCompatibleAssignmentTypes(leftRedirect.getComponentType(), rightRedirect.getComponentType()); - } else if (rightRedirect.isArray() && !leftRedirect.isArray()) { - return false; - } - return true; - } - - // simple check on being subclass - if (right.isDerivedFrom(left) || (left.isInterface() && right.implementsInterface(left))) return true; - - // if left and right are primitives or numbers allow - if (isPrimitiveType(leftRedirect) && isPrimitiveType(rightRedirect)) return true; - if (isNumberType(leftRedirect) && isNumberType(rightRedirect)) return true; - - // left is a float/double and right is a BigDecimal - if (WideningCategories.isFloatingCategory(leftRedirect) && BigDecimal_TYPE.equals(rightRedirect)) { - return true; - } - - if (GROOVY_OBJECT_TYPE.equals(leftRedirect) && isBeingCompiled(right)) { - return true; - } - - if (left.isGenericsPlaceHolder()) { - // GROOVY-7307 - GenericsType[] genericsTypes = left.getGenericsTypes(); - if (genericsTypes != null && genericsTypes.length == 1) { - // should always be the case, but safe guard is better - return genericsTypes[0].isCompatibleWith(right); - } - } - - // GROOVY-7316 : it is an apparently legal thing to allow this. It's not type safe, - // but it is allowed... - return right.isGenericsPlaceHolder(); - } - - private static boolean isGroovyConstructorCompatible(final Expression rightExpression) { - return rightExpression instanceof ListExpression - || rightExpression instanceof MapExpression - || rightExpression instanceof ArrayExpression; - } - - /** - * Tells if a class is one of the "accept all" classes as the left hand side of an - * assignment. - * - * @param node the classnode to test - * @return true if it's an Object, String, boolean, Boolean or Class. - */ - public static boolean isWildcardLeftHandSide(final ClassNode node) { - if (OBJECT_TYPE.equals(node) || - STRING_TYPE.equals(node) || - boolean_TYPE.equals(node) || - Boolean_TYPE.equals(node) || - CLASS_Type.equals(node)) { - return true; - } - return false; - } - - public static boolean isBeingCompiled(ClassNode node) { - return node.getCompileUnit() != null; - } - - @Deprecated - static boolean checkPossibleLooseOfPrecision(ClassNode left, ClassNode right, Expression rightExpr) { - return checkPossibleLossOfPrecision(left, right, rightExpr); - } - - static boolean checkPossibleLossOfPrecision(ClassNode left, ClassNode right, Expression rightExpr) { - if (left == right || left.equals(right)) return false; // identical types - int leftIndex = NUMBER_TYPES.get(left); - int rightIndex = NUMBER_TYPES.get(right); - if (leftIndex >= rightIndex) return false; - // here we must check if the right number is short enough to fit in the left type - if (rightExpr instanceof ConstantExpression) { - Object value = ((ConstantExpression) rightExpr).getValue(); - if (!(value instanceof Number)) return true; - Number number = (Number) value; - switch (leftIndex) { - case 0: { // byte - byte val = number.byteValue(); - if (number instanceof Short) { - return !Short.valueOf(val).equals(number); - } - if (number instanceof Integer) { - return !Integer.valueOf(val).equals(number); - } - if (number instanceof Long) { - return !Long.valueOf(val).equals(number); - } - if (number instanceof Float) { - return !Float.valueOf(val).equals(number); - } - return !Double.valueOf(val).equals(number); - } - case 1: { // short - short val = number.shortValue(); - if (number instanceof Integer) { - return !Integer.valueOf(val).equals(number); - } - if (number instanceof Long) { - return !Long.valueOf(val).equals(number); - } - if (number instanceof Float) { - return !Float.valueOf(val).equals(number); - } - return !Double.valueOf(val).equals(number); - } - case 2: { // integer - int val = number.intValue(); - if (number instanceof Long) { - return !Long.valueOf(val).equals(number); - } - if (number instanceof Float) { - return !Float.valueOf(val).equals(number); - } - return !Double.valueOf(val).equals(number); - } - case 3: { // long - long val = number.longValue(); - if (number instanceof Float) { - return !Float.valueOf(val).equals(number); - } - return !Double.valueOf(val).equals(number); - } - case 4: { // float - float val = number.floatValue(); - return !Double.valueOf(val).equals(number); - } - default: // double - return false; // no possible loose here - } - } - return true; // possible loss of precision - } - - static String toMethodParametersString(String methodName, ClassNode... parameters) { - StringBuilder sb = new StringBuilder(); - sb.append(methodName).append("("); - if (parameters != null) { - for (int i = 0, parametersLength = parameters.length; i < parametersLength; i++) { - final ClassNode parameter = parameters[i]; - sb.append(prettyPrintType(parameter)); - if (i < parametersLength - 1) sb.append(", "); - } - } - sb.append(")"); - return sb.toString(); - } - - static String prettyPrintType(ClassNode type) { - if (type.isArray()) { - return prettyPrintType(type.getComponentType()) + "[]"; - } - return type.toString(false); - } - - public static boolean implementsInterfaceOrIsSubclassOf(ClassNode type, ClassNode superOrInterface) { - boolean result = type.equals(superOrInterface) - || type.isDerivedFrom(superOrInterface) - || type.implementsInterface(superOrInterface) - || type == UNKNOWN_PARAMETER_TYPE; - if (result) { - return true; - } - if (superOrInterface instanceof WideningCategories.LowestUpperBoundClassNode) { - WideningCategories.LowestUpperBoundClassNode cn = (WideningCategories.LowestUpperBoundClassNode) superOrInterface; - result = implementsInterfaceOrIsSubclassOf(type, cn.getSuperClass()); - if (result) { - for (ClassNode interfaceNode : cn.getInterfaces()) { - result = type.implementsInterface(interfaceNode); - if (!result) break; - } - } - if (result) return true; - } else if (superOrInterface instanceof UnionTypeClassNode) { - UnionTypeClassNode union = (UnionTypeClassNode) superOrInterface; - for (ClassNode delegate : union.getDelegates()) { - if (implementsInterfaceOrIsSubclassOf(type, delegate)) return true; - } - } - if (type.isArray() && superOrInterface.isArray()) { - return implementsInterfaceOrIsSubclassOf(type.getComponentType(), superOrInterface.getComponentType()); - } - if (GROOVY_OBJECT_TYPE.equals(superOrInterface) && !type.isInterface() && isBeingCompiled(type)) { - return true; - } - return false; - } - - static int getPrimitiveDistance(ClassNode primA, ClassNode primB) { - return Math.abs(NUMBER_TYPES.get(primA) - NUMBER_TYPES.get(primB)); - } - - static int getDistance(final ClassNode receiver, final ClassNode compare) { - if (receiver.isArray() && compare.isArray()) { - return getDistance(receiver.getComponentType(), compare.getComponentType()); - } - int dist = 0; - ClassNode unwrapReceiver = getUnwrapper(receiver); - ClassNode unwrapCompare = getUnwrapper(compare); - if (isPrimitiveType(unwrapReceiver) - && isPrimitiveType(unwrapCompare) - && unwrapReceiver != unwrapCompare) { - dist = getPrimitiveDistance(unwrapReceiver, unwrapCompare); - } - // Add a penalty against boxing or unboxing, to get a resolution similar to JLS 15.12.2 - // (http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2). - if (isPrimitiveType(receiver) ^ isPrimitiveType(compare)) { - dist = (dist + 1) << 1; - } - if (unwrapCompare.equals(unwrapReceiver)) return dist; - if (receiver.isArray() && !compare.isArray()) { - // Object[] vs Object - dist += 256; - } - - if (receiver == UNKNOWN_PARAMETER_TYPE) { - return dist; - } - - ClassNode ref = isPrimitiveType(receiver) && !isPrimitiveType(compare) ? ClassHelper.getWrapper(receiver) : receiver; - while (ref != null) { - if (compare.equals(ref)) { - break; - } - if (compare.isInterface() && ref.implementsInterface(compare)) { - dist += getMaximumInterfaceDistance(ref, compare); - break; - } - ref = ref.getSuperClass(); - dist++; - if (ref == null) dist++; - dist = (dist + 1) << 1; - } - return dist; - } - - private static int getMaximumInterfaceDistance(ClassNode c, ClassNode interfaceClass) { - // -1 means a mismatch - if (c == null) return -1; - // 0 means a direct match - if (c.equals(interfaceClass)) return 0; - ClassNode[] interfaces = c.getInterfaces(); - int max = -1; - for (int i = 0; i < interfaces.length; i++) { - final ClassNode anInterface = interfaces[i]; - int sub = getMaximumInterfaceDistance(anInterface, interfaceClass); - // we need to keep the -1 to track the mismatch, a +1 - // by any means could let it look like a direct match - // we want to add one, because there is an interface between - // the interface we search for and the interface we are in. - if (sub != -1) { - sub += 1; - } - // we are interested in the longest path only - max = Math.max(max, sub); - } - // we do not add one for super classes, only for interfaces - int superClassMax = getMaximumInterfaceDistance(c.getSuperClass(), interfaceClass); - return Math.max(max, superClassMax); - } - - /** - * @deprecated Use {@link #findDGMMethodsByNameAndArguments(ClassLoader, ClassNode, String, ClassNode[], List)} instead - */ - @Deprecated - public static List findDGMMethodsByNameAndArguments(final ClassNode receiver, final String name, final ClassNode[] args) { - return findDGMMethodsByNameAndArguments(MetaClassRegistryImpl.class.getClassLoader(), receiver, name, args); - } - - public static List findDGMMethodsByNameAndArguments(final ClassLoader loader, final ClassNode receiver, final String name, final ClassNode[] args) { - return findDGMMethodsByNameAndArguments(loader, receiver, name, args, new LinkedList()); - } - - /** - * @deprecated Use {@link #findDGMMethodsByNameAndArguments(ClassLoader, ClassNode, String, ClassNode[], List)} instead - */ - @Deprecated - public static List findDGMMethodsByNameAndArguments(final ClassNode receiver, final String name, final ClassNode[] args, final List methods) { - return findDGMMethodsByNameAndArguments(MetaClassRegistryImpl.class.getClassLoader(), receiver, name, args, methods); - } - - public static List findDGMMethodsByNameAndArguments(final ClassLoader loader, final ClassNode receiver, final String name, final ClassNode[] args, final List methods) { - final List chosen; - methods.addAll(findDGMMethodsForClassNode(loader, receiver, name)); - if (methods.isEmpty()) return methods; - - chosen = chooseBestMethod(receiver, methods, args); - return chosen; - } - - /** - * Returns true if the provided class node, when considered as a receiver of a message or as a parameter, - * is using a placeholder in its generics type. In this case, we're facing unchecked generics and type - * checking is limited (ex: void foo(Set s) { s.keySet() } - * - * @param node the node to test - * @return true if it is using any placeholder in generics types - */ - public static boolean isUsingUncheckedGenerics(ClassNode node) { - if (node.isArray()) return isUsingUncheckedGenerics(node.getComponentType()); - if (node.isUsingGenerics()) { - GenericsType[] genericsTypes = node.getGenericsTypes(); - if (genericsTypes != null) { - for (GenericsType genericsType : genericsTypes) { - if (genericsType.isPlaceholder()) { - return true; - } else { - if (isUsingUncheckedGenerics(genericsType.getType())) { - return true; - } - } - } - } - } else { - return false; - } - return false; - } - - /** - * Given a list of candidate methods, returns the one which best matches the argument types - * - * @param receiver - * @param methods candidate methods - * @param args argument types - * @return the list of methods which best matches the argument types. It is still possible that multiple - * methods match the argument types. - */ - public static List chooseBestMethod(final ClassNode receiver, Collection methods, ClassNode... args) { - if (methods.isEmpty()) return Collections.emptyList(); - if (isUsingUncheckedGenerics(receiver)) { - ClassNode raw = makeRawType(receiver); - return chooseBestMethod(raw, methods, args); - } - List bestChoices = new LinkedList(); - int bestDist = Integer.MAX_VALUE; - Collection choicesLeft = removeCovariantsAndInterfaceEquivalents(methods); - for (MethodNode candidateNode : choicesLeft) { - ClassNode declaringClassForDistance = candidateNode.getDeclaringClass(); - ClassNode actualReceiverForDistance = receiver != null ? receiver : candidateNode.getDeclaringClass(); - MethodNode safeNode = candidateNode; - ClassNode[] safeArgs = args; - boolean isExtensionMethodNode = candidateNode instanceof ExtensionMethodNode; - if (isExtensionMethodNode) { - safeArgs = new ClassNode[args.length + 1]; - System.arraycopy(args, 0, safeArgs, 1, args.length); - safeArgs[0] = receiver; - safeNode = ((ExtensionMethodNode) candidateNode).getExtensionMethodNode(); - } - - // todo : corner case - /* - class B extends A {} - - Animal foo(A o) {...} - Person foo(B i){...} - - B a = new B() - Person p = foo(b) - */ - - Map declaringAndActualGenericsTypeMap = GenericsUtils.makeDeclaringAndActualGenericsTypeMap(declaringClassForDistance, actualReceiverForDistance); - Parameter[] params = makeRawTypes(safeNode.getParameters(), declaringAndActualGenericsTypeMap); - int dist = measureParametersAndArgumentsDistance(params, safeArgs); - if (dist >= 0) { - dist += getClassDistance(declaringClassForDistance, actualReceiverForDistance); - dist += getExtensionDistance(isExtensionMethodNode); - if (dist < bestDist) { - bestChoices.clear(); - bestChoices.add(candidateNode); - bestDist = dist; - } else if (dist == bestDist) { - bestChoices.add(candidateNode); - } - } - } - if (bestChoices.size() > 1) { - // GROOVY-6849: prefer extension methods in case of ambiguity - List onlyExtensionMethods = new LinkedList(); - for (MethodNode choice : bestChoices) { - if (choice instanceof ExtensionMethodNode) { - onlyExtensionMethods.add(choice); - } - } - if (onlyExtensionMethods.size() == 1) { - return onlyExtensionMethods; - } - } - return bestChoices; - } - - private static int measureParametersAndArgumentsDistance(Parameter[] params, ClassNode[] args) { - int dist = -1; - if (params.length == args.length) { - int allPMatch = allParametersAndArgumentsMatch(params, args); - int firstParamDist = firstParametersAndArgumentsMatch(params, args); - int lastArgMatch = isVargs(params) && firstParamDist >= 0 ? lastArgMatchesVarg(params, args) : -1; - if (lastArgMatch >= 0) { - lastArgMatch += getVarargsDistance(params); - } - dist = allPMatch >= 0 ? Math.max(allPMatch, lastArgMatch) : lastArgMatch; - } else if (isVargs(params)) { - dist = firstParametersAndArgumentsMatch(params, args); - if (dist >= 0) { - // varargs methods must not be preferred to methods without varargs - // for example : - // int sum(int x) should be preferred to int sum(int x, int... y) - dist += getVarargsDistance(params); - // there are three case for vargs - // (1) varg part is left out (there's one less argument than there are parameters) - // (2) last argument is put in the vargs array - // that case is handled above already when params and args have the same length - if (params.length < args.length) { - // (3) there is more than one argument for the vargs array - int excessArgumentsDistance = excessArgumentsMatchesVargsParameter(params, args); - if (excessArgumentsDistance < 0) { - dist = -1; - } else { - dist += excessArgumentsDistance; - } - } - } - } - return dist; - } - - private static int firstParametersAndArgumentsMatch(Parameter[] params, ClassNode[] safeArgs) { - int dist = 0; - // check first parameters - if (params.length > 0) { - Parameter[] firstParams = new Parameter[params.length - 1]; - System.arraycopy(params, 0, firstParams, 0, firstParams.length); - dist = allParametersAndArgumentsMatch(firstParams, safeArgs); - } - return dist; - } - - private static int getVarargsDistance(Parameter[] params) { - return 256 - params.length; // ensure exact matches are preferred over vargs - } - - private static int getClassDistance(ClassNode declaringClassForDistance, ClassNode actualReceiverForDistance) { - if (actualReceiverForDistance.equals(declaringClassForDistance)) { - return 0; - } - return getDistance(actualReceiverForDistance, declaringClassForDistance); - } - - private static int getExtensionDistance(boolean isExtensionMethodNode) { - return isExtensionMethodNode ? 0 : 1; - } - - private static Parameter[] makeRawTypes(Parameter[] params, Map genericsPlaceholderAndTypeMap) { - - Parameter[] newParam = new Parameter[params.length]; - for (int i = 0; i < params.length; i++) { - Parameter oldP = params[i]; - - ClassNode actualType = GenericsUtils.findActualTypeByGenericsPlaceholderName(oldP.getType().getUnresolvedName(), genericsPlaceholderAndTypeMap); - Parameter newP = new Parameter(makeRawType(null == actualType ? oldP.getType() : actualType), oldP.getName()); - newParam[i] = newP; - } - return newParam; - } - - private static ClassNode makeRawType(final ClassNode receiver) { - if (receiver.isArray()) { - return makeRawType(receiver.getComponentType()).makeArray(); - } - ClassNode raw = receiver.getPlainNodeReference(); - raw.setUsingGenerics(false); - raw.setGenericsTypes(null); - return raw; - } - - private static Collection removeCovariantsAndInterfaceEquivalents(Collection collection) { - if (collection.size() <= 1) return collection; - List toBeRemoved = new LinkedList(); - List list = new LinkedList(new LinkedHashSet(collection)); - for (int i = 0; i < list.size() - 1; i++) { - MethodNode one = list.get(i); - if (toBeRemoved.contains(one)) continue; - for (int j = i + 1; j < list.size(); j++) { - MethodNode two = list.get(j); - if (toBeRemoved.contains(two)) continue; - if (one.getParameters().length == two.getParameters().length) { - if (areOverloadMethodsInSameClass(one, two)) { - if (ParameterUtils.parametersEqual(one.getParameters(), two.getParameters())) { - removeMethodWithSuperReturnType(toBeRemoved, one, two); - } else { - // this is an imperfect solution to determining if two methods are - // equivalent, for example String#compareTo(Object) and String#compareTo(String) - // in that case, Java marks the Object version as synthetic - removeSyntheticMethodIfOne(toBeRemoved, one, two); - } - } else if (areEquivalentInterfaceMethods(one, two)) { - // GROOVY-6970 choose between equivalent interface methods - removeMethodInSuperInterface(toBeRemoved, one, two); - } - } - } - } - if (toBeRemoved.isEmpty()) return list; - List result = new LinkedList(list); - result.removeAll(toBeRemoved); - return result; - } - - private static void removeMethodInSuperInterface(List toBeRemoved, MethodNode one, MethodNode two) { - ClassNode oneDC = one.getDeclaringClass(); - ClassNode twoDC = two.getDeclaringClass(); - if (oneDC.implementsInterface(twoDC)) { - toBeRemoved.add(two); - } else { - toBeRemoved.add(one); - } - } - - private static boolean areEquivalentInterfaceMethods(MethodNode one, MethodNode two) { - return one.getName().equals(two.getName()) - && one.getDeclaringClass().isInterface() - && two.getDeclaringClass().isInterface() - && ParameterUtils.parametersEqual(one.getParameters(), two.getParameters()); - } - - private static void removeSyntheticMethodIfOne(List toBeRemoved, MethodNode one, MethodNode two) { - if (one.isSynthetic() && !two.isSynthetic()) { - toBeRemoved.add(one); - } else if (two.isSynthetic() && !one.isSynthetic()) { - toBeRemoved.add(two); - } - } - - private static void removeMethodWithSuperReturnType(List toBeRemoved, MethodNode one, MethodNode two) { - ClassNode oneRT = one.getReturnType(); - ClassNode twoRT = two.getReturnType(); - if (isCovariant(oneRT, twoRT)) { - toBeRemoved.add(two); - } else if (isCovariant(twoRT, oneRT)) { - toBeRemoved.add(one); - } - } - - private static boolean isCovariant(ClassNode left, ClassNode right) { - if (left.isArray() && right.isArray()) { - return isCovariant(left.getComponentType(), right.getComponentType()); - } - return left.isDerivedFrom(right) || left.implementsInterface(right); - } - - private static boolean areOverloadMethodsInSameClass(MethodNode one, MethodNode two) { - return one.getName().equals(two.getName()) && one.getDeclaringClass() == two.getDeclaringClass(); - } - - /** - * Given a receiver and a method node, parameterize the method arguments using - * available generic type information. - * - * @param receiver the class - * @param m the method - * @return the parameterized arguments - */ - public static Parameter[] parameterizeArguments(final ClassNode receiver, final MethodNode m) { - Map genericFromReceiver = GenericsUtils.extractPlaceholders(receiver); - Map contextPlaceholders = extractGenericsParameterMapOfThis(m); - Parameter[] methodParameters = m.getParameters(); - Parameter[] params = new Parameter[methodParameters.length]; - for (int i = 0; i < methodParameters.length; i++) { - Parameter methodParameter = methodParameters[i]; - ClassNode paramType = methodParameter.getType(); - params[i] = buildParameter(genericFromReceiver, contextPlaceholders, methodParameter, paramType); - } - return params; - } - - /** - * Given a parameter, builds a new parameter for which the known generics placeholders are resolved. - * - * @param genericFromReceiver resolved generics from the receiver of the message - * @param placeholdersFromContext, resolved generics from the method context - * @param methodParameter the method parameter for which we want to resolve generic types - * @param paramType the (unresolved) type of the method parameter - * @return a new parameter with the same name and type as the original one, but with resolved generic types - */ - private static Parameter buildParameter(final Map genericFromReceiver, final Map placeholdersFromContext, final Parameter methodParameter, final ClassNode paramType) { - if (genericFromReceiver.isEmpty() && (placeholdersFromContext == null || placeholdersFromContext.isEmpty())) { - return methodParameter; - } - if (paramType.isArray()) { - ClassNode componentType = paramType.getComponentType(); - Parameter subMethodParameter = new Parameter(componentType, methodParameter.getName()); - Parameter component = buildParameter(genericFromReceiver, placeholdersFromContext, subMethodParameter, componentType); - return new Parameter(component.getType().makeArray(), component.getName()); - } - ClassNode resolved = resolveClassNodeGenerics(genericFromReceiver, placeholdersFromContext, paramType); - - return new Parameter(resolved, methodParameter.getName()); - } - - /** - * Returns true if a class node makes use of generic types. If the class node represents an - * array type, then checks if the component type is using generics. - * - * @param cn a class node for which to check if it is using generics - * @return true if the type (or component type) is using generics - */ - public static boolean isUsingGenericsOrIsArrayUsingGenerics(ClassNode cn) { - if (cn.isArray()) { - return isUsingGenericsOrIsArrayUsingGenerics(cn.getComponentType()); - } - return (cn.isUsingGenerics() && cn.getGenericsTypes() != null); - } - - /** - * Given a generics type representing SomeClass<T,V> and a resolved placeholder map, returns a new generics type - * for which placeholders are resolved recursively. - */ - protected static GenericsType fullyResolve(GenericsType gt, Map placeholders) { - GenericsType fromMap = placeholders.get(gt.getName()); - if (gt.isPlaceholder() && fromMap != null) { - gt = fromMap; - } - - ClassNode type = fullyResolveType(gt.getType(), placeholders); - ClassNode lowerBound = gt.getLowerBound(); - if (lowerBound != null) lowerBound = fullyResolveType(lowerBound, placeholders); - ClassNode[] upperBounds = gt.getUpperBounds(); - if (upperBounds != null) { - ClassNode[] copy = new ClassNode[upperBounds.length]; - for (int i = 0, upperBoundsLength = upperBounds.length; i < upperBoundsLength; i++) { - final ClassNode upperBound = upperBounds[i]; - copy[i] = fullyResolveType(upperBound, placeholders); - } - upperBounds = copy; - } - GenericsType genericsType = new GenericsType(type, upperBounds, lowerBound); - genericsType.setWildcard(gt.isWildcard()); - return genericsType; - } - - protected static ClassNode fullyResolveType(final ClassNode type, final Map placeholders) { - if (type.isUsingGenerics() && !type.isGenericsPlaceHolder()) { - GenericsType[] gts = type.getGenericsTypes(); - if (gts != null) { - GenericsType[] copy = new GenericsType[gts.length]; - for (int i = 0; i < gts.length; i++) { - GenericsType genericsType = gts[i]; - if (genericsType.isPlaceholder() && placeholders.containsKey(genericsType.getName())) { - copy[i] = placeholders.get(genericsType.getName()); - } else { - copy[i] = fullyResolve(genericsType, placeholders); - } - } - gts = copy; - } - ClassNode result = type.getPlainNodeReference(); - result.setGenericsTypes(gts); - return result; - } else if (type.isUsingGenerics() && OBJECT_TYPE.equals(type) && type.getGenericsTypes() != null) { - // Object - GenericsType genericsType = placeholders.get(type.getGenericsTypes()[0].getName()); - if (genericsType != null) { - return genericsType.getType(); - } - } else if (type.isArray()) { - return fullyResolveType(type.getComponentType(), placeholders).makeArray(); - } - return type; - } - - /** - * Checks that the parameterized generics of an argument are compatible with the generics of the parameter. - * - * @param parameterType the parameter type of a method - * @param argumentType the type of the argument passed to the method - */ - protected static boolean typeCheckMethodArgumentWithGenerics(ClassNode parameterType, ClassNode argumentType, boolean lastArg) { - if (UNKNOWN_PARAMETER_TYPE == argumentType) { - // called with null - return !isPrimitiveType(parameterType); - } - if (!isAssignableTo(argumentType, parameterType) && !lastArg) { - // incompatible assignment - return false; - } - if (!isAssignableTo(argumentType, parameterType) && lastArg) { - if (parameterType.isArray()) { - if (!isAssignableTo(argumentType, parameterType.getComponentType())) { - return false; - } - } else { - return false; - } - } - if (parameterType.isUsingGenerics() && argumentType.isUsingGenerics()) { - GenericsType gt = GenericsUtils.buildWildcardType(parameterType); - if (!gt.isCompatibleWith(argumentType)) { - boolean samCoercion = isSAMType(parameterType) && argumentType.equals(CLOSURE_TYPE); - if (!samCoercion) return false; - } - } else if (parameterType.isArray() && argumentType.isArray()) { - // verify component type - return typeCheckMethodArgumentWithGenerics(parameterType.getComponentType(), argumentType.getComponentType(), lastArg); - } else if (lastArg && parameterType.isArray()) { - // verify component type, but if we reach that point, the only possibility is that the argument is - // the last one of the call, so we're in the cast of a vargs call - // (otherwise, we face a type checker bug) - return typeCheckMethodArgumentWithGenerics(parameterType.getComponentType(), argumentType, lastArg); - } - return true; - } - - static void addMethodLevelDeclaredGenerics(MethodNode method, Map resolvedPlaceholders) { - ClassNode dummy = OBJECT_TYPE.getPlainNodeReference(); - dummy.setGenericsTypes(method.getGenericsTypes()); - GenericsUtils.extractPlaceholders(dummy, resolvedPlaceholders); - } - - protected static boolean typeCheckMethodsWithGenerics(ClassNode receiver, ClassNode[] arguments, MethodNode candidateMethod) { - if (isUsingUncheckedGenerics(receiver)) { - return true; - } - if (CLASS_Type.equals(receiver) - && receiver.isUsingGenerics() - && !candidateMethod.getDeclaringClass().equals(receiver) - && !(candidateMethod instanceof ExtensionMethodNode)) { - return typeCheckMethodsWithGenerics(receiver.getGenericsTypes()[0].getType(), arguments, candidateMethod); - } - // both candidate method and receiver have generic information so a check is possible - GenericsType[] genericsTypes = candidateMethod.getGenericsTypes(); - boolean methodUsesGenerics = (genericsTypes != null && genericsTypes.length > 0); - boolean isExtensionMethod = candidateMethod instanceof ExtensionMethodNode; - if (isExtensionMethod && methodUsesGenerics) { - ClassNode[] dgmArgs = new ClassNode[arguments.length + 1]; - dgmArgs[0] = receiver; - System.arraycopy(arguments, 0, dgmArgs, 1, arguments.length); - MethodNode extensionMethodNode = ((ExtensionMethodNode) candidateMethod).getExtensionMethodNode(); - return typeCheckMethodsWithGenerics(extensionMethodNode.getDeclaringClass(), dgmArgs, extensionMethodNode, true); - } else { - return typeCheckMethodsWithGenerics(receiver, arguments, candidateMethod, false); - } - } - - private static boolean typeCheckMethodsWithGenerics(ClassNode receiver, ClassNode[] arguments, MethodNode candidateMethod, boolean isExtensionMethod) { - boolean failure = false; - - // correct receiver for inner class - // we assume the receiver is an instance of the declaring class of the - // candidate method, but findMethod returns also outer class methods - // for that receiver. For now we skip receiver based checks in that case - // TODO: correct generics for when receiver is to be skipped - boolean skipBecauseOfInnerClassNotReceiver = isOuterClassOf(receiver, candidateMethod.getDeclaringClass()); - - Parameter[] parameters = candidateMethod.getParameters(); - Map classGTs; - if (skipBecauseOfInnerClassNotReceiver) { - classGTs = Collections.EMPTY_MAP; - } else { - classGTs = GenericsUtils.extractPlaceholders(receiver); - } - if (parameters.length > arguments.length || parameters.length == 0) { - // this is a limitation that must be removed in a future version - // we cannot check generic type arguments if there are default parameters! - return true; - } - - // we have here different generics contexts we have to deal with. - // There is firstly the context given through the class, and the method. - // The method context may hide generics given through the class, but use - // the non-hidden ones. - Map resolvedMethodGenerics = new HashMap(); - if (!skipBecauseOfInnerClassNotReceiver) { - addMethodLevelDeclaredGenerics(candidateMethod, resolvedMethodGenerics); - } - // so first we remove hidden generics - for (String key : resolvedMethodGenerics.keySet()) classGTs.remove(key); - // then we use the remaining information to refine the given generics - applyGenericsConnections(classGTs, resolvedMethodGenerics); - // and then start our checks with the receiver - if (!skipBecauseOfInnerClassNotReceiver) { - failure |= inferenceCheck(Collections.EMPTY_SET, resolvedMethodGenerics, candidateMethod.getDeclaringClass(), receiver, false); - } - // the outside context parts till now define placeholder we are not allowed to - // generalize, thus we save that for later use... - // extension methods are special, since they set the receiver as - // first parameter. While we normally allow generalization for the first - // parameter, in case of an extension method we must not. - Set fixedGenericsPlaceHolders = extractResolvedPlaceHolders(resolvedMethodGenerics); - - for (int i = 0; i < arguments.length; i++) { - int pindex = min(i, parameters.length - 1); - ClassNode wrappedArgument = arguments[i]; - ClassNode type = parameters[pindex].getOriginType(); - - failure |= inferenceCheck(fixedGenericsPlaceHolders, resolvedMethodGenerics, type, wrappedArgument, i >= parameters.length - 1); - - // set real fixed generics for extension methods - if (isExtensionMethod && i == 0) - fixedGenericsPlaceHolders = extractResolvedPlaceHolders(resolvedMethodGenerics); - } - return !failure; - } - - private static boolean isOuterClassOf(ClassNode receiver, ClassNode type) { - if (implementsInterfaceOrIsSubclassOf(receiver, type)) return false; - return true; - } - - private static Set extractResolvedPlaceHolders(Map resolvedMethodGenerics) { - if (resolvedMethodGenerics.isEmpty()) return Collections.EMPTY_SET; - Set result = new HashSet(); - for (Entry entry : resolvedMethodGenerics.entrySet()) { - GenericsType value = entry.getValue(); - if (value.isPlaceholder()) continue; - result.add(entry.getKey()); - } - return result; - } - - private static boolean inferenceCheck(Set fixedGenericsPlaceHolders, Map resolvedMethodGenerics, ClassNode type, ClassNode wrappedArgument, boolean lastArg) { - Map connections = new HashMap(); - if (isPrimitiveType(wrappedArgument)) wrappedArgument = getWrapper(wrappedArgument); - // the context we compare with in the end is the one of the callsite - // so far we specified the context of the method declaration only - // thus for each argument, we try to find the connected generics first - extractGenericsConnections(connections, wrappedArgument, type); - // each found connection must comply with already found connections - boolean failure = !compatibleConnections(connections, resolvedMethodGenerics, fixedGenericsPlaceHolders); - // and then apply the found information to refine the method level - // information. This way the method level information slowly turns - // into information for the callsite - applyGenericsConnections(connections, resolvedMethodGenerics); - // since it is possible that the callsite uses some generics as well, - // we may have to add additional elements here - addMissingEntries(connections, resolvedMethodGenerics); - // to finally see if the parameter and the argument fit together, - // we use the provided information to transform the parameter - // into something that can exist in the callsite context - type = applyGenericsContext(resolvedMethodGenerics, type); - // there of course transformed parameter type and argument must fit - failure |= !typeCheckMethodArgumentWithGenerics(type, wrappedArgument, lastArg); - return failure; - } - - private static GenericsType buildWildcardType(GenericsType origin) { - ClassNode lowerBound = origin.getType().getPlainNodeReference(); - if (hasNonTrivialBounds(origin)) { - lowerBound.setGenericsTypes(new GenericsType[]{origin}); - } - ClassNode base = makeWithoutCaching("?"); - GenericsType gt = new GenericsType(base, null, lowerBound); - gt.setWildcard(true); - return gt; - } - - private static boolean compatibleConnections(Map connections, Map resolvedMethodGenerics, Set fixedGenericsPlaceHolders) { - for (Entry entry : connections.entrySet()) { - GenericsType resolved = resolvedMethodGenerics.get(entry.getKey()); - if (resolved == null) continue; - GenericsType connection = entry.getValue(); - if (connection.isPlaceholder() && !hasNonTrivialBounds(connection)) { - continue; - } - if (!compatibleConnection(resolved, connection)) { - if (!(resolved.isPlaceholder() || resolved.isWildcard()) && - !fixedGenericsPlaceHolders.contains(entry.getKey()) && - compatibleConnection(connection, resolved)) { - // we did for example find T=String and now check against - // T=Object, which fails the first compatibleConnection check - // but since T=Object works for both, the second one will pass - // and we need to change the type for T to the more general one - resolvedMethodGenerics.put(entry.getKey(), connection); - } else { - return false; - } - } - } - return true; - } - - private static boolean compatibleConnection(GenericsType resolved, GenericsType connection) { - GenericsType gt = connection; - if (!connection.isWildcard()) gt = buildWildcardType(connection); - if (resolved.isPlaceholder() && resolved.getUpperBounds() != null && - resolved.getUpperBounds().length == 1 && !resolved.getUpperBounds()[0].isGenericsPlaceHolder() && - resolved.getUpperBounds()[0].getName().equals("java.lang.Object")) { - return true; - } - ClassNode compareNode; - if (hasNonTrivialBounds(resolved)) { - compareNode = getCombinedBoundType(resolved); - compareNode = compareNode.redirect().getPlainNodeReference(); - } else { - if (!resolved.isPlaceholder()) { - compareNode = resolved.getType().getPlainNodeReference(); - } else { - return true; - } - } - return gt.isCompatibleWith(compareNode); - } - - private static void addMissingEntries(Map connections, Map resolved) { - for (Entry entry : connections.entrySet()) { - if (resolved.containsKey(entry.getKey())) continue; - GenericsType gt = entry.getValue(); - ClassNode cn = gt.getType(); - if (cn.redirect() == UNKNOWN_PARAMETER_TYPE) continue; - resolved.put(entry.getKey(), gt); - } - } - - public static ClassNode resolveClassNodeGenerics(Map resolvedPlaceholders, final Map placeholdersFromContext, ClassNode currentType) { - ClassNode target = currentType.redirect(); - resolvedPlaceholders = new HashMap(resolvedPlaceholders); - applyContextGenerics(resolvedPlaceholders, placeholdersFromContext); - - Map connections = new HashMap(); - extractGenericsConnections(connections, currentType, target); - applyGenericsConnections(connections, resolvedPlaceholders); - currentType = applyGenericsContext(resolvedPlaceholders, currentType); - return currentType; - } - - static void applyGenericsConnections( - Map connections, - Map resolvedPlaceholders - ) { - if (connections == null) return; - int count = 0; - while (count < 10000) { - count++; - boolean checkForMorePlaceHolders = false; - for (Entry entry : resolvedPlaceholders.entrySet()) { - String name = entry.getKey(); - GenericsType replacement = connections.get(name); - if (replacement == null) { - GenericsType value = entry.getValue(); - GenericsType newValue = applyGenericsContext(connections, value); - entry.setValue(newValue); - checkForMorePlaceHolders = checkForMorePlaceHolders || !equalIncludingGenerics(value, newValue); - continue; - } - GenericsType original = entry.getValue(); - if (!original.isWildcard() && !original.isPlaceholder()) { - continue; - } - boolean placeholderReplacement = replacement.isPlaceholder(); - if (placeholderReplacement) { - GenericsType connectedType = resolvedPlaceholders.get(replacement.getName()); - if (replacement == connectedType) continue; - } - // GROOVY-6787: Don't override the original if the replacement placeholder doesn't respect the bounds, - // otherwise the original bounds are lost which can result in accepting an incompatible type as an - // argument, for example. - ClassNode replacementType = extractType(replacement); - if (original.isCompatibleWith(replacementType)) { - entry.setValue(replacement); - if (placeholderReplacement) { - checkForMorePlaceHolders = checkForMorePlaceHolders || !equalIncludingGenerics(original, replacement); - } - } - } - if (!checkForMorePlaceHolders) break; - } - if (count >= 10000) - throw new GroovyBugError("unable to handle generics in " + resolvedPlaceholders + " with connections " + connections); - } - - private static ClassNode extractType(GenericsType gt) { - if (!gt.isPlaceholder()) { - return gt.getType(); - } - // For a placeholder, a type based on the generics type is used for the compatibility check, to match on - // the actual bounds and not the name of the placeholder. - ClassNode replacementType = OBJECT_TYPE; - if (gt.getType().getGenericsTypes() != null) { - GenericsType realGt = gt.getType().getGenericsTypes()[0]; - if (realGt.getLowerBound() != null) { - replacementType = realGt.getLowerBound(); - } else if (realGt.getUpperBounds() != null && realGt.getUpperBounds().length > 0) { - replacementType = realGt.getUpperBounds()[0]; - } - } - return replacementType; - } - - private static boolean equalIncludingGenerics(GenericsType orig, GenericsType copy) { - if (orig == copy) return true; - if (orig.isPlaceholder() != copy.isPlaceholder()) return false; - if (orig.isWildcard() != copy.isWildcard()) return false; - if (!equalIncludingGenerics(orig.getType(), copy.getType())) return false; - ClassNode lower1 = orig.getLowerBound(); - ClassNode lower2 = copy.getLowerBound(); - if ((lower1 == null) ^ (lower2 == null)) return false; - if (lower1 != lower2) { - if (!equalIncludingGenerics(lower1, lower2)) return false; - } - ClassNode[] upper1 = orig.getUpperBounds(); - ClassNode[] upper2 = copy.getUpperBounds(); - if ((upper1 == null) ^ (upper2 == null)) return false; - if (upper1 != upper2) { - if (upper1.length != upper2.length) return false; - for (int i = 0; i < upper1.length; i++) { - if (!equalIncludingGenerics(upper1[i], upper2[i])) return false; - } - } - return true; - } - - private static boolean equalIncludingGenerics(ClassNode orig, ClassNode copy) { - if (orig == copy) return true; - if (orig.isGenericsPlaceHolder() != copy.isGenericsPlaceHolder()) return false; - if (!orig.equals(copy)) return false; - GenericsType[] gt1 = orig.getGenericsTypes(); - GenericsType[] gt2 = orig.getGenericsTypes(); - if ((gt1 == null) ^ (gt2 == null)) return false; - if (gt1 != gt2) { - if (gt1.length != gt2.length) return false; - for (int i = 0; i < gt1.length; i++) { - if (!equalIncludingGenerics(gt1[i], gt2[i])) return false; - } - } - return true; - } - - /** - * use supplied type to make a connection from usage to declaration - * The method operates in two modes. - * * For type !instanceof target a structural compare will be done - * (for example Dummy<T> and List<R> to get T=R) - * * If type equals target, a structural match is done as well - * (for example Collection<U> and Collection<E> to get U=E) - * * otherwise we climb the hierarchy to find a case of type equals target - * to then execute the structural match, while applying possibly existing - * generics contexts on the way (for example for IntRange and Collection<E> - * to get E=Integer, since IntRange is an AbstractList<Integer>) - * Should the target not have any generics this method does nothing. - */ - static void extractGenericsConnections(Map connections, ClassNode type, ClassNode target) { - if (target == null || type == target || !isUsingGenericsOrIsArrayUsingGenerics(target)) return; - if (type == null || type == UNKNOWN_PARAMETER_TYPE) return; - if (type.isArray() && target.isArray()) { - extractGenericsConnections(connections, type.getComponentType(), target.getComponentType()); - } else if (target.isGenericsPlaceHolder() || type.equals(target) || !implementsInterfaceOrIsSubclassOf(type, target)) { - // structural match route - if (target.isGenericsPlaceHolder()) { - connections.put(target.getGenericsTypes()[0].getName(), new GenericsType(type)); - } else { - extractGenericsConnections(connections, type.getGenericsTypes(), target.getGenericsTypes()); - } - } else { - // have first to find matching super class or interface - ClassNode superClass = getSuperClass(type, target); - - if (superClass != null) { - ClassNode corrected = getCorrectedClassNode(type, superClass, true); - extractGenericsConnections(connections, corrected, target); - } else { - // if we reach here, we have an unhandled case - throw new GroovyBugError("The type " + type + " seems not to normally extend " + target + ". Sorry, I cannot handle this."); - } - } - } - - public static ClassNode getCorrectedClassNode(ClassNode type, ClassNode superClass, boolean handlingGenerics) { - ClassNode corrected; - if (handlingGenerics && missesGenericsTypes(type)) { - corrected = superClass.getPlainNodeReference(); - } else { - corrected = GenericsUtils.correctToGenericsSpecRecurse(GenericsUtils.createGenericsSpec(type), superClass); - } - return corrected; - } - - private static void extractGenericsConnections(Map connections, GenericsType[] usage, GenericsType[] declaration) { - // if declaration does not provide generics, there is no connection to make - if (usage == null || declaration == null || declaration.length == 0) return; - if (usage.length != declaration.length) return; - - // both have generics - for (int i = 0; i < usage.length; i++) { - GenericsType ui = usage[i]; - GenericsType di = declaration[i]; - if (di.isPlaceholder()) { - connections.put(di.getName(), ui); - } else if (di.isWildcard()) { - if (ui.isWildcard()) { - extractGenericsConnections(connections, ui.getLowerBound(), di.getLowerBound()); - extractGenericsConnections(connections, ui.getUpperBounds(), di.getUpperBounds()); - } else { - ClassNode cu = ui.getType(); - extractGenericsConnections(connections, cu, di.getLowerBound()); - ClassNode[] upperBounds = di.getUpperBounds(); - if (upperBounds != null) { - for (ClassNode cn : upperBounds) { - extractGenericsConnections(connections, cu, cn); - } - } - } - } else { - extractGenericsConnections(connections, ui.getType(), di.getType()); - } - } - } - - private static void extractGenericsConnections(Map connections, ClassNode[] usage, ClassNode[] declaration) { - if (usage == null || declaration == null || declaration.length == 0) return; - // both have generics - for (int i = 0; i < usage.length; i++) { - ClassNode ui = usage[i]; - ClassNode di = declaration[i]; - if (di.isGenericsPlaceHolder()) { - GenericsType gt = new GenericsType(di); - gt.setPlaceholder(di.isGenericsPlaceHolder()); - connections.put(di.getGenericsTypes()[0].getName(), gt); - } else if (di.isUsingGenerics()) { - extractGenericsConnections(connections, ui.getGenericsTypes(), di.getGenericsTypes()); - } - } - } - - static GenericsType[] getGenericsWithoutArray(ClassNode type) { - if (type.isArray()) return getGenericsWithoutArray(type.getComponentType()); - return type.getGenericsTypes(); - } - - static Map applyGenericsContextToParameterClass( - Map spec, ClassNode parameterUsage - ) { - GenericsType[] gts = parameterUsage.getGenericsTypes(); - if (gts == null) return Collections.EMPTY_MAP; - - GenericsType[] newGTs = applyGenericsContext(spec, gts); - ClassNode newTarget = parameterUsage.redirect().getPlainNodeReference(); - newTarget.setGenericsTypes(newGTs); - return GenericsUtils.extractPlaceholders(newTarget); - } - - private static GenericsType[] applyGenericsContext( - Map spec, GenericsType[] gts - ) { - if (gts == null) return null; - GenericsType[] newGTs = new GenericsType[gts.length]; - for (int i = 0; i < gts.length; i++) { - GenericsType gt = gts[i]; - newGTs[i] = applyGenericsContext(spec, gt); - } - return newGTs; - } - - private static GenericsType applyGenericsContext(Map spec, GenericsType gt) { - if (gt.isPlaceholder()) { - String name = gt.getName(); - GenericsType specType = spec.get(name); - if (specType != null) return specType; - if (hasNonTrivialBounds(gt)) { - GenericsType newGT = new GenericsType(gt.getType(), applyGenericsContext(spec, gt.getUpperBounds()), applyGenericsContext(spec, gt.getLowerBound())); - newGT.setPlaceholder(true); - return newGT; - } - return gt; - } else if (gt.isWildcard()) { - GenericsType newGT = new GenericsType(gt.getType(), applyGenericsContext(spec, gt.getUpperBounds()), applyGenericsContext(spec, gt.getLowerBound())); - newGT.setWildcard(true); - return newGT; - } - ClassNode type = gt.getType(); - /* GRECLIPSE edit - if (type.getGenericsTypes() == null) return gt; - ClassNode newType = type.getPlainNodeReference(); - newType.setGenericsPlaceHolder(type.isGenericsPlaceHolder()); - newType.setGenericsTypes(applyGenericsContext(spec, type.getGenericsTypes())); - */ - ClassNode newType; - if (type.isArray()) { - newType = applyGenericsContext(spec, type.getComponentType()).makeArray(); - } else { - if (type.getGenericsTypes() == null) return gt; - newType = type.getPlainNodeReference(); - newType.setGenericsPlaceHolder(type.isGenericsPlaceHolder()); - newType.setGenericsTypes(applyGenericsContext(spec, type.getGenericsTypes())); - } - // GRECLIPSE end - GenericsType newGT = new GenericsType(newType); - return newGT; - } - - private static boolean hasNonTrivialBounds(GenericsType gt) { - ClassNode[] upperBounds = gt.getUpperBounds(); - return gt.getLowerBound() != null || gt.isWildcard() || - (upperBounds != null && ( - upperBounds.length != 1 - || upperBounds[0].isGenericsPlaceHolder() - || !OBJECT_TYPE.equals(upperBounds[0]))); - } - - private static ClassNode[] applyGenericsContext( - Map spec, ClassNode[] bounds - ) { - if (bounds == null) return null; - ClassNode[] newBounds = new ClassNode[bounds.length]; - for (int i = 0; i < bounds.length; i++) { - newBounds[i] = applyGenericsContext(spec, bounds[i]); - } - return newBounds; - } - - static ClassNode applyGenericsContext( - Map spec, ClassNode bound - ) { - if (bound == null) return null; - if (bound.isArray()) { - return applyGenericsContext(spec, bound.getComponentType()).makeArray(); - } - if (!bound.isUsingGenerics()) return bound; - ClassNode newBound = bound.getPlainNodeReference(); - newBound.setGenericsTypes(applyGenericsContext(spec, bound.getGenericsTypes())); - if (bound.isGenericsPlaceHolder()) { - GenericsType[] gt = newBound.getGenericsTypes(); - boolean hasBounds = hasNonTrivialBounds(gt[0]); - if (hasBounds || !gt[0].isPlaceholder()) return getCombinedBoundType(gt[0]); - String placeHolderName = newBound.getGenericsTypes()[0].getName(); - if (!placeHolderName.equals(newBound.getUnresolvedName())) { - // we should produce a clean placeholder ClassNode here - ClassNode clean = make(placeHolderName); - clean.setGenericsTypes(newBound.getGenericsTypes()); - clean.setRedirect(newBound); - newBound = clean; - } - newBound.setGenericsPlaceHolder(true); - } - return newBound; - } - - private static ClassNode getCombinedBoundType(GenericsType genericsType) { - //TODO: this method should really return some kind of meta ClassNode - // representing the combination of all bounds. The code here, just picks - // something out to be able to proceed and is not actually correct - if (hasNonTrivialBounds(genericsType)) { - if (genericsType.getLowerBound() != null) return genericsType.getLowerBound(); - if (genericsType.getUpperBounds() != null) return genericsType.getUpperBounds()[0]; - } - return genericsType.getType(); - } - - private static void applyContextGenerics(Map resolvedPlaceholders, Map placeholdersFromContext) { - if (placeholdersFromContext == null) return; - for (Entry entry : resolvedPlaceholders.entrySet()) { - GenericsType gt = entry.getValue(); - if (gt.isPlaceholder()) { - String name = gt.getName(); - GenericsType outer = placeholdersFromContext.get(name); - if (outer == null) continue; - entry.setValue(outer); - } - } - } - - private static Map getGenericsParameterMapOfThis(ClassNode cn) { - if (cn == null) return null; - Map map = null; - if (cn.getEnclosingMethod() != null) { - map = extractGenericsParameterMapOfThis(cn.getEnclosingMethod()); - } else if (cn.getOuterClass() != null) { - map = getGenericsParameterMapOfThis(cn.getOuterClass()); - } - map = mergeGenerics(map, cn.getGenericsTypes()); - return map; - } - - /** - * Apply the bounds from the declared type when the using type simply declares a parameter as an unbounded wildcard. - * - * @param type A parameterized type - * @return A parameterized type with more precise wildcards - */ - static ClassNode boundUnboundedWildcards(ClassNode type) { - if (type.isArray()) { - return boundUnboundedWildcards(type.getComponentType()).makeArray(); - } - ClassNode target = type.redirect(); - if (target == null || type == target || !isUsingGenericsOrIsArrayUsingGenerics(target)) return type; - ClassNode newType = type.getPlainNodeReference(); - newType.setGenericsPlaceHolder(type.isGenericsPlaceHolder()); - newType.setGenericsTypes(boundUnboundedWildcards(type.getGenericsTypes(), target.getGenericsTypes())); - return newType; - } - - private static GenericsType[] boundUnboundedWildcards(GenericsType[] usage, GenericsType[] declaration) { - GenericsType[] newGts = new GenericsType[usage.length]; - for (int i = 0; i < usage.length; i++) { - newGts[i] = boundUnboundedWildcard(usage[i], declaration[i]); - } - return newGts; - } - - private static GenericsType boundUnboundedWildcard(GenericsType gt, GenericsType spec) { - if (isUnboundedWildcard(gt)) { - ClassNode base = makeWithoutCaching("?"); - // The bounds on the declared type are at least as good as the ones on an unbounded wildcard, since it has - // none! - GenericsType newGt = new GenericsType(base, spec.getUpperBounds(), spec.getLowerBound()); - newGt.setWildcard(true); - return newGt; - } - return gt; - } - - private static boolean isUnboundedWildcard(GenericsType gt) { - if (gt.isWildcard() && gt.getLowerBound() == null) { - ClassNode[] upperBounds = gt.getUpperBounds(); - return upperBounds == null || - upperBounds.length == 0 || - (upperBounds.length == 1 && OBJECT_TYPE.equals(upperBounds[0])); - } - return false; - } - - static Map extractGenericsParameterMapOfThis(MethodNode mn) { - if (mn == null) return null; - - Map map; - if (mn.isStatic()) { - map = new HashMap<>(); - } else { - map = getGenericsParameterMapOfThis(mn.getDeclaringClass()); - } - - return mergeGenerics(map, mn.getGenericsTypes()); - } - - private static Map mergeGenerics(Map current, GenericsType[] newGenerics) { - if (newGenerics == null || newGenerics.length == 0) return current; - if (current == null) current = new HashMap(); - for (GenericsType gt : newGenerics) { - if (!gt.isPlaceholder()) continue; - String name = gt.getName(); - if (!current.containsKey(name)) current.put(name, gt); - } - return current; - } - - /** - * A DGM-like method which adds support for method calls which are handled - * specifically by the Groovy compiler. - */ - public static class ObjectArrayStaticTypesHelper { - public static T getAt(T[] arr, int index) { - return null == arr ? null : arr[index]; - } - - public static void putAt(T[] arr, int index, U object) { - if (null == arr) { - return; - } - - arr[index] = object; - } - } - - public static class BooleanArrayStaticTypesHelper { - public static Boolean getAt(boolean[] arr, int index) { - return null == arr ? null : arr[index]; - } - - public static void putAt(boolean[] arr, int index, boolean object) { - if (null == arr) { - return; - } - - arr[index] = object; - } - } - - public static class CharArrayStaticTypesHelper { - public static Character getAt(char[] arr, int index) { - return null == arr ? null : arr[index]; - } - - public static void putAt(char[] arr, int index, char object) { - if (null == arr) { - return; - } - - arr[index] = object; - } - } - - public static class ByteArrayStaticTypesHelper { - public static Byte getAt(byte[] arr, int index) { - return null == arr ? null : arr[index]; - } - - public static void putAt(byte[] arr, int index, byte object) { - if (null == arr) { - return; - } - - arr[index] = object; - } - } - - public static class ShortArrayStaticTypesHelper { - public static Short getAt(short[] arr, int index) { - return null == arr ? null : arr[index]; - } - - public static void putAt(short[] arr, int index, short object) { - if (null == arr) { - return; - } - - arr[index] = object; - } - } - - public static class IntArrayStaticTypesHelper { - public static Integer getAt(int[] arr, int index) { - return null == arr ? null : arr[index]; - } - - public static void putAt(int[] arr, int index, int object) { - if (null == arr) { - return; - } - - arr[index] = object; - } - } - - public static class LongArrayStaticTypesHelper { - public static Long getAt(long[] arr, int index) { - return null == arr ? null : arr[index]; - } - - public static void putAt(long[] arr, int index, long object) { - if (null == arr) { - return; - } - - arr[index] = object; - } - } - - public static class FloatArrayStaticTypesHelper { - public static Float getAt(float[] arr, int index) { - return null == arr ? null : arr[index]; - } - - public static void putAt(float[] arr, int index, float object) { - if (null == arr) { - return; - } - - arr[index] = object; - } - } - - public static class DoubleArrayStaticTypesHelper { - public static Double getAt(double[] arr, int index) { - return null == arr ? null : arr[index]; - } - - public static void putAt(double[] arr, int index, double object) { - if (null == arr) { - return; - } - - arr[index] = object; - } - } - - - /** - * This class is used to make extension methods lookup faster. Basically, it will only - * collect the list of extension methods (see {@link ExtensionModule} if the list of - * extension modules has changed. It avoids recomputing the whole list each time we perform - * a method lookup. - */ - private static class ExtensionMethodCache { - private final EvictableCache>> cache = new ConcurrentCommonCache>>(new WeakHashMap>>()); - - public Map> getExtensionMethods(ClassLoader loader) { - return cache.getAndPut( - loader, - new EvictableCache.ValueProvider>>() { - @Override - public Map> provide(final ClassLoader key) { - final List modules = new LinkedList(); - ExtensionModuleScanner scanner = - new ExtensionModuleScanner( - new ExtensionModuleScanner.ExtensionModuleListener() { - public void onModule(final ExtensionModule module) { - boolean skip = false; - for (ExtensionModule extensionModule : modules) { - if (extensionModule.getName().equals(module.getName())) { - skip = true; - break; - } - } - if (!skip) modules.add(module); - } - }, - key - ); - scanner.scanClasspathModules(); - - return Collections.unmodifiableMap(getDGMMethods(modules)); - } - }); - } - - /** - * Returns a map which contains, as the key, the name of a class. The value - * consists of a list of MethodNode, one for each default groovy method found - * which is applicable for this class. - * - * @param modules - * @return - */ - private static Map> getDGMMethods(List modules) { - Set instanceExtClasses = new LinkedHashSet(); - Set staticExtClasses = new LinkedHashSet(); - for (ExtensionModule module : modules) { - if (module instanceof MetaInfExtensionModule) { - MetaInfExtensionModule extensionModule = (MetaInfExtensionModule) module; - instanceExtClasses.addAll(extensionModule.getInstanceMethodsExtensionClasses()); - staticExtClasses.addAll(extensionModule.getStaticMethodsExtensionClasses()); - } - } - Map> methods = new HashMap>(); - Collections.addAll(instanceExtClasses, DefaultGroovyMethods.DGM_LIKE_CLASSES); - Collections.addAll(instanceExtClasses, DefaultGroovyMethods.ADDITIONAL_CLASSES); - staticExtClasses.add(DefaultGroovyStaticMethods.class); - - instanceExtClasses.add(ObjectArrayStaticTypesHelper.class); - instanceExtClasses.add(BooleanArrayStaticTypesHelper.class); - instanceExtClasses.add(CharArrayStaticTypesHelper.class); - instanceExtClasses.add(ByteArrayStaticTypesHelper.class); - instanceExtClasses.add(ShortArrayStaticTypesHelper.class); - instanceExtClasses.add(IntArrayStaticTypesHelper.class); - instanceExtClasses.add(LongArrayStaticTypesHelper.class); - instanceExtClasses.add(FloatArrayStaticTypesHelper.class); - instanceExtClasses.add(DoubleArrayStaticTypesHelper.class); - - Collections.addAll(instanceExtClasses, VMPluginFactory.getPlugin().getPluginDefaultGroovyMethods()); - Collections.addAll(staticExtClasses, VMPluginFactory.getPlugin().getPluginStaticGroovyMethods()); - - scanClassesForDGMMethods(methods, staticExtClasses, true); - scanClassesForDGMMethods(methods, instanceExtClasses, false); - - return methods; - } - - private static void scanClassesForDGMMethods(Map> accumulator, - Iterable allClasses, boolean isStatic) { - for (Class dgmLikeClass : allClasses) { - ClassNode cn = makeWithoutCaching(dgmLikeClass, true); - for (MethodNode metaMethod : cn.getMethods()) { - Parameter[] types = metaMethod.getParameters(); - if (metaMethod.isStatic() && metaMethod.isPublic() && types.length > 0 - && metaMethod.getAnnotations(Deprecated_TYPE).isEmpty()) { - Parameter[] parameters = new Parameter[types.length - 1]; - System.arraycopy(types, 1, parameters, 0, parameters.length); - ExtensionMethodNode node = new ExtensionMethodNode( - metaMethod, - metaMethod.getName(), - metaMethod.getModifiers(), - metaMethod.getReturnType(), - parameters, - ClassNode.EMPTY_ARRAY, null, - isStatic); - node.setGenericsTypes(metaMethod.getGenericsTypes()); - ClassNode declaringClass = types[0].getType(); - String declaringClassName = declaringClass.getName(); - node.setDeclaringClass(declaringClass); - - List nodes = accumulator.get(declaringClassName); - if (nodes == null) { - nodes = new LinkedList(); - accumulator.put(declaringClassName, nodes); - } - nodes.add(node); - } - } - } - } - - } - - /** - * @return true if the class node is either a GString or the LUB of String and GString. - */ - public static boolean isGStringOrGStringStringLUB(ClassNode node) { - return GSTRING_TYPE.equals(node) || GSTRING_STRING_CLASSNODE.equals(node); - } - - /** - * @param node the node to be tested - * @return true if the node is using generics types and one of those types is a gstring or string/gstring lub - */ - public static boolean isParameterizedWithGStringOrGStringString(ClassNode node) { - if (node.isArray()) return isParameterizedWithGStringOrGStringString(node.getComponentType()); - if (node.isUsingGenerics()) { - GenericsType[] genericsTypes = node.getGenericsTypes(); - if (genericsTypes != null) { - for (GenericsType genericsType : genericsTypes) { - if (isGStringOrGStringStringLUB(genericsType.getType())) return true; - } - } - } - return node.getSuperClass() != null && isParameterizedWithGStringOrGStringString(node.getUnresolvedSuperClass()); - } - - /** - * @param node the node to be tested - * @return true if the node is using generics types and one of those types is a string - */ - public static boolean isParameterizedWithString(ClassNode node) { - if (node.isArray()) return isParameterizedWithString(node.getComponentType()); - if (node.isUsingGenerics()) { - GenericsType[] genericsTypes = node.getGenericsTypes(); - if (genericsTypes != null) { - for (GenericsType genericsType : genericsTypes) { - if (STRING_TYPE.equals(genericsType.getType())) return true; - } - } - } - return node.getSuperClass() != null && isParameterizedWithString(node.getUnresolvedSuperClass()); - } - - public static boolean missesGenericsTypes(ClassNode cn) { - if (cn.isArray()) return missesGenericsTypes(cn.getComponentType()); - GenericsType[] cnTypes = cn.getGenericsTypes(); - GenericsType[] rnTypes = cn.redirect().getGenericsTypes(); - if (rnTypes != null && cnTypes == null) return true; - if (cnTypes != null) { - for (GenericsType genericsType : cnTypes) { - if (genericsType.isPlaceholder()) return true; - } - } - return false; - } - - /** - * A helper method that can be used to evaluate expressions as found in annotation - * parameters. For example, it will evaluate a constant, be it referenced directly as - * an integer or as a reference to a field. - *

- * If this method throws an exception, then the expression cannot be evaluated on its own. - * - * @param expr the expression to be evaluated - * @param config the compiler configuration - * @return the result of the expression - */ - public static Object evaluateExpression(Expression expr, CompilerConfiguration config) { - String className = "Expression$" + UUID.randomUUID().toString().replace('-', '$'); - ClassNode node = new ClassNode(className, Opcodes.ACC_PUBLIC, OBJECT_TYPE); - ReturnStatement code = new ReturnStatement(expr); - node.addMethod(new MethodNode("eval", Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, code)); - CompilerConfiguration copyConf = new CompilerConfiguration(config); - CompilationUnit cu = new CompilationUnit(copyConf); - cu.addClassNode(node); - cu.compile(Phases.CLASS_GENERATION); - List classes = (List) cu.getClasses(); - Class aClass = cu.getClassLoader().defineClass(className, classes.get(0).getBytes()); - try { - return aClass.getMethod("eval").invoke(null); - } catch (IllegalAccessException e) { - throw new GroovyBugError(e); - } catch (InvocationTargetException e) { - throw new GroovyBugError(e); - } catch (NoSuchMethodException e) { - throw new GroovyBugError(e); - } - } - - /** - * Collects all interfaces of a class node, including those defined by the - * super class. - * - * @param node a class for which we want to retrieve all interfaces - * @return a set of interfaces implemented by this class node - */ - public static Set collectAllInterfaces(ClassNode node) { - Set result = new HashSet(); - collectAllInterfaces(node, result); - return result; - } - - /** - * Collects all interfaces of a class node, including those defined by the - * super class. - * - * @param node a class for which we want to retrieve all interfaces - * @param out the set where to collect interfaces - */ - private static void collectAllInterfaces(final ClassNode node, final Set out) { - if (node == null) return; - Set allInterfaces = node.getAllInterfaces(); - out.addAll(allInterfaces); - collectAllInterfaces(node.getSuperClass(), out); - } - - /** - * Returns true if the class node represents a the class node for the Class class - * and if the parametrized type is a neither a placeholder or a wildcard. For example, - * the class node Class<Foo> where Foo is a class would return true, but the class - * node for Class<?> would return false. - * - * @param classNode a class node to be tested - * @return true if it is the class node for Class and its generic type is a real class - */ - public static boolean isClassClassNodeWrappingConcreteType(ClassNode classNode) { - GenericsType[] genericsTypes = classNode.getGenericsTypes(); - return CLASS_Type.equals(classNode) - && classNode.isUsingGenerics() - && genericsTypes != null - && !genericsTypes[0].isPlaceholder() - && !genericsTypes[0].isWildcard(); - } - - public static List findSetters(ClassNode cn, String setterName, boolean voidOnly) { - List result = null; - for (MethodNode method : cn.getDeclaredMethods(setterName)) { - if (setterName.equals(method.getName()) - && (!voidOnly || VOID_TYPE == method.getReturnType()) - && method.getParameters().length == 1) { - if (result == null) { - result = new LinkedList(); - } - result.add(method); - } - } - if (result == null) { - ClassNode parent = cn.getSuperClass(); - if (parent != null) { - return findSetters(parent, setterName, voidOnly); - } - return Collections.emptyList(); - } - return result; - } - - public static ClassNode isTraitSelf(VariableExpression vexp) { - if (Traits.THIS_OBJECT.equals(vexp.getName())) { - Variable accessedVariable = vexp.getAccessedVariable(); - ClassNode type = accessedVariable != null ? accessedVariable.getType() : null; - if (accessedVariable instanceof Parameter - && Traits.isTrait(type)) { - return type; - } - } - return null; - } -} diff --git a/base/org.codehaus.groovy26/.checkstyle b/base/org.codehaus.groovy30/.checkstyle similarity index 97% rename from base/org.codehaus.groovy26/.checkstyle rename to base/org.codehaus.groovy30/.checkstyle index a3e78be317..82acf81d11 100644 --- a/base/org.codehaus.groovy26/.checkstyle +++ b/base/org.codehaus.groovy30/.checkstyle @@ -25,7 +25,6 @@ - @@ -33,6 +32,7 @@ + @@ -40,6 +40,7 @@ + @@ -72,7 +73,6 @@ - diff --git a/base/org.codehaus.groovy26/.classpath b/base/org.codehaus.groovy30/.classpath similarity index 68% rename from base/org.codehaus.groovy26/.classpath rename to base/org.codehaus.groovy30/.classpath index d22d959068..b6fa83c870 100644 --- a/base/org.codehaus.groovy26/.classpath +++ b/base/org.codehaus.groovy30/.classpath @@ -6,17 +6,17 @@ - + - + - + - + - + diff --git a/base/org.codehaus.groovy26/.externalToolBuilders/Antlr2 Builder.launch b/base/org.codehaus.groovy30/.externalToolBuilders/Antlr2 Builder.launch similarity index 93% rename from base/org.codehaus.groovy26/.externalToolBuilders/Antlr2 Builder.launch rename to base/org.codehaus.groovy30/.externalToolBuilders/Antlr2 Builder.launch index 85953ebc4e..7b83fbc438 100644 --- a/base/org.codehaus.groovy26/.externalToolBuilders/Antlr2 Builder.launch +++ b/base/org.codehaus.groovy30/.externalToolBuilders/Antlr2 Builder.launch @@ -4,14 +4,14 @@ - + - + diff --git a/base/org.codehaus.groovy26/.externalToolBuilders/Antlr4 Builder.launch b/base/org.codehaus.groovy30/.externalToolBuilders/Antlr4 Builder.launch similarity index 89% rename from base/org.codehaus.groovy26/.externalToolBuilders/Antlr4 Builder.launch rename to base/org.codehaus.groovy30/.externalToolBuilders/Antlr4 Builder.launch index efa5d9a456..9b814ec8b7 100644 --- a/base/org.codehaus.groovy26/.externalToolBuilders/Antlr4 Builder.launch +++ b/base/org.codehaus.groovy30/.externalToolBuilders/Antlr4 Builder.launch @@ -4,14 +4,14 @@ - + - + diff --git a/base/org.codehaus.groovy26/.gitignore b/base/org.codehaus.groovy30/.gitignore similarity index 100% rename from base/org.codehaus.groovy26/.gitignore rename to base/org.codehaus.groovy30/.gitignore diff --git a/base/org.codehaus.groovy26/.project b/base/org.codehaus.groovy30/.project similarity index 98% rename from base/org.codehaus.groovy26/.project rename to base/org.codehaus.groovy30/.project index 07fea37a7f..7bc3b69f03 100644 --- a/base/org.codehaus.groovy26/.project +++ b/base/org.codehaus.groovy30/.project @@ -1,7 +1,7 @@ - org.codehaus.groovy26 + org.codehaus.groovy30 org.eclipse.ui.externaltools.ExternalToolBuilder diff --git a/base/org.codehaus.groovy26/.settings/org.eclipse.core.resources.prefs b/base/org.codehaus.groovy30/.settings/org.eclipse.core.resources.prefs similarity index 100% rename from base/org.codehaus.groovy26/.settings/org.eclipse.core.resources.prefs rename to base/org.codehaus.groovy30/.settings/org.eclipse.core.resources.prefs diff --git a/base/org.codehaus.groovy26/.settings/org.eclipse.core.runtime.prefs b/base/org.codehaus.groovy30/.settings/org.eclipse.core.runtime.prefs similarity index 100% rename from base/org.codehaus.groovy26/.settings/org.eclipse.core.runtime.prefs rename to base/org.codehaus.groovy30/.settings/org.eclipse.core.runtime.prefs diff --git a/base/org.codehaus.groovy26/.settings/org.eclipse.jdt.core.prefs b/base/org.codehaus.groovy30/.settings/org.eclipse.jdt.core.prefs similarity index 100% rename from base/org.codehaus.groovy26/.settings/org.eclipse.jdt.core.prefs rename to base/org.codehaus.groovy30/.settings/org.eclipse.jdt.core.prefs diff --git a/base/org.codehaus.groovy26/.settings/org.eclipse.jdt.groovy.core.prefs b/base/org.codehaus.groovy30/.settings/org.eclipse.jdt.groovy.core.prefs similarity index 100% rename from base/org.codehaus.groovy26/.settings/org.eclipse.jdt.groovy.core.prefs rename to base/org.codehaus.groovy30/.settings/org.eclipse.jdt.groovy.core.prefs diff --git a/base/org.codehaus.groovy26/.settings/org.eclipse.jdt.ui.prefs b/base/org.codehaus.groovy30/.settings/org.eclipse.jdt.ui.prefs similarity index 100% rename from base/org.codehaus.groovy26/.settings/org.eclipse.jdt.ui.prefs rename to base/org.codehaus.groovy30/.settings/org.eclipse.jdt.ui.prefs diff --git a/base/org.codehaus.groovy30/META-INF/MANIFEST.MF b/base/org.codehaus.groovy30/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..c94353ff58 --- /dev/null +++ b/base/org.codehaus.groovy30/META-INF/MANIFEST.MF @@ -0,0 +1,112 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: org.codehaus.groovy +Automatic-Module-Name: org.codehaus.groovy +Bundle-Name: Groovy Runtime +Bundle-Vendor: Pivotal Software, Inc. +Bundle-Version: 3.0.0.qualifier +Bundle-ClassPath: eclipse-trace.jar, + groovy-eclipse.jar, + lib/ivy-2.4.0.jar, + lib/groovy-3.0.0-indy.jar, + lib/groovy-test-3.0.0-indy.jar +Export-Package: groovy.beans;version="3.0.0", + groovy.cli;version="3.0.0", + groovy.grape;version="3.0.0", + groovy.inspect;version="3.0.0", + groovy.io;version="3.0.0", + groovy.lang;version="3.0.0", + groovy.lang.groovydoc;version="3.0.0", + groovy.mock.interceptor;version="3.0.0", + groovy.security;version="3.0.0", + groovy.test;version="3.0.0", + groovy.time;version="3.0.0", + groovy.transform;version="3.0.0", + groovy.transform.builder;version="3.0.0", + groovy.transform.options;version="3.0.0", + groovy.transform.stc;version="3.0.0", + groovy.ui;version="3.0.0", + groovy.util;version="3.0.0", + groovy.util.logging;version="3.0.0", + groovy.xml;version="3.0.0", + groovyjarjarantlr;x-internal:=true, + groovyjarjarasm.asm;x-internal:=true, + org.apache.groovy.ast.tools;version="3.0.0", + org.apache.groovy.internal.metaclass;version="3.0.0", + org.apache.groovy.internal.util;version="3.0.0", + org.apache.groovy.io;version="3.0.0", + org.apache.groovy.lang.annotation;version="3.0.0", + org.apache.groovy.metaclass;version="3.0.0", + org.apache.groovy.parser;version="3.0.0", + org.apache.groovy.parser.antlr4;version="3.0.0", + org.apache.groovy.parser.antlr4.util;version="3.0.0", + org.apache.groovy.plugin;version="3.0.0", + org.apache.groovy.util;version="3.0.0", + org.apache.groovy.util.concurrentlinkedhashmap;version="3.0.0", + org.codehaus.greclipse;x-internal:=true, + org.codehaus.groovy;version="3.0.0", + org.codehaus.groovy.activator, + org.codehaus.groovy.antlr;version="3.0.0", + org.codehaus.groovy.antlr.java;version="3.0.0", + org.codehaus.groovy.antlr.parser;version="3.0.0", + org.codehaus.groovy.antlr.treewalker;version="3.0.0", + org.codehaus.groovy.ast;version="3.0.0", + org.codehaus.groovy.ast.builder;version="3.0.0", + org.codehaus.groovy.ast.decompiled;version="3.0.0", + org.codehaus.groovy.ast.expr;version="3.0.0", + org.codehaus.groovy.ast.stmt;version="3.0.0", + org.codehaus.groovy.ast.tools;version="3.0.0", + org.codehaus.groovy.classgen;version="3.0.0", + org.codehaus.groovy.classgen.asm;version="3.0.0", + org.codehaus.groovy.classgen.asm.indy;version="3.0.0", + org.codehaus.groovy.classgen.asm.indy.sc;version="3.0.0", + org.codehaus.groovy.classgen.asm.sc;version="3.0.0", + org.codehaus.groovy.classgen.asm.util;version="3.0.0", + org.codehaus.groovy.control;version="3.0.0", + org.codehaus.groovy.control.customizers;version="3.0.0", + org.codehaus.groovy.control.customizers.builder;version="3.0.0", + org.codehaus.groovy.control.io;version="3.0.0", + org.codehaus.groovy.control.messages;version="3.0.0", + org.codehaus.groovy.eclipse, + org.codehaus.groovy.plugin;version="3.0.0", + org.codehaus.groovy.reflection;version="3.0.0", + org.codehaus.groovy.reflection.android;version="3.0.0", + org.codehaus.groovy.reflection.stdclasses;version="3.0.0", + org.codehaus.groovy.reflection.v7;version="3.0.0", + org.codehaus.groovy.runtime;version="3.0.0", + org.codehaus.groovy.runtime.callsite;version="3.0.0", + org.codehaus.groovy.runtime.dgmimpl;version="3.0.0", + org.codehaus.groovy.runtime.dgmimpl.arrays;version="3.0.0", + org.codehaus.groovy.runtime.m12n;version="3.0.0", + org.codehaus.groovy.runtime.memoize;version="3.0.0", + org.codehaus.groovy.runtime.metaclass;version="3.0.0", + org.codehaus.groovy.runtime.powerassert;version="3.0.0", + org.codehaus.groovy.runtime.typehandling;version="3.0.0", + org.codehaus.groovy.runtime.wrappers;version="3.0.0", + org.codehaus.groovy.syntax;version="3.0.0", + org.codehaus.groovy.tools;version="3.0.0", + org.codehaus.groovy.tools.ast;version="3.0.0", + org.codehaus.groovy.tools.gse;version="3.0.0", + org.codehaus.groovy.tools.javac;version="3.0.0", + org.codehaus.groovy.tools.shell;version="3.0.0", + org.codehaus.groovy.tools.shell.util;version="3.0.0", + org.codehaus.groovy.transform;version="3.0.0", + org.codehaus.groovy.transform.sc;version="3.0.0", + org.codehaus.groovy.transform.sc.transformers;version="3.0.0", + org.codehaus.groovy.transform.stc;version="3.0.0", + org.codehaus.groovy.transform.tailrec;version="3.0.0", + org.codehaus.groovy.transform.trait;version="3.0.0", + org.codehaus.groovy.util;version="3.0.0", + org.codehaus.groovy.vmplugin;version="3.0.0", + org.codehaus.groovy.vmplugin.v5;version="3.0.0", + org.codehaus.groovy.vmplugin.v6;version="3.0.0", + org.codehaus.groovy.vmplugin.v7;version="3.0.0", + org.codehaus.groovy.vmplugin.v8;version="3.0.0", + org.codehaus.groovy.vmplugin.v9;version="3.0.0" +Require-Bundle: org.eclipse.core.runtime, + org.apache.ant;resolution:=optional, + org.junit;resolution:=optional +Bundle-ActivationPolicy: lazy +Bundle-Activator: org.codehaus.groovy.activator.GroovyActivator +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Eclipse-BundleShape: dir diff --git a/base/org.codehaus.groovy30/VERSION b/base/org.codehaus.groovy30/VERSION new file mode 100644 index 0000000000..74c9a97812 --- /dev/null +++ b/base/org.codehaus.groovy30/VERSION @@ -0,0 +1 @@ +2018-12-31: GROOVY_3_0_0_ALPHA_4 diff --git a/base/org.codehaus.groovy26/about.html b/base/org.codehaus.groovy30/about.html similarity index 85% rename from base/org.codehaus.groovy26/about.html rename to base/org.codehaus.groovy30/about.html index b849e061e3..e301a13011 100644 --- a/base/org.codehaus.groovy26/about.html +++ b/base/org.codehaus.groovy30/about.html @@ -24,12 +24,12 @@

License

Third Party Content

-

groovy-2.6.0-indy.jar

-

groovy-test-2.6.0-indy.jar

+

groovy-3.0.0-indy.jar

+

groovy-test-3.0.0-indy.jar

    -
  • Obtained from: https://dist.apache.org/repos/dist/dev/groovy/2.6.0/distribution/apache-groovy-binary-2.6.0.zip
  • -
  • Sources available at: https://dist.apache.org/repos/dist/dev/groovy/2.6.0/sources/apache-groovy-src-2.6.0.zip
  • +
  • Obtained from: https://dist.apache.org/repos/dist/dev/groovy/3.0.0/distribution/apache-groovy-binary-3.0.0.zip
  • +
  • Sources available at: https://dist.apache.org/repos/dist/dev/groovy/3.0.0/sources/apache-groovy-src-3.0.0.zip
  • License kind: ASL
  • License URL: http://www.apache.org/licenses/LICENSE-2.0.html
  • License text: asl-v20.txt
  • diff --git a/base/org.codehaus.groovy26/about_files/antlr2-license.txt b/base/org.codehaus.groovy30/about_files/antlr2-license.txt similarity index 100% rename from base/org.codehaus.groovy26/about_files/antlr2-license.txt rename to base/org.codehaus.groovy30/about_files/antlr2-license.txt diff --git a/base/org.codehaus.groovy26/about_files/antlr4-license.txt b/base/org.codehaus.groovy30/about_files/antlr4-license.txt similarity index 100% rename from base/org.codehaus.groovy26/about_files/antlr4-license.txt rename to base/org.codehaus.groovy30/about_files/antlr4-license.txt diff --git a/base/org.codehaus.groovy26/about_files/asl2-license.txt b/base/org.codehaus.groovy30/about_files/asl2-license.txt similarity index 100% rename from base/org.codehaus.groovy26/about_files/asl2-license.txt rename to base/org.codehaus.groovy30/about_files/asl2-license.txt diff --git a/base/org.codehaus.groovy26/about_files/asm-license.txt b/base/org.codehaus.groovy30/about_files/asm-license.txt similarity index 100% rename from base/org.codehaus.groovy26/about_files/asm-license.txt rename to base/org.codehaus.groovy30/about_files/asm-license.txt diff --git a/base/org.codehaus.groovy26/build.antlr2x b/base/org.codehaus.groovy30/build.antlr2x similarity index 89% rename from base/org.codehaus.groovy26/build.antlr2x rename to base/org.codehaus.groovy30/build.antlr2x index 11b73c533c..f3b0bacea0 100644 --- a/base/org.codehaus.groovy26/build.antlr2x +++ b/base/org.codehaus.groovy30/build.antlr2x @@ -1,7 +1,7 @@ - + diff --git a/base/org.codehaus.groovy26/build.antlr4x b/base/org.codehaus.groovy30/build.antlr4x similarity index 100% rename from base/org.codehaus.groovy26/build.antlr4x rename to base/org.codehaus.groovy30/build.antlr4x diff --git a/base/org.codehaus.groovy26/build.properties b/base/org.codehaus.groovy30/build.properties similarity index 100% rename from base/org.codehaus.groovy26/build.properties rename to base/org.codehaus.groovy30/build.properties diff --git a/base/org.codehaus.groovy26/lib/groovy-2.6.0-indy.jar b/base/org.codehaus.groovy30/lib/groovy-3.0.0-indy.jar similarity index 59% rename from base/org.codehaus.groovy26/lib/groovy-2.6.0-indy.jar rename to base/org.codehaus.groovy30/lib/groovy-3.0.0-indy.jar index a8f43a2fdc..ebb1e52df9 100644 Binary files a/base/org.codehaus.groovy26/lib/groovy-2.6.0-indy.jar and b/base/org.codehaus.groovy30/lib/groovy-3.0.0-indy.jar differ diff --git a/base/org.codehaus.groovy30/lib/groovy-3.0.0-javadoc.jar b/base/org.codehaus.groovy30/lib/groovy-3.0.0-javadoc.jar new file mode 100644 index 0000000000..e4291fc1f2 Binary files /dev/null and b/base/org.codehaus.groovy30/lib/groovy-3.0.0-javadoc.jar differ diff --git a/base/org.codehaus.groovy26/lib/groovy-2.6.0-sources.jar b/base/org.codehaus.groovy30/lib/groovy-3.0.0-sources.jar similarity index 62% rename from base/org.codehaus.groovy26/lib/groovy-2.6.0-sources.jar rename to base/org.codehaus.groovy30/lib/groovy-3.0.0-sources.jar index 585fb4aed5..709b77c082 100644 Binary files a/base/org.codehaus.groovy26/lib/groovy-2.6.0-sources.jar and b/base/org.codehaus.groovy30/lib/groovy-3.0.0-sources.jar differ diff --git a/base/org.codehaus.groovy30/lib/groovy-test-3.0.0-indy.jar b/base/org.codehaus.groovy30/lib/groovy-test-3.0.0-indy.jar new file mode 100644 index 0000000000..0dcedaf8a0 Binary files /dev/null and b/base/org.codehaus.groovy30/lib/groovy-test-3.0.0-indy.jar differ diff --git a/base/org.codehaus.groovy30/lib/groovy-test-3.0.0-javadoc.jar b/base/org.codehaus.groovy30/lib/groovy-test-3.0.0-javadoc.jar new file mode 100644 index 0000000000..9666999584 Binary files /dev/null and b/base/org.codehaus.groovy30/lib/groovy-test-3.0.0-javadoc.jar differ diff --git a/base/org.codehaus.groovy26/lib/groovy-test-2.6.0-sources.jar b/base/org.codehaus.groovy30/lib/groovy-test-3.0.0-sources.jar similarity index 89% rename from base/org.codehaus.groovy26/lib/groovy-test-2.6.0-sources.jar rename to base/org.codehaus.groovy30/lib/groovy-test-3.0.0-sources.jar index 4d3f58e579..e24d176c14 100644 Binary files a/base/org.codehaus.groovy26/lib/groovy-test-2.6.0-sources.jar and b/base/org.codehaus.groovy30/lib/groovy-test-3.0.0-sources.jar differ diff --git a/base/org.codehaus.groovy26/lib/ivy-2.4.0-javadoc.jar b/base/org.codehaus.groovy30/lib/ivy-2.4.0-javadoc.jar similarity index 100% rename from base/org.codehaus.groovy26/lib/ivy-2.4.0-javadoc.jar rename to base/org.codehaus.groovy30/lib/ivy-2.4.0-javadoc.jar diff --git a/base/org.codehaus.groovy26/lib/ivy-2.4.0-sources.jar b/base/org.codehaus.groovy30/lib/ivy-2.4.0-sources.jar similarity index 100% rename from base/org.codehaus.groovy26/lib/ivy-2.4.0-sources.jar rename to base/org.codehaus.groovy30/lib/ivy-2.4.0-sources.jar diff --git a/base/org.codehaus.groovy26/lib/ivy-2.4.0.jar b/base/org.codehaus.groovy30/lib/ivy-2.4.0.jar similarity index 100% rename from base/org.codehaus.groovy26/lib/ivy-2.4.0.jar rename to base/org.codehaus.groovy30/lib/ivy-2.4.0.jar diff --git a/base/org.codehaus.groovy26/plugin_dsld_support/dsld/basic_transforms.dsld b/base/org.codehaus.groovy30/plugin_dsld_support/dsld/basic_transforms.dsld similarity index 100% rename from base/org.codehaus.groovy26/plugin_dsld_support/dsld/basic_transforms.dsld rename to base/org.codehaus.groovy30/plugin_dsld_support/dsld/basic_transforms.dsld diff --git a/base/org.codehaus.groovy26/plugin_dsld_support/dsld/beans_transforms.dsld b/base/org.codehaus.groovy30/plugin_dsld_support/dsld/beans_transforms.dsld similarity index 100% rename from base/org.codehaus.groovy26/plugin_dsld_support/dsld/beans_transforms.dsld rename to base/org.codehaus.groovy30/plugin_dsld_support/dsld/beans_transforms.dsld diff --git a/base/org.codehaus.groovy26/plugin_dsld_support/dsld/builder_transform.dsld b/base/org.codehaus.groovy30/plugin_dsld_support/dsld/builder_transform.dsld similarity index 100% rename from base/org.codehaus.groovy26/plugin_dsld_support/dsld/builder_transform.dsld rename to base/org.codehaus.groovy30/plugin_dsld_support/dsld/builder_transform.dsld diff --git a/base/org.codehaus.groovy26/plugin_dsld_support/dsld/logging_transforms.dsld b/base/org.codehaus.groovy30/plugin_dsld_support/dsld/logging_transforms.dsld similarity index 100% rename from base/org.codehaus.groovy26/plugin_dsld_support/dsld/logging_transforms.dsld rename to base/org.codehaus.groovy30/plugin_dsld_support/dsld/logging_transforms.dsld diff --git a/base/org.codehaus.groovy26/plugin_dsld_support/dsld/meta_script.dsld b/base/org.codehaus.groovy30/plugin_dsld_support/dsld/meta_script.dsld similarity index 100% rename from base/org.codehaus.groovy26/plugin_dsld_support/dsld/meta_script.dsld rename to base/org.codehaus.groovy30/plugin_dsld_support/dsld/meta_script.dsld diff --git a/base/org.codehaus.groovy26/plugin_dsld_support/dsld/script_config.dsld b/base/org.codehaus.groovy30/plugin_dsld_support/dsld/script_config.dsld similarity index 100% rename from base/org.codehaus.groovy26/plugin_dsld_support/dsld/script_config.dsld rename to base/org.codehaus.groovy30/plugin_dsld_support/dsld/script_config.dsld diff --git a/base/org.codehaus.groovy26/plugin_dsld_support/dsld/swing_builder.dsld b/base/org.codehaus.groovy30/plugin_dsld_support/dsld/swing_builder.dsld similarity index 100% rename from base/org.codehaus.groovy26/plugin_dsld_support/dsld/swing_builder.dsld rename to base/org.codehaus.groovy30/plugin_dsld_support/dsld/swing_builder.dsld diff --git a/base/org.codehaus.groovy26/plugin_dsld_support/readme.txt b/base/org.codehaus.groovy30/plugin_dsld_support/readme.txt similarity index 100% rename from base/org.codehaus.groovy26/plugin_dsld_support/readme.txt rename to base/org.codehaus.groovy30/plugin_dsld_support/readme.txt diff --git a/base/org.codehaus.groovy26/pom.xml b/base/org.codehaus.groovy30/pom.xml similarity index 96% rename from base/org.codehaus.groovy26/pom.xml rename to base/org.codehaus.groovy30/pom.xml index 9d1f183e1a..f52894358e 100644 --- a/base/org.codehaus.groovy26/pom.xml +++ b/base/org.codehaus.groovy30/pom.xml @@ -8,7 +8,7 @@ org.codehaus.groovy.eclipse org.codehaus.groovy - 2.6.0-SNAPSHOT + 3.0.0-SNAPSHOT eclipse-plugin diff --git a/base/org.codehaus.groovy26/src-trace/org/codehaus/groovy/eclipse/DefaultGroovyLogger.java b/base/org.codehaus.groovy30/src-trace/org/codehaus/groovy/eclipse/DefaultGroovyLogger.java similarity index 100% rename from base/org.codehaus.groovy26/src-trace/org/codehaus/groovy/eclipse/DefaultGroovyLogger.java rename to base/org.codehaus.groovy30/src-trace/org/codehaus/groovy/eclipse/DefaultGroovyLogger.java diff --git a/base/org.codehaus.groovy26/src-trace/org/codehaus/groovy/eclipse/GroovyLogManager.java b/base/org.codehaus.groovy30/src-trace/org/codehaus/groovy/eclipse/GroovyLogManager.java similarity index 100% rename from base/org.codehaus.groovy26/src-trace/org/codehaus/groovy/eclipse/GroovyLogManager.java rename to base/org.codehaus.groovy30/src-trace/org/codehaus/groovy/eclipse/GroovyLogManager.java diff --git a/base/org.codehaus.groovy26/src-trace/org/codehaus/groovy/eclipse/IGroovyLogger.java b/base/org.codehaus.groovy30/src-trace/org/codehaus/groovy/eclipse/IGroovyLogger.java similarity index 100% rename from base/org.codehaus.groovy26/src-trace/org/codehaus/groovy/eclipse/IGroovyLogger.java rename to base/org.codehaus.groovy30/src-trace/org/codehaus/groovy/eclipse/IGroovyLogger.java diff --git a/base/org.codehaus.groovy26/src-trace/org/codehaus/groovy/eclipse/LoggerTest.java b/base/org.codehaus.groovy30/src-trace/org/codehaus/groovy/eclipse/LoggerTest.java similarity index 100% rename from base/org.codehaus.groovy26/src-trace/org/codehaus/groovy/eclipse/LoggerTest.java rename to base/org.codehaus.groovy30/src-trace/org/codehaus/groovy/eclipse/LoggerTest.java diff --git a/base/org.codehaus.groovy26/src-trace/org/codehaus/groovy/eclipse/TraceCategory.java b/base/org.codehaus.groovy30/src-trace/org/codehaus/groovy/eclipse/TraceCategory.java similarity index 100% rename from base/org.codehaus.groovy26/src-trace/org/codehaus/groovy/eclipse/TraceCategory.java rename to base/org.codehaus.groovy30/src-trace/org/codehaus/groovy/eclipse/TraceCategory.java diff --git a/base/org.codehaus.groovy26/src/GroovyLexer.g4 b/base/org.codehaus.groovy30/src/GroovyLexer.g4 similarity index 99% rename from base/org.codehaus.groovy26/src/GroovyLexer.g4 rename to base/org.codehaus.groovy30/src/GroovyLexer.g4 index c296288892..1ca690fb67 100644 --- a/base/org.codehaus.groovy26/src/GroovyLexer.g4 +++ b/base/org.codehaus.groovy30/src/GroovyLexer.g4 @@ -317,14 +317,14 @@ mode DEFAULT_MODE; // character in the double quotation string. e.g. "a" fragment DqStringCharacter - : ~["\\$] + : ~["\r\n\\$] | EscapeSequence ; // character in the single quotation string. e.g. 'a' fragment SqStringCharacter - : ~['\\] + : ~['\r\n\\] | EscapeSequence ; diff --git a/base/org.codehaus.groovy26/src/GroovyParser.g4 b/base/org.codehaus.groovy30/src/GroovyParser.g4 similarity index 95% rename from base/org.codehaus.groovy26/src/GroovyParser.g4 rename to base/org.codehaus.groovy30/src/GroovyParser.g4 index 36155314fc..926fb5b38b 100644 --- a/base/org.codehaus.groovy26/src/GroovyParser.g4 +++ b/base/org.codehaus.groovy30/src/GroovyParser.g4 @@ -41,17 +41,14 @@ options { @header { import java.util.Map; - import org.codehaus.groovy.util.ListHashMap; import org.codehaus.groovy.ast.NodeMetaDataHandler; - import org.codehaus.groovy.ast.NodeMetaDataHandlerHelper; import org.apache.groovy.parser.antlr4.SemanticPredicates; } @members { public static class GroovyParserRuleContext extends ParserRuleContext implements NodeMetaDataHandler { - private Map metaDataMap = null; - private NodeMetaDataHandlerHelper helper = new NodeMetaDataHandlerHelper(this); + private Map metaDataMap = null; public GroovyParserRuleContext() {} @@ -59,36 +56,6 @@ options { super(parent, invokingStateNumber); } - @Override - public T getNodeMetaData(Object key) { - return helper.getNodeMetaData(key); - } - - @Override - public void copyNodeMetaData(NodeMetaDataHandler other) { - helper.copyNodeMetaData(other); - } - - @Override - public void setNodeMetaData(Object key, Object value) { - helper.setNodeMetaData(key, value); - } - - @Override - public Object putNodeMetaData(Object key, Object value) { - return helper.putNodeMetaData(key, value); - } - - @Override - public void removeNodeMetaData(Object key) { - helper.removeNodeMetaData(key); - } - - @Override - public Map getNodeMetaData() { - return helper.getNodeMetaData(); - } - @Override public Map getMetaDataMap() { return this.metaDataMap; @@ -801,14 +768,8 @@ enhancedStatementExpression | standardLambdaExpression ; -/** - * In order to resolve the syntactic ambiguities, e.g. (String)'abc' can be parsed as a cast expression or a parentheses-less method call(method name: (String), arguments: 'abc') - * try to match expression first. - * If it is not a normal expression, then try to match the command expression - */ statementExpression - : expression #normalExprAlt - | commandExpression #commandExprAlt + : commandExpression #commandExprAlt ; postfixExpression @@ -919,9 +880,9 @@ enhancedExpression */ commandExpression - : pathExpression + : expression ( - { SemanticPredicates.isFollowingMethodName($pathExpression.t) }? + { !SemanticPredicates.isFollowingArgumentsOrClosure($expression.ctx) }? argumentList | /* if pathExpression is a method call, no need to have any more arguments */ @@ -984,7 +945,7 @@ pathElement returns [int t] namePart { $t = 1; } | - DOT nls NEW creator[1] + nls DOT nls NEW creator[1] { $t = 6; } | arguments { $t = 2; } @@ -1046,7 +1007,7 @@ indexPropertyArgs ; namedPropertyArgs - : LBRACK mapEntryList RBRACK + : QUESTION? LBRACK (mapEntryList | COLON) RBRACK ; primary @@ -1178,6 +1139,10 @@ identifier // if 'static' followed by DOT, we can treat them as identifiers, e.g. static.unused = { -> } { DOT == _input.LT(2).getType() }? STATIC + | IN +// | DEF + | TRAIT + | AS ; builtInType diff --git a/base/org.codehaus.groovy26/src/groovy/grape/GrabAnnotationTransformation.java b/base/org.codehaus.groovy30/src/groovy/grape/GrabAnnotationTransformation.java similarity index 100% rename from base/org.codehaus.groovy26/src/groovy/grape/GrabAnnotationTransformation.java rename to base/org.codehaus.groovy30/src/groovy/grape/GrabAnnotationTransformation.java diff --git a/base/org.codehaus.groovy26/src/groovy/grape/GrapeIvy.groovy b/base/org.codehaus.groovy30/src/groovy/grape/GrapeIvy.groovy similarity index 79% rename from base/org.codehaus.groovy26/src/groovy/grape/GrapeIvy.groovy rename to base/org.codehaus.groovy30/src/groovy/grape/GrapeIvy.groovy index e45a6714c3..a25b9e28a3 100644 --- a/base/org.codehaus.groovy26/src/groovy/grape/GrapeIvy.groovy +++ b/base/org.codehaus.groovy30/src/groovy/grape/GrapeIvy.groovy @@ -18,9 +18,11 @@ */ package groovy.grape +import groovy.transform.CompileStatic import org.apache.groovy.plugin.GroovyRunner import org.apache.groovy.plugin.GroovyRunnerRegistry import org.apache.ivy.Ivy +import org.apache.ivy.core.IvyContext import org.apache.ivy.core.cache.ResolutionCacheManager import org.apache.ivy.core.event.IvyListener import org.apache.ivy.core.event.download.PrepareDownloadEvent @@ -41,6 +43,7 @@ import org.apache.ivy.plugins.matcher.ExactPatternMatcher import org.apache.ivy.plugins.matcher.PatternMatcher import org.apache.ivy.plugins.resolver.ChainResolver import org.apache.ivy.plugins.resolver.IBiblioResolver +import org.apache.ivy.plugins.resolver.ResolverSettings import org.apache.ivy.util.DefaultMessageLogger import org.apache.ivy.util.Message import org.codehaus.groovy.reflection.CachedClass @@ -84,7 +87,7 @@ class GrapeIvy implements GrapeEngine { // we keep the settings so that addResolver can add to the resolver chain IvySettings settings - public GrapeIvy() { + GrapeIvy() { // if we are already initialized, quit if (enableGrapes) return @@ -111,7 +114,7 @@ class GrapeIvy implements GrapeEngine { settings.setVariable("ivy.default.configuration.m2compatible", "true") ivyInstance = Ivy.newInstance(settings) - org.apache.ivy.core.IvyContext.getContext().setIvy(ivyInstance); + IvyContext.getContext().setIvy(ivyInstance) resolvedDependencies = [] downloadedArtifacts = [] @@ -120,7 +123,8 @@ class GrapeIvy implements GrapeEngine { enableGrapes = true } - public File getGroovyRoot() { + @CompileStatic + File getGroovyRoot() { String root = System.getProperty("groovy.root") def groovyRoot if (root == null) { @@ -136,7 +140,8 @@ class GrapeIvy implements GrapeEngine { return groovyRoot } - public File getLocalGrapeConfig() { + @CompileStatic + File getLocalGrapeConfig() { String grapeConfig = System.getProperty("grape.config") if(grapeConfig) { return new File(grapeConfig) @@ -144,7 +149,8 @@ class GrapeIvy implements GrapeEngine { return new File(getGrapeDir(), 'grapeConfig.xml') } - public File getGrapeDir() { + @CompileStatic + File getGrapeDir() { String root = System.getProperty("grape.root") if(root == null) { return getGroovyRoot() @@ -158,7 +164,8 @@ class GrapeIvy implements GrapeEngine { return grapeRoot } - public File getGrapeCacheDir() { + @CompileStatic + File getGrapeCacheDir() { File cache = new File(getGrapeDir(), 'grapes') if (!cache.exists()) { cache.mkdirs() @@ -168,12 +175,13 @@ class GrapeIvy implements GrapeEngine { return cache } - public def chooseClassLoader(Map args) { - def loader = args.classLoader + @CompileStatic + ClassLoader chooseClassLoader(Map args) { + ClassLoader loader = (ClassLoader) args.classLoader if (!isValidTargetClassLoader(loader)) { - loader = (args.refObject?.class - ?:ReflectionUtils.getCallingClass(args.calleeDepth?:1) - )?.classLoader + loader = ((Class) ((args.refObject?.class + ?: ReflectionUtils.getCallingClass((int) (args.calleeDepth ?: 1)) + )))?.classLoader while (loader && !isValidTargetClassLoader(loader)) { loader = loader.parent } @@ -192,10 +200,12 @@ class GrapeIvy implements GrapeEngine { return loader } + @CompileStatic private boolean isValidTargetClassLoader(loader) { return isValidTargetClassLoaderClass(loader?.class) } + @CompileStatic private boolean isValidTargetClassLoaderClass(Class loaderClass) { return (loaderClass != null) && ( @@ -205,7 +215,7 @@ class GrapeIvy implements GrapeEngine { ) } - public IvyGrabRecord createGrabRecord(Map deps) { + IvyGrabRecord createGrabRecord(Map deps) { // parse the actual dependency arguments String module = deps.module ?: deps.artifactId ?: deps.artifact if (!module) { @@ -235,16 +245,22 @@ class GrapeIvy implements GrapeEngine { return new IvyGrabRecord(mrid:mrid, conf:conf, changing:changing, transitive:transitive, force:force, classifier:classifier, ext:ext, type:type) } - public grab(String endorsedModule) { + @Override + @CompileStatic + grab(String endorsedModule) { return grab(group:'groovy.endorsed', module:endorsedModule, version:GroovySystem.version) } - public grab(Map args) { + @Override + @CompileStatic + grab(Map args) { args.calleeDepth = args.calleeDepth?:DEFAULT_DEPTH + 1 return grab(args, args) } - public grab(Map args, Map... dependencies) { + @Override + @CompileStatic + grab(Map args, Map... dependencies) { ClassLoader loader = null grabRecordsForCurrDependencies.clear() @@ -262,7 +278,7 @@ class GrapeIvy implements GrapeEngine { def uris = resolve(loader, args, dependencies) for (URI uri in uris) { - loader.addURL(uri.toURL()) + addURL(loader, uri) } boolean runnerServicesFound = false for (URI uri in uris) { @@ -291,27 +307,54 @@ class GrapeIvy implements GrapeEngine { return null } + private void addURL(ClassLoader loader, URI uri) { + loader.addURL(uri.toURL()) + } + + @CompileStatic private processCategoryMethods(ClassLoader loader, File file) { // register extension methods if jar if (file.name.toLowerCase().endsWith(".jar")) { def mcRegistry = GroovySystem.metaClassRegistry if (mcRegistry instanceof MetaClassRegistryImpl) { + // GRECLIPSE edit + //try (JarFile jar = new JarFile(file)) { + JarFile jar = null try { - JarFile jar = new JarFile(file) + jar = new JarFile(file) + // GRECLIPSE end def entry = jar.getEntry(ExtensionModuleScanner.MODULE_META_INF_FILE) if (!entry) { entry = jar.getEntry(ExtensionModuleScanner.LEGACY_MODULE_META_INF_FILE) } if (entry) { Properties props = new Properties() - props.load(jar.getInputStream(entry)) + // GRECLIPSE edit + //try (InputStream is = jar.getInputStream(entry)) { + InputStream is = null + try { + is = jar.getInputStream(entry) + // GRECLIPSE end + props.load(is) + // GRECLIPSE add + } finally { + if (null != is) { + try { + is.close() + } catch (e) { + // ignore + } + } + // GRECLIPSE end + } + Map> metaMethods = new HashMap>() mcRegistry.registerExtensionModuleFromProperties(props, loader, metaMethods) // add old methods to the map metaMethods.each { CachedClass c, List methods -> // GROOVY-5543: if a module was loaded using grab, there are chances that subclasses // have their own ClassInfo, and we must change them as well! - Set classesToBeUpdated = [c] + Set classesToBeUpdated = [c].toSet() ClassInfo.onAllClassInfo { ClassInfo info -> if (c.theClass.isAssignableFrom(info.cachedClass.theClass)) { classesToBeUpdated << info.cachedClass @@ -320,14 +363,24 @@ class GrapeIvy implements GrapeEngine { classesToBeUpdated*.addNewMopMethods(methods) } } - } - catch(ZipException zipException) { + } catch(ZipException zipException) { throw new RuntimeException("Grape could not load jar '$file'", zipException) + // GRECLIPSE add + } finally { + if (null != jar) { + try { + jar.close() + } catch (e) { + // ignore + } + } + // GRECLIPSE end } } } } + @CompileStatic void processOtherServices(ClassLoader loader, File f) { processMetaInfServices(loader, f) // ignore result } @@ -340,22 +393,63 @@ class GrapeIvy implements GrapeEngine { * @param f ZipFile in which to search for services * @return a collection of service provider files that were found */ + @CompileStatic private Collection processMetaInfServices(ClassLoader loader, File f) { List services = new ArrayList<>() + // GRECLIPSE edit + //try (ZipFile zf = new ZipFile(f)) { + ZipFile zf = null try { - ZipFile zf = new ZipFile(f) + zf = new ZipFile(f) + // GRECLIPSE end String providerConfig = 'org.codehaus.groovy.runtime.SerializedCategoryMethods' ZipEntry serializedCategoryMethods = zf.getEntry(METAINF_PREFIX + providerConfig) if (serializedCategoryMethods != null) { services.add(providerConfig) - processSerializedCategoryMethods(zf.getInputStream(serializedCategoryMethods)) + + // GRECLIPSE edit + //try (InputStream is = zf.getInputStream(serializedCategoryMethods)) { + InputStream is = null + try { + is = zf.getInputStream(serializedCategoryMethods) + // GRECLIPSE end + processSerializedCategoryMethods(is) + // GRECLIPSE add + } finally { + if (null != is) { + try { + is.close() + } catch (e) { + // ignore + } + } + // GRECLIPSE end + } } // TODO: remove in a future release (replaced by GroovyRunnerRegistry) providerConfig = 'org.codehaus.groovy.plugins.Runners' ZipEntry pluginRunners = zf.getEntry(METAINF_PREFIX + providerConfig) if (pluginRunners != null) { services.add(providerConfig) - processRunners(zf.getInputStream(pluginRunners), f.getName(), loader) + + // GRFECLIPSE edit + //try (InputStream is = zf.getInputStream(pluginRunners)) { + InputStream is = null + try { + is = zf.getInputStream(pluginRunners) + // GRECLIPSE end + processRunners(is, f.getName(), loader) + // GRECLIPSE add + } finally { + if (null != is) { + try { + is.close() + } catch (e) { + // ignore + } + } + // GRECLIPSE end + } } // GroovyRunners are loaded per ClassLoader using a ServiceLoader so here // it only needs to be indicated that the service provider file was found @@ -365,28 +459,41 @@ class GrapeIvy implements GrapeEngine { } catch(ZipException ignore) { // ignore files we can't process, e.g. non-jar/zip artifacts // TODO log a warning + // GRECLIPSE add + } finally { + if (null != zf) { + try { + zf.close() + } catch (e) { + // ignore + } + } + // GRECLIPSE end } return services } + @CompileStatic void processSerializedCategoryMethods(InputStream is) { is.text.readLines().each { println it.trim() // TODO implement this or delete it } } + @CompileStatic void processRunners(InputStream is, String name, ClassLoader loader) { GroovyRunnerRegistry registry = GroovyRunnerRegistry.getInstance() - is.text.readLines()*.trim().findAll{ !it.isEmpty() && it[0] != '#' }.each { + is.text.readLines()*.trim().findAll{ String line -> !line.isEmpty() && line[0] != '#' }.each { + String line = (String) it try { - registry[name] = loader.loadClass(it).newInstance() + registry[name] = (GroovyRunner) loader.loadClass(line).newInstance() } catch (Exception ex) { throw new IllegalStateException("Error registering runner class '" + it + "'", ex) } } } - public ResolveReport getDependencies(Map args, IvyGrabRecord... grabRecords) { + ResolveReport getDependencies(Map args, IvyGrabRecord... grabRecords) { ResolutionCacheManager cacheManager = ivyInstance.resolutionCacheManager def millis = System.currentTimeMillis() @@ -399,7 +506,7 @@ class GrapeIvy implements GrapeEngine { for (IvyGrabRecord grabRecord : grabRecords) { def conf = grabRecord.conf ?: ['*'] - DefaultDependencyDescriptor dd = md.dependencies.find {it.dependencyRevisionId.equals(grabRecord.mrid)} + DefaultDependencyDescriptor dd = (DefaultDependencyDescriptor) md.dependencies.find {it.dependencyRevisionId.equals(grabRecord.mrid)} if (dd) { createAndAddDependencyArtifactDescriptor(dd, grabRecord, conf) } else { @@ -412,10 +519,10 @@ class GrapeIvy implements GrapeEngine { } // resolve grab and dependencies - ResolveOptions resolveOptions = new ResolveOptions()\ - .setConfs(['default'] as String[])\ - .setOutputReport(false)\ - .setValidate(args.containsKey('validate') ? args.validate : false) + ResolveOptions resolveOptions = new ResolveOptions() + .setConfs(['default'] as String[]) + .setOutputReport(false) + .setValidate((boolean) (args.containsKey('validate') ? args.validate : false)) ivyInstance.settings.defaultResolver = args.autoDownload ? 'downloadGrapes' : 'cachedGrapes' if (args.disableChecksums) { @@ -423,26 +530,7 @@ class GrapeIvy implements GrapeEngine { } boolean reportDownloads = System.getProperty('groovy.grape.report.downloads', 'false') == 'true' if (reportDownloads) { - ivyInstance.eventManager.addIvyListener([progress:{ ivyEvent -> switch(ivyEvent) { - case StartResolveEvent: - ivyEvent.moduleDescriptor.dependencies.each { it -> - def name = it.toString() - if (!resolvedDependencies.contains(name)) { - resolvedDependencies << name - System.err.println "Resolving " + name - } - } - break - case PrepareDownloadEvent: - ivyEvent.artifacts.each { it -> - def name = it.toString() - if (!downloadedArtifacts.contains(name)) { - downloadedArtifacts << name - System.err.println "Preparing to download artifact " + name - } - } - break - } } ] as IvyListener) + addIvyListener() } ResolveReport report = null @@ -478,6 +566,32 @@ class GrapeIvy implements GrapeEngine { return report } + private addIvyListener() { + ivyInstance.eventManager.addIvyListener([progress: { ivyEvent -> + switch (ivyEvent) { + case StartResolveEvent: + ivyEvent.moduleDescriptor.dependencies.each { it -> + def name = it.toString() + if (!resolvedDependencies.contains(name)) { + resolvedDependencies << name + System.err.println "Resolving " + name + } + } + break + case PrepareDownloadEvent: + ivyEvent.artifacts.each { it -> + def name = it.toString() + if (!downloadedArtifacts.contains(name)) { + downloadedArtifacts << name + System.err.println "Preparing to download artifact " + name + } + } + break + } + }] as IvyListener) + } + + @CompileStatic private void createAndAddDependencyArtifactDescriptor(DefaultDependencyDescriptor dd, IvyGrabRecord grabRecord, List conf) { // TODO: find out "unknown" reason and change comment below - also, confirm conf[0] check vs conf.contains('optional') if (conf[0]!="optional" || grabRecord.classifier) { // for some unknown reason optional dependencies should not have an artifactDescriptor @@ -488,7 +602,7 @@ class GrapeIvy implements GrapeEngine { } } - public void uninstallArtifact(String group, String module, String rev) { + void uninstallArtifact(String group, String module, String rev) { // TODO consider transitive uninstall as an option Pattern ivyFilePattern = ~/ivy-(.*)\.xml/ //TODO get pattern from ivy conf grapeCacheDir.eachDir { File groupDir -> @@ -503,9 +617,9 @@ class GrapeIvy implements GrapeEngine { def db = dbf.newDocumentBuilder() def root = db.parse(ivyFile).documentElement def publis = root.getElementsByTagName('publications') - for (int i=0; i>> enumerateGrapes() { + @Override + @CompileStatic + Map>> enumerateGrapes() { Map>> bunches = [:] Pattern ivyFilePattern = ~/ivy-(.*)\.xml/ //TODO get pattern from ivy conf grapeCacheDir.eachDir {File groupDir -> Map> grapes = [:] bunches[groupDir.name] = grapes groupDir.eachDir { File moduleDir -> - def versions = [] + List versions = [] moduleDir.eachFileMatch(ivyFilePattern) {File ivyFile -> def m = ivyFilePattern.matcher(ivyFile.name) if (m.matches()) versions += m.group(1) @@ -557,13 +673,17 @@ class GrapeIvy implements GrapeEngine { return bunches } - public URI[] resolve(Map args, Map ... dependencies) { + @Override + @CompileStatic + URI[] resolve(Map args, Map ... dependencies) { resolve(args, null, dependencies) } - public URI[] resolve(Map args, List depsInfo, Map ... dependencies) { + @Override + @CompileStatic + URI[] resolve(Map args, List depsInfo, Map ... dependencies) { // identify the target classloader early, so we fail before checking repositories - def loader = chooseClassLoader( + ClassLoader loader = chooseClassLoader( classLoader: args.remove('classLoader'), refObject: args.remove('refObject'), calleeDepth: args.calleeDepth ?: DEFAULT_DEPTH, @@ -576,11 +696,12 @@ class GrapeIvy implements GrapeEngine { resolve(loader, args, depsInfo, dependencies) } - URI [] resolve(ClassLoader loader, Map args, Map... dependencies) { + @CompileStatic + URI[] resolve(ClassLoader loader, Map args, Map... dependencies) { return resolve(loader, args, null, dependencies) } - URI [] resolve(ClassLoader loader, Map args, List depsInfo, Map... dependencies) { + URI[] resolve(ClassLoader loader, Map args, List depsInfo, Map... dependencies) { // check for mutually exclusive arguments Set keys = args.keySet() keys.each {a -> @@ -637,6 +758,7 @@ class GrapeIvy implements GrapeEngine { return results as URI[] } + @CompileStatic private Set getLoadedDepsForLoader(ClassLoader loader) { Set localDeps = loadedDeps.get(loader) if (localDeps == null) { @@ -647,7 +769,8 @@ class GrapeIvy implements GrapeEngine { return localDeps } - public Map[] listDependencies (ClassLoader classLoader) { + @Override + Map[] listDependencies (ClassLoader classLoader) { if (loadedDeps.containsKey(classLoader)) { List results = [] loadedDeps[classLoader].each { IvyGrabRecord grabbed -> @@ -684,11 +807,16 @@ class GrapeIvy implements GrapeEngine { return null } - public void addResolver(Map args) { - ChainResolver chainResolver = settings.getResolver("downloadGrapes") + @Override + @CompileStatic + void addResolver(Map args) { + ChainResolver chainResolver = (ChainResolver) settings.getResolver("downloadGrapes") - IBiblioResolver resolver = new IBiblioResolver(name: args.name, root:args.root, - m2compatible:(args.m2Compatible ?: true), settings:settings) + IBiblioResolver resolver = new IBiblioResolver( + name: (String) args.name, + root: (String) args.root, + m2compatible: (boolean) (args.m2Compatible ?: true), + settings: (ResolverSettings) settings) chainResolver.add(resolver) @@ -698,6 +826,7 @@ class GrapeIvy implements GrapeEngine { } } +@CompileStatic class IvyGrabRecord { ModuleRevisionId mrid List conf @@ -708,7 +837,8 @@ class IvyGrabRecord { String ext String type - public int hashCode() { + @Override + int hashCode() { return (mrid.hashCode() ^ conf.hashCode() ^ (changing ? 0xaaaaaaaa : 0x55555555) ^ (transitive ? 0xbbbbbbbb : 0x66666666) @@ -718,16 +848,21 @@ class IvyGrabRecord { ^ (type ? type.hashCode() : 0)) } - public boolean equals(Object o) { - return ((o.class == IvyGrabRecord) - && (changing == o.changing) - && (transitive == o.transitive) - && (force== o.force) - && (mrid == o.mrid) - && (conf == o.conf) - && (classifier == o.classifier) - && (ext == o.ext) - && (type == o.type)) - } + @Override + boolean equals(Object obj) { + if (null == obj || obj.class != IvyGrabRecord) { + return false + } + IvyGrabRecord o = (IvyGrabRecord) obj + + return ((changing == o.changing) + && (transitive == o.transitive) + && (force == o.force) + && (mrid == o.mrid) + && (conf == o.conf) + && (classifier == o.classifier) + && (ext == o.ext) + && (type == o.type)) + } } diff --git a/base/org.codehaus.groovy30/src/org/apache/groovy/ast/tools/ExpressionUtils.java b/base/org.codehaus.groovy30/src/org/apache/groovy/ast/tools/ExpressionUtils.java new file mode 100644 index 0000000000..5ac5720e7d --- /dev/null +++ b/base/org.codehaus.groovy30/src/org/apache/groovy/ast/tools/ExpressionUtils.java @@ -0,0 +1,378 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.groovy.ast.tools; + +import org.codehaus.groovy.ast.ClassCodeVisitorSupport; +import org.codehaus.groovy.ast.ClassHelper; +import org.codehaus.groovy.ast.ClassNode; +import org.codehaus.groovy.ast.FieldNode; +import org.codehaus.groovy.ast.expr.BinaryExpression; +import org.codehaus.groovy.ast.expr.ClassExpression; +import org.codehaus.groovy.ast.expr.ConstantExpression; +import org.codehaus.groovy.ast.expr.Expression; +import org.codehaus.groovy.ast.expr.ListExpression; +import org.codehaus.groovy.ast.expr.PropertyExpression; +import org.codehaus.groovy.ast.expr.VariableExpression; +import org.codehaus.groovy.runtime.DefaultGroovyMethods; +import org.codehaus.groovy.runtime.typehandling.NumberMath; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; + +import static org.codehaus.groovy.syntax.Types.BITWISE_AND; +import static org.codehaus.groovy.syntax.Types.BITWISE_OR; +import static org.codehaus.groovy.syntax.Types.BITWISE_XOR; +import static org.codehaus.groovy.syntax.Types.DIVIDE; +import static org.codehaus.groovy.syntax.Types.LEFT_SHIFT; +import static org.codehaus.groovy.syntax.Types.MINUS; +import static org.codehaus.groovy.syntax.Types.MULTIPLY; +import static org.codehaus.groovy.syntax.Types.PLUS; +import static org.codehaus.groovy.syntax.Types.POWER; +import static org.codehaus.groovy.syntax.Types.RIGHT_SHIFT; +import static org.codehaus.groovy.syntax.Types.RIGHT_SHIFT_UNSIGNED; + +public class ExpressionUtils { + private static ArrayList handledTypes = new ArrayList(); + static { + handledTypes.add(PLUS); + handledTypes.add(MINUS); + handledTypes.add(MULTIPLY); + handledTypes.add(DIVIDE); + handledTypes.add(LEFT_SHIFT); + handledTypes.add(RIGHT_SHIFT); + handledTypes.add(RIGHT_SHIFT_UNSIGNED); + handledTypes.add(BITWISE_OR); + handledTypes.add(BITWISE_AND); + handledTypes.add(BITWISE_XOR); + handledTypes.add(POWER); + } + + private ExpressionUtils() { + } + + /** + * Turns expressions of the form ConstantExpression(40) + ConstantExpression(2) + * into the simplified ConstantExpression(42) at compile time. + * + * @param be the binary expression + * @param targetType the type of the result + * @return the transformed expression or the original if no transformation was performed + */ + public static ConstantExpression transformBinaryConstantExpression(BinaryExpression be, ClassNode targetType) { + ClassNode wrapperType = ClassHelper.getWrapper(targetType); + if (isTypeOrArrayOfType(targetType, ClassHelper.STRING_TYPE, false)) { + if (be.getOperation().getType() == PLUS) { + Expression left = transformInlineConstants(be.getLeftExpression(), targetType); + Expression right = transformInlineConstants(be.getRightExpression(), targetType); + if (left instanceof ConstantExpression && right instanceof ConstantExpression) { + return configure(be, new ConstantExpression((String) ((ConstantExpression) left).getValue() + + ((ConstantExpression) right).getValue())); + } + } + } else if (isNumberOrArrayOfNumber(wrapperType, false)) { + int type = be.getOperation().getType(); + if (handledTypes.contains(type)) { + Expression leftX = transformInlineConstants(be.getLeftExpression(), targetType); + Expression rightX = transformInlineConstants(be.getRightExpression(), targetType); + if (leftX instanceof ConstantExpression && rightX instanceof ConstantExpression) { + Number left = safeNumber((ConstantExpression) leftX); + Number right = safeNumber((ConstantExpression) rightX); + if (left == null || right == null) return null; + Number result = null; + switch(type) { + case PLUS: + result = NumberMath.add(left, right); + break; + case MINUS: + result = NumberMath.subtract(left, right); + break; + case MULTIPLY: + result = NumberMath.multiply(left, right); + break; + case DIVIDE: + result = NumberMath.divide(left, right); + break; + case LEFT_SHIFT: + result = NumberMath.leftShift(left, right); + break; + case RIGHT_SHIFT: + result = NumberMath.rightShift(left, right); + break; + case RIGHT_SHIFT_UNSIGNED: + result = NumberMath.rightShiftUnsigned(left, right); + break; + case BITWISE_AND: + result = NumberMath.and(left, right); + break; + case BITWISE_OR: + result = NumberMath.or(left, right); + break; + case BITWISE_XOR: + result = NumberMath.xor(left, right); + break; + case POWER: + result = DefaultGroovyMethods.power(left, right); + break; + } + if (result != null) { + if (ClassHelper.Byte_TYPE.equals(wrapperType)) { + return configure(be, new ConstantExpression(result.byteValue(), true)); + } + if (ClassHelper.Short_TYPE.equals(wrapperType)) { + return configure(be, new ConstantExpression(result.shortValue(), true)); + } + if (ClassHelper.Long_TYPE.equals(wrapperType)) { + return configure(be, new ConstantExpression(result.longValue(), true)); + } + if (ClassHelper.Integer_TYPE.equals(wrapperType) || ClassHelper.Character_TYPE.equals(wrapperType)) { + return configure(be, new ConstantExpression(result.intValue(), true)); + } + if (ClassHelper.Float_TYPE.equals(wrapperType)) { + return configure(be, new ConstantExpression(result.floatValue(), true)); + } + if (ClassHelper.Double_TYPE.equals(wrapperType)) { + return configure(be, new ConstantExpression(result.doubleValue(), true)); + } + return configure(be, new ConstantExpression(result, true)); + } + } + } + } + return null; + } + + private static Number safeNumber(ConstantExpression constX) { + Object value = constX.getValue(); + if (value instanceof Number) return (Number) value; + return null; + } + + // GRECLIPSE add + private static Expression clone(ConstantExpression constX, Expression origX) { + ConstantExpression newX = new ConstantExpression(constX.getValue()); + // TODO: Copy any other fields or metadata? + configure(origX, newX); + return newX; + } + // GRECLIPSE end + + private static ConstantExpression configure(Expression origX, ConstantExpression newX) { + // GRECLIPSE edit + newX.setNodeMetaData(ClassCodeVisitorSupport.ORIGINAL_EXPRESSION, origX); + //newX.setSourcePosition(origX); + // GRECLIPSE end + return newX; + } + + /** + * Determine if a type matches another type (or array thereof). + * + * @param targetType the candidate type + * @param type the type we are checking against + * @param recurse true if we can have multi-dimension arrays; should be false for annotation member types + * @return true if the type equals the targetType or array thereof + */ + public static boolean isTypeOrArrayOfType(ClassNode targetType, ClassNode type, boolean recurse) { + if (targetType == null) return false; + return type.equals(targetType) || + (targetType.isArray() && recurse + ? isTypeOrArrayOfType(targetType.getComponentType(), type, recurse) + : type.equals(targetType.getComponentType())); + } + + /** + * Determine if a type is derived from Number (or array thereof). + * + * @param targetType the candidate type + * @param recurse true if we can have multi-dimension arrays; should be false for annotation member types + * @return true if the type equals the targetType or array thereof + */ + public static boolean isNumberOrArrayOfNumber(ClassNode targetType, boolean recurse) { + if (targetType == null) return false; + return targetType.isDerivedFrom(ClassHelper.Number_TYPE) || + (targetType.isArray() && recurse + ? isNumberOrArrayOfNumber(targetType.getComponentType(), recurse) + : targetType.isArray() && targetType.getComponentType().isDerivedFrom(ClassHelper.Number_TYPE)); + } + + /** + * Converts simple expressions of constants into pre-evaluated simple constants. + * Handles: + *
      + *
    • Property expressions - referencing constants
    • + *
    • Simple binary expressions - String concatenation and numeric +, -, /, *
    • + *
    • List expressions - list of constants
    • + *
    • Variable expressions - referencing constants
    • + *
    + * @param exp the original expression + * @param attrType the type that the final constant should be + * @return the transformed type or the original if no transformation was possible + */ + public static Expression transformInlineConstants(final Expression exp, final ClassNode attrType) { + if (exp instanceof PropertyExpression) { + PropertyExpression pe = (PropertyExpression) exp; + if (pe.getObjectExpression() instanceof ClassExpression) { + ClassExpression ce = (ClassExpression) pe.getObjectExpression(); + ClassNode type = ce.getType(); + if (type.isEnum() || !(type.isResolved() || type.isPrimaryClassNode())) + return exp; + + if (type.isPrimaryClassNode()) { + FieldNode fn = type.redirect().getField(pe.getPropertyAsString()); + if (fn != null && fn.isStatic() && fn.isFinal()) { + Expression ce2 = transformInlineConstants(fn.getInitialValueExpression(), attrType); + // GRECLIPSE add + if (ce2 instanceof ConstantExpression) { + return clone((ConstantExpression) ce2, exp); + } + // GRECLIPSE end + if (ce2 != null) { + return ce2; + } + } + } else { + try { + Field field = type.redirect().getTypeClass().getField(pe.getPropertyAsString()); + if (field != null && Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers())) { + ConstantExpression ce3 = new ConstantExpression(field.get(null), true); + // GRECLIPSE edit + //ce3.setSourcePosition(exp); + configure(exp, ce3); + // GRECLIPSE end + return ce3; + } + } catch(Exception e) { + // ignore, leave property expression in place and we'll report later + } + } + } + } else if (exp instanceof BinaryExpression) { + ConstantExpression ce = transformBinaryConstantExpression((BinaryExpression) exp, attrType); + if (ce != null) { + return ce; + } + } else if (exp instanceof VariableExpression) { + VariableExpression ve = (VariableExpression) exp; + if (ve.getAccessedVariable() instanceof FieldNode) { + FieldNode fn = (FieldNode) ve.getAccessedVariable(); + if (fn.isStatic() && fn.isFinal()) { + Expression ce = transformInlineConstants(fn.getInitialValueExpression(), attrType); + // GRECLIPSE add + if (ce instanceof ConstantExpression) { + return clone((ConstantExpression) ce, exp); + } + // GRECLIPSE end + if (ce != null) { + return ce; + } + } + } + } else if (exp instanceof ListExpression) { + return transformListOfConstants((ListExpression) exp, attrType); + } + return exp; + } + + /** + * Given a list of constants, transform each item in the list. + * + * @param origList the list to transform + * @param attrType the target type + * @return the transformed list or the original if nothing was changed + */ + public static Expression transformListOfConstants(ListExpression origList, ClassNode attrType) { + ListExpression newList = new ListExpression(); + boolean changed = false; + for (Expression e : origList.getExpressions()) { + try { + Expression transformed = transformInlineConstants(e, attrType); + newList.addExpression(transformed); + if (transformed != e) changed = true; + } catch(Exception ignored) { + newList.addExpression(e); + } + } + if (changed) { + newList.setSourcePosition(origList); + return newList; + } + return origList; + } + + /** + * The attribute values of annotations must be primitive, String or Enum constants. + * In various places, such constants can be seen during type resolution but won't be + * readily accessible in later phases, e.g. they might be embedded into constructor code. + * This method transforms constants that would appear in annotations early so they aren't lost. + * Subsequent processing determines whether they are valid, this method simply retains + * the constant value as a constant expression. + * + * @param exp the original expression + * @return the converted expression + */ + public static Expression transformInlineConstants(final Expression exp) { + if (exp instanceof PropertyExpression) { + PropertyExpression pe = (PropertyExpression) exp; + if (pe.getObjectExpression() instanceof ClassExpression) { + ClassExpression ce = (ClassExpression) pe.getObjectExpression(); + ClassNode type = ce.getType(); + FieldNode field = ClassNodeUtils.getField(type, pe.getPropertyAsString()); + if (type.isEnum() && field != null && field.isEnum()) return exp; + Expression constant = findConstant(field); + // GRECLIPSE edit + //if (constant != null) return constant; + if (constant instanceof ConstantExpression) { + return clone((ConstantExpression) constant, exp); + } + // GRECLIPSE end + } + } else if (exp instanceof BinaryExpression) { + BinaryExpression be = (BinaryExpression) exp; + be.setLeftExpression(transformInlineConstants(be.getLeftExpression())); + be.setRightExpression(transformInlineConstants(be.getRightExpression())); + return be; + } else if (exp instanceof ListExpression) { + ListExpression origList = (ListExpression) exp; + ListExpression newList = new ListExpression(); + boolean changed = false; + for (Expression e : origList.getExpressions()) { + Expression transformed = transformInlineConstants(e); + newList.addExpression(transformed); + if (transformed != e) changed = true; + } + if (changed) { + newList.setSourcePosition(origList); + return newList; + } + return origList; + } + + return exp; + } + + private static Expression findConstant(FieldNode fn) { + if (fn != null && !fn.isEnum() && fn.isStatic() && fn.isFinal()) { + if (fn.getInitialValueExpression() instanceof ConstantExpression) { + return fn.getInitialValueExpression(); + } + } + return null; + } +} diff --git a/base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/AstBuilder.java b/base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/AstBuilder.java similarity index 87% rename from base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/AstBuilder.java rename to base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/AstBuilder.java index d880a1ea63..8461fde035 100644 --- a/base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/AstBuilder.java +++ b/base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/AstBuilder.java @@ -23,15 +23,18 @@ import groovyjarjarantlr4.v4.runtime.CharStream; import groovyjarjarantlr4.v4.runtime.CharStreams; import groovyjarjarantlr4.v4.runtime.CommonTokenStream; +import groovyjarjarantlr4.v4.runtime.ParserRuleContext; import groovyjarjarantlr4.v4.runtime.RecognitionException; import groovyjarjarantlr4.v4.runtime.Recognizer; import groovyjarjarantlr4.v4.runtime.Token; import groovyjarjarantlr4.v4.runtime.atn.PredictionMode; +import groovyjarjarantlr4.v4.runtime.misc.Interval; import groovyjarjarantlr4.v4.runtime.misc.ParseCancellationException; import groovyjarjarantlr4.v4.runtime.tree.ParseTree; import groovyjarjarantlr4.v4.runtime.tree.TerminalNode; -import org.apache.groovy.parser.antlr4.internal.AtnManager; +import org.apache.groovy.parser.antlr4.GroovyParser.QualifiedNameElementContext; import org.apache.groovy.parser.antlr4.internal.DescriptiveErrorStrategy; +import org.apache.groovy.parser.antlr4.internal.atnmanager.AtnManager; import org.apache.groovy.parser.antlr4.util.PositionConfigureUtils; import org.apache.groovy.parser.antlr4.util.StringUtils; import org.apache.groovy.util.Maps; @@ -113,8 +116,10 @@ import org.codehaus.groovy.ast.stmt.WhileStatement; import org.codehaus.groovy.control.CompilationFailedException; import org.codehaus.groovy.control.CompilePhase; +import org.codehaus.groovy.control.CompilerConfiguration; import org.codehaus.groovy.control.SourceUnit; import org.codehaus.groovy.control.messages.SyntaxErrorMessage; +import org.codehaus.groovy.runtime.DefaultGroovyMethods; import org.codehaus.groovy.runtime.StringGroovyMethods; import org.codehaus.groovy.syntax.Numbers; import org.codehaus.groovy.syntax.SyntaxException; @@ -134,8 +139,12 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import static groovy.lang.Tuple.tuple; import static org.apache.groovy.parser.antlr4.GroovyLangParser.ADD; import static org.apache.groovy.parser.antlr4.GroovyLangParser.AS; import static org.apache.groovy.parser.antlr4.GroovyLangParser.AdditiveExprAltContext; @@ -274,7 +283,6 @@ import static org.apache.groovy.parser.antlr4.GroovyLangParser.NamedPropertyArgsContext; import static org.apache.groovy.parser.antlr4.GroovyLangParser.NewPrmrAltContext; import static org.apache.groovy.parser.antlr4.GroovyLangParser.NonWildcardTypeArgumentsContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.NormalExprAltContext; import static org.apache.groovy.parser.antlr4.GroovyLangParser.NullLiteralAltContext; import static org.apache.groovy.parser.antlr4.GroovyLangParser.PRIVATE; import static org.apache.groovy.parser.antlr4.GroovyLangParser.PackageDeclarationContext; @@ -289,7 +297,6 @@ import static org.apache.groovy.parser.antlr4.GroovyLangParser.QualifiedClassNameContext; import static org.apache.groovy.parser.antlr4.GroovyLangParser.QualifiedClassNameListContext; import static org.apache.groovy.parser.antlr4.GroovyLangParser.QualifiedNameContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.QualifiedNameElementContext; import static org.apache.groovy.parser.antlr4.GroovyLangParser.QualifiedStandardClassNameContext; import static org.apache.groovy.parser.antlr4.GroovyLangParser.RegexExprAltContext; import static org.apache.groovy.parser.antlr4.GroovyLangParser.RelationalExprAltContext; @@ -351,10 +358,9 @@ */ public class AstBuilder extends GroovyParserBaseVisitor { - public AstBuilder(SourceUnit sourceUnit) { + public AstBuilder(SourceUnit sourceUnit, CompilerConfiguration compilerConfiguration) { this.sourceUnit = sourceUnit; this.moduleNode = new ModuleNode(sourceUnit); - CharStream charStream = createCharStream(sourceUnit); this.lexer = new GroovyLangLexer(charStream); @@ -362,7 +368,7 @@ public AstBuilder(SourceUnit sourceUnit) { this.parser.setErrorHandler(new DescriptiveErrorStrategy(charStream)); this.tryWithResourcesASTTransformation = new TryWithResourcesASTTransformation(this); - this.groovydocManager = GroovydocManager.getInstance(); + this.groovydocManager = new GroovydocManager(compilerConfiguration); // GRECLIPSE add try (BufferedReader reader = new BufferedReader(sourceUnit.getSource().getReader())) { @@ -443,7 +449,7 @@ private GroovyParserRuleContext buildCST() throws CompilationFailedException { try { // parsing have to wait util clearing is complete. - AtnManager.RRWL.readLock().lock(); + AtnManager.READ_LOCK.lock(); try { result = buildCST(PredictionMode.SLL); } catch (Throwable t) { @@ -454,7 +460,7 @@ private GroovyParserRuleContext buildCST() throws CompilationFailedException { result = buildCST(PredictionMode.LL); } finally { - AtnManager.RRWL.readLock().unlock(); + AtnManager.READ_LOCK.unlock(); } } catch (Throwable t) { throw convertException(t); @@ -502,20 +508,19 @@ public ModuleNode buildAST() { public ModuleNode visitCompilationUnit(CompilationUnitContext ctx) { this.visit(ctx.packageDeclaration()); - for (ASTNode e : this.visitStatements(ctx.statements())) { - if (e instanceof DeclarationListStatement) { // local variable declaration - for (Statement ds : ((DeclarationListStatement) e).getDeclarationStatements()) { - moduleNode.addStatement(ds); - } - } else if (e instanceof Statement) { - moduleNode.addStatement((Statement) e); - } else if (e instanceof MethodNode) { // script method - moduleNode.addMethod((MethodNode) e); - } - } - for (ClassNode cl : this.classNodeList) { - moduleNode.addClass(cl); - } + this.visitStatements(ctx.statements()) + .forEach(e -> { + if (e instanceof DeclarationListStatement) { // local variable declaration + ((DeclarationListStatement) e).getDeclarationStatements().forEach(moduleNode::addStatement); + } else if (e instanceof Statement) { + moduleNode.addStatement((Statement) e); + } else if (e instanceof MethodNode) { // script method + moduleNode.addMethod((MethodNode) e); + } + }); + + this.classNodeList.forEach(moduleNode::addClass); + if (this.isPackageInfoDeclaration()) { this.addPackageInfoClassNode(); } else { @@ -528,7 +533,7 @@ public ModuleNode visitCompilationUnit(CompilationUnitContext ctx) { this.configureScriptClassNode(); if (null != this.numberFormatError) { - throw createParsingFailedException(this.numberFormatError.getSecond().getMessage(), this.numberFormatError.getFirst()); + throw createParsingFailedException(this.numberFormatError.getV2().getMessage(), this.numberFormatError.getV1()); } // GRECLIPSE add @@ -634,13 +639,9 @@ public List visitStatements(StatementsContext ctx) { return Collections.emptyList(); } - List nodeList = new ArrayList<>(ctx.statement().size()); - - for (StatementContext statementContext : ctx.statement()) { - nodeList.add((ASTNode) this.visit(statementContext)); - } - - return nodeList; + return ctx.statement().stream() + .map(e -> (ASTNode) visit(e)) + .collect(Collectors.toList()); } @Override @@ -684,28 +685,20 @@ public ImportNode visitImportDeclaration(ImportDeclarationContext ctx) { importNode = last(moduleNode.getStaticStarImports().values()); } else { // e.g. import static java.lang.Math.pow // GRECLIPSE edit - //List identifierList = new LinkedList<>(ctx.qualifiedName().qualifiedNameElement()); + //List identifierList = new LinkedList<>(ctx.qualifiedName().qualifiedNameElement()); List identifierList = ctx.qualifiedName().qualifiedNameElement(); // GRECLIPSE end int identifierListSize = identifierList.size(); String name = identifierList.get(identifierListSize - 1).getText(); - StringBuilder builder = new StringBuilder(); - long limit = identifierListSize - 1; - for (GroovyParserRuleContext groovyParserRuleContext : identifierList) { - if (limit-- == 0) break; - String text = groovyParserRuleContext.getText(); - if (builder.length() > 0) { - builder.append(DOT_STR); - } - builder.append(text); - } - /* GRECLIPSE edit ClassNode classNode = - ClassHelper.make( - builder.toString()); - */ - ClassNode classNode = makeClassNode(builder.toString()); - // GRECLIPSE end + // GRECLIPSE edit + //ClassHelper.make( + makeClassNode( + // GRECLIPSE end + identifierList.stream() + .limit(identifierListSize - 1) + .map(ParseTree::getText) + .collect(Collectors.joining(DOT_STR))); String alias = hasAlias ? ctx.alias.getText() : name; @@ -795,6 +788,7 @@ private static ClassNode makeClassNode(String name) { // GRECLIPSE and // statement { -------------------------------------------------------------------- + @Override public AssertStatement visitAssertStatement(AssertStatementContext ctx) { visitingAssertStatementCnt++; @@ -867,7 +861,6 @@ public IfStatement visitIfElseStatement(IfElseStatementContext ctx) { return configureAST(new IfStatement(booleanExpression, ifBlock, elseBlock), ctx); } - @Override public Statement visitLoopStmtAlt(LoopStmtAltContext ctx) { visitingLoopStatementCnt++; @@ -879,12 +872,12 @@ public Statement visitLoopStmtAlt(LoopStmtAltContext ctx) { @Override public ForStatement visitForStmtAlt(ForStmtAltContext ctx) { - Tuple2 controlPair = this.visitForControl(ctx.forControl()); + Tuple2 controlTuple = this.visitForControl(ctx.forControl()); Statement loopBlock = this.unpackStatement((Statement) this.visit(ctx.statement())); return configureAST( - new ForStatement(controlPair.getFirst(), controlPair.getSecond(), asBoolean(loopBlock) ? loopBlock : EmptyStatement.INSTANCE), + new ForStatement(controlTuple.getV1(), controlTuple.getV2(), asBoolean(loopBlock) ? loopBlock : EmptyStatement.INSTANCE), ctx); } @@ -956,13 +949,13 @@ public Tuple2 visitEnhancedForControl(EnhancedForControlC parameter.setColumnNumber(ctx.variableModifiersOpt().getStart().getCharPositionInLine() + 1); parameter.setStart(locationSupport.findOffset(parameter.getLineNumber(), parameter.getColumnNumber())); - ModifierNode var = new ModifierManager(this, this.visitVariableModifiersOpt(ctx.variableModifiersOpt())).get(VAR); - if (var != null) { - parameter.setNodeMetaData("reserved.type.name", var); + Optional var = new ModifierManager(this, this.visitVariableModifiersOpt(ctx.variableModifiersOpt())).get(VAR); + if (var != null && var.isPresent()) { + parameter.setNodeMetaData("reserved.type.name", var.get()); } // GRECLIPSE end - return new Tuple2<>(parameter, (Expression) this.visit(ctx.expression())); + return tuple(parameter, (Expression) this.visit(ctx.expression())); } @Override @@ -973,26 +966,29 @@ public Tuple2 visitClassicalForControl(ClassicalForContro closureListExpression.addExpression(asBoolean(ctx.expression()) ? (Expression) this.visit(ctx.expression()) : EmptyExpression.INSTANCE); closureListExpression.addExpression(this.visitForUpdate(ctx.forUpdate())); - return new Tuple2(ForStatement.FOR_LOOP_DUMMY, closureListExpression); + return tuple(ForStatement.FOR_LOOP_DUMMY, closureListExpression); } @Override public WhileStatement visitWhileStmtAlt(WhileStmtAltContext ctx) { - Expression conditionExpression = this.visitExpressionInPar(ctx.expressionInPar()); - BooleanExpression booleanExpression = - configureAST( - new BooleanExpression(conditionExpression), conditionExpression); - - Statement loopBlock = this.unpackStatement((Statement) this.visit(ctx.statement())); + Tuple2 conditionAndBlock = createLoopConditionExpressionAndBlock(ctx.expressionInPar(), ctx.statement()); return configureAST( - new WhileStatement(booleanExpression, asBoolean(loopBlock) ? loopBlock : EmptyStatement.INSTANCE), + new WhileStatement(conditionAndBlock.getV1(), asBoolean(conditionAndBlock.getV2()) ? conditionAndBlock.getV2() : EmptyStatement.INSTANCE), ctx); } @Override public DoWhileStatement visitDoWhileStmtAlt(DoWhileStmtAltContext ctx) { - Expression conditionExpression = this.visitExpressionInPar(ctx.expressionInPar()); + Tuple2 conditionAndBlock = createLoopConditionExpressionAndBlock(ctx.expressionInPar(), ctx.statement()); + + return configureAST( + new DoWhileStatement(conditionAndBlock.getV1(), asBoolean(conditionAndBlock.getV2()) ? conditionAndBlock.getV2() : EmptyStatement.INSTANCE), + ctx); + } + + private Tuple2 createLoopConditionExpressionAndBlock(ExpressionInParContext eipc, StatementContext sc) { + Expression conditionExpression = this.visitExpressionInPar(eipc); BooleanExpression booleanExpression = configureAST( @@ -1000,11 +996,9 @@ public DoWhileStatement visitDoWhileStmtAlt(DoWhileStmtAltContext ctx) { conditionExpression ); - Statement loopBlock = this.unpackStatement((Statement) this.visit(ctx.statement())); + Statement loopBlock = this.unpackStatement((Statement) this.visit(sc)); - return configureAST( - new DoWhileStatement(booleanExpression, asBoolean(loopBlock) ? loopBlock : EmptyStatement.INSTANCE), - ctx); + return tuple(booleanExpression, loopBlock); } @Override @@ -1027,17 +1021,16 @@ public Statement visitTryCatchStatement(TryCatchStatementContext ctx) { this.visitFinallyBlock(ctx.finallyBlock())); if (resourcesExists) { - for (ExpressionStatement e : this.visitResources(ctx.resources())) { - tryCatchStatement.addResource(e); - } + this.visitResources(ctx.resources()).forEach(tryCatchStatement::addResource); } - for (CatchClauseContext cc : ctx.catchClause()) { - List list = this.visitCatchClause(cc); - for (CatchStatement cs : list) { - tryCatchStatement.addCatch(cs); - } - } + ctx.catchClause().stream().map(this::visitCatchClause) + .reduce(new LinkedList(), (r, e) -> { + r.addAll(e); // merge several LinkedList instances into one LinkedList instance + return r; + }) + .forEach(tryCatchStatement::addCatch); + return configureAST( tryWithResourcesASTTransformation.transform( configureAST(tryCatchStatement, ctx)), @@ -1052,12 +1045,7 @@ public List visitResources(ResourcesContext ctx) { @Override public List visitResourceList(ResourceListContext ctx) { - List list = new ArrayList<>(); - for (ResourceContext resourceContext : ctx.resource()) { - ExpressionStatement expressionStatement = visitResource(resourceContext); - list.add(expressionStatement); - } - return list; + return ctx.resource().stream().map(this::visitResource).collect(Collectors.toList()); } @Override @@ -1085,24 +1073,7 @@ public ExpressionStatement visitResource(ResourceContext ctx) { if (isVariableDeclaration) { assignmentExpression = (BinaryExpression) expression; } else if (isVariableAccess) { - /* See https://docs.oracle.com/javase/specs/jls/se9/html/jls-14.html - * 14.20.3.1. Basic try-with-resources - * - * If a basic try-with-resource statement is of the form: - * try (VariableAccess ...) - * Block - * - * then the resource is first converted to a local variable declaration by the following translation: - * try (T #r = VariableAccess ...) { - * Block - * } - */ - assignmentExpression = - new BinaryExpression( - new VariableExpression(genResourceName()), - org.codehaus.groovy.syntax.Token.newSymbol(Types.ASSIGN, -1, -1), - expression - ); + assignmentExpression = tryWithResourcesASTTransformation.transformResourceAccess(expression); } else { throw createParsingFailedException("Unsupported resource declaration", ctx); } @@ -1124,11 +1095,6 @@ public ExpressionStatement visitResource(ResourceContext ctx) { throw createParsingFailedException("Unsupported resource declaration: " + ctx.getText(), ctx); } - private int resourceCnt = 0; - private String genResourceName() { - return "__$$resource" + resourceCnt++; - } - /** * Multi-catch(1..*) clause will be unpacked to several normal catch clauses, so the return type is List * @@ -1137,10 +1103,17 @@ private String genResourceName() { */ @Override public List visitCatchClause(CatchClauseContext ctx) { - // GRECLIPSE add + /* GRECLIPSE edit + return this.visitCatchType(ctx.catchType()).stream() + .map(e -> configureAST( + new CatchStatement( + new Parameter(e, this.visitIdentifier(ctx.identifier())), + this.visitBlock(ctx.block())), + ctx)) + .collect(Collectors.toList()); + */ ASTNode nameNode = null; Parameter catchParameter = null; - // GRECLIPSE end List list = new ArrayList<>(); for (ClassNode e : this.visitCatchType(ctx.catchType())) { CatchStatement catchStatement = configureAST( @@ -1148,14 +1121,11 @@ public List visitCatchClause(CatchClauseContext ctx) { new Parameter(e, this.visitIdentifier(ctx.identifier())), this.visitBlock(ctx.block())), ctx); - // GRECLIPSE add catchParameter = configureAST(catchStatement.getVariable(), ctx.catchType() != null ? ctx.catchType() : ctx.identifier()); nameNode = configureAST(new ConstantExpression(catchParameter.getName()), ctx.identifier()); catchParameter.setNameStart(nameNode.getStart()); catchParameter.setNameEnd(nameNode.getEnd()); - // GRECLIPSE end list.add(catchStatement); } - // GRECLIPSE add if (catchParameter != null) { catchParameter.setEnd(nameNode.getEnd()); catchParameter.setLastLineNumber(nameNode.getLastLineNumber()); @@ -1166,8 +1136,8 @@ public List visitCatchClause(CatchClauseContext ctx) { catchParameter.setColumnNumber(ctx.variableModifiersOpt().getStart().getCharPositionInLine() + 1); catchParameter.setStart(locationSupport.findOffset(catchParameter.getLineNumber(), catchParameter.getColumnNumber())); } - // GRECLIPSE end return list; + // GRECLIPSE end } @Override @@ -1176,12 +1146,9 @@ public List visitCatchType(CatchTypeContext ctx) { return Collections.singletonList(ClassHelper.OBJECT_TYPE); } - List list = new ArrayList<>(); - for (QualifiedClassNameContext qualifiedClassNameContext : ctx.qualifiedClassName()) { - ClassNode classNode = visitQualifiedClassName(qualifiedClassNameContext); - list.add(classNode); - } - return list; + return ctx.qualifiedClassName().stream() + .map(this::visitQualifiedClassName) + .collect(Collectors.toList()); } @@ -1200,21 +1167,24 @@ public Statement visitFinallyBlock(FinallyBlockContext ctx) { public SwitchStatement visitSwitchStatement(SwitchStatementContext ctx) { visitingSwitchStatementCnt++; - List statementList = new LinkedList<>(); - for (SwitchBlockStatementGroupContext c : ctx.switchBlockStatementGroup()) { - statementList.addAll(this.visitSwitchBlockStatementGroup(c)); - } + List statementList = + ctx.switchBlockStatementGroup().stream() + .map(this::visitSwitchBlockStatementGroup) + .reduce(new LinkedList<>(), (r, e) -> { + r.addAll(e); + return r; + }); List caseStatementList = new LinkedList<>(); List defaultStatementList = new LinkedList<>(); - for (Statement e : statementList) { + statementList.forEach(e -> { if (e instanceof CaseStatement) { caseStatementList.add((CaseStatement) e); } else if (isTrue(e, IS_SWITCH_DEFAULT)) { defaultStatementList.add(e); } - } + }); int defaultStatementListSize = defaultStatementList.size(); if (defaultStatementListSize > 1) { @@ -1236,7 +1206,6 @@ public SwitchStatement visitSwitchStatement(SwitchStatementContext ctx) { visitingSwitchStatementCnt--; return result; - } @@ -1245,54 +1214,58 @@ public List visitSwitchBlockStatementGroup(SwitchBlockStatementGroupC int labelCnt = ctx.switchLabel().size(); List firstLabelHolder = new ArrayList<>(1); - List statementList = new ArrayList<>(4); - for (SwitchLabelContext e : ctx.switchLabel()) { - Tuple2 tuple = this.visitSwitchLabel(e); + return (List) ctx.switchLabel().stream() + .map(e -> (Object) this.visitSwitchLabel(e)) + .reduce(new ArrayList(4), (r, e) -> { + List statementList = (List) r; + Tuple2 tuple = (Tuple2) e; - boolean isLast = labelCnt - 1 == statementList.size(); + boolean isLast = labelCnt - 1 == statementList.size(); - switch (tuple.getFirst().getType()) { - case CASE: { - if (!asBoolean(statementList)) { - firstLabelHolder.add(tuple.getFirst()); - } + switch (tuple.getV1().getType()) { + case CASE: { + if (!asBoolean(statementList)) { + firstLabelHolder.add(tuple.getV1()); + } - statementList.add( - configureAST( - new CaseStatement( - tuple.getSecond(), + statementList.add( + configureAST( + new CaseStatement( + tuple.getV2(), - // check whether processing the last label. if yes, block statement should be attached. - isLast ? this.visitBlockStatements(ctx.blockStatements()) - : EmptyStatement.INSTANCE - ), - firstLabelHolder.get(0))); + // check whether processing the last label. if yes, block statement should be attached. + isLast ? this.visitBlockStatements(ctx.blockStatements()) + : EmptyStatement.INSTANCE + ), + firstLabelHolder.get(0))); - break; - } - case DEFAULT: { + break; + } + case DEFAULT: { - BlockStatement blockStatement = this.visitBlockStatements(ctx.blockStatements()); - blockStatement.putNodeMetaData(IS_SWITCH_DEFAULT, true); + BlockStatement blockStatement = this.visitBlockStatements(ctx.blockStatements()); + blockStatement.putNodeMetaData(IS_SWITCH_DEFAULT, true); - statementList.add( - // configureAST(blockStatement, tuple.getKey()) - blockStatement - ); + statementList.add( + // this.configureAST(blockStatement, tuple.getKey()) + blockStatement + ); + + break; + } + } + + return statementList; + }); - break; - } - } - } - return statementList; } @Override public Tuple2 visitSwitchLabel(SwitchLabelContext ctx) { if (asBoolean(ctx.CASE())) { - return new Tuple2<>(ctx.CASE().getSymbol(), (Expression) this.visit(ctx.expression())); + return tuple(ctx.CASE().getSymbol(), (Expression) this.visit(ctx.expression())); } else if (asBoolean(ctx.DEFAULT())) { - return new Tuple2<>(ctx.DEFAULT().getSymbol(), (Expression) EmptyExpression.INSTANCE); + return tuple(ctx.DEFAULT().getSymbol(), EmptyExpression.INSTANCE); } throw createParsingFailedException("Unsupported switch label: " + ctx.getText(), ctx); @@ -1331,7 +1304,7 @@ public Statement visitLabeledStmtAlt(LabeledStmtAltContext ctx) { statement.addStatementLabel(this.visitIdentifier(ctx.identifier())); - return statement; // configureAST(statement, ctx); + return statement; // this.configureAST(statement, ctx); } @Override @@ -1559,18 +1532,22 @@ private void attachAnnotation(ClassNode classNode, String annotationClassName) { */ private boolean containsDefaultMethods(ClassDeclarationContext ctx) { - for (ClassBodyDeclarationContext c : ctx.classBody().classBodyDeclaration()) { - MemberDeclarationContext memberDeclarationContext = c.memberDeclaration(); - if(memberDeclarationContext != null) { - MethodDeclarationContext methodDeclarationContext = memberDeclarationContext.methodDeclaration(); - if (methodDeclarationContext != null) { + List methodDeclarationContextList = + (List) ctx.classBody().classBodyDeclaration().stream() + .map(ClassBodyDeclarationContext::memberDeclaration) + .filter(Objects::nonNull) + .map(e -> (Object) e.methodDeclaration()) + .filter(Objects::nonNull).reduce(new LinkedList(), (r, e) -> { + MethodDeclarationContext methodDeclarationContext = (MethodDeclarationContext) e; + if (createModifierManager(methodDeclarationContext).containsAny(DEFAULT)) { - return true; + ((List) r).add(methodDeclarationContext); } - } - } - } - return false; + + return r; + }); + + return !methodDeclarationContextList.isEmpty(); } @Override @@ -1583,10 +1560,10 @@ public Void visitClassBody(ClassBodyContext ctx) { this.visitEnumConstants(ctx.enumConstants()); } - for (ClassBodyDeclarationContext e : ctx.classBodyDeclaration()) { + ctx.classBodyDeclaration().forEach(e -> { e.putNodeMetaData(CLASS_DECLARATION_CLASS_NODE, classNode); this.visitClassBodyDeclaration(e); - } + }); return null; } @@ -1596,12 +1573,12 @@ public List visitEnumConstants(EnumConstantsContext ctx) { ClassNode classNode = ctx.getNodeMetaData(CLASS_DECLARATION_CLASS_NODE); Objects.requireNonNull(classNode, "classNode should not be null"); - List list = new LinkedList<>(); - for (EnumConstantContext e : ctx.enumConstant()) { - e.putNodeMetaData(CLASS_DECLARATION_CLASS_NODE, classNode); - list.add(visitEnumConstant(e)); - } - return list; + return ctx.enumConstant().stream() + .map(e -> { + e.putNodeMetaData(CLASS_DECLARATION_CLASS_NODE, classNode); + return this.visitEnumConstant(e); + }) + .collect(Collectors.toList()); } @Override @@ -1649,14 +1626,11 @@ private Expression createEnumConstantInitExpression(ArgumentsContext ctx, InnerC if (expression instanceof NamedArgumentListExpression) { // e.g. SOME_ENUM_CONSTANT(a: "1", b: "2") List mapEntryExpressionList = ((NamedArgumentListExpression) expression).getMapEntryExpressions(); - List list = new ArrayList<>(); - for (MapEntryExpression e : mapEntryExpressionList) { - Expression e1 = (Expression) e; - list.add(e1); - } ListExpression listExpression = new ListExpression( - list); + mapEntryExpressionList.stream() + .map(e -> (Expression) e) + .collect(Collectors.toList())); if (asBoolean(anonymousInnerClassNode)) { listExpression.addExpression( @@ -1686,9 +1660,7 @@ private Expression createEnumConstantInitExpression(ArgumentsContext ctx, InnerC ListExpression listExpression = new ListExpression(); if (expression instanceof ListExpression) { - for (Expression e : ((ListExpression) expression).getExpressions()) { - listExpression.addExpression(e); - } + ((ListExpression) expression).getExpressions().forEach(listExpression::addExpression); } else { listExpression.addExpression(expression); } @@ -1775,12 +1747,9 @@ public GenericsType[] visitTypeParameters(TypeParametersContext ctx) { return null; } - List list = new ArrayList<>(); - for (TypeParameterContext typeParameterContext : ctx.typeParameter()) { - GenericsType genericsType = visitTypeParameter(typeParameterContext); - list.add(genericsType); - } - return list.toArray(GenericsType.EMPTY_ARRAY); + return ctx.typeParameter().stream() + .map(this::visitTypeParameter) + .toArray(GenericsType[]::new); } @Override @@ -1803,12 +1772,9 @@ public ClassNode[] visitTypeBound(TypeBoundContext ctx) { return null; } - List list = new ArrayList<>(); - for (TypeContext typeContext : ctx.type()) { - ClassNode classNode = visitType(typeContext); - list.add(classNode); - } - return list.toArray(new ClassNode[0]); + return ctx.type().stream() + .map(this::visitType) + .toArray(ClassNode[]::new); } @Override @@ -1858,17 +1824,15 @@ private void validateParametersOfMethodDeclaration(Parameter[] parameters, Class return; } - for (Parameter e : parameters) { - if (e.hasInitialExpression()) { - throw createParsingFailedException("Cannot specify default value for method parameter '" + e.getName() + " = " + e.getInitialExpression().getText() + "' inside an interface", e); + for (Parameter parameter : parameters) { + if (parameter.hasInitialExpression()) { + throw createParsingFailedException("Cannot specify default value for method parameter '" + parameter.getName() + " = " + parameter.getInitialExpression().getText() + "' inside an interface", parameter); } } } @Override public MethodNode visitMethodDeclaration(MethodDeclarationContext ctx) { - validateMethodDeclaration(ctx); - ModifierManager modifierManager = createModifierManager(ctx); if (modifierManager.containsAny(VAR)) { @@ -1880,7 +1844,7 @@ public MethodNode visitMethodDeclaration(MethodDeclarationContext ctx) { Parameter[] parameters = this.visitFormalParameters(ctx.formalParameters()); ClassNode[] exceptions = this.visitQualifiedClassNameList(ctx.qualifiedClassNameList()); - anonymousInnerClassesDefinedInMethodStack.push(new LinkedList()); + anonymousInnerClassesDefinedInMethodStack.push(new LinkedList<>()); Statement code = this.visitMethodBody(ctx.methodBody()); List anonymousInnerClassList = anonymousInnerClassesDefinedInMethodStack.pop(); @@ -1894,9 +1858,7 @@ public MethodNode visitMethodDeclaration(MethodDeclarationContext ctx) { } else { // script method declaration methodNode = createScriptMethodNode(modifierManager, methodName, returnType, parameters, exceptions, code); } - for (InnerClassNode e : anonymousInnerClassList) { - e.setEnclosingMethod(methodNode); - } + anonymousInnerClassList.forEach(e -> e.setEnclosingMethod(methodNode)); methodNode.setGenericsTypes(this.visitTypeParameters(ctx.typeParameters())); methodNode.setSyntheticPublic( @@ -1907,9 +1869,10 @@ public MethodNode visitMethodDeclaration(MethodDeclarationContext ctx) { modifierManager)); if (modifierManager.containsAny(STATIC)) { - for (Parameter e : methodNode.getParameters()) { - e.setInStaticContext(true); + for (Parameter parameter : methodNode.getParameters()) { + parameter.setInStaticContext(true); } + methodNode.getVariableScope().setInStaticContext(true); } @@ -1932,7 +1895,7 @@ public MethodNode visitMethodDeclaration(MethodDeclarationContext ctx) { return methodNode; } - private void validateMethodDeclaration(MethodDeclarationContext ctx) { + private void validateMethodDeclaration(MethodDeclarationContext ctx, MethodNode methodNode, ModifierManager modifierManager, ClassNode classNode) { if (1 == ctx.t || 2 == ctx.t || 3 == ctx.t) { // 1: normal method declaration; 2: abstract method declaration; 3: normal method declaration OR abstract method declaration if (!(asBoolean(ctx.modifiersOpt().modifiers()) || asBoolean(ctx.returnType()))) { throw createParsingFailedException("Modifiers or return type is required", ctx); @@ -1950,9 +1913,7 @@ private void validateMethodDeclaration(MethodDeclarationContext ctx) { throw createParsingFailedException("Abstract method should not have method body", ctx); } } - } - private void validateMethodDeclaration(MethodDeclarationContext ctx, MethodNode methodNode, ModifierManager modifierManager, ClassNode classNode) { boolean isAbstractMethod = methodNode.isAbstract(); boolean hasMethodBody = asBoolean(methodNode.getCode()); @@ -1961,6 +1922,12 @@ private void validateMethodDeclaration(MethodDeclarationContext ctx, MethodNode throw createParsingFailedException("You can not define a " + (isAbstractMethod ? "abstract" : "") + " method[" + methodNode.getName() + "] " + (!hasMethodBody ? "without method body" : "") + " in the script. Try " + (isAbstractMethod ? "removing the 'abstract'" : "") + (isAbstractMethod && !hasMethodBody ? " and" : "") + (!hasMethodBody ? " adding a method body" : ""), methodNode); } } else { + if (4 == ctx.ct) { // trait + if (isAbstractMethod && hasMethodBody) { + throw createParsingFailedException("Abstract method should not have method body", ctx); + } + } + if (!isAbstractMethod && !hasMethodBody) { // non-abstract method without body in the non-script(e.g. class, enum, trait) is not allowed! throw createParsingFailedException("You defined a method[" + methodNode.getName() + "] without body. Try adding a method body, or declare it abstract", methodNode); } @@ -2116,11 +2083,6 @@ private DeclarationListStatement createMultiAssignmentDeclarationListStatement(V } */ - List list = new ArrayList<>(); - for (Expression e : this.visitTypeNamePairs(ctx.typeNamePairs())) { - modifierManager.processVariableExpression((VariableExpression) e); - list.add(e); - } /* GRECLIPSE edit return configureAST( new DeclarationListStatement( @@ -2128,7 +2090,9 @@ private DeclarationListStatement createMultiAssignmentDeclarationListStatement(V modifierManager.attachAnnotations( new DeclarationExpression( new ArgumentListExpression( - list + this.visitTypeNamePairs(ctx.typeNamePairs()).stream() + .peek(e -> modifierManager.processVariableExpression((VariableExpression) e)) + .collect(Collectors.toList()) ), this.createGroovyTokenByType(ctx.ASSIGN().getSymbol(), Types.ASSIGN), this.visitVariableInitializer(ctx.variableInitializer()) @@ -2140,12 +2104,16 @@ private DeclarationListStatement createMultiAssignmentDeclarationListStatement(V ctx ); */ - DeclarationExpression de = new DeclarationExpression(new ArgumentListExpression(list), + DeclarationExpression de = new DeclarationExpression(new ArgumentListExpression( + this.visitTypeNamePairs(ctx.typeNamePairs()).stream() + .peek(e -> modifierManager.processVariableExpression((VariableExpression) e)) + .collect(Collectors.toList()) + ), this.createGroovyTokenByType(ctx.ASSIGN().getSymbol(), Types.ASSIGN), this.visitVariableInitializer(ctx.variableInitializer())); - ModifierNode var = modifierManager.get(VAR); - if (var != null) { - de.setNodeMetaData("reserved.type.name", var); + Optional var = modifierManager.get(VAR); + if (var != null && var.isPresent()) { + de.setNodeMetaData("reserved.type.name", var.get()); } configureAST(modifierManager.attachAnnotations(de), ctx); return configureAST(new DeclarationListStatement(de), ctx); @@ -2188,17 +2156,18 @@ public DeclarationListStatement visitVariableDeclaration(VariableDeclarationCont return createFieldDeclarationListStatement(ctx, modifierManager, variableType, declarationExpressionList, classNode); } - for (DeclarationExpression e : declarationExpressionList) { + declarationExpressionList.forEach(e -> { VariableExpression variableExpression = (VariableExpression) e.getLeftExpression(); + modifierManager.processVariableExpression(variableExpression); modifierManager.attachAnnotations(e); // GRECLIPSE add - ModifierNode var = modifierManager.get(VAR); - if (var != null) { - e.setNodeMetaData("reserved.type.name", var); + Optional var = modifierManager.get(VAR); + if (var != null && var.isPresent()) { + e.setNodeMetaData("reserved.type.name", var.get()); } // GRECLIPSE end - } + }); int size = declarationExpressionList.size(); if (size > 0) { @@ -2350,12 +2319,7 @@ private boolean isFieldDeclaration(ModifierManager modifierManager, ClassNode cl @Override public List visitTypeNamePairs(TypeNamePairsContext ctx) { - List list = new ArrayList<>(); - for (TypeNamePairContext typeNamePairContext : ctx.typeNamePair()) { - VariableExpression variableExpression = visitTypeNamePair(typeNamePairContext); - list.add(variableExpression); - } - return list; + return ctx.typeNamePair().stream().map(this::visitTypeNamePair).collect(Collectors.toList()); } @Override @@ -2377,12 +2341,13 @@ public List visitVariableDeclarators(VariableDeclaratorsC ClassNode variableType = ctx.getNodeMetaData(VARIABLE_DECLARATION_VARIABLE_TYPE); Objects.requireNonNull(variableType, "variableType should not be null"); - List list = new LinkedList<>(); - for (VariableDeclaratorContext e : ctx.variableDeclarator()) { - e.putNodeMetaData(VARIABLE_DECLARATION_VARIABLE_TYPE, variableType); - list.add(this.visitVariableDeclarator(e)); - } - return list; + return ctx.variableDeclarator().stream() + .map(e -> { + e.putNodeMetaData(VARIABLE_DECLARATION_VARIABLE_TYPE, variableType); + return this.visitVariableDeclarator(e); +// return this.configureAST(this.visitVariableDeclarator(e), ctx); + }) + .collect(Collectors.toList()); } @Override @@ -2427,21 +2392,25 @@ public List visitVariableInitializers(VariableInitializersContext ct return Collections.emptyList(); } - List list = new ArrayList<>(); - for (VariableInitializerContext variableInitializerContext : ctx.variableInitializer()) { - Expression expression = visitVariableInitializer(variableInitializerContext); - list.add(expression); - } - return list; + return ctx.variableInitializer().stream() + .map(this::visitVariableInitializer) + .collect(Collectors.toList()); } + private int visitingArrayInitializerCnt = 0; + @Override public List visitArrayInitializer(ArrayInitializerContext ctx) { if (!asBoolean(ctx)) { return Collections.emptyList(); } - return this.visitVariableInitializers(ctx.variableInitializers()); + try { + visitingArrayInitializerCnt++; + return this.visitVariableInitializers(ctx.variableInitializers()); + } finally { + visitingArrayInitializerCnt--; + } } @Override @@ -2455,12 +2424,6 @@ public Statement visitBlock(BlockContext ctx) { ctx); } - - @Override - public ExpressionStatement visitNormalExprAlt(NormalExprAltContext ctx) { - return configureAST(new ExpressionStatement((Expression) this.visit(ctx.expression())), ctx); - } - /* @Override public Expression visitEnhancedExpression(EnhancedExpressionContext ctx) { @@ -2485,62 +2448,94 @@ public ExpressionStatement visitCommandExprAlt(CommandExprAltContext ctx) { @Override public Expression visitCommandExpression(CommandExpressionContext ctx) { - Expression baseExpr = this.visitPathExpression(ctx.pathExpression()); - Expression arguments = this.visitEnhancedArgumentList(ctx.enhancedArgumentList()); - - MethodCallExpression methodCallExpression; - if (baseExpr instanceof PropertyExpression) { // e.g. obj.a 1, 2 - methodCallExpression = - configureAST( - this.createMethodCallExpression( - (PropertyExpression) baseExpr, arguments), - arguments); - - } else if (baseExpr instanceof MethodCallExpression && !isInsideParentheses(baseExpr)) { // e.g. m {} a, b OR m(...) a, b - if (asBoolean(arguments)) { - // The error should never be thrown. - throw new GroovyBugError("When baseExpr is a instance of MethodCallExpression, which should follow NO argumentList"); - } + boolean hasArgumentList = asBoolean(ctx.enhancedArgumentList()); + boolean hasCommandArgument = asBoolean(ctx.commandArgument()); - methodCallExpression = (MethodCallExpression) baseExpr; - } else if ( - !isInsideParentheses(baseExpr) - && (baseExpr instanceof VariableExpression /* e.g. m 1, 2 */ - || baseExpr instanceof GStringExpression /* e.g. "$m" 1, 2 */ - || (baseExpr instanceof ConstantExpression && isTrue(baseExpr, IS_STRING)) /* e.g. "m" 1, 2 */) - ) { - methodCallExpression = - configureAST( - this.createMethodCallExpression(baseExpr, arguments), - arguments); - } else { // e.g. a[x] b, new A() b, etc. - methodCallExpression = configureAST(this.createCallMethodCallExpression(baseExpr, arguments), arguments); + if (visitingArrayInitializerCnt > 0 && (hasArgumentList || hasCommandArgument)) { + // To avoid ambiguities, command chain expression should not be used in array initializer + // the old parser does not support either, so no breaking changes + // SEE http://groovy.329449.n5.nabble.com/parrot-Command-expressions-in-array-initializer-tt5752273.html + throw createParsingFailedException("Command chain expression can not be used in array initializer", ctx); } - methodCallExpression.putNodeMetaData(IS_COMMAND_EXPRESSION, true); - // GRECLIPSE add - methodCallExpression.setColumnNumber(baseExpr.getColumnNumber()); - methodCallExpression.setLineNumber(baseExpr.getLineNumber()); - methodCallExpression.setStart(baseExpr.getStart()); + Expression baseExpr = (Expression) this.visit(ctx.expression()); + - if (methodCallExpression.getMethod() instanceof ConstantExpression) { - Expression nameExpr = methodCallExpression.getMethod(); - methodCallExpression.setNameStart(nameExpr.getStart()); - methodCallExpression.setNameEnd(nameExpr.getEnd() - 1); + if (hasArgumentList || hasCommandArgument) { + if (baseExpr instanceof BinaryExpression) { + if (!"[".equals(((BinaryExpression) baseExpr).getOperation().getText()) && !isInsideParentheses(baseExpr)) { + throw createParsingFailedException("Unexpected input: '" + getOriginalText(ctx.expression()) + "'", ctx.expression()); + } + } } - // GRECLIPSE end - if (!asBoolean(ctx.commandArgument())) { - return configureAST(methodCallExpression, ctx); + MethodCallExpression methodCallExpression = null; + + if (hasArgumentList) { + Expression arguments = this.visitEnhancedArgumentList(ctx.enhancedArgumentList()); + + if (baseExpr instanceof PropertyExpression) { // e.g. obj.a 1, 2 + methodCallExpression = + configureAST( + this.createMethodCallExpression( + (PropertyExpression) baseExpr, arguments), + arguments); + + } else if (baseExpr instanceof MethodCallExpression && !isInsideParentheses(baseExpr)) { // e.g. m {} a, b OR m(...) a, b + if (asBoolean(arguments)) { + // The error should never be thrown. + throw new GroovyBugError("When baseExpr is a instance of MethodCallExpression, which should follow NO argumentList"); + } + + methodCallExpression = (MethodCallExpression) baseExpr; + } else if ( + !isInsideParentheses(baseExpr) + && (baseExpr instanceof VariableExpression /* e.g. m 1, 2 */ + || baseExpr instanceof GStringExpression /* e.g. "$m" 1, 2 */ + || (baseExpr instanceof ConstantExpression && isTrue(baseExpr, IS_STRING)) /* e.g. "m" 1, 2 */) + ) { + methodCallExpression = + configureAST( + this.createMethodCallExpression(baseExpr, arguments), + arguments); + } else { // e.g. a[x] b, new A() b, etc. + methodCallExpression = configureAST(this.createCallMethodCallExpression(baseExpr, arguments), arguments); + } + + methodCallExpression.putNodeMetaData(IS_COMMAND_EXPRESSION, true); + // GRECLIPSE add + methodCallExpression.setColumnNumber(baseExpr.getColumnNumber()); + methodCallExpression.setLineNumber(baseExpr.getLineNumber()); + methodCallExpression.setStart(baseExpr.getStart()); + + if (methodCallExpression.getMethod() instanceof ConstantExpression) { + Expression nameExpr = methodCallExpression.getMethod(); + methodCallExpression.setNameStart(nameExpr.getStart()); + methodCallExpression.setNameEnd(nameExpr.getEnd() - 1); + } + // GRECLIPSE end + + if (!hasCommandArgument) { + return configureAST(methodCallExpression, ctx); + } } - Expression r = methodCallExpression; - for (CommandArgumentContext commandArgumentContext : ctx.commandArgument()) { - commandArgumentContext.putNodeMetaData(CMD_EXPRESSION_BASE_EXPR, r); - r = this.visitCommandArgument(commandArgumentContext); + if (hasCommandArgument) { + baseExpr.putNodeMetaData(IS_COMMAND_EXPRESSION, true); } - return configureAST(r, ctx); + return configureAST( + (Expression) ctx.commandArgument().stream() + .map(e -> (Object) e) + .reduce(null == methodCallExpression ? baseExpr : methodCallExpression, + (r, e) -> { + CommandArgumentContext commandArgumentContext = (CommandArgumentContext) e; + commandArgumentContext.putNodeMetaData(CMD_EXPRESSION_BASE_EXPR, r); + + return this.visitCommandArgument(commandArgumentContext); + } + ), + ctx); } @Override @@ -2664,7 +2659,7 @@ public Expression visitPathElement(PathElementContext ctx) { expression.putNodeMetaData(PATH_EXPRESSION_BASE_EXPR_SAFE_CHAIN, true); return expression; - } else if (asBoolean(ctx.METHOD_POINTER())) { // e.g. obj.&m + } else if (asBoolean(ctx.METHOD_POINTER())) { // e.g. obj.&m return configureAST(new MethodPointerExpression(baseExpr, namePartExpr), ctx); } else if (asBoolean(ctx.METHOD_REFERENCE())) { // e.g. obj::m return configureAST(new MethodReferenceExpression(baseExpr, namePartExpr), ctx); @@ -2694,28 +2689,39 @@ public Expression visitPathElement(PathElementContext ctx) { boolean isSafeChain = isTrue(baseExpr, PATH_EXPRESSION_BASE_EXPR_SAFE_CHAIN); return configureAST( - new BinaryExpression(baseExpr, createGroovyToken(tuple.getFirst()), tuple.getSecond(), isSafeChain || asBoolean(ctx.indexPropertyArgs().QUESTION())), + new BinaryExpression(baseExpr, createGroovyToken(tuple.getV1()), tuple.getV2(), isSafeChain || asBoolean(ctx.indexPropertyArgs().QUESTION())), ctx); - } else if (asBoolean(ctx.namedPropertyArgs())) { // this is a special way to new instance, e.g. Person(name: 'Daniel.Sun', location: 'Shanghai') + } else if (asBoolean(ctx.namedPropertyArgs())) { // this is a special way to signify a cast, e.g. Person[name: 'Daniel.Sun', location: 'Shanghai'] List mapEntryExpressionList = this.visitNamedPropertyArgs(ctx.namedPropertyArgs()); Expression right; - if (mapEntryExpressionList.size() == 1) { - MapEntryExpression mapEntryExpression = mapEntryExpressionList.get(0); - - if (mapEntryExpression.getKeyExpression() instanceof SpreadMapExpression) { - right = mapEntryExpression.getKeyExpression(); - } else { - right = mapEntryExpression; - } + Expression firstKeyExpression; + int mapEntryExpressionListSize = mapEntryExpressionList.size(); + if (mapEntryExpressionListSize == 0) { + // expecting list of MapEntryExpressions later so use SpreadMap to smuggle empty MapExpression to later stages + right = configureAST( + new SpreadMapExpression(configureAST(new MapExpression(), ctx.namedPropertyArgs())), + ctx.namedPropertyArgs()); + } else if (mapEntryExpressionListSize == 1 && (firstKeyExpression = mapEntryExpressionList.get(0).getKeyExpression()) instanceof SpreadMapExpression) { + right = firstKeyExpression; } else { - List list = new LinkedList<>(); - for (MapEntryExpression e : mapEntryExpressionList) { - list.add(e.getKeyExpression() instanceof SpreadMapExpression ? - e.getKeyExpression() : e); - } - ListExpression listExpression = configureAST(new ListExpression(list), ctx.namedPropertyArgs()); + ListExpression listExpression = + configureAST( + new ListExpression( + mapEntryExpressionList.stream() + .map( + e -> { + if (e.getKeyExpression() instanceof SpreadMapExpression) { + return e.getKeyExpression(); + } + + return e; + } + ) + .collect(Collectors.toList())), + ctx.namedPropertyArgs() + ); listExpression.setWrapped(true); right = listExpression; } @@ -2737,7 +2743,7 @@ public Expression visitPathElement(PathElementContext ctx) { AttributeExpression attributeExpression = (AttributeExpression) baseExpr; attributeExpression.setSpreadSafe(false); // whether attributeExpression is spread safe or not, we must reset it as false - return configureAST(this.createCallMethodCallExpression(attributeExpression, argumentsExpr, true), ctx); + return configureAST(createCallMethodCallExpression(attributeExpression, argumentsExpr, true), ctx); } if (baseExpr instanceof PropertyExpression) { // e.g. obj.a(1, 2) @@ -2750,7 +2756,7 @@ public Expression visitPathElement(PathElementContext ctx) { if (baseExpr instanceof VariableExpression) { // void and primitive type AST node must be an instance of VariableExpression String baseExprText = baseExpr.getText(); if (VOID_STR.equals(baseExprText)) { // e.g. void() - return configureAST(this.createCallMethodCallExpression(this.createConstantExpression(baseExpr), argumentsExpr), ctx); + return configureAST(createCallMethodCallExpression(this.createConstantExpression(baseExpr), argumentsExpr), ctx); } else if (PRIMITIVE_TYPE_SET.contains(baseExprText)) { // e.g. int(), long(), float(), etc. throw createParsingFailedException("Primitive type literal: " + baseExprText + " cannot be used as a method name", ctx); } @@ -2813,20 +2819,16 @@ public Expression visitPathElement(PathElementContext ctx) { NamedArgumentListExpression namedArgumentListExpression = (NamedArgumentListExpression) tupleExpression.getExpression(0); if (asBoolean(tupleExpression.getExpressions())) { - List list = new ArrayList<>(); - for (Expression expression : Arrays.asList( - configureAST( - new MapExpression(namedArgumentListExpression.getMapEntryExpressions()), - namedArgumentListExpression - ), - closureExpression - )) { - list.add(expression); - } methodCallExpression.setArguments( configureAST( new ArgumentListExpression( - list + Stream.of( + configureAST( + new MapExpression(namedArgumentListExpression.getMapEntryExpressions()), + namedArgumentListExpression + ), + closureExpression + ).collect(Collectors.toList()) ), tupleExpression ) @@ -2850,12 +2852,12 @@ public Expression visitPathElement(PathElementContext ctx) { return configureAST(this.createCallMethodCallExpression( baseExpr, configureAST( - new ArgumentListExpression(closureExpression), - closureExpression - ) + new ArgumentListExpression(closureExpression), + closureExpression) ), ctx); } + if (baseExpr instanceof PropertyExpression) { // e.g. obj.m { } PropertyExpression propertyExpression = (PropertyExpression) baseExpr; @@ -2922,12 +2924,9 @@ public GenericsType[] visitNonWildcardTypeArguments(NonWildcardTypeArgumentsCont return null; } - List list = new ArrayList<>(); - for (ClassNode classNode : this.visitTypeList(ctx.typeList())) { - GenericsType genericsType = createGenericsType(classNode); - list.add(genericsType); - } - return list.toArray(GenericsType.EMPTY_ARRAY); + return Arrays.stream(this.visitTypeList(ctx.typeList())) + .map(this::createGenericsType) + .toArray(GenericsType[]::new); } @Override @@ -2936,12 +2935,9 @@ public ClassNode[] visitTypeList(TypeListContext ctx) { return ClassNode.EMPTY_ARRAY; } - List list = new ArrayList<>(); - for (TypeContext typeContext : ctx.type()) { - ClassNode classNode = visitType(typeContext); - list.add(classNode); - } - return list.toArray(new ClassNode[0]); + return ctx.type().stream() + .map(this::visitType) + .toArray(ClassNode[]::new); } @Override @@ -2983,17 +2979,20 @@ public Expression visitEnhancedArgumentList(EnhancedArgumentListContext ctx) { List expressionList = new LinkedList<>(); List mapEntryExpressionList = new LinkedList<>(); - for (EnhancedArgumentListElementContext c : ctx.enhancedArgumentListElement()) { - Expression e = visitEnhancedArgumentListElement(c); - if (e instanceof MapEntryExpression) { - MapEntryExpression mapEntryExpression = (MapEntryExpression) e; - validateDuplicatedNamedParameter(mapEntryExpressionList, mapEntryExpression); + ctx.enhancedArgumentListElement().stream() + .map(this::visitEnhancedArgumentListElement) + .forEach(e -> { + + if (e instanceof MapEntryExpression) { + MapEntryExpression mapEntryExpression = (MapEntryExpression) e; + validateDuplicatedNamedParameter(mapEntryExpressionList, mapEntryExpression); + + mapEntryExpressionList.add(mapEntryExpression); + } else { + expressionList.add(e); + } + }); - mapEntryExpressionList.add(mapEntryExpression); - } else { - expressionList.add(e); - } - } if (!asBoolean(mapEntryExpressionList)) { // e.g. arguments like 1, 2 OR someArg, e -> e return configureAST( new ArgumentListExpression(expressionList), @@ -3011,8 +3010,7 @@ public Expression visitEnhancedArgumentList(EnhancedArgumentListContext ctx) { if (asBoolean(mapEntryExpressionList) && asBoolean(expressionList)) { // e.g. arguments like x: 1, 'a', y: 2, 'b', z: 3 ArgumentListExpression argumentListExpression = new ArgumentListExpression(expressionList); - argumentListExpression.getExpressions().add(0, new MapExpression(mapEntryExpressionList)); // TODO: confirm BUG OR NOT? All map entries will be put at first, which is not friendly to Groovy developers - + argumentListExpression.getExpressions().add(0, configureAST(new MapExpression(mapEntryExpressionList), ctx)); return configureAST(argumentListExpression, ctx); } @@ -3031,14 +3029,10 @@ private void validateDuplicatedNamedParameter(List mapEntryE } String parameterName = keyExpression.getText(); - boolean isDuplicatedNamedParameter = false; - for (MapEntryExpression me : mapEntryExpressionList) { - if (me.getKeyExpression().getText().equals(parameterName)) { - isDuplicatedNamedParameter = true; - break; - } - } + boolean isDuplicatedNamedParameter = + mapEntryExpressionList.stream() + .anyMatch(m -> m.getKeyExpression().getText().equals(parameterName)); if (!isDuplicatedNamedParameter) { return; @@ -3121,14 +3115,14 @@ public Tuple2 visitIndexPropertyArgs(IndexPropertyArgsContext indexExpr = expr; } - return new Tuple2<>(ctx.LBRACK().getSymbol(), indexExpr); + return tuple(ctx.LBRACK().getSymbol(), indexExpr); } // e.g. a[1, 2] ListExpression listExpression = new ListExpression(expressionList); listExpression.setWrapped(true); - return new Tuple2<>(ctx.LBRACK().getSymbol(), (Expression) configureAST(listExpression, ctx)); + return tuple(ctx.LBRACK().getSymbol(), configureAST(listExpression, ctx)); } @Override @@ -3231,18 +3225,16 @@ public Expression visitUnaryAddExprAlt(UnaryAddExprAltContext ctx) { ExpressionContext expressionCtx = ctx.expression(); Expression expression = (Expression) this.visit(expressionCtx); - Boolean insidePar = isInsideParentheses(expression); - switch (ctx.op.getType()) { case ADD: { - if (expression instanceof ConstantExpression && !insidePar) { + if (isNonStringConstantOutsideParentheses(expression)) { return configureAST(expression, ctx); } return configureAST(new UnaryPlusExpression(expression), ctx); } case SUB: { - if (expression instanceof ConstantExpression && !insidePar) { + if (isNonStringConstantOutsideParentheses(expression)) { ConstantExpression constantExpression = (ConstantExpression) expression; try { @@ -3283,6 +3275,12 @@ public Expression visitUnaryAddExprAlt(UnaryAddExprAltContext ctx) { } } + private boolean isNonStringConstantOutsideParentheses(Expression expression) { + return expression instanceof ConstantExpression + && !(((ConstantExpression) expression).getValue() instanceof String) + && !isInsideParentheses(expression); + } + @Override public BinaryExpression visitMultiplicativeExprAlt(MultiplicativeExprAltContext ctx) { return this.createBinaryExpression(ctx.left, ctx.op, ctx.right, ctx); @@ -3655,31 +3653,23 @@ public Expression visitCreator(CreatorContext ctx) { if (asBoolean(emptyDimList)) { empties = new Expression[emptyDimList.size()]; - for (int i = 0; i < empties.length; ++i) { - empties[i] = ConstantExpression.EMPTY_EXPRESSION; - } + Arrays.fill(empties, ConstantExpression.EMPTY_EXPRESSION); } else { empties = Expression.EMPTY_ARRAY; } - List sizes = new LinkedList<>(); - for (ExpressionContext e : ctx.expression()) { - sizes.add((Expression)this.visit(e)); - } - for (Expression e : empties) { - sizes.add(e); - } - arrayExpression = new ArrayExpression( classNode, null, - sizes); + Stream.concat( + ctx.expression().stream() + .map(e -> (Expression) this.visit(e)), + Arrays.stream(empties) + ).collect(Collectors.toList())); - List> exprDimList = new ArrayList>(); - for (AnnotationsOptContext annotationsOptContext : ctx.annotationsOpt()) { - exprDimList.add(this.visitAnnotationsOpt(annotationsOptContext)); - } + + List> exprDimList = ctx.annotationsOpt().stream().map(this::visitAnnotationsOpt).collect(Collectors.toList()); allDimList = new ArrayList<>(exprDimList); Collections.reverse(emptyDimList); allDimList.addAll(emptyDimList); @@ -3815,12 +3805,9 @@ private List createMapEntryList(List list = new ArrayList<>(); - for (MapEntryContext mapEntryContext : mapEntryContextList) { - MapEntryExpression mapEntryExpression = visitMapEntry(mapEntryContext); - list.add(mapEntryExpression); - } - return list; + return mapEntryContextList.stream() + .map(this::visitMapEntry) + .collect(Collectors.toList()); } @Override @@ -3910,12 +3897,9 @@ private List createExpressionList(List list = new ArrayList<>(); - for (ExpressionListElementContext expressionListElementContext : expressionListElementContextList) { - Expression expression = visitExpressionListElement(expressionListElementContext); - list.add(expression); - } - return list; + return expressionListElementContextList.stream() + .map(this::visitExpressionListElement) + .collect(Collectors.toList()); } @Override @@ -3939,7 +3923,7 @@ private void validateExpressionListElement(ExpressionListElementContext ctx, Exp // statements like `foo(String a)` is invalid MethodCallExpression methodCallExpression = (MethodCallExpression) expression; String methodName = methodCallExpression.getMethodAsString(); - if (Character.isUpperCase(methodName.codePointAt(0)) || PRIMITIVE_TYPE_SET.contains(methodName)) { + if (methodCallExpression.isImplicitThis() && Character.isUpperCase(methodName.codePointAt(0)) || PRIMITIVE_TYPE_SET.contains(methodName)) { throw createParsingFailedException("Invalid method declaration", ctx); } } @@ -3954,7 +3938,7 @@ public ConstantExpression visitIntegerLiteralAlt(IntegerLiteralAltContext ctx) { try { num = Numbers.parseInteger(null, text); } catch (Exception e) { - this.numberFormatError = new Tuple2(ctx, e); + this.numberFormatError = tuple(ctx, e); } ConstantExpression constantExpression = new ConstantExpression(num, !text.startsWith(SUB_STR)); @@ -3972,7 +3956,7 @@ public ConstantExpression visitFloatingPointLiteralAlt(FloatingPointLiteralAltCo try { num = Numbers.parseDecimal(text); } catch (Exception e) { - this.numberFormatError = new Tuple2(ctx, e); + this.numberFormatError = tuple(ctx, e); } ConstantExpression constantExpression = new ConstantExpression(num, !text.startsWith(SUB_STR)); @@ -4011,38 +3995,31 @@ public GStringExpression visitGstring(GstringContext ctx) { final String beginQuotation = beginQuotation(begin); stringLiteralList.add(configureAST(new ConstantExpression(parseGStringBegin(ctx, beginQuotation)), ctx.GStringBegin())); - List partStrings = new LinkedList<>(); - for (TerminalNode e : ctx.GStringPart()) { - partStrings.add(configureAST(new ConstantExpression(parseGStringPart(e, beginQuotation)), e)); - } + List partStrings = + ctx.GStringPart().stream() + .map(e -> configureAST(new ConstantExpression(parseGStringPart(e, beginQuotation)), e)) + .collect(Collectors.toList()); stringLiteralList.addAll(partStrings); stringLiteralList.add(configureAST(new ConstantExpression(parseGStringEnd(ctx, beginQuotation)), ctx.GStringEnd())); - List values = new LinkedList<>(); - for (GstringValueContext e : ctx.gstringValue()) { - Expression expression = this.visitGstringValue(e); + List values = ctx.gstringValue().stream() + .map(e -> { + Expression expression = this.visitGstringValue(e); - if (expression instanceof ClosureExpression && !asBoolean(e.closure().ARROW())) { - List statementList = ((BlockStatement) ((ClosureExpression) expression).getCode()).getStatements(); + if (expression instanceof ClosureExpression && !asBoolean(e.closure().ARROW())) { + List statementList = ((BlockStatement) ((ClosureExpression) expression).getCode()).getStatements(); - // Java 8: if (statementList.stream().allMatch(x -> !asBoolean(x))) { - boolean allFalse = true; - for (Statement x : statementList) { - if (asBoolean(x)) { - allFalse = false; - break; + if (statementList.stream().noneMatch(DefaultGroovyMethods::asBoolean)) { + return configureAST(new ConstantExpression(null), e); + } + + return configureAST(this.createCallMethodCallExpression(expression, new ArgumentListExpression(), true), e); } - } - if (allFalse) { - values.add(configureAST(new ConstantExpression(null), e)); - } else { - values.add(configureAST(this.createCallMethodCallExpression(expression, new ArgumentListExpression(), true), e)); - } - } else { - values.add(expression); - } - } + + return expression; + }) + .collect(Collectors.toList()); StringBuilder verbatimText = new StringBuilder(ctx.getText().length()); for (int i = 0, n = stringLiteralList.size(), s = values.size(); i < n; i++) { @@ -4101,7 +4078,6 @@ private String beginQuotation(String text) { } } - @Override public Expression visitGstringValue(GstringValueContext ctx) { if (asBoolean(ctx.gstringPath())) { @@ -4128,21 +4104,25 @@ public Expression visitGstringPath(GstringPathContext ctx) { VariableExpression variableExpression = new VariableExpression(this.visitIdentifier(ctx.identifier())); if (asBoolean(ctx.GStringPathPart())) { - Expression propertyExpression = configureAST(variableExpression, ctx.identifier()); - for (TerminalNode e : ctx.GStringPathPart()) { - Expression expression = configureAST((Expression) new ConstantExpression(e.getText().substring(1)), e); - // GRECLIPSE add - expression.setStart(expression.getStart() + 1); - int[] row_col = locationSupport.getRowCol(expression.getStart()); - expression.setLineNumber(row_col[0]); expression.setColumnNumber(row_col[1]); - // GRECLIPSE end - propertyExpression = configureAST(new PropertyExpression(propertyExpression, expression), expression); - // GRECLIPSE add - propertyExpression.setStart(((PropertyExpression) propertyExpression).getObjectExpression().getStart()); - propertyExpression.setLineNumber(((PropertyExpression) propertyExpression).getObjectExpression().getLineNumber()); - propertyExpression.setColumnNumber(((PropertyExpression) propertyExpression).getObjectExpression().getColumnNumber()); - // GRECLIPSE end - } + Expression propertyExpression = ctx.GStringPathPart().stream() + .map(e -> configureAST((Expression) new ConstantExpression(e.getText().substring(1)), e)) + // GRECLIPSE add + .peek(expression -> { + expression.setStart(expression.getStart() + 1); + int[] row_col = locationSupport.getRowCol(expression.getStart()); + expression.setLineNumber(row_col[0]); expression.setColumnNumber(row_col[1]); + }) + // GRECLIPSE end + // GRECLIPSE edit + //.reduce(configureAST(variableExpression, ctx.identifier()), (r, e) -> configureAST(new PropertyExpression(r, e), e)); + .reduce(configureAST(variableExpression, ctx.identifier()), (r, e) -> { + PropertyExpression pe = configureAST(new PropertyExpression(r, e), e); + pe.setStart(pe.getObjectExpression().getStart()); + pe.setLineNumber(pe.getObjectExpression().getLineNumber()); + pe.setColumnNumber(pe.getObjectExpression().getColumnNumber()); + return pe; + }); + // GRECLIPSE end // GRECLIPSE edit //return configureAST(propertyExpression, ctx); @@ -4217,7 +4197,6 @@ public ClosureExpression visitClosure(ClosureContext ctx) { } Statement code = this.visitBlockStatementsOpt(ctx.blockStatementsOpt()); - ClosureExpression result = configureAST(new ClosureExpression(parameters, code), ctx); visitingClosureCnt--; @@ -4250,16 +4229,19 @@ public Parameter[] visitFormalParameterList(FormalParameterListContext ctx) { if (asBoolean(formalParameterList)) { validateVarArgParameter(formalParameterList); - List list = new ArrayList<>(); - for (FormalParameterContext formalParameterContext : formalParameterList) { - Parameter parameter = visitFormalParameter(formalParameterContext); - // GRECLIPSE add - ASTNode nameNode = configureAST(new ConstantExpression(parameter.getName()), formalParameterContext.variableDeclaratorId()); - parameter.setNameStart(nameNode.getStart()); parameter.setNameEnd(nameNode.getEnd()); - // GRECLIPSE end - list.add(parameter); - } - parameterList.addAll(list); + parameterList.addAll( + formalParameterList.stream() + // GRECLIPSE edit + //.map(this::visitFormalParameter) + .map(formalParameterContext -> { + Parameter parameter = visitFormalParameter(formalParameterContext); + ASTNode nameNode = configureAST(new ConstantExpression(parameter.getName()), formalParameterContext.variableDeclaratorId()); + parameter.setNameStart(nameNode.getStart()); + parameter.setNameEnd(nameNode.getEnd()); + return parameter; + }) + // GRECLIPSE end + .collect(Collectors.toList())); } validateParameterList(parameterList); @@ -4313,12 +4295,9 @@ public List visitClassOrInterfaceModifiersOpt(ClassOrInterfaceModi @Override public List visitClassOrInterfaceModifiers(ClassOrInterfaceModifiersContext ctx) { - List list = new ArrayList<>(); - for (ClassOrInterfaceModifierContext classOrInterfaceModifierContext : ctx.classOrInterfaceModifier()) { - ModifierNode modifierNode = visitClassOrInterfaceModifier(classOrInterfaceModifierContext); - list.add(modifierNode); - } - return list; + return ctx.classOrInterfaceModifier().stream() + .map(this::visitClassOrInterfaceModifier) + .collect(Collectors.toList()); } @@ -4350,12 +4329,9 @@ public ModifierNode visitModifier(ModifierContext ctx) { @Override public List visitModifiers(ModifiersContext ctx) { - List list = new ArrayList<>(); - for (ModifierContext modifierContext : ctx.modifier()) { - ModifierNode modifierNode = visitModifier(modifierContext); - list.add(modifierNode); - } - return list; + return ctx.modifier().stream() + .map(this::visitModifier) + .collect(Collectors.toList()); } @Override @@ -4392,20 +4368,17 @@ public List visitVariableModifiersOpt(VariableModifiersOptContext @Override public List visitVariableModifiers(VariableModifiersContext ctx) { - List list = new ArrayList<>(); - for (VariableModifierContext variableModifierContext : ctx.variableModifier()) { - ModifierNode modifierNode = visitVariableModifier(variableModifierContext); - list.add(modifierNode); - } - return list; + return ctx.variableModifier().stream() + .map(this::visitVariableModifier) + .collect(Collectors.toList()); } @Override public List> visitDims(DimsContext ctx) { - List> dimList = new ArrayList>(); - for (AnnotationsOptContext annotationsOptContext : ctx.annotationsOpt()) { - dimList.add(this.visitAnnotationsOpt(annotationsOptContext)); - } + List> dimList = + ctx.annotationsOpt().stream() + .map(this::visitAnnotationsOpt) + .collect(Collectors.toList()); Collections.reverse(dimList); @@ -4483,7 +4456,8 @@ public ClassNode visitClassOrInterfaceType(ClassOrInterfaceTypeContext ctx) { } if (asBoolean(ctx.typeArguments())) { - classNode.setGenericsTypes(this.visitTypeArguments(ctx.typeArguments())); + classNode.setGenericsTypes( + this.visitTypeArguments(ctx.typeArguments())); } // GRECLIPSE edit @@ -4508,12 +4482,7 @@ public GenericsType[] visitTypeArgumentsOrDiamond(TypeArgumentsOrDiamondContext @Override public GenericsType[] visitTypeArguments(TypeArgumentsContext ctx) { - List list = new ArrayList<>(); - for (TypeArgumentContext typeArgumentContext : ctx.typeArgument()) { - GenericsType genericsType = visitTypeArgument(typeArgumentContext); - list.add(genericsType); - } - return list.toArray(GenericsType.EMPTY_ARRAY); + return ctx.typeArgument().stream().map(this::visitTypeArgument).toArray(GenericsType[]::new); } @Override @@ -4569,14 +4538,11 @@ public VariableExpression visitVariableDeclaratorId(VariableDeclaratorIdContext @Override public TupleExpression visitVariableNames(VariableNamesContext ctx) { - List list = new ArrayList<>(); - for (VariableDeclaratorIdContext variableDeclaratorIdContext : ctx.variableDeclaratorId()) { - VariableExpression variableExpression = visitVariableDeclaratorId(variableDeclaratorIdContext); - list.add(variableExpression); - } return configureAST( new TupleExpression( - list + ctx.variableDeclaratorId().stream() + .map(this::visitVariableDeclaratorId) + .collect(Collectors.toList()) ), ctx); } @@ -4592,14 +4558,13 @@ public BlockStatement visitBlockStatementsOpt(BlockStatementsOptContext ctx) { @Override public BlockStatement visitBlockStatements(BlockStatementsContext ctx) { - List result = new ArrayList<>(); - for (BlockStatementContext blockStatementContext : ctx.blockStatement()) { - Statement e = visitBlockStatement(blockStatementContext); - if (asBoolean(e)) { - result.add(e); - } - } - return configureAST(this.createBlockStatement(result), ctx); + return configureAST( + this.createBlockStatement( + ctx.blockStatement().stream() + .map(this::visitBlockStatement) + .filter(DefaultGroovyMethods::asBoolean) + .collect(Collectors.toList())), + ctx); } @Override @@ -4609,7 +4574,7 @@ public Statement visitBlockStatement(BlockStatementContext ctx) { } if (asBoolean(ctx.statement())) { - Object astNode = this.visit(ctx.statement()); //configureAST((Statement) this.visit(ctx.statement()), ctx); + Object astNode = this.visit(ctx.statement()); //this.configureAST((Statement) this.visit(ctx.statement()), ctx); if (null == astNode) { return null; @@ -4635,11 +4600,9 @@ public List visitAnnotationsOpt(AnnotationsOptContext ctx) { return Collections.emptyList(); } - List list = new LinkedList<>(); - for (AnnotationContext c : ctx.annotation()) { - list.add(this.visitAnnotation(c)); - } - return list; + return ctx.annotation().stream() + .map(this::visitAnnotation) + .collect(Collectors.toList()); } @Override @@ -4648,9 +4611,7 @@ public AnnotationNode visitAnnotation(AnnotationContext ctx) { AnnotationNode annotationNode = new AnnotationNode(ClassHelper.make(annotationName)); List> annotationElementValues = this.visitElementValues(ctx.elementValues()); - for (Tuple2 e : annotationElementValues) { - annotationNode.addMember(e.getFirst(), e.getSecond()); - } + annotationElementValues.forEach(e -> annotationNode.addMember(e.getV1(), e.getV2())); // GRECLIPSE edit /*return*/ configureAST(annotationNode, ctx); @@ -4674,11 +4635,9 @@ public List> visitElementValues(ElementValuesContext List> annotationElementValues = new LinkedList<>(); if (asBoolean(ctx.elementValuePairs())) { - for (Map.Entry e : this.visitElementValuePairs(ctx.elementValuePairs()).entrySet()) { - annotationElementValues.add(new Tuple2<>(e.getKey(), e.getValue())); - } + this.visitElementValuePairs(ctx.elementValuePairs()).forEach((key, value) -> annotationElementValues.add(tuple(key, value))); } else if (asBoolean(ctx.elementValue())) { - annotationElementValues.add(new Tuple2<>(VALUE_STR, this.visitElementValue(ctx.elementValue()))); + annotationElementValues.add(tuple(VALUE_STR, this.visitElementValue(ctx.elementValue()))); } return annotationElementValues; @@ -4692,21 +4651,21 @@ public String visitAnnotationName(AnnotationNameContext ctx) { @Override public Map visitElementValuePairs(ElementValuePairsContext ctx) { - LinkedHashMap map = new LinkedHashMap<>(); - for (ElementValuePairContext elementValuePairContext : ctx.elementValuePair()) { - Tuple2 stringExpressionPair = visitElementValuePair(elementValuePairContext); - if (map.containsKey(stringExpressionPair.getFirst())) { - throw new IllegalStateException(String.format("Duplicate key %s", stringExpressionPair.getFirst())); - } else{ - map.put(stringExpressionPair.getFirst(), stringExpressionPair.getSecond()); - } - } - return map; + return ctx.elementValuePair().stream() + .map(this::visitElementValuePair) + .collect(Collectors.toMap( + Tuple2::getV1, + Tuple2::getV2, + (k, v) -> { + throw new IllegalStateException(String.format("Duplicate key %s", k)); + }, + LinkedHashMap::new + )); } @Override public Tuple2 visitElementValuePair(ElementValuePairContext ctx) { - return new Tuple2<>(ctx.elementValuePairName().getText(), this.visitElementValue(ctx.elementValue())); + return tuple(ctx.elementValuePairName().getText(), this.visitElementValue(ctx.elementValue())); } @Override @@ -4728,12 +4687,7 @@ public Expression visitElementValue(ElementValueContext ctx) { @Override public ListExpression visitElementValueArrayInitializer(ElementValueArrayInitializerContext ctx) { - List list = new ArrayList<>(); - for (ElementValueContext elementValueContext : ctx.elementValue()) { - Expression expression = visitElementValue(elementValueContext); - list.add(expression); - } - return configureAST(new ListExpression(list), ctx); + return configureAST(new ListExpression(ctx.elementValue().stream().map(this::visitElementValue).collect(Collectors.toList())), ctx); } @Override @@ -4749,15 +4703,9 @@ public String visitIdentifier(IdentifierContext ctx) { @Override public String visitQualifiedName(QualifiedNameContext ctx) { - StringBuilder builder = new StringBuilder(); - for (QualifiedNameElementContext qualifiedNameElementContext : ctx.qualifiedNameElement()) { - String text = qualifiedNameElementContext.getText(); - if (builder.length() > 0) { - builder.append(DOT_STR); - } - builder.append(text); - } - return builder.toString(); + return ctx.qualifiedNameElement().stream() + .map(ParseTree::getText) + .collect(Collectors.joining(DOT_STR)); } @Override @@ -4775,12 +4723,9 @@ public ClassNode[] visitQualifiedClassNameList(QualifiedClassNameListContext ctx return ClassNode.EMPTY_ARRAY; } - List list = new ArrayList<>(); - for (AnnotatedQualifiedClassNameContext annotatedQualifiedClassNameContext : ctx.annotatedQualifiedClassName()) { - ClassNode classNode = visitAnnotatedQualifiedClassName(annotatedQualifiedClassNameContext); - list.add(classNode); - } - return list.toArray(new ClassNode[0]); + return ctx.annotatedQualifiedClassName().stream() + .map(this::visitAnnotatedQualifiedClassName) + .toArray(ClassNode[]::new); } @Override @@ -4851,7 +4796,7 @@ private MethodCallExpression createMethodCallExpression(PropertyExpression prope } // if the generics types meta data is not empty, it is a generic method call, e.g. obj.a(1, 2) - methodCallExpression.setGenericsTypes( (GenericsType[]) + methodCallExpression.setGenericsTypes( propertyExpression.getNodeMetaData(PATH_EXPRESSION_BASE_EXPR_GENERICS_TYPES)); return methodCallExpression; @@ -4910,33 +4855,36 @@ private Parameter processFormalParameter(GroovyParserRuleContext ctx, } private Expression createPathExpression(Expression primaryExpr, List pathElementContextList) { - Expression expr = primaryExpr; - for (PathElementContext pathElementContext : pathElementContextList) { - pathElementContext.putNodeMetaData(PATH_EXPRESSION_BASE_EXPR, expr); - - boolean isSafeChain = isTrue(expr, PATH_EXPRESSION_BASE_EXPR_SAFE_CHAIN); - - expr = this.visitPathElement(pathElementContext); - // GRECLIPSE add - Expression base = pathElementContext.getNodeMetaData(PATH_EXPRESSION_BASE_EXPR); - expr.setColumnNumber(base.getColumnNumber()); - expr.setLineNumber(base.getLineNumber()); - expr.setStart(base.getStart()); - - if (expr instanceof MethodCallExpression) { - Expression meth = ((MethodCallExpression) expr).getMethod(); - if (meth instanceof ConstantExpression) { - expr.setNameStart(meth.getStart()); - expr.setNameEnd(meth.getEnd() - 1); - } - } - // GRECLIPSE end - - if (isSafeChain) { - expr.putNodeMetaData(PATH_EXPRESSION_BASE_EXPR_SAFE_CHAIN, true); - } - } - return expr; + return (Expression) pathElementContextList.stream() + .map(e -> (Object) e) + .reduce(primaryExpr, + (r, e) -> { + PathElementContext pathElementContext = (PathElementContext) e; + pathElementContext.putNodeMetaData(PATH_EXPRESSION_BASE_EXPR, r); + Expression expression = this.visitPathElement(pathElementContext); + // GRECLIPSE add + Expression base = pathElementContext.getNodeMetaData(PATH_EXPRESSION_BASE_EXPR); + expression.setColumnNumber(base.getColumnNumber()); + expression.setLineNumber(base.getLineNumber()); + expression.setStart(base.getStart()); + + if (expression instanceof MethodCallExpression) { + Expression meth = ((MethodCallExpression) expression).getMethod(); + if (meth instanceof ConstantExpression) { + expression.setNameStart(meth.getStart()); + expression.setNameEnd(meth.getEnd() - 1); + } + } + // GRECLIPSE end + + boolean isSafeChain = isTrue((Expression) r, PATH_EXPRESSION_BASE_EXPR_SAFE_CHAIN); + if (isSafeChain) { + expression.putNodeMetaData(PATH_EXPRESSION_BASE_EXPR_SAFE_CHAIN, true); + } + + return expression; + } + ); } private GenericsType createGenericsType(ClassNode classNode) { @@ -4992,16 +4940,18 @@ public BlockStatement appendStatementsToBlockStatement(BlockStatement bs, Statem } private BlockStatement appendStatementsToBlockStatement(BlockStatement bs, List statementList) { - for (Statement e : statementList) { - if (e instanceof DeclarationListStatement) { - for (ExpressionStatement s : ((DeclarationListStatement) e).getDeclarationStatements()) { - bs.addStatement(s); - } - } else { - bs.addStatement(e); - } - } - return bs; + return (BlockStatement) statementList.stream() + .reduce(bs, (r, e) -> { + BlockStatement blockStatement = (BlockStatement) r; + + if (e instanceof DeclarationListStatement) { + ((DeclarationListStatement) e).getDeclarationStatements().forEach(blockStatement::addStatement); + } else { + blockStatement.addStatement(e); + } + + return blockStatement; + }); } private boolean isAnnotationDeclaration(ClassNode classNode) { @@ -5039,7 +4989,7 @@ private void hackMixins(ClassNode classNode) { classNode.setMixins(null); } - private static final Map TYPE_DEFAULT_VALUE_MAP = Maps.of( + private static final Map TYPE_DEFAULT_VALUE_MAP = Maps.of( ClassHelper.int_TYPE, 0, ClassHelper.long_TYPE, 0L, ClassHelper.double_TYPE, 0.0D, @@ -5142,6 +5092,12 @@ private void configureScriptClassNode() { } + private String getOriginalText(ParserRuleContext context) { + CharStream charStream = lexer.getInputStream(); + return charStream.getText(Interval.of(context.getStart().getStartIndex(), context.getStop().getStopIndex())); + + } + private boolean isTrue(NodeMetaDataHandler nodeMetaDataHandler, String key) { Object nmd = nodeMetaDataHandler.getNodeMetaData(key); @@ -5246,7 +5202,7 @@ private void addErrorListeners() { parser.addErrorListener(this.createANTLRErrorListener()); } - private class DeclarationListStatement extends Statement { + private /*static*/ class DeclarationListStatement extends Statement { private final List declarationStatements; public DeclarationListStatement(DeclarationExpression... declarations) { @@ -5254,44 +5210,36 @@ public DeclarationListStatement(DeclarationExpression... declarations) { } public DeclarationListStatement(List declarations) { - List list = new ArrayList<>(); - for (DeclarationExpression e : declarations) { - ExpressionStatement expressionStatement = configureAST(new ExpressionStatement(e), e); - list.add(expressionStatement); - } this.declarationStatements = - list; + declarations.stream() + .map(e -> configureAST(new ExpressionStatement(e), e)) + .collect(Collectors.toList()); } public List getDeclarationStatements() { List declarationListStatementLabels = this.getStatementLabels(); - for (ExpressionStatement e: this.declarationStatements) { + this.declarationStatements.forEach(e -> { if (null != declarationListStatementLabels) { // clear existing statement labels before setting labels if (null != e.getStatementLabels()) { e.getStatementLabels().clear(); } - for (String s : declarationListStatementLabels) { - e.addStatementLabel(s); - } + + declarationListStatementLabels.forEach(e::addStatementLabel); } - } + }); return this.declarationStatements; } public List getDeclarationExpressions() { - List list = new ArrayList<>(); - for (ExpressionStatement e : this.declarationStatements) { - DeclarationExpression expression = (DeclarationExpression) e.getExpression(); - list.add(expression); - } - return list; + return this.declarationStatements.stream() + .map(e -> (DeclarationExpression) e.getExpression()) + .collect(Collectors.toList()); } } - private final ModuleNode moduleNode; private final SourceUnit sourceUnit; private final GroovyLangLexer lexer; diff --git a/base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/GroovyLexer.java b/base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/GroovyLexer.java new file mode 100644 index 0000000000..eda053975b --- /dev/null +++ b/base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/GroovyLexer.java @@ -0,0 +1,1362 @@ +// Generated from GroovyLexer.g4 by ANTLR 4.7 +package org.apache.groovy.parser.antlr4; + + import static org.apache.groovy.parser.antlr4.SemanticPredicates.*; + import org.codehaus.groovy.ast.Comment; + import java.util.*; + +import groovyjarjarantlr4.v4.runtime.Lexer; +import groovyjarjarantlr4.v4.runtime.CharStream; +import groovyjarjarantlr4.v4.runtime.Token; +import groovyjarjarantlr4.v4.runtime.TokenStream; +import groovyjarjarantlr4.v4.runtime.*; +import groovyjarjarantlr4.v4.runtime.atn.*; +import groovyjarjarantlr4.v4.runtime.dfa.DFA; +import groovyjarjarantlr4.v4.runtime.misc.*; + +public class GroovyLexer extends AbstractLexer { + public static final int + StringLiteral=1, GStringBegin=2, GStringEnd=3, GStringPart=4, GStringPathPart=5, + RollBackOne=6, AS=7, DEF=8, IN=9, TRAIT=10, THREADSAFE=11, VAR=12, BuiltInPrimitiveType=13, + ABSTRACT=14, ASSERT=15, BREAK=16, CASE=17, CATCH=18, CLASS=19, CONST=20, + CONTINUE=21, DEFAULT=22, DO=23, ELSE=24, ENUM=25, EXTENDS=26, FINAL=27, + FINALLY=28, FOR=29, IF=30, GOTO=31, IMPLEMENTS=32, IMPORT=33, INSTANCEOF=34, + INTERFACE=35, NATIVE=36, NEW=37, PACKAGE=38, PRIVATE=39, PROTECTED=40, + PUBLIC=41, RETURN=42, STATIC=43, STRICTFP=44, SUPER=45, SWITCH=46, SYNCHRONIZED=47, + THIS=48, THROW=49, THROWS=50, TRANSIENT=51, TRY=52, VOID=53, VOLATILE=54, + WHILE=55, IntegerLiteral=56, FloatingPointLiteral=57, BooleanLiteral=58, + NullLiteral=59, RANGE_INCLUSIVE=60, RANGE_EXCLUSIVE=61, SPREAD_DOT=62, + SAFE_DOT=63, SAFE_CHAIN_DOT=64, ELVIS=65, METHOD_POINTER=66, METHOD_REFERENCE=67, + REGEX_FIND=68, REGEX_MATCH=69, POWER=70, POWER_ASSIGN=71, SPACESHIP=72, + IDENTICAL=73, NOT_IDENTICAL=74, ARROW=75, NOT_INSTANCEOF=76, NOT_IN=77, + LPAREN=78, RPAREN=79, LBRACE=80, RBRACE=81, LBRACK=82, RBRACK=83, SEMI=84, + COMMA=85, DOT=86, ASSIGN=87, GT=88, LT=89, NOT=90, BITNOT=91, QUESTION=92, + COLON=93, EQUAL=94, LE=95, GE=96, NOTEQUAL=97, AND=98, OR=99, INC=100, + DEC=101, ADD=102, SUB=103, MUL=104, DIV=105, BITAND=106, BITOR=107, XOR=108, + MOD=109, ADD_ASSIGN=110, SUB_ASSIGN=111, MUL_ASSIGN=112, DIV_ASSIGN=113, + AND_ASSIGN=114, OR_ASSIGN=115, XOR_ASSIGN=116, MOD_ASSIGN=117, LSHIFT_ASSIGN=118, + RSHIFT_ASSIGN=119, URSHIFT_ASSIGN=120, ELVIS_ASSIGN=121, CapitalizedIdentifier=122, + Identifier=123, AT=124, ELLIPSIS=125, WS=126, NL=127, SH_COMMENT=128, + UNEXPECTED_CHAR=129; + public static final int + DQ_GSTRING_MODE=1, TDQ_GSTRING_MODE=2, SLASHY_GSTRING_MODE=3, DOLLAR_SLASHY_GSTRING_MODE=4, + GSTRING_TYPE_SELECTOR_MODE=5, GSTRING_PATH_MODE=6; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE", "DQ_GSTRING_MODE", "TDQ_GSTRING_MODE", "SLASHY_GSTRING_MODE", + "DOLLAR_SLASHY_GSTRING_MODE", "GSTRING_TYPE_SELECTOR_MODE", "GSTRING_PATH_MODE" + }; + + public static final String[] ruleNames = { + "StringLiteral", "GStringBegin", "TdqGStringBegin", "SlashyGStringBegin", + "DollarSlashyGStringBegin", "GStringEnd", "GStringPart", "GStringCharacter", + "TdqGStringEnd", "TdqGStringPart", "TdqGStringCharacter", "SlashyGStringEnd", + "SlashyGStringPart", "SlashyGStringCharacter", "DollarSlashyGStringEnd", + "DollarSlashyGStringPart", "DollarSlashyGStringCharacter", "GStringLBrace", + "GStringIdentifier", "GStringPathPart", "RollBackOne", "DqStringCharacter", + "SqStringCharacter", "TdqStringCharacter", "TsqStringCharacter", "SlashyStringCharacter", + "DollarSlashyStringCharacter", "AS", "DEF", "IN", "TRAIT", "THREADSAFE", + "VAR", "BuiltInPrimitiveType", "ABSTRACT", "ASSERT", "BOOLEAN", "BREAK", + "BYTE", "CASE", "CATCH", "CHAR", "CLASS", "CONST", "CONTINUE", "DEFAULT", + "DO", "DOUBLE", "ELSE", "ENUM", "EXTENDS", "FINAL", "FINALLY", "FLOAT", + "FOR", "IF", "GOTO", "IMPLEMENTS", "IMPORT", "INSTANCEOF", "INT", "INTERFACE", + "LONG", "NATIVE", "NEW", "PACKAGE", "PRIVATE", "PROTECTED", "PUBLIC", + "RETURN", "SHORT", "STATIC", "STRICTFP", "SUPER", "SWITCH", "SYNCHRONIZED", + "THIS", "THROW", "THROWS", "TRANSIENT", "TRY", "VOID", "VOLATILE", "WHILE", + "IntegerLiteral", "Zero", "DecimalIntegerLiteral", "HexIntegerLiteral", + "OctalIntegerLiteral", "BinaryIntegerLiteral", "IntegerTypeSuffix", "DecimalNumeral", + "Digits", "Digit", "NonZeroDigit", "DigitOrUnderscore", "Underscores", + "Underscore", "HexNumeral", "HexDigits", "HexDigit", "HexDigitOrUnderscore", + "OctalNumeral", "OctalDigits", "OctalDigit", "OctalDigitOrUnderscore", + "BinaryNumeral", "BinaryDigits", "BinaryDigit", "BinaryDigitOrUnderscore", + "FloatingPointLiteral", "DecimalFloatingPointLiteral", "ExponentPart", + "ExponentIndicator", "SignedInteger", "Sign", "FloatTypeSuffix", "HexadecimalFloatingPointLiteral", + "HexSignificand", "BinaryExponent", "BinaryExponentIndicator", "Dot", + "BooleanLiteral", "EscapeSequence", "OctalEscape", "UnicodeEscape", "ZeroToThree", + "DollarEscape", "LineEscape", "SlashEscape", "Backslash", "Slash", "Dollar", + "GStringQuotationMark", "SqStringQuotationMark", "TdqStringQuotationMark", + "TsqStringQuotationMark", "DollarSlashyGStringQuotationMarkBegin", "DollarSlashyGStringQuotationMarkEnd", + "DollarSlashEscape", "DollarDollarEscape", "NullLiteral", "RANGE_INCLUSIVE", + "RANGE_EXCLUSIVE", "SPREAD_DOT", "SAFE_DOT", "SAFE_CHAIN_DOT", "ELVIS", + "METHOD_POINTER", "METHOD_REFERENCE", "REGEX_FIND", "REGEX_MATCH", "POWER", + "POWER_ASSIGN", "SPACESHIP", "IDENTICAL", "NOT_IDENTICAL", "ARROW", "NOT_INSTANCEOF", + "NOT_IN", "LPAREN", "RPAREN", "LBRACE", "RBRACE", "LBRACK", "RBRACK", + "SEMI", "COMMA", "DOT", "ASSIGN", "GT", "LT", "NOT", "BITNOT", "QUESTION", + "COLON", "EQUAL", "LE", "GE", "NOTEQUAL", "AND", "OR", "INC", "DEC", "ADD", + "SUB", "MUL", "DIV", "BITAND", "BITOR", "XOR", "MOD", "ADD_ASSIGN", "SUB_ASSIGN", + "MUL_ASSIGN", "DIV_ASSIGN", "AND_ASSIGN", "OR_ASSIGN", "XOR_ASSIGN", "MOD_ASSIGN", + "LSHIFT_ASSIGN", "RSHIFT_ASSIGN", "URSHIFT_ASSIGN", "ELVIS_ASSIGN", "CapitalizedIdentifier", + "Identifier", "IdentifierInGString", "JavaLetterInGString", "JavaLetterOrDigitInGString", + "JavaLetter", "JavaLetterOrDigit", "AT", "ELLIPSIS", "WS", "NL", "ML_COMMENT", + "SL_COMMENT", "SH_COMMENT", "UNEXPECTED_CHAR" + }; + + private static final String[] _LITERAL_NAMES = { + null, null, null, null, null, null, null, "'as'", "'def'", "'in'", "'trait'", + "'threadsafe'", "'var'", null, "'abstract'", "'assert'", "'break'", "'case'", + "'catch'", "'class'", "'const'", "'continue'", "'default'", "'do'", "'else'", + "'enum'", "'extends'", "'final'", "'finally'", "'for'", "'if'", "'goto'", + "'implements'", "'import'", "'instanceof'", "'interface'", "'native'", + "'new'", "'package'", "'private'", "'protected'", "'public'", "'return'", + "'static'", "'strictfp'", "'super'", "'switch'", "'synchronized'", "'this'", + "'throw'", "'throws'", "'transient'", "'try'", "'void'", "'volatile'", + "'while'", null, null, null, "'null'", "'..'", "'..<'", "'*.'", "'?.'", + "'??.'", "'?:'", "'.&'", "'::'", "'=~'", "'==~'", "'**'", "'**='", "'<=>'", + "'==='", "'!=='", "'->'", "'!instanceof'", "'!in'", null, null, null, + null, null, null, "';'", "','", null, "'='", "'>'", "'<'", "'!'", "'~'", + "'?'", "':'", "'=='", "'<='", "'>='", "'!='", "'&&'", "'||'", "'++'", + "'--'", "'+'", "'-'", "'*'", null, "'&'", "'|'", "'^'", "'%'", "'+='", + "'-='", "'*='", "'/='", "'&='", "'|='", "'^='", "'%='", "'<<='", "'>>='", + "'>>>='", "'?='", null, null, "'@'", "'...'" + }; + private static final String[] _SYMBOLIC_NAMES = { + null, "StringLiteral", "GStringBegin", "GStringEnd", "GStringPart", "GStringPathPart", + "RollBackOne", "AS", "DEF", "IN", "TRAIT", "THREADSAFE", "VAR", "BuiltInPrimitiveType", + "ABSTRACT", "ASSERT", "BREAK", "CASE", "CATCH", "CLASS", "CONST", "CONTINUE", + "DEFAULT", "DO", "ELSE", "ENUM", "EXTENDS", "FINAL", "FINALLY", "FOR", + "IF", "GOTO", "IMPLEMENTS", "IMPORT", "INSTANCEOF", "INTERFACE", "NATIVE", + "NEW", "PACKAGE", "PRIVATE", "PROTECTED", "PUBLIC", "RETURN", "STATIC", + "STRICTFP", "SUPER", "SWITCH", "SYNCHRONIZED", "THIS", "THROW", "THROWS", + "TRANSIENT", "TRY", "VOID", "VOLATILE", "WHILE", "IntegerLiteral", "FloatingPointLiteral", + "BooleanLiteral", "NullLiteral", "RANGE_INCLUSIVE", "RANGE_EXCLUSIVE", + "SPREAD_DOT", "SAFE_DOT", "SAFE_CHAIN_DOT", "ELVIS", "METHOD_POINTER", + "METHOD_REFERENCE", "REGEX_FIND", "REGEX_MATCH", "POWER", "POWER_ASSIGN", + "SPACESHIP", "IDENTICAL", "NOT_IDENTICAL", "ARROW", "NOT_INSTANCEOF", + "NOT_IN", "LPAREN", "RPAREN", "LBRACE", "RBRACE", "LBRACK", "RBRACK", + "SEMI", "COMMA", "DOT", "ASSIGN", "GT", "LT", "NOT", "BITNOT", "QUESTION", + "COLON", "EQUAL", "LE", "GE", "NOTEQUAL", "AND", "OR", "INC", "DEC", "ADD", + "SUB", "MUL", "DIV", "BITAND", "BITOR", "XOR", "MOD", "ADD_ASSIGN", "SUB_ASSIGN", + "MUL_ASSIGN", "DIV_ASSIGN", "AND_ASSIGN", "OR_ASSIGN", "XOR_ASSIGN", "MOD_ASSIGN", + "LSHIFT_ASSIGN", "RSHIFT_ASSIGN", "URSHIFT_ASSIGN", "ELVIS_ASSIGN", "CapitalizedIdentifier", + "Identifier", "AT", "ELLIPSIS", "WS", "NL", "SH_COMMENT", "UNEXPECTED_CHAR" + }; + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + @NotNull + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + private long tokenIndex = 0; + private int lastTokenType = 0; + private int invalidDigitCount = 0; + + /** + * Record the index and token type of the current token while emitting tokens. + */ + @Override + public void emit(Token token) { + this.tokenIndex++; + + int tokenType = token.getType(); + if (Token.DEFAULT_CHANNEL == token.getChannel()) { + this.lastTokenType = tokenType; + } + + if (RollBackOne == tokenType) { + this.rollbackOneChar(); + } + + super.emit(token); + } + + private static final Set REGEX_CHECK_SET = + Collections.unmodifiableSet( + new HashSet<>(Arrays.asList(Identifier, CapitalizedIdentifier, NullLiteral, BooleanLiteral, THIS, RPAREN, RBRACK, RBRACE, IntegerLiteral, FloatingPointLiteral, StringLiteral, GStringEnd, INC, DEC))); + private boolean isRegexAllowed() { + if (REGEX_CHECK_SET.contains(this.lastTokenType)) { + return false; + } + + return true; + } + + /** + * just a hook, which will be overrided by GroovyLangLexer + */ + protected void rollbackOneChar() {} + + private static class Paren { + private String text; + private int lastTokenType; + private int line; + private int column; + + public Paren(String text, int lastTokenType, int line, int column) { + this.text = text; + this.lastTokenType = lastTokenType; + this.line = line; + this.column = column; + } + + public String getText() { + return this.text; + } + + public int getLastTokenType() { + return this.lastTokenType; + } + + public int getLine() { + return line; + } + + public int getColumn() { + return column; + } + + @Override + public int hashCode() { + return (int) (text.hashCode() * line + column); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Paren)) { + return false; + } + + Paren other = (Paren) obj; + + return this.text.equals(other.text) && (this.line == other.line && this.column == other.column); + } + } + + /* GRECLIPSE edit + private static final Map PAREN_MAP = Collections.unmodifiableMap(new HashMap() { + { + put("(", ")"); + put("[", "]"); + put("{", "}"); + } + }); + */ + private static final Map PAREN_MAP = org.apache.groovy.util.Maps.of( + "(", ")", + "[", "]", + "{", "}" + ); + // GRECLIPSE end + + private final Deque parenStack = new ArrayDeque<>(32); + private void enterParen() { + parenStack.push(new Paren(getText(), this.lastTokenType, getLine(), getCharPositionInLine())); + } + private void exitParen() { + Paren paren = parenStack.peek(); + String text = getText(); + + require(null != paren, "Too many '" + text + "'"); + require(text.equals(PAREN_MAP.get(paren.getText())), + "'" + paren.getText() + "'" + new PositionInfo(paren.getLine(), paren.getColumn()) + " can not match '" + text + "'", -1); + + parenStack.pop(); + } + private boolean isInsideParens() { + Paren paren = parenStack.peek(); + + // We just care about "(" and "[", inside which the new lines will be ignored. + // Notice: the new lines between "{" and "}" can not be ignored. + if (null == paren) { + return false; + } + return ("(".equals(paren.getText()) && TRY != paren.getLastTokenType()) // we don't treat try-paren(i.e. try (....)) as parenthesis + || "[".equals(paren.getText()); + } + private void ignoreTokenInsideParens() { + if (!this.isInsideParens()) { + return; + } + + this.setChannel(Token.HIDDEN_CHANNEL); + } + private void ignoreMultiLineCommentConditionally() { + if (!this.isInsideParens() && isFollowedByWhiteSpaces(_input)) { + return; + } + + this.setChannel(Token.HIDDEN_CHANNEL); + } + + @Override + public int getSyntaxErrorSource() { + return GroovySyntaxError.LEXER; + } + + @Override + public int getErrorLine() { + return getLine(); + } + + @Override + public int getErrorColumn() { + return getCharPositionInLine() + 1; + } + + // GRECLIPSE add + private void addComment(int type) { + String text = _input.getText(Interval.of(_tokenStartCharIndex, getCharIndex() - 1)); + Comment comment; + if (type == 0) { + comment = Comment.makeMultiLineComment( _tokenStartLine, _tokenStartCharPositionInLine + 1, getLine(), getCharPositionInLine() + 1, text); + } else { + comment = Comment.makeSingleLineComment(_tokenStartLine, _tokenStartCharPositionInLine + 1, getLine(), getCharPositionInLine() + 1, text); + } + comments.add(comment); + } + public List getComments() { return comments; } + private final List comments = new ArrayList<>(); + // GRECLIPSE end + + + public GroovyLexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN); + validateInputStream(_ATN, input); + } + + @Override + public String getGrammarFileName() { return "GroovyLexer.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + @NotNull + public String[] getChannelNames() { return channelNames; } + + @Override + @NotNull + public String[] getModeNames() { return modeNames; } + + @Override + public void action(RuleContext _localctx, int ruleIndex, int actionIndex) { + switch (ruleIndex) { + case 17: + GStringLBrace_action(_localctx, actionIndex); + break; + + case 20: + RollBackOne_action(_localctx, actionIndex); + break; + + case 84: + IntegerLiteral_action(_localctx, actionIndex); + break; + + case 110: + FloatingPointLiteral_action(_localctx, actionIndex); + break; + + case 160: + LPAREN_action(_localctx, actionIndex); + break; + + case 161: + RPAREN_action(_localctx, actionIndex); + break; + + case 162: + LBRACE_action(_localctx, actionIndex); + break; + + case 163: + RBRACE_action(_localctx, actionIndex); + break; + + case 164: + LBRACK_action(_localctx, actionIndex); + break; + + case 165: + RBRACK_action(_localctx, actionIndex); + break; + + case 214: + NL_action(_localctx, actionIndex); + break; + + case 215: + ML_COMMENT_action(_localctx, actionIndex); + break; + + case 216: + SL_COMMENT_action(_localctx, actionIndex); + break; + + case 217: + SH_COMMENT_action(_localctx, actionIndex); + break; + } + } + private void GStringLBrace_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 0: + this.enterParen(); + break; + } + } + private void RollBackOne_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 1: + + // a trick to handle GStrings followed by EOF properly + if (EOF == _input.LA(1) && ('"' == _input.LA(-1) || '/' == _input.LA(-1))) { + setType(GStringEnd); + } else { + setChannel(HIDDEN); + } + + break; + } + } + private void IntegerLiteral_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 2: + require(false, "Number ending with underscores is invalid", -1, true); + break; + + case 3: + invalidDigitCount++; + break; + + case 4: + require(false, "Invalid octal number", -(invalidDigitCount + 1), true); + break; + } + } + private void FloatingPointLiteral_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 5: + require(false, "Number ending with underscores is invalid", -1, true); + break; + } + } + private void LPAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 6: + this.enterParen(); + break; + } + } + private void RPAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 7: + this.exitParen(); + break; + } + } + private void LBRACE_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 8: + this.enterParen(); + break; + } + } + private void RBRACE_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 9: + this.exitParen(); + break; + } + } + private void LBRACK_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 10: + this.enterParen(); + break; + } + } + private void RBRACK_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 11: + this.exitParen(); + break; + } + } + private void NL_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 12: + this.ignoreTokenInsideParens(); + break; + } + } + private void ML_COMMENT_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 13: + addComment(0); ignoreMultiLineCommentConditionally(); + break; + } + } + private void SL_COMMENT_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 14: + addComment(1); ignoreTokenInsideParens(); + break; + } + } + private void SH_COMMENT_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 15: + require(0 == this.tokenIndex, "Shebang comment should appear at the first line", -2, true); + break; + } + } + @Override + public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { + switch (ruleIndex) { + case 0: + return StringLiteral_sempred(_localctx, predIndex); + + case 3: + return SlashyGStringBegin_sempred(_localctx, predIndex); + + case 4: + return DollarSlashyGStringBegin_sempred(_localctx, predIndex); + + case 12: + return SlashyGStringPart_sempred(_localctx, predIndex); + + case 15: + return DollarSlashyGStringPart_sempred(_localctx, predIndex); + + case 23: + return TdqStringCharacter_sempred(_localctx, predIndex); + + case 24: + return TsqStringCharacter_sempred(_localctx, predIndex); + + case 25: + return SlashyStringCharacter_sempred(_localctx, predIndex); + + case 26: + return DollarSlashyStringCharacter_sempred(_localctx, predIndex); + + case 158: + return NOT_INSTANCEOF_sempred(_localctx, predIndex); + + case 159: + return NOT_IN_sempred(_localctx, predIndex); + + case 207: + return JavaLetterInGString_sempred(_localctx, predIndex); + + case 208: + return JavaLetterOrDigitInGString_sempred(_localctx, predIndex); + + case 209: + return JavaLetter_sempred(_localctx, predIndex); + + case 210: + return JavaLetterOrDigit_sempred(_localctx, predIndex); + } + return true; + } + private boolean StringLiteral_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 0: + return this.isRegexAllowed() && _input.LA(1) != '*' ; + } + return true; + } + private boolean SlashyGStringBegin_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 1: + return this.isRegexAllowed() && _input.LA(1) != '*' ; + + case 2: + return isFollowedByJavaLetterInGString(_input) ; + } + return true; + } + private boolean DollarSlashyGStringBegin_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 3: + return isFollowedByJavaLetterInGString(_input) ; + } + return true; + } + private boolean SlashyGStringPart_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 4: + return isFollowedByJavaLetterInGString(_input) ; + } + return true; + } + private boolean DollarSlashyGStringPart_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 5: + return isFollowedByJavaLetterInGString(_input) ; + } + return true; + } + private boolean TdqStringCharacter_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 6: + return _input.LA(1) != '"' || _input.LA(2) != '"' || _input.LA(3) == '"' && (_input.LA(4) != '"' || _input.LA(5) != '"') ; + } + return true; + } + private boolean TsqStringCharacter_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 7: + return _input.LA(1) != '\'' || _input.LA(2) != '\'' || _input.LA(3) == '\'' && (_input.LA(4) != '\'' || _input.LA(5) != '\'') ; + } + return true; + } + private boolean SlashyStringCharacter_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 8: + return !isFollowedByJavaLetterInGString(_input) ; + } + return true; + } + private boolean DollarSlashyStringCharacter_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 9: + return _input.LA(1) != '$' ; + + case 10: + return !isFollowedByJavaLetterInGString(_input) ; + } + return true; + } + private boolean NOT_INSTANCEOF_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 11: + return isFollowedBy(_input, ' ', '\t', '\r', '\n') ; + } + return true; + } + private boolean NOT_IN_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 12: + return isFollowedBy(_input, ' ', '\t', '\r', '\n', '[', '(', '{') ; + } + return true; + } + private boolean JavaLetterInGString_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 13: + return Character.isJavaIdentifierStart(_input.LA(-1)); + + case 14: + return Character.isJavaIdentifierStart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1))); + } + return true; + } + private boolean JavaLetterOrDigitInGString_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 15: + return Character.isJavaIdentifierPart(_input.LA(-1)); + + case 16: + return Character.isJavaIdentifierPart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1))); + } + return true; + } + private boolean JavaLetter_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 17: + return Character.isJavaIdentifierStart(_input.LA(-1)); + + case 18: + return Character.isJavaIdentifierStart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1))); + } + return true; + } + private boolean JavaLetterOrDigit_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 19: + return Character.isJavaIdentifierPart(_input.LA(-1)); + + case 20: + return Character.isJavaIdentifierPart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1))); + } + return true; + } + + public static final String _serializedATN = + "\3\uc91d\ucaba\u058d\uafba\u4f53\u0607\uea8b\uc241\2\u0083\u0698\b\1\b"+ + "\1\b\1\b\1\b\1\b\1\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7"+ + "\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17"+ + "\4\20\t\20\4\21\t\21\4\22\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26"+ + "\4\27\t\27\4\30\t\30\4\31\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35"+ + "\4\36\t\36\4\37\t\37\4 \t \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t"+ + "\'\4(\t(\4)\t)\4*\t*\4+\t+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61"+ + "\4\62\t\62\4\63\t\63\4\64\t\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49"+ + "\t9\4:\t:\4;\t;\4<\t<\4=\t=\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD"+ + "\4E\tE\4F\tF\4G\tG\4H\tH\4I\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P"+ + "\tP\4Q\tQ\4R\tR\4S\tS\4T\tT\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t["+ + "\4\\\t\\\4]\t]\4^\t^\4_\t_\4`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4"+ + "g\tg\4h\th\4i\ti\4j\tj\4k\tk\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\t"+ + "r\4s\ts\4t\tt\4u\tu\4v\tv\4w\tw\4x\tx\4y\ty\4z\tz\4{\t{\4|\t|\4}\t}\4"+ + "~\t~\4\177\t\177\4\u0080\t\u0080\4\u0081\t\u0081\4\u0082\t\u0082\4\u0083"+ + "\t\u0083\4\u0084\t\u0084\4\u0085\t\u0085\4\u0086\t\u0086\4\u0087\t\u0087"+ + "\4\u0088\t\u0088\4\u0089\t\u0089\4\u008a\t\u008a\4\u008b\t\u008b\4\u008c"+ + "\t\u008c\4\u008d\t\u008d\4\u008e\t\u008e\4\u008f\t\u008f\4\u0090\t\u0090"+ + "\4\u0091\t\u0091\4\u0092\t\u0092\4\u0093\t\u0093\4\u0094\t\u0094\4\u0095"+ + "\t\u0095\4\u0096\t\u0096\4\u0097\t\u0097\4\u0098\t\u0098\4\u0099\t\u0099"+ + "\4\u009a\t\u009a\4\u009b\t\u009b\4\u009c\t\u009c\4\u009d\t\u009d\4\u009e"+ + "\t\u009e\4\u009f\t\u009f\4\u00a0\t\u00a0\4\u00a1\t\u00a1\4\u00a2\t\u00a2"+ + "\4\u00a3\t\u00a3\4\u00a4\t\u00a4\4\u00a5\t\u00a5\4\u00a6\t\u00a6\4\u00a7"+ + "\t\u00a7\4\u00a8\t\u00a8\4\u00a9\t\u00a9\4\u00aa\t\u00aa\4\u00ab\t\u00ab"+ + "\4\u00ac\t\u00ac\4\u00ad\t\u00ad\4\u00ae\t\u00ae\4\u00af\t\u00af\4\u00b0"+ + "\t\u00b0\4\u00b1\t\u00b1\4\u00b2\t\u00b2\4\u00b3\t\u00b3\4\u00b4\t\u00b4"+ + "\4\u00b5\t\u00b5\4\u00b6\t\u00b6\4\u00b7\t\u00b7\4\u00b8\t\u00b8\4\u00b9"+ + "\t\u00b9\4\u00ba\t\u00ba\4\u00bb\t\u00bb\4\u00bc\t\u00bc\4\u00bd\t\u00bd"+ + "\4\u00be\t\u00be\4\u00bf\t\u00bf\4\u00c0\t\u00c0\4\u00c1\t\u00c1\4\u00c2"+ + "\t\u00c2\4\u00c3\t\u00c3\4\u00c4\t\u00c4\4\u00c5\t\u00c5\4\u00c6\t\u00c6"+ + "\4\u00c7\t\u00c7\4\u00c8\t\u00c8\4\u00c9\t\u00c9\4\u00ca\t\u00ca\4\u00cb"+ + "\t\u00cb\4\u00cc\t\u00cc\4\u00cd\t\u00cd\4\u00ce\t\u00ce\4\u00cf\t\u00cf"+ + "\4\u00d0\t\u00d0\4\u00d1\t\u00d1\4\u00d2\t\u00d2\4\u00d3\t\u00d3\4\u00d4"+ + "\t\u00d4\4\u00d5\t\u00d5\4\u00d6\t\u00d6\4\u00d7\t\u00d7\4\u00d8\t\u00d8"+ + "\4\u00d9\t\u00d9\4\u00da\t\u00da\4\u00db\t\u00db\4\u00dc\t\u00dc\3\2\3"+ + "\2\7\2\u01c2\n\2\f\2\16\2\u01c5\13\2\3\2\3\2\3\2\3\2\7\2\u01cb\n\2\f\2"+ + "\16\2\u01ce\13\2\3\2\3\2\3\2\3\2\3\2\6\2\u01d5\n\2\r\2\16\2\u01d6\3\2"+ + "\3\2\3\2\3\2\7\2\u01dd\n\2\f\2\16\2\u01e0\13\2\3\2\3\2\3\2\3\2\7\2\u01e6"+ + "\n\2\f\2\16\2\u01e9\13\2\3\2\3\2\3\2\3\2\6\2\u01ef\n\2\r\2\16\2\u01f0"+ + "\3\2\3\2\5\2\u01f5\n\2\3\3\3\3\7\3\u01f9\n\3\f\3\16\3\u01fc\13\3\3\3\3"+ + "\3\3\3\3\3\3\3\3\4\3\4\7\4\u0205\n\4\f\4\16\4\u0208\13\4\3\4\3\4\3\4\3"+ + "\4\3\4\3\4\3\5\3\5\3\5\7\5\u0213\n\5\f\5\16\5\u0216\13\5\3\5\3\5\3\5\3"+ + "\5\3\5\3\5\3\5\3\6\3\6\7\6\u0221\n\6\f\6\16\6\u0224\13\6\3\6\3\6\3\6\3"+ + "\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\n\3\n"+ + "\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\r\5\r\u0248\n"+ + "\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3"+ + "\17\3\20\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3"+ + "\22\3\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3"+ + "\24\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26\3\27\3\27\5\27\u027f\n\27"+ + "\3\30\3\30\5\30\u0283\n\30\3\31\3\31\3\31\3\31\3\31\5\31\u028a\n\31\3"+ + "\32\3\32\3\32\3\32\3\32\5\32\u0291\n\32\3\33\3\33\3\33\3\33\3\33\5\33"+ + "\u0298\n\33\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\5\34\u02a4"+ + "\n\34\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\37\3\37\3\37\3 \3 \3 \3 \3"+ + " \3 \3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3\"\3\"\3\"\3\"\3#\3#\3#\3#\3#\3"+ + "#\3#\3#\5#\u02cd\n#\3$\3$\3$\3$\3$\3$\3$\3$\3$\3%\3%\3%\3%\3%\3%\3%\3"+ + "&\3&\3&\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3\'\3\'\3(\3(\3(\3(\3(\3)\3)\3"+ + ")\3)\3)\3*\3*\3*\3*\3*\3*\3+\3+\3+\3+\3+\3,\3,\3,\3,\3,\3,\3-\3-\3-\3"+ + "-\3-\3-\3.\3.\3.\3.\3.\3.\3.\3.\3.\3/\3/\3/\3/\3/\3/\3/\3/\3\60\3\60\3"+ + "\60\3\61\3\61\3\61\3\61\3\61\3\61\3\61\3\62\3\62\3\62\3\62\3\62\3\63\3"+ + "\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64\3\64\3\64\3\64\3\64\3\65\3\65\3"+ + "\65\3\65\3\65\3\65\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\67\3\67\3"+ + "\67\3\67\3\67\3\67\38\38\38\38\39\39\39\3:\3:\3:\3:\3:\3;\3;\3;\3;\3;"+ + "\3;\3;\3;\3;\3;\3;\3<\3<\3<\3<\3<\3<\3<\3=\3=\3=\3=\3=\3=\3=\3=\3=\3="+ + "\3=\3>\3>\3>\3>\3?\3?\3?\3?\3?\3?\3?\3?\3?\3?\3@\3@\3@\3@\3@\3A\3A\3A"+ + "\3A\3A\3A\3A\3B\3B\3B\3B\3C\3C\3C\3C\3C\3C\3C\3C\3D\3D\3D\3D\3D\3D\3D"+ + "\3D\3E\3E\3E\3E\3E\3E\3E\3E\3E\3E\3F\3F\3F\3F\3F\3F\3F\3G\3G\3G\3G\3G"+ + "\3G\3G\3H\3H\3H\3H\3H\3H\3I\3I\3I\3I\3I\3I\3I\3J\3J\3J\3J\3J\3J\3J\3J"+ + "\3J\3K\3K\3K\3K\3K\3K\3L\3L\3L\3L\3L\3L\3L\3M\3M\3M\3M\3M\3M\3M\3M\3M"+ + "\3M\3M\3M\3M\3N\3N\3N\3N\3N\3O\3O\3O\3O\3O\3O\3P\3P\3P\3P\3P\3P\3P\3Q"+ + "\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3S\3S\3S\3S\3S\3T\3T\3T\3T\3T"+ + "\3T\3T\3T\3T\3U\3U\3U\3U\3U\3U\3V\3V\3V\3V\5V\u0426\nV\3V\3V\3V\5V\u042b"+ + "\nV\3V\3V\3V\6V\u0430\nV\rV\16V\u0431\3V\3V\5V\u0436\nV\5V\u0438\nV\3"+ + "W\3W\3X\3X\5X\u043e\nX\3Y\3Y\5Y\u0442\nY\3Z\3Z\5Z\u0446\nZ\3[\3[\5[\u044a"+ + "\n[\3\\\3\\\3]\3]\3]\5]\u0451\n]\3]\3]\3]\5]\u0456\n]\5]\u0458\n]\3^\3"+ + "^\7^\u045c\n^\f^\16^\u045f\13^\3^\5^\u0462\n^\3_\3_\5_\u0466\n_\3`\3`"+ + "\3a\3a\5a\u046c\na\3b\6b\u046f\nb\rb\16b\u0470\3c\3c\3d\3d\3d\3d\3e\3"+ + "e\7e\u047b\ne\fe\16e\u047e\13e\3e\5e\u0481\ne\3f\3f\3g\3g\5g\u0487\ng"+ + "\3h\3h\5h\u048b\nh\3h\3h\3i\3i\7i\u0491\ni\fi\16i\u0494\13i\3i\5i\u0497"+ + "\ni\3j\3j\3k\3k\5k\u049d\nk\3l\3l\3l\3l\3m\3m\7m\u04a5\nm\fm\16m\u04a8"+ + "\13m\3m\5m\u04ab\nm\3n\3n\3o\3o\5o\u04b1\no\3p\3p\5p\u04b5\np\3p\3p\3"+ + "p\5p\u04ba\np\3q\3q\3q\3q\5q\u04c0\nq\3q\5q\u04c3\nq\3q\3q\3q\5q\u04c8"+ + "\nq\3q\3q\3q\5q\u04cd\nq\3r\3r\3r\3s\3s\3t\5t\u04d5\nt\3t\3t\3u\3u\3v"+ + "\3v\3w\3w\3w\5w\u04e0\nw\3x\3x\5x\u04e4\nx\3x\3x\3x\5x\u04e9\nx\3x\3x"+ + "\3x\5x\u04ee\nx\3y\3y\3y\3z\3z\3{\3{\3|\3|\3|\3|\3|\3|\3|\3|\3|\5|\u0500"+ + "\n|\3}\3}\3}\3}\3}\3}\3}\5}\u0509\n}\3~\3~\3~\3~\3~\3~\3~\3~\3~\3~\3~"+ + "\3~\5~\u0517\n~\3\177\3\177\3\177\3\177\3\177\3\177\3\177\3\u0080\3\u0080"+ + "\3\u0081\3\u0081\3\u0081\3\u0082\3\u0082\5\u0082\u0527\n\u0082\3\u0082"+ + "\3\u0082\3\u0083\3\u0083\3\u0083\3\u0084\3\u0084\3\u0085\3\u0085\3\u0086"+ + "\3\u0086\3\u0087\3\u0087\3\u0088\3\u0088\3\u0089\3\u0089\3\u0089\3\u0089"+ + "\3\u008a\3\u008a\3\u008a\3\u008a\3\u008b\3\u008b\3\u008b\3\u008c\3\u008c"+ + "\3\u008c\3\u008d\3\u008d\3\u008d\3\u008d\3\u008e\3\u008e\3\u008e\3\u008f"+ + "\3\u008f\3\u008f\3\u008f\3\u008f\3\u0090\3\u0090\3\u0090\3\u0091\3\u0091"+ + "\3\u0091\3\u0091\3\u0092\3\u0092\3\u0092\3\u0093\3\u0093\3\u0093\3\u0094"+ + "\3\u0094\3\u0094\3\u0094\3\u0095\3\u0095\3\u0095\3\u0096\3\u0096\3\u0096"+ + "\3\u0097\3\u0097\3\u0097\3\u0098\3\u0098\3\u0098\3\u0099\3\u0099\3\u0099"+ + "\3\u0099\3\u009a\3\u009a\3\u009a\3\u009b\3\u009b\3\u009b\3\u009b\3\u009c"+ + "\3\u009c\3\u009c\3\u009c\3\u009d\3\u009d\3\u009d\3\u009d\3\u009e\3\u009e"+ + "\3\u009e\3\u009e\3\u009f\3\u009f\3\u009f\3\u00a0\3\u00a0\3\u00a0\3\u00a0"+ + "\3\u00a0\3\u00a0\3\u00a0\3\u00a0\3\u00a0\3\u00a0\3\u00a0\3\u00a0\3\u00a0"+ + "\3\u00a0\3\u00a1\3\u00a1\3\u00a1\3\u00a1\3\u00a1\3\u00a1\3\u00a2\3\u00a2"+ + "\3\u00a2\3\u00a2\3\u00a2\3\u00a3\3\u00a3\3\u00a3\3\u00a3\3\u00a3\3\u00a4"+ + "\3\u00a4\3\u00a4\3\u00a4\3\u00a4\3\u00a5\3\u00a5\3\u00a5\3\u00a5\3\u00a5"+ + "\3\u00a6\3\u00a6\3\u00a6\3\u00a6\3\u00a6\3\u00a7\3\u00a7\3\u00a7\3\u00a7"+ + "\3\u00a7\3\u00a8\3\u00a8\3\u00a9\3\u00a9\3\u00aa\3\u00aa\3\u00ab\3\u00ab"+ + "\3\u00ac\3\u00ac\3\u00ad\3\u00ad\3\u00ae\3\u00ae\3\u00af\3\u00af\3\u00b0"+ + "\3\u00b0\3\u00b1\3\u00b1\3\u00b2\3\u00b2\3\u00b2\3\u00b3\3\u00b3\3\u00b3"+ + "\3\u00b4\3\u00b4\3\u00b4\3\u00b5\3\u00b5\3\u00b5\3\u00b6\3\u00b6\3\u00b6"+ + "\3\u00b7\3\u00b7\3\u00b7\3\u00b8\3\u00b8\3\u00b8\3\u00b9\3\u00b9\3\u00b9"+ + "\3\u00ba\3\u00ba\3\u00bb\3\u00bb\3\u00bc\3\u00bc\3\u00bd\3\u00bd\3\u00be"+ + "\3\u00be\3\u00bf\3\u00bf\3\u00c0\3\u00c0\3\u00c1\3\u00c1\3\u00c2\3\u00c2"+ + "\3\u00c2\3\u00c3\3\u00c3\3\u00c3\3\u00c4\3\u00c4\3\u00c4\3\u00c5\3\u00c5"+ + "\3\u00c5\3\u00c6\3\u00c6\3\u00c6\3\u00c7\3\u00c7\3\u00c7\3\u00c8\3\u00c8"+ + "\3\u00c8\3\u00c9\3\u00c9\3\u00c9\3\u00ca\3\u00ca\3\u00ca\3\u00ca\3\u00cb"+ + "\3\u00cb\3\u00cb\3\u00cb\3\u00cc\3\u00cc\3\u00cc\3\u00cc\3\u00cc\3\u00cd"+ + "\3\u00cd\3\u00cd\3\u00ce\3\u00ce\7\u00ce\u0621\n\u00ce\f\u00ce\16\u00ce"+ + "\u0624\13\u00ce\3\u00cf\3\u00cf\7\u00cf\u0628\n\u00cf\f\u00cf\16\u00cf"+ + "\u062b\13\u00cf\3\u00d0\3\u00d0\7\u00d0\u062f\n\u00d0\f\u00d0\16\u00d0"+ + "\u0632\13\u00d0\3\u00d1\3\u00d1\3\u00d1\3\u00d1\3\u00d1\3\u00d1\5\u00d1"+ + "\u063a\n\u00d1\3\u00d2\3\u00d2\3\u00d2\3\u00d2\3\u00d2\3\u00d2\5\u00d2"+ + "\u0642\n\u00d2\3\u00d3\3\u00d3\3\u00d3\3\u00d3\3\u00d3\3\u00d3\5\u00d3"+ + "\u064a\n\u00d3\3\u00d4\3\u00d4\3\u00d4\3\u00d4\3\u00d4\3\u00d4\5\u00d4"+ + "\u0652\n\u00d4\3\u00d5\3\u00d5\3\u00d6\3\u00d6\3\u00d6\3\u00d6\3\u00d7"+ + "\6\u00d7\u065b\n\u00d7\r\u00d7\16\u00d7\u065c\3\u00d7\6\u00d7\u0660\n"+ + "\u00d7\r\u00d7\16\u00d7\u0661\5\u00d7\u0664\n\u00d7\3\u00d7\3\u00d7\3"+ + "\u00d8\5\u00d8\u0669\n\u00d8\3\u00d8\3\u00d8\3\u00d8\3\u00d9\3\u00d9\3"+ + "\u00d9\3\u00d9\7\u00d9\u0672\n\u00d9\f\u00d9\16\u00d9\u0675\13\u00d9\3"+ + "\u00d9\3\u00d9\3\u00d9\3\u00d9\3\u00d9\3\u00d9\3\u00d9\3\u00da\3\u00da"+ + "\3\u00da\3\u00da\7\u00da\u0682\n\u00da\f\u00da\16\u00da\u0685\13\u00da"+ + "\3\u00da\3\u00da\3\u00da\3\u00da\3\u00db\3\u00db\3\u00db\3\u00db\3\u00db"+ + "\7\u00db\u0690\n\u00db\f\u00db\16\u00db\u0693\13\u00db\3\u00db\3\u00db"+ + "\3\u00dc\3\u00dc\3\u0673\2\2\u00dd\t\2\3\13\2\4\r\2\2\17\2\2\21\2\2\23"+ + "\2\5\25\2\6\27\2\2\31\2\2\33\2\2\35\2\2\37\2\2!\2\2#\2\2%\2\2\'\2\2)\2"+ + "\2+\2\2-\2\2/\2\7\61\2\b\63\2\2\65\2\2\67\2\29\2\2;\2\2=\2\2?\2\tA\2\n"+ + "C\2\13E\2\fG\2\rI\2\16K\2\17M\2\20O\2\21Q\2\2S\2\22U\2\2W\2\23Y\2\24["+ + "\2\2]\2\25_\2\26a\2\27c\2\30e\2\31g\2\2i\2\32k\2\33m\2\34o\2\35q\2\36"+ + "s\2\2u\2\37w\2 y\2!{\2\"}\2#\177\2$\u0081\2\2\u0083\2%\u0085\2\2\u0087"+ + "\2&\u0089\2\'\u008b\2(\u008d\2)\u008f\2*\u0091\2+\u0093\2,\u0095\2\2\u0097"+ + "\2-\u0099\2.\u009b\2/\u009d\2\60\u009f\2\61\u00a1\2\62\u00a3\2\63\u00a5"+ + "\2\64\u00a7\2\65\u00a9\2\66\u00ab\2\67\u00ad\28\u00af\29\u00b1\2:\u00b3"+ + "\2\2\u00b5\2\2\u00b7\2\2\u00b9\2\2\u00bb\2\2\u00bd\2\2\u00bf\2\2\u00c1"+ + "\2\2\u00c3\2\2\u00c5\2\2\u00c7\2\2\u00c9\2\2\u00cb\2\2\u00cd\2\2\u00cf"+ + "\2\2\u00d1\2\2\u00d3\2\2\u00d5\2\2\u00d7\2\2\u00d9\2\2\u00db\2\2\u00dd"+ + "\2\2\u00df\2\2\u00e1\2\2\u00e3\2\2\u00e5\2;\u00e7\2\2\u00e9\2\2\u00eb"+ + "\2\2\u00ed\2\2\u00ef\2\2\u00f1\2\2\u00f3\2\2\u00f5\2\2\u00f7\2\2\u00f9"+ + "\2\2\u00fb\2\2\u00fd\2<\u00ff\2\2\u0101\2\2\u0103\2\2\u0105\2\2\u0107"+ + "\2\2\u0109\2\2\u010b\2\2\u010d\2\2\u010f\2\2\u0111\2\2\u0113\2\2\u0115"+ + "\2\2\u0117\2\2\u0119\2\2\u011b\2\2\u011d\2\2\u011f\2\2\u0121\2\2\u0123"+ + "\2=\u0125\2>\u0127\2?\u0129\2@\u012b\2A\u012d\2B\u012f\2C\u0131\2D\u0133"+ + "\2E\u0135\2F\u0137\2G\u0139\2H\u013b\2I\u013d\2J\u013f\2K\u0141\2L\u0143"+ + "\2M\u0145\2N\u0147\2O\u0149\2P\u014b\2Q\u014d\2R\u014f\2S\u0151\2T\u0153"+ + "\2U\u0155\2V\u0157\2W\u0159\2X\u015b\2Y\u015d\2Z\u015f\2[\u0161\2\\\u0163"+ + "\2]\u0165\2^\u0167\2_\u0169\2`\u016b\2a\u016d\2b\u016f\2c\u0171\2d\u0173"+ + "\2e\u0175\2f\u0177\2g\u0179\2h\u017b\2i\u017d\2j\u017f\2k\u0181\2l\u0183"+ + "\2m\u0185\2n\u0187\2o\u0189\2p\u018b\2q\u018d\2r\u018f\2s\u0191\2t\u0193"+ + "\2u\u0195\2v\u0197\2w\u0199\2x\u019b\2y\u019d\2z\u019f\2{\u01a1\2|\u01a3"+ + "\2}\u01a5\2\2\u01a7\2\2\u01a9\2\2\u01ab\2\2\u01ad\2\2\u01af\2~\u01b1\2"+ + "\177\u01b3\2\u0080\u01b5\2\u0081\u01b7\2\2\u01b9\2\2\u01bb\2\u0082\u01bd"+ + "\2\u0083\t\2\3\4\5\6\7\b\37\7\2\f\f\17\17$$&&^^\6\2\f\f\17\17))^^\5\2"+ + "$$&&^^\4\2))^^\5\2\2\2&&\61\61\3\2\62;\b\2IIKKNNiikknn\3\2\63;\4\2ZZz"+ + "z\5\2\62;CHch\3\2\629\4\2DDdd\3\2\62\63\4\2GGgg\4\2--//\6\2FFHIffhi\4"+ + "\2RRrr\n\2$$))^^ddhhppttvv\3\2\62\65\3\2C\\\5\2C\\aac|\4\2\2\u0081\ud802"+ + "\udc01\3\2\ud802\udc01\3\2\udc02\ue001\6\2\62;C\\aac|\6\2&&C\\aac|\7\2"+ + "&&\62;C\\aac|\5\2\13\13\16\16\"\"\5\2\f\f\17\17\1\1\2\u06af\2\t\3\2\2"+ + "\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2?\3\2\2\2\2A\3"+ + "\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2"+ + "\2\2O\3\2\2\2\2S\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2"+ + "a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3"+ + "\2\2\2\2q\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2"+ + "\2\2\177\3\2\2\2\2\u0083\3\2\2\2\2\u0087\3\2\2\2\2\u0089\3\2\2\2\2\u008b"+ + "\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2\2\2\u0091\3\2\2\2\2\u0093\3\2\2"+ + "\2\2\u0097\3\2\2\2\2\u0099\3\2\2\2\2\u009b\3\2\2\2\2\u009d\3\2\2\2\2\u009f"+ + "\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2"+ + "\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad\3\2\2\2\2\u00af\3\2\2\2\2\u00b1"+ + "\3\2\2\2\2\u00e5\3\2\2\2\2\u00fd\3\2\2\2\2\u0123\3\2\2\2\2\u0125\3\2\2"+ + "\2\2\u0127\3\2\2\2\2\u0129\3\2\2\2\2\u012b\3\2\2\2\2\u012d\3\2\2\2\2\u012f"+ + "\3\2\2\2\2\u0131\3\2\2\2\2\u0133\3\2\2\2\2\u0135\3\2\2\2\2\u0137\3\2\2"+ + "\2\2\u0139\3\2\2\2\2\u013b\3\2\2\2\2\u013d\3\2\2\2\2\u013f\3\2\2\2\2\u0141"+ + "\3\2\2\2\2\u0143\3\2\2\2\2\u0145\3\2\2\2\2\u0147\3\2\2\2\2\u0149\3\2\2"+ + "\2\2\u014b\3\2\2\2\2\u014d\3\2\2\2\2\u014f\3\2\2\2\2\u0151\3\2\2\2\2\u0153"+ + "\3\2\2\2\2\u0155\3\2\2\2\2\u0157\3\2\2\2\2\u0159\3\2\2\2\2\u015b\3\2\2"+ + "\2\2\u015d\3\2\2\2\2\u015f\3\2\2\2\2\u0161\3\2\2\2\2\u0163\3\2\2\2\2\u0165"+ + "\3\2\2\2\2\u0167\3\2\2\2\2\u0169\3\2\2\2\2\u016b\3\2\2\2\2\u016d\3\2\2"+ + "\2\2\u016f\3\2\2\2\2\u0171\3\2\2\2\2\u0173\3\2\2\2\2\u0175\3\2\2\2\2\u0177"+ + "\3\2\2\2\2\u0179\3\2\2\2\2\u017b\3\2\2\2\2\u017d\3\2\2\2\2\u017f\3\2\2"+ + "\2\2\u0181\3\2\2\2\2\u0183\3\2\2\2\2\u0185\3\2\2\2\2\u0187\3\2\2\2\2\u0189"+ + "\3\2\2\2\2\u018b\3\2\2\2\2\u018d\3\2\2\2\2\u018f\3\2\2\2\2\u0191\3\2\2"+ + "\2\2\u0193\3\2\2\2\2\u0195\3\2\2\2\2\u0197\3\2\2\2\2\u0199\3\2\2\2\2\u019b"+ + "\3\2\2\2\2\u019d\3\2\2\2\2\u019f\3\2\2\2\2\u01a1\3\2\2\2\2\u01a3\3\2\2"+ + "\2\2\u01af\3\2\2\2\2\u01b1\3\2\2\2\2\u01b3\3\2\2\2\2\u01b5\3\2\2\2\2\u01b7"+ + "\3\2\2\2\2\u01b9\3\2\2\2\2\u01bb\3\2\2\2\2\u01bd\3\2\2\2\3\23\3\2\2\2"+ + "\3\25\3\2\2\2\3\27\3\2\2\2\4\31\3\2\2\2\4\33\3\2\2\2\4\35\3\2\2\2\5\37"+ + "\3\2\2\2\5!\3\2\2\2\5#\3\2\2\2\6%\3\2\2\2\6\'\3\2\2\2\6)\3\2\2\2\7+\3"+ + "\2\2\2\7-\3\2\2\2\b/\3\2\2\2\b\61\3\2\2\2\t\u01f4\3\2\2\2\13\u01f6\3\2"+ + "\2\2\r\u0202\3\2\2\2\17\u020f\3\2\2\2\21\u021e\3\2\2\2\23\u022c\3\2\2"+ + "\2\25\u0230\3\2\2\2\27\u0234\3\2\2\2\31\u0238\3\2\2\2\33\u023d\3\2\2\2"+ + "\35\u0242\3\2\2\2\37\u0247\3\2\2\2!\u024e\3\2\2\2#\u0254\3\2\2\2%\u0258"+ + "\3\2\2\2\'\u025d\3\2\2\2)\u0263\3\2\2\2+\u0267\3\2\2\2-\u026e\3\2\2\2"+ + "/\u0274\3\2\2\2\61\u0277\3\2\2\2\63\u027e\3\2\2\2\65\u0282\3\2\2\2\67"+ + "\u0289\3\2\2\29\u0290\3\2\2\2;\u0297\3\2\2\2=\u02a3\3\2\2\2?\u02a5\3\2"+ + "\2\2A\u02a8\3\2\2\2C\u02ac\3\2\2\2E\u02af\3\2\2\2G\u02b5\3\2\2\2I\u02c0"+ + "\3\2\2\2K\u02cc\3\2\2\2M\u02ce\3\2\2\2O\u02d7\3\2\2\2Q\u02de\3\2\2\2S"+ + "\u02e6\3\2\2\2U\u02ec\3\2\2\2W\u02f1\3\2\2\2Y\u02f6\3\2\2\2[\u02fc\3\2"+ + "\2\2]\u0301\3\2\2\2_\u0307\3\2\2\2a\u030d\3\2\2\2c\u0316\3\2\2\2e\u031e"+ + "\3\2\2\2g\u0321\3\2\2\2i\u0328\3\2\2\2k\u032d\3\2\2\2m\u0332\3\2\2\2o"+ + "\u033a\3\2\2\2q\u0340\3\2\2\2s\u0348\3\2\2\2u\u034e\3\2\2\2w\u0352\3\2"+ + "\2\2y\u0355\3\2\2\2{\u035a\3\2\2\2}\u0365\3\2\2\2\177\u036c\3\2\2\2\u0081"+ + "\u0377\3\2\2\2\u0083\u037b\3\2\2\2\u0085\u0385\3\2\2\2\u0087\u038a\3\2"+ + "\2\2\u0089\u0391\3\2\2\2\u008b\u0395\3\2\2\2\u008d\u039d\3\2\2\2\u008f"+ + "\u03a5\3\2\2\2\u0091\u03af\3\2\2\2\u0093\u03b6\3\2\2\2\u0095\u03bd\3\2"+ + "\2\2\u0097\u03c3\3\2\2\2\u0099\u03ca\3\2\2\2\u009b\u03d3\3\2\2\2\u009d"+ + "\u03d9\3\2\2\2\u009f\u03e0\3\2\2\2\u00a1\u03ed\3\2\2\2\u00a3\u03f2\3\2"+ + "\2\2\u00a5\u03f8\3\2\2\2\u00a7\u03ff\3\2\2\2\u00a9\u0409\3\2\2\2\u00ab"+ + "\u040d\3\2\2\2\u00ad\u0412\3\2\2\2\u00af\u041b\3\2\2\2\u00b1\u0437\3\2"+ + "\2\2\u00b3\u0439\3\2\2\2\u00b5\u043b\3\2\2\2\u00b7\u043f\3\2\2\2\u00b9"+ + "\u0443\3\2\2\2\u00bb\u0447\3\2\2\2\u00bd\u044b\3\2\2\2\u00bf\u0457\3\2"+ + "\2\2\u00c1\u0459\3\2\2\2\u00c3\u0465\3\2\2\2\u00c5\u0467\3\2\2\2\u00c7"+ + "\u046b\3\2\2\2\u00c9\u046e\3\2\2\2\u00cb\u0472\3\2\2\2\u00cd\u0474\3\2"+ + "\2\2\u00cf\u0478\3\2\2\2\u00d1\u0482\3\2\2\2\u00d3\u0486\3\2\2\2\u00d5"+ + "\u0488\3\2\2\2\u00d7\u048e\3\2\2\2\u00d9\u0498\3\2\2\2\u00db\u049c\3\2"+ + "\2\2\u00dd\u049e\3\2\2\2\u00df\u04a2\3\2\2\2\u00e1\u04ac\3\2\2\2\u00e3"+ + "\u04b0\3\2\2\2\u00e5\u04b4\3\2\2\2\u00e7\u04cc\3\2\2\2\u00e9\u04ce\3\2"+ + "\2\2\u00eb\u04d1\3\2\2\2\u00ed\u04d4\3\2\2\2\u00ef\u04d8\3\2\2\2\u00f1"+ + "\u04da\3\2\2\2\u00f3\u04dc\3\2\2\2\u00f5\u04ed\3\2\2\2\u00f7\u04ef\3\2"+ + "\2\2\u00f9\u04f2\3\2\2\2\u00fb\u04f4\3\2\2\2\u00fd\u04ff\3\2\2\2\u00ff"+ + "\u0508\3\2\2\2\u0101\u0516\3\2\2\2\u0103\u0518\3\2\2\2\u0105\u051f\3\2"+ + "\2\2\u0107\u0521\3\2\2\2\u0109\u0524\3\2\2\2\u010b\u052a\3\2\2\2\u010d"+ + "\u052d\3\2\2\2\u010f\u052f\3\2\2\2\u0111\u0531\3\2\2\2\u0113\u0533\3\2"+ + "\2\2\u0115\u0535\3\2\2\2\u0117\u0537\3\2\2\2\u0119\u053b\3\2\2\2\u011b"+ + "\u053f\3\2\2\2\u011d\u0542\3\2\2\2\u011f\u0545\3\2\2\2\u0121\u0549\3\2"+ + "\2\2\u0123\u054c\3\2\2\2\u0125\u0551\3\2\2\2\u0127\u0554\3\2\2\2\u0129"+ + "\u0558\3\2\2\2\u012b\u055b\3\2\2\2\u012d\u055e\3\2\2\2\u012f\u0562\3\2"+ + "\2\2\u0131\u0565\3\2\2\2\u0133\u0568\3\2\2\2\u0135\u056b\3\2\2\2\u0137"+ + "\u056e\3\2\2\2\u0139\u0572\3\2\2\2\u013b\u0575\3\2\2\2\u013d\u0579\3\2"+ + "\2\2\u013f\u057d\3\2\2\2\u0141\u0581\3\2\2\2\u0143\u0585\3\2\2\2\u0145"+ + "\u0588\3\2\2\2\u0147\u0596\3\2\2\2\u0149\u059c\3\2\2\2\u014b\u05a1\3\2"+ + "\2\2\u014d\u05a6\3\2\2\2\u014f\u05ab\3\2\2\2\u0151\u05b0\3\2\2\2\u0153"+ + "\u05b5\3\2\2\2\u0155\u05ba\3\2\2\2\u0157\u05bc\3\2\2\2\u0159\u05be\3\2"+ + "\2\2\u015b\u05c0\3\2\2\2\u015d\u05c2\3\2\2\2\u015f\u05c4\3\2\2\2\u0161"+ + "\u05c6\3\2\2\2\u0163\u05c8\3\2\2\2\u0165\u05ca\3\2\2\2\u0167\u05cc\3\2"+ + "\2\2\u0169\u05ce\3\2\2\2\u016b\u05d1\3\2\2\2\u016d\u05d4\3\2\2\2\u016f"+ + "\u05d7\3\2\2\2\u0171\u05da\3\2\2\2\u0173\u05dd\3\2\2\2\u0175\u05e0\3\2"+ + "\2\2\u0177\u05e3\3\2\2\2\u0179\u05e6\3\2\2\2\u017b\u05e8\3\2\2\2\u017d"+ + "\u05ea\3\2\2\2\u017f\u05ec\3\2\2\2\u0181\u05ee\3\2\2\2\u0183\u05f0\3\2"+ + "\2\2\u0185\u05f2\3\2\2\2\u0187\u05f4\3\2\2\2\u0189\u05f6\3\2\2\2\u018b"+ + "\u05f9\3\2\2\2\u018d\u05fc\3\2\2\2\u018f\u05ff\3\2\2\2\u0191\u0602\3\2"+ + "\2\2\u0193\u0605\3\2\2\2\u0195\u0608\3\2\2\2\u0197\u060b\3\2\2\2\u0199"+ + "\u060e\3\2\2\2\u019b\u0612\3\2\2\2\u019d\u0616\3\2\2\2\u019f\u061b\3\2"+ + "\2\2\u01a1\u061e\3\2\2\2\u01a3\u0625\3\2\2\2\u01a5\u062c\3\2\2\2\u01a7"+ + "\u0639\3\2\2\2\u01a9\u0641\3\2\2\2\u01ab\u0649\3\2\2\2\u01ad\u0651\3\2"+ + "\2\2\u01af\u0653\3\2\2\2\u01b1\u0655\3\2\2\2\u01b3\u0663\3\2\2\2\u01b5"+ + "\u0668\3\2\2\2\u01b7\u066d\3\2\2\2\u01b9\u067d\3\2\2\2\u01bb\u068a\3\2"+ + "\2\2\u01bd\u0696\3\2\2\2\u01bf\u01c3\5\u0113\u0087\2\u01c0\u01c2\5\63"+ + "\27\2\u01c1\u01c0\3\2\2\2\u01c2\u01c5\3\2\2\2\u01c3\u01c1\3\2\2\2\u01c3"+ + "\u01c4\3\2\2\2\u01c4\u01c6\3\2\2\2\u01c5\u01c3\3\2\2\2\u01c6\u01c7\5\u0113"+ + "\u0087\2\u01c7\u01f5\3\2\2\2\u01c8\u01cc\5\u0115\u0088\2\u01c9\u01cb\5"+ + "\65\30\2\u01ca\u01c9\3\2\2\2\u01cb\u01ce\3\2\2\2\u01cc\u01ca\3\2\2\2\u01cc"+ + "\u01cd\3\2\2\2\u01cd\u01cf\3\2\2\2\u01ce\u01cc\3\2\2\2\u01cf\u01d0\5\u0115"+ + "\u0088\2\u01d0\u01f5\3\2\2\2\u01d1\u01d2\5\u010f\u0085\2\u01d2\u01d4\6"+ + "\2\2\2\u01d3\u01d5\5;\33\2\u01d4\u01d3\3\2\2\2\u01d5\u01d6\3\2\2\2\u01d6"+ + "\u01d4\3\2\2\2\u01d6\u01d7\3\2\2\2\u01d7\u01d8\3\2\2\2\u01d8\u01d9\5\u010f"+ + "\u0085\2\u01d9\u01f5\3\2\2\2\u01da\u01de\5\u0117\u0089\2\u01db\u01dd\5"+ + "\67\31\2\u01dc\u01db\3\2\2\2\u01dd\u01e0\3\2\2\2\u01de\u01dc\3\2\2\2\u01de"+ + "\u01df\3\2\2\2\u01df\u01e1\3\2\2\2\u01e0\u01de\3\2\2\2\u01e1\u01e2\5\u0117"+ + "\u0089\2\u01e2\u01f5\3\2\2\2\u01e3\u01e7\5\u0119\u008a\2\u01e4\u01e6\5"+ + "9\32\2\u01e5\u01e4\3\2\2\2\u01e6\u01e9\3\2\2\2\u01e7\u01e5\3\2\2\2\u01e7"+ + "\u01e8\3\2\2\2\u01e8\u01ea\3\2\2\2\u01e9\u01e7\3\2\2\2\u01ea\u01eb\5\u0119"+ + "\u008a\2\u01eb\u01f5\3\2\2\2\u01ec\u01ee\5\u011b\u008b\2\u01ed\u01ef\5"+ + "=\34\2\u01ee\u01ed\3\2\2\2\u01ef\u01f0\3\2\2\2\u01f0\u01ee\3\2\2\2\u01f0"+ + "\u01f1\3\2\2\2\u01f1\u01f2\3\2\2\2\u01f2\u01f3\5\u011d\u008c\2\u01f3\u01f5"+ + "\3\2\2\2\u01f4\u01bf\3\2\2\2\u01f4\u01c8\3\2\2\2\u01f4\u01d1\3\2\2\2\u01f4"+ + "\u01da\3\2\2\2\u01f4\u01e3\3\2\2\2\u01f4\u01ec\3\2\2\2\u01f5\n\3\2\2\2"+ + "\u01f6\u01fa\5\u0113\u0087\2\u01f7\u01f9\5\63\27\2\u01f8\u01f7\3\2\2\2"+ + "\u01f9\u01fc\3\2\2\2\u01fa\u01f8\3\2\2\2\u01fa\u01fb\3\2\2\2\u01fb\u01fd"+ + "\3\2\2\2\u01fc\u01fa\3\2\2\2\u01fd\u01fe\5\u0111\u0086\2\u01fe\u01ff\3"+ + "\2\2\2\u01ff\u0200\b\3\2\2\u0200\u0201\b\3\3\2\u0201\f\3\2\2\2\u0202\u0206"+ + "\5\u0117\u0089\2\u0203\u0205\5\67\31\2\u0204\u0203\3\2\2\2\u0205\u0208"+ + "\3\2\2\2\u0206\u0204\3\2\2\2\u0206\u0207\3\2\2\2\u0207\u0209\3\2\2\2\u0208"+ + "\u0206\3\2\2\2\u0209\u020a\5\u0111\u0086\2\u020a\u020b\3\2\2\2\u020b\u020c"+ + "\b\4\4\2\u020c\u020d\b\4\5\2\u020d\u020e\b\4\3\2\u020e\16\3\2\2\2\u020f"+ + "\u0210\5\u010f\u0085\2\u0210\u0214\6\5\3\2\u0211\u0213\5;\33\2\u0212\u0211"+ + "\3\2\2\2\u0213\u0216\3\2\2\2\u0214\u0212\3\2\2\2\u0214\u0215\3\2\2\2\u0215"+ + "\u0217\3\2\2\2\u0216\u0214\3\2\2\2\u0217\u0218\5\u0111\u0086\2\u0218\u0219"+ + "\6\5\4\2\u0219\u021a\3\2\2\2\u021a\u021b\b\5\4\2\u021b\u021c\b\5\6\2\u021c"+ + "\u021d\b\5\3\2\u021d\20\3\2\2\2\u021e\u0222\5\u011b\u008b\2\u021f\u0221"+ + "\5=\34\2\u0220\u021f\3\2\2\2\u0221\u0224\3\2\2\2\u0222\u0220\3\2\2\2\u0222"+ + "\u0223\3\2\2\2\u0223\u0225\3\2\2\2\u0224\u0222\3\2\2\2\u0225\u0226\5\u0111"+ + "\u0086\2\u0226\u0227\6\6\5\2\u0227\u0228\3\2\2\2\u0228\u0229\b\6\4\2\u0229"+ + "\u022a\b\6\7\2\u022a\u022b\b\6\3\2\u022b\22\3\2\2\2\u022c\u022d\5\u0113"+ + "\u0087\2\u022d\u022e\3\2\2\2\u022e\u022f\b\7\b\2\u022f\24\3\2\2\2\u0230"+ + "\u0231\5\u0111\u0086\2\u0231\u0232\3\2\2\2\u0232\u0233\b\b\3\2\u0233\26"+ + "\3\2\2\2\u0234\u0235\5\63\27\2\u0235\u0236\3\2\2\2\u0236\u0237\b\t\t\2"+ + "\u0237\30\3\2\2\2\u0238\u0239\5\u0117\u0089\2\u0239\u023a\3\2\2\2\u023a"+ + "\u023b\b\n\n\2\u023b\u023c\b\n\b\2\u023c\32\3\2\2\2\u023d\u023e\5\u0111"+ + "\u0086\2\u023e\u023f\3\2\2\2\u023f\u0240\b\13\13\2\u0240\u0241\b\13\3"+ + "\2\u0241\34\3\2\2\2\u0242\u0243\5\67\31\2\u0243\u0244\3\2\2\2\u0244\u0245"+ + "\b\f\t\2\u0245\36\3\2\2\2\u0246\u0248\5\u0111\u0086\2\u0247\u0246\3\2"+ + "\2\2\u0247\u0248\3\2\2\2\u0248\u0249\3\2\2\2\u0249\u024a\5\u010f\u0085"+ + "\2\u024a\u024b\3\2\2\2\u024b\u024c\b\r\n\2\u024c\u024d\b\r\b\2\u024d "+ + "\3\2\2\2\u024e\u024f\5\u0111\u0086\2\u024f\u0250\6\16\6\2\u0250\u0251"+ + "\3\2\2\2\u0251\u0252\b\16\13\2\u0252\u0253\b\16\3\2\u0253\"\3\2\2\2\u0254"+ + "\u0255\5;\33\2\u0255\u0256\3\2\2\2\u0256\u0257\b\17\t\2\u0257$\3\2\2\2"+ + "\u0258\u0259\5\u011d\u008c\2\u0259\u025a\3\2\2\2\u025a\u025b\b\20\n\2"+ + "\u025b\u025c\b\20\b\2\u025c&\3\2\2\2\u025d\u025e\5\u0111\u0086\2\u025e"+ + "\u025f\6\21\7\2\u025f\u0260\3\2\2\2\u0260\u0261\b\21\13\2\u0261\u0262"+ + "\b\21\3\2\u0262(\3\2\2\2\u0263\u0264\5=\34\2\u0264\u0265\3\2\2\2\u0265"+ + "\u0266\b\22\t\2\u0266*\3\2\2\2\u0267\u0268\7}\2\2\u0268\u0269\b\23\f\2"+ + "\u0269\u026a\3\2\2\2\u026a\u026b\b\23\r\2\u026b\u026c\b\23\b\2\u026c\u026d"+ + "\b\23\16\2\u026d,\3\2\2\2\u026e\u026f\5\u01a5\u00d0\2\u026f\u0270\3\2"+ + "\2\2\u0270\u0271\b\24\17\2\u0271\u0272\b\24\b\2\u0272\u0273\b\24\20\2"+ + "\u0273.\3\2\2\2\u0274\u0275\5\u00fb{\2\u0275\u0276\5\u01a5\u00d0\2\u0276"+ + "\60\3\2\2\2\u0277\u0278\13\2\2\2\u0278\u0279\b\26\21\2\u0279\u027a\3\2"+ + "\2\2\u027a\u027b\b\26\b\2\u027b\62\3\2\2\2\u027c\u027f\n\2\2\2\u027d\u027f"+ + "\5\u00ff}\2\u027e\u027c\3\2\2\2\u027e\u027d\3\2\2\2\u027f\64\3\2\2\2\u0280"+ + "\u0283\n\3\2\2\u0281\u0283\5\u00ff}\2\u0282\u0280\3\2\2\2\u0282\u0281"+ + "\3\2\2\2\u0283\66\3\2\2\2\u0284\u028a\n\4\2\2\u0285\u0286\5\u0113\u0087"+ + "\2\u0286\u0287\6\31\b\2\u0287\u028a\3\2\2\2\u0288\u028a\5\u00ff}\2\u0289"+ + "\u0284\3\2\2\2\u0289\u0285\3\2\2\2\u0289\u0288\3\2\2\2\u028a8\3\2\2\2"+ + "\u028b\u0291\n\5\2\2\u028c\u028d\5\u0115\u0088\2\u028d\u028e\6\32\t\2"+ + "\u028e\u0291\3\2\2\2\u028f\u0291\5\u00ff}\2\u0290\u028b\3\2\2\2\u0290"+ + "\u028c\3\2\2\2\u0290\u028f\3\2\2\2\u0291:\3\2\2\2\u0292\u0298\5\u010b"+ + "\u0083\2\u0293\u0294\5\u0111\u0086\2\u0294\u0295\6\33\n\2\u0295\u0298"+ + "\3\2\2\2\u0296\u0298\n\6\2\2\u0297\u0292\3\2\2\2\u0297\u0293\3\2\2\2\u0297"+ + "\u0296\3\2\2\2\u0298<\3\2\2\2\u0299\u02a4\5\u010b\u0083\2\u029a\u02a4"+ + "\5\u011f\u008d\2\u029b\u02a4\5\u0121\u008e\2\u029c\u029d\5\u010f\u0085"+ + "\2\u029d\u029e\6\34\13\2\u029e\u02a4\3\2\2\2\u029f\u02a0\5\u0111\u0086"+ + "\2\u02a0\u02a1\6\34\f\2\u02a1\u02a4\3\2\2\2\u02a2\u02a4\n\6\2\2\u02a3"+ + "\u0299\3\2\2\2\u02a3\u029a\3\2\2\2\u02a3\u029b\3\2\2\2\u02a3\u029c\3\2"+ + "\2\2\u02a3\u029f\3\2\2\2\u02a3\u02a2\3\2\2\2\u02a4>\3\2\2\2\u02a5\u02a6"+ + "\7c\2\2\u02a6\u02a7\7u\2\2\u02a7@\3\2\2\2\u02a8\u02a9\7f\2\2\u02a9\u02aa"+ + "\7g\2\2\u02aa\u02ab\7h\2\2\u02abB\3\2\2\2\u02ac\u02ad\7k\2\2\u02ad\u02ae"+ + "\7p\2\2\u02aeD\3\2\2\2\u02af\u02b0\7v\2\2\u02b0\u02b1\7t\2\2\u02b1\u02b2"+ + "\7c\2\2\u02b2\u02b3\7k\2\2\u02b3\u02b4\7v\2\2\u02b4F\3\2\2\2\u02b5\u02b6"+ + "\7v\2\2\u02b6\u02b7\7j\2\2\u02b7\u02b8\7t\2\2\u02b8\u02b9\7g\2\2\u02b9"+ + "\u02ba\7c\2\2\u02ba\u02bb\7f\2\2\u02bb\u02bc\7u\2\2\u02bc\u02bd\7c\2\2"+ + "\u02bd\u02be\7h\2\2\u02be\u02bf\7g\2\2\u02bfH\3\2\2\2\u02c0\u02c1\7x\2"+ + "\2\u02c1\u02c2\7c\2\2\u02c2\u02c3\7t\2\2\u02c3J\3\2\2\2\u02c4\u02cd\5"+ + "Q&\2\u02c5\u02cd\5[+\2\u02c6\u02cd\5U(\2\u02c7\u02cd\5\u0095H\2\u02c8"+ + "\u02cd\5\u0081>\2\u02c9\u02cd\5\u0085@\2\u02ca\u02cd\5s\67\2\u02cb\u02cd"+ + "\5g\61\2\u02cc\u02c4\3\2\2\2\u02cc\u02c5\3\2\2\2\u02cc\u02c6\3\2\2\2\u02cc"+ + "\u02c7\3\2\2\2\u02cc\u02c8\3\2\2\2\u02cc\u02c9\3\2\2\2\u02cc\u02ca\3\2"+ + "\2\2\u02cc\u02cb\3\2\2\2\u02cdL\3\2\2\2\u02ce\u02cf\7c\2\2\u02cf\u02d0"+ + "\7d\2\2\u02d0\u02d1\7u\2\2\u02d1\u02d2\7v\2\2\u02d2\u02d3\7t\2\2\u02d3"+ + "\u02d4\7c\2\2\u02d4\u02d5\7e\2\2\u02d5\u02d6\7v\2\2\u02d6N\3\2\2\2\u02d7"+ + "\u02d8\7c\2\2\u02d8\u02d9\7u\2\2\u02d9\u02da\7u\2\2\u02da\u02db\7g\2\2"+ + "\u02db\u02dc\7t\2\2\u02dc\u02dd\7v\2\2\u02ddP\3\2\2\2\u02de\u02df\7d\2"+ + "\2\u02df\u02e0\7q\2\2\u02e0\u02e1\7q\2\2\u02e1\u02e2\7n\2\2\u02e2\u02e3"+ + "\7g\2\2\u02e3\u02e4\7c\2\2\u02e4\u02e5\7p\2\2\u02e5R\3\2\2\2\u02e6\u02e7"+ + "\7d\2\2\u02e7\u02e8\7t\2\2\u02e8\u02e9\7g\2\2\u02e9\u02ea\7c\2\2\u02ea"+ + "\u02eb\7m\2\2\u02ebT\3\2\2\2\u02ec\u02ed\7d\2\2\u02ed\u02ee\7{\2\2\u02ee"+ + "\u02ef\7v\2\2\u02ef\u02f0\7g\2\2\u02f0V\3\2\2\2\u02f1\u02f2\7e\2\2\u02f2"+ + "\u02f3\7c\2\2\u02f3\u02f4\7u\2\2\u02f4\u02f5\7g\2\2\u02f5X\3\2\2\2\u02f6"+ + "\u02f7\7e\2\2\u02f7\u02f8\7c\2\2\u02f8\u02f9\7v\2\2\u02f9\u02fa\7e\2\2"+ + "\u02fa\u02fb\7j\2\2\u02fbZ\3\2\2\2\u02fc\u02fd\7e\2\2\u02fd\u02fe\7j\2"+ + "\2\u02fe\u02ff\7c\2\2\u02ff\u0300\7t\2\2\u0300\\\3\2\2\2\u0301\u0302\7"+ + "e\2\2\u0302\u0303\7n\2\2\u0303\u0304\7c\2\2\u0304\u0305\7u\2\2\u0305\u0306"+ + "\7u\2\2\u0306^\3\2\2\2\u0307\u0308\7e\2\2\u0308\u0309\7q\2\2\u0309\u030a"+ + "\7p\2\2\u030a\u030b\7u\2\2\u030b\u030c\7v\2\2\u030c`\3\2\2\2\u030d\u030e"+ + "\7e\2\2\u030e\u030f\7q\2\2\u030f\u0310\7p\2\2\u0310\u0311\7v\2\2\u0311"+ + "\u0312\7k\2\2\u0312\u0313\7p\2\2\u0313\u0314\7w\2\2\u0314\u0315\7g\2\2"+ + "\u0315b\3\2\2\2\u0316\u0317\7f\2\2\u0317\u0318\7g\2\2\u0318\u0319\7h\2"+ + "\2\u0319\u031a\7c\2\2\u031a\u031b\7w\2\2\u031b\u031c\7n\2\2\u031c\u031d"+ + "\7v\2\2\u031dd\3\2\2\2\u031e\u031f\7f\2\2\u031f\u0320\7q\2\2\u0320f\3"+ + "\2\2\2\u0321\u0322\7f\2\2\u0322\u0323\7q\2\2\u0323\u0324\7w\2\2\u0324"+ + "\u0325\7d\2\2\u0325\u0326\7n\2\2\u0326\u0327\7g\2\2\u0327h\3\2\2\2\u0328"+ + "\u0329\7g\2\2\u0329\u032a\7n\2\2\u032a\u032b\7u\2\2\u032b\u032c\7g\2\2"+ + "\u032cj\3\2\2\2\u032d\u032e\7g\2\2\u032e\u032f\7p\2\2\u032f\u0330\7w\2"+ + "\2\u0330\u0331\7o\2\2\u0331l\3\2\2\2\u0332\u0333\7g\2\2\u0333\u0334\7"+ + "z\2\2\u0334\u0335\7v\2\2\u0335\u0336\7g\2\2\u0336\u0337\7p\2\2\u0337\u0338"+ + "\7f\2\2\u0338\u0339\7u\2\2\u0339n\3\2\2\2\u033a\u033b\7h\2\2\u033b\u033c"+ + "\7k\2\2\u033c\u033d\7p\2\2\u033d\u033e\7c\2\2\u033e\u033f\7n\2\2\u033f"+ + "p\3\2\2\2\u0340\u0341\7h\2\2\u0341\u0342\7k\2\2\u0342\u0343\7p\2\2\u0343"+ + "\u0344\7c\2\2\u0344\u0345\7n\2\2\u0345\u0346\7n\2\2\u0346\u0347\7{\2\2"+ + "\u0347r\3\2\2\2\u0348\u0349\7h\2\2\u0349\u034a\7n\2\2\u034a\u034b\7q\2"+ + "\2\u034b\u034c\7c\2\2\u034c\u034d\7v\2\2\u034dt\3\2\2\2\u034e\u034f\7"+ + "h\2\2\u034f\u0350\7q\2\2\u0350\u0351\7t\2\2\u0351v\3\2\2\2\u0352\u0353"+ + "\7k\2\2\u0353\u0354\7h\2\2\u0354x\3\2\2\2\u0355\u0356\7i\2\2\u0356\u0357"+ + "\7q\2\2\u0357\u0358\7v\2\2\u0358\u0359\7q\2\2\u0359z\3\2\2\2\u035a\u035b"+ + "\7k\2\2\u035b\u035c\7o\2\2\u035c\u035d\7r\2\2\u035d\u035e\7n\2\2\u035e"+ + "\u035f\7g\2\2\u035f\u0360\7o\2\2\u0360\u0361\7g\2\2\u0361\u0362\7p\2\2"+ + "\u0362\u0363\7v\2\2\u0363\u0364\7u\2\2\u0364|\3\2\2\2\u0365\u0366\7k\2"+ + "\2\u0366\u0367\7o\2\2\u0367\u0368\7r\2\2\u0368\u0369\7q\2\2\u0369\u036a"+ + "\7t\2\2\u036a\u036b\7v\2\2\u036b~\3\2\2\2\u036c\u036d\7k\2\2\u036d\u036e"+ + "\7p\2\2\u036e\u036f\7u\2\2\u036f\u0370\7v\2\2\u0370\u0371\7c\2\2\u0371"+ + "\u0372\7p\2\2\u0372\u0373\7e\2\2\u0373\u0374\7g\2\2\u0374\u0375\7q\2\2"+ + "\u0375\u0376\7h\2\2\u0376\u0080\3\2\2\2\u0377\u0378\7k\2\2\u0378\u0379"+ + "\7p\2\2\u0379\u037a\7v\2\2\u037a\u0082\3\2\2\2\u037b\u037c\7k\2\2\u037c"+ + "\u037d\7p\2\2\u037d\u037e\7v\2\2\u037e\u037f\7g\2\2\u037f\u0380\7t\2\2"+ + "\u0380\u0381\7h\2\2\u0381\u0382\7c\2\2\u0382\u0383\7e\2\2\u0383\u0384"+ + "\7g\2\2\u0384\u0084\3\2\2\2\u0385\u0386\7n\2\2\u0386\u0387\7q\2\2\u0387"+ + "\u0388\7p\2\2\u0388\u0389\7i\2\2\u0389\u0086\3\2\2\2\u038a\u038b\7p\2"+ + "\2\u038b\u038c\7c\2\2\u038c\u038d\7v\2\2\u038d\u038e\7k\2\2\u038e\u038f"+ + "\7x\2\2\u038f\u0390\7g\2\2\u0390\u0088\3\2\2\2\u0391\u0392\7p\2\2\u0392"+ + "\u0393\7g\2\2\u0393\u0394\7y\2\2\u0394\u008a\3\2\2\2\u0395\u0396\7r\2"+ + "\2\u0396\u0397\7c\2\2\u0397\u0398\7e\2\2\u0398\u0399\7m\2\2\u0399\u039a"+ + "\7c\2\2\u039a\u039b\7i\2\2\u039b\u039c\7g\2\2\u039c\u008c\3\2\2\2\u039d"+ + "\u039e\7r\2\2\u039e\u039f\7t\2\2\u039f\u03a0\7k\2\2\u03a0\u03a1\7x\2\2"+ + "\u03a1\u03a2\7c\2\2\u03a2\u03a3\7v\2\2\u03a3\u03a4\7g\2\2\u03a4\u008e"+ + "\3\2\2\2\u03a5\u03a6\7r\2\2\u03a6\u03a7\7t\2\2\u03a7\u03a8\7q\2\2\u03a8"+ + "\u03a9\7v\2\2\u03a9\u03aa\7g\2\2\u03aa\u03ab\7e\2\2\u03ab\u03ac\7v\2\2"+ + "\u03ac\u03ad\7g\2\2\u03ad\u03ae\7f\2\2\u03ae\u0090\3\2\2\2\u03af\u03b0"+ + "\7r\2\2\u03b0\u03b1\7w\2\2\u03b1\u03b2\7d\2\2\u03b2\u03b3\7n\2\2\u03b3"+ + "\u03b4\7k\2\2\u03b4\u03b5\7e\2\2\u03b5\u0092\3\2\2\2\u03b6\u03b7\7t\2"+ + "\2\u03b7\u03b8\7g\2\2\u03b8\u03b9\7v\2\2\u03b9\u03ba\7w\2\2\u03ba\u03bb"+ + "\7t\2\2\u03bb\u03bc\7p\2\2\u03bc\u0094\3\2\2\2\u03bd\u03be\7u\2\2\u03be"+ + "\u03bf\7j\2\2\u03bf\u03c0\7q\2\2\u03c0\u03c1\7t\2\2\u03c1\u03c2\7v\2\2"+ + "\u03c2\u0096\3\2\2\2\u03c3\u03c4\7u\2\2\u03c4\u03c5\7v\2\2\u03c5\u03c6"+ + "\7c\2\2\u03c6\u03c7\7v\2\2\u03c7\u03c8\7k\2\2\u03c8\u03c9\7e\2\2\u03c9"+ + "\u0098\3\2\2\2\u03ca\u03cb\7u\2\2\u03cb\u03cc\7v\2\2\u03cc\u03cd\7t\2"+ + "\2\u03cd\u03ce\7k\2\2\u03ce\u03cf\7e\2\2\u03cf\u03d0\7v\2\2\u03d0\u03d1"+ + "\7h\2\2\u03d1\u03d2\7r\2\2\u03d2\u009a\3\2\2\2\u03d3\u03d4\7u\2\2\u03d4"+ + "\u03d5\7w\2\2\u03d5\u03d6\7r\2\2\u03d6\u03d7\7g\2\2\u03d7\u03d8\7t\2\2"+ + "\u03d8\u009c\3\2\2\2\u03d9\u03da\7u\2\2\u03da\u03db\7y\2\2\u03db\u03dc"+ + "\7k\2\2\u03dc\u03dd\7v\2\2\u03dd\u03de\7e\2\2\u03de\u03df\7j\2\2\u03df"+ + "\u009e\3\2\2\2\u03e0\u03e1\7u\2\2\u03e1\u03e2\7{\2\2\u03e2\u03e3\7p\2"+ + "\2\u03e3\u03e4\7e\2\2\u03e4\u03e5\7j\2\2\u03e5\u03e6\7t\2\2\u03e6\u03e7"+ + "\7q\2\2\u03e7\u03e8\7p\2\2\u03e8\u03e9\7k\2\2\u03e9\u03ea\7|\2\2\u03ea"+ + "\u03eb\7g\2\2\u03eb\u03ec\7f\2\2\u03ec\u00a0\3\2\2\2\u03ed\u03ee\7v\2"+ + "\2\u03ee\u03ef\7j\2\2\u03ef\u03f0\7k\2\2\u03f0\u03f1\7u\2\2\u03f1\u00a2"+ + "\3\2\2\2\u03f2\u03f3\7v\2\2\u03f3\u03f4\7j\2\2\u03f4\u03f5\7t\2\2\u03f5"+ + "\u03f6\7q\2\2\u03f6\u03f7\7y\2\2\u03f7\u00a4\3\2\2\2\u03f8\u03f9\7v\2"+ + "\2\u03f9\u03fa\7j\2\2\u03fa\u03fb\7t\2\2\u03fb\u03fc\7q\2\2\u03fc\u03fd"+ + "\7y\2\2\u03fd\u03fe\7u\2\2\u03fe\u00a6\3\2\2\2\u03ff\u0400\7v\2\2\u0400"+ + "\u0401\7t\2\2\u0401\u0402\7c\2\2\u0402\u0403\7p\2\2\u0403\u0404\7u\2\2"+ + "\u0404\u0405\7k\2\2\u0405\u0406\7g\2\2\u0406\u0407\7p\2\2\u0407\u0408"+ + "\7v\2\2\u0408\u00a8\3\2\2\2\u0409\u040a\7v\2\2\u040a\u040b\7t\2\2\u040b"+ + "\u040c\7{\2\2\u040c\u00aa\3\2\2\2\u040d\u040e\7x\2\2\u040e\u040f\7q\2"+ + "\2\u040f\u0410\7k\2\2\u0410\u0411\7f\2\2\u0411\u00ac\3\2\2\2\u0412\u0413"+ + "\7x\2\2\u0413\u0414\7q\2\2\u0414\u0415\7n\2\2\u0415\u0416\7c\2\2\u0416"+ + "\u0417\7v\2\2\u0417\u0418\7k\2\2\u0418\u0419\7n\2\2\u0419\u041a\7g\2\2"+ + "\u041a\u00ae\3\2\2\2\u041b\u041c\7y\2\2\u041c\u041d\7j\2\2\u041d\u041e"+ + "\7k\2\2\u041e\u041f\7n\2\2\u041f\u0420\7g\2\2\u0420\u00b0\3\2\2\2\u0421"+ + "\u0426\5\u00b5X\2\u0422\u0426\5\u00b7Y\2\u0423\u0426\5\u00b9Z\2\u0424"+ + "\u0426\5\u00bb[\2\u0425\u0421\3\2\2\2\u0425\u0422\3\2\2\2\u0425\u0423"+ + "\3\2\2\2\u0425\u0424\3\2\2\2\u0426\u042a\3\2\2\2\u0427\u0428\5\u00cbc"+ + "\2\u0428\u0429\bV\22\2\u0429\u042b\3\2\2\2\u042a\u0427\3\2\2\2\u042a\u042b"+ + "\3\2\2\2\u042b\u0438\3\2\2\2\u042c\u042f\5\u00b3W\2\u042d\u042e\t\7\2"+ + "\2\u042e\u0430\bV\23\2\u042f\u042d\3\2\2\2\u0430\u0431\3\2\2\2\u0431\u042f"+ + "\3\2\2\2\u0431\u0432\3\2\2\2\u0432\u0433\3\2\2\2\u0433\u0435\bV\24\2\u0434"+ + "\u0436\5\u00bd\\\2\u0435\u0434\3\2\2\2\u0435\u0436\3\2\2\2\u0436\u0438"+ + "\3\2\2\2\u0437\u0425\3\2\2\2\u0437\u042c\3\2\2\2\u0438\u00b2\3\2\2\2\u0439"+ + "\u043a\7\62\2\2\u043a\u00b4\3\2\2\2\u043b\u043d\5\u00bf]\2\u043c\u043e"+ + "\5\u00bd\\\2\u043d\u043c\3\2\2\2\u043d\u043e\3\2\2\2\u043e\u00b6\3\2\2"+ + "\2\u043f\u0441\5\u00cdd\2\u0440\u0442\5\u00bd\\\2\u0441\u0440\3\2\2\2"+ + "\u0441\u0442\3\2\2\2\u0442\u00b8\3\2\2\2\u0443\u0445\5\u00d5h\2\u0444"+ + "\u0446\5\u00bd\\\2\u0445\u0444\3\2\2\2\u0445\u0446\3\2\2\2\u0446\u00ba"+ + "\3\2\2\2\u0447\u0449\5\u00ddl\2\u0448\u044a\5\u00bd\\\2\u0449\u0448\3"+ + "\2\2\2\u0449\u044a\3\2\2\2\u044a\u00bc\3\2\2\2\u044b\u044c\t\b\2\2\u044c"+ + "\u00be\3\2\2\2\u044d\u0458\5\u00b3W\2\u044e\u0455\5\u00c5`\2\u044f\u0451"+ + "\5\u00c1^\2\u0450\u044f\3\2\2\2\u0450\u0451\3\2\2\2\u0451\u0456\3\2\2"+ + "\2\u0452\u0453\5\u00c9b\2\u0453\u0454\5\u00c1^\2\u0454\u0456\3\2\2\2\u0455"+ + "\u0450\3\2\2\2\u0455\u0452\3\2\2\2\u0456\u0458\3\2\2\2\u0457\u044d\3\2"+ + "\2\2\u0457\u044e\3\2\2\2\u0458\u00c0\3\2\2\2\u0459\u0461\5\u00c3_\2\u045a"+ + "\u045c\5\u00c7a\2\u045b\u045a\3\2\2\2\u045c\u045f\3\2\2\2\u045d\u045b"+ + "\3\2\2\2\u045d\u045e\3\2\2\2\u045e\u0460\3\2\2\2\u045f\u045d\3\2\2\2\u0460"+ + "\u0462\5\u00c3_\2\u0461\u045d\3\2\2\2\u0461\u0462\3\2\2\2\u0462\u00c2"+ + "\3\2\2\2\u0463\u0466\5\u00b3W\2\u0464\u0466\5\u00c5`\2\u0465\u0463\3\2"+ + "\2\2\u0465\u0464\3\2\2\2\u0466\u00c4\3\2\2\2\u0467\u0468\t\t\2\2\u0468"+ + "\u00c6\3\2\2\2\u0469\u046c\5\u00c3_\2\u046a\u046c\5\u00cbc\2\u046b\u0469"+ + "\3\2\2\2\u046b\u046a\3\2\2\2\u046c\u00c8\3\2\2\2\u046d\u046f\5\u00cbc"+ + "\2\u046e\u046d\3\2\2\2\u046f\u0470\3\2\2\2\u0470\u046e\3\2\2\2\u0470\u0471"+ + "\3\2\2\2\u0471\u00ca\3\2\2\2\u0472\u0473\7a\2\2\u0473\u00cc\3\2\2\2\u0474"+ + "\u0475\5\u00b3W\2\u0475\u0476\t\n\2\2\u0476\u0477\5\u00cfe\2\u0477\u00ce"+ + "\3\2\2\2\u0478\u0480\5\u00d1f\2\u0479\u047b\5\u00d3g\2\u047a\u0479\3\2"+ + "\2\2\u047b\u047e\3\2\2\2\u047c\u047a\3\2\2\2\u047c\u047d\3\2\2\2\u047d"+ + "\u047f\3\2\2\2\u047e\u047c\3\2\2\2\u047f\u0481\5\u00d1f\2\u0480\u047c"+ + "\3\2\2\2\u0480\u0481\3\2\2\2\u0481\u00d0\3\2\2\2\u0482\u0483\t\13\2\2"+ + "\u0483\u00d2\3\2\2\2\u0484\u0487\5\u00d1f\2\u0485\u0487\5\u00cbc\2\u0486"+ + "\u0484\3\2\2\2\u0486\u0485\3\2\2\2\u0487\u00d4\3\2\2\2\u0488\u048a\5\u00b3"+ + "W\2\u0489\u048b\5\u00c9b\2\u048a\u0489\3\2\2\2\u048a\u048b\3\2\2\2\u048b"+ + "\u048c\3\2\2\2\u048c\u048d\5\u00d7i\2\u048d\u00d6\3\2\2\2\u048e\u0496"+ + "\5\u00d9j\2\u048f\u0491\5\u00dbk\2\u0490\u048f\3\2\2\2\u0491\u0494\3\2"+ + "\2\2\u0492\u0490\3\2\2\2\u0492\u0493\3\2\2\2\u0493\u0495\3\2\2\2\u0494"+ + "\u0492\3\2\2\2\u0495\u0497\5\u00d9j\2\u0496\u0492\3\2\2\2\u0496\u0497"+ + "\3\2\2\2\u0497\u00d8\3\2\2\2\u0498\u0499\t\f\2\2\u0499\u00da\3\2\2\2\u049a"+ + "\u049d\5\u00d9j\2\u049b\u049d\5\u00cbc\2\u049c\u049a\3\2\2\2\u049c\u049b"+ + "\3\2\2\2\u049d\u00dc\3\2\2\2\u049e\u049f\5\u00b3W\2\u049f\u04a0\t\r\2"+ + "\2\u04a0\u04a1\5\u00dfm\2\u04a1\u00de\3\2\2\2\u04a2\u04aa\5\u00e1n\2\u04a3"+ + "\u04a5\5\u00e3o\2\u04a4\u04a3\3\2\2\2\u04a5\u04a8\3\2\2\2\u04a6\u04a4"+ + "\3\2\2\2\u04a6\u04a7\3\2\2\2\u04a7\u04a9\3\2\2\2\u04a8\u04a6\3\2\2\2\u04a9"+ + "\u04ab\5\u00e1n\2\u04aa\u04a6\3\2\2\2\u04aa\u04ab\3\2\2\2\u04ab\u00e0"+ + "\3\2\2\2\u04ac\u04ad\t\16\2\2\u04ad\u00e2\3\2\2\2\u04ae\u04b1\5\u00e1"+ + "n\2\u04af\u04b1\5\u00cbc\2\u04b0\u04ae\3\2\2\2\u04b0\u04af\3\2\2\2\u04b1"+ + "\u00e4\3\2\2\2\u04b2\u04b5\5\u00e7q\2\u04b3\u04b5\5\u00f3w\2\u04b4\u04b2"+ + "\3\2\2\2\u04b4\u04b3\3\2\2\2\u04b5\u04b9\3\2\2\2\u04b6\u04b7\5\u00cbc"+ + "\2\u04b7\u04b8\bp\25\2\u04b8\u04ba\3\2\2\2\u04b9\u04b6\3\2\2\2\u04b9\u04ba"+ + "\3\2\2\2\u04ba\u00e6\3\2\2\2\u04bb\u04bc\5\u00c1^\2\u04bc\u04bd\5\u00fb"+ + "{\2\u04bd\u04bf\5\u00c1^\2\u04be\u04c0\5\u00e9r\2\u04bf\u04be\3\2\2\2"+ + "\u04bf\u04c0\3\2\2\2\u04c0\u04c2\3\2\2\2\u04c1\u04c3\5\u00f1v\2\u04c2"+ + "\u04c1\3\2\2\2\u04c2\u04c3\3\2\2\2\u04c3\u04cd\3\2\2\2\u04c4\u04c5\5\u00c1"+ + "^\2\u04c5\u04c7\5\u00e9r\2\u04c6\u04c8\5\u00f1v\2\u04c7\u04c6\3\2\2\2"+ + "\u04c7\u04c8\3\2\2\2\u04c8\u04cd\3\2\2\2\u04c9\u04ca\5\u00c1^\2\u04ca"+ + "\u04cb\5\u00f1v\2\u04cb\u04cd\3\2\2\2\u04cc\u04bb\3\2\2\2\u04cc\u04c4"+ + "\3\2\2\2\u04cc\u04c9\3\2\2\2\u04cd\u00e8\3\2\2\2\u04ce\u04cf\5\u00ebs"+ + "\2\u04cf\u04d0\5\u00edt\2\u04d0\u00ea\3\2\2\2\u04d1\u04d2\t\17\2\2\u04d2"+ + "\u00ec\3\2\2\2\u04d3\u04d5\5\u00efu\2\u04d4\u04d3\3\2\2\2\u04d4\u04d5"+ + "\3\2\2\2\u04d5\u04d6\3\2\2\2\u04d6\u04d7\5\u00c1^\2\u04d7\u00ee\3\2\2"+ + "\2\u04d8\u04d9\t\20\2\2\u04d9\u00f0\3\2\2\2\u04da\u04db\t\21\2\2\u04db"+ + "\u00f2\3\2\2\2\u04dc\u04dd\5\u00f5x\2\u04dd\u04df\5\u00f7y\2\u04de\u04e0"+ + "\5\u00f1v\2\u04df\u04de\3\2\2\2\u04df\u04e0\3\2\2\2\u04e0\u00f4\3\2\2"+ + "\2\u04e1\u04e3\5\u00cdd\2\u04e2\u04e4\5\u00fb{\2\u04e3\u04e2\3\2\2\2\u04e3"+ + "\u04e4\3\2\2\2\u04e4\u04ee\3\2\2\2\u04e5\u04e6\5\u00b3W\2\u04e6\u04e8"+ + "\t\n\2\2\u04e7\u04e9\5\u00cfe\2\u04e8\u04e7\3\2\2\2\u04e8\u04e9\3\2\2"+ + "\2\u04e9\u04ea\3\2\2\2\u04ea\u04eb\5\u00fb{\2\u04eb\u04ec\5\u00cfe\2\u04ec"+ + "\u04ee\3\2\2\2\u04ed\u04e1\3\2\2\2\u04ed\u04e5\3\2\2\2\u04ee\u00f6\3\2"+ + "\2\2\u04ef\u04f0\5\u00f9z\2\u04f0\u04f1\5\u00edt\2\u04f1\u00f8\3\2\2\2"+ + "\u04f2\u04f3\t\22\2\2\u04f3\u00fa\3\2\2\2\u04f4\u04f5\7\60\2\2\u04f5\u00fc"+ + "\3\2\2\2\u04f6\u04f7\7v\2\2\u04f7\u04f8\7t\2\2\u04f8\u04f9\7w\2\2\u04f9"+ + "\u0500\7g\2\2\u04fa\u04fb\7h\2\2\u04fb\u04fc\7c\2\2\u04fc\u04fd\7n\2\2"+ + "\u04fd\u04fe\7u\2\2\u04fe\u0500\7g\2\2\u04ff\u04f6\3\2\2\2\u04ff\u04fa"+ + "\3\2\2\2\u0500\u00fe\3\2\2\2\u0501\u0502\5\u010d\u0084\2\u0502\u0503\t"+ + "\23\2\2\u0503\u0509\3\2\2\2\u0504\u0509\5\u0101~\2\u0505\u0509\5\u0103"+ + "\177\2\u0506\u0509\5\u0107\u0081\2\u0507\u0509\5\u0109\u0082\2\u0508\u0501"+ + "\3\2\2\2\u0508\u0504\3\2\2\2\u0508\u0505\3\2\2\2\u0508\u0506\3\2\2\2\u0508"+ + "\u0507\3\2\2\2\u0509\u0100\3\2\2\2\u050a\u050b\5\u010d\u0084\2\u050b\u050c"+ + "\5\u00d9j\2\u050c\u0517\3\2\2\2\u050d\u050e\5\u010d\u0084\2\u050e\u050f"+ + "\5\u00d9j\2\u050f\u0510\5\u00d9j\2\u0510\u0517\3\2\2\2\u0511\u0512\5\u010d"+ + "\u0084\2\u0512\u0513\5\u0105\u0080\2\u0513\u0514\5\u00d9j\2\u0514\u0515"+ + "\5\u00d9j\2\u0515\u0517\3\2\2\2\u0516\u050a\3\2\2\2\u0516\u050d\3\2\2"+ + "\2\u0516\u0511\3\2\2\2\u0517\u0102\3\2\2\2\u0518\u0519\5\u010d\u0084\2"+ + "\u0519\u051a\7w\2\2\u051a\u051b\5\u00d1f\2\u051b\u051c\5\u00d1f\2\u051c"+ + "\u051d\5\u00d1f\2\u051d\u051e\5\u00d1f\2\u051e\u0104\3\2\2\2\u051f\u0520"+ + "\t\24\2\2\u0520\u0106\3\2\2\2\u0521\u0522\5\u010d\u0084\2\u0522\u0523"+ + "\5\u0111\u0086\2\u0523\u0108\3\2\2\2\u0524\u0526\5\u010d\u0084\2\u0525"+ + "\u0527\7\17\2\2\u0526\u0525\3\2\2\2\u0526\u0527\3\2\2\2\u0527\u0528\3"+ + "\2\2\2\u0528\u0529\7\f\2\2\u0529\u010a\3\2\2\2\u052a\u052b\5\u010d\u0084"+ + "\2\u052b\u052c\5\u010f\u0085\2\u052c\u010c\3\2\2\2\u052d\u052e\7^\2\2"+ + "\u052e\u010e\3\2\2\2\u052f\u0530\7\61\2\2\u0530\u0110\3\2\2\2\u0531\u0532"+ + "\7&\2\2\u0532\u0112\3\2\2\2\u0533\u0534\7$\2\2\u0534\u0114\3\2\2\2\u0535"+ + "\u0536\7)\2\2\u0536\u0116\3\2\2\2\u0537\u0538\7$\2\2\u0538\u0539\7$\2"+ + "\2\u0539\u053a\7$\2\2\u053a\u0118\3\2\2\2\u053b\u053c\7)\2\2\u053c\u053d"+ + "\7)\2\2\u053d\u053e\7)\2\2\u053e\u011a\3\2\2\2\u053f\u0540\7&\2\2\u0540"+ + "\u0541\7\61\2\2\u0541\u011c\3\2\2\2\u0542\u0543\7\61\2\2\u0543\u0544\7"+ + "&\2\2\u0544\u011e\3\2\2\2\u0545\u0546\7&\2\2\u0546\u0547\7\61\2\2\u0547"+ + "\u0548\7&\2\2\u0548\u0120\3\2\2\2\u0549\u054a\7&\2\2\u054a\u054b\7&\2"+ + "\2\u054b\u0122\3\2\2\2\u054c\u054d\7p\2\2\u054d\u054e\7w\2\2\u054e\u054f"+ + "\7n\2\2\u054f\u0550\7n\2\2\u0550\u0124\3\2\2\2\u0551\u0552\7\60\2\2\u0552"+ + "\u0553\7\60\2\2\u0553\u0126\3\2\2\2\u0554\u0555\7\60\2\2\u0555\u0556\7"+ + "\60\2\2\u0556\u0557\7>\2\2\u0557\u0128\3\2\2\2\u0558\u0559\7,\2\2\u0559"+ + "\u055a\7\60\2\2\u055a\u012a\3\2\2\2\u055b\u055c\7A\2\2\u055c\u055d\7\60"+ + "\2\2\u055d\u012c\3\2\2\2\u055e\u055f\7A\2\2\u055f\u0560\7A\2\2\u0560\u0561"+ + "\7\60\2\2\u0561\u012e\3\2\2\2\u0562\u0563\7A\2\2\u0563\u0564\7<\2\2\u0564"+ + "\u0130\3\2\2\2\u0565\u0566\7\60\2\2\u0566\u0567\7(\2\2\u0567\u0132\3\2"+ + "\2\2\u0568\u0569\7<\2\2\u0569\u056a\7<\2\2\u056a\u0134\3\2\2\2\u056b\u056c"+ + "\7?\2\2\u056c\u056d\7\u0080\2\2\u056d\u0136\3\2\2\2\u056e\u056f\7?\2\2"+ + "\u056f\u0570\7?\2\2\u0570\u0571\7\u0080\2\2\u0571\u0138\3\2\2\2\u0572"+ + "\u0573\7,\2\2\u0573\u0574\7,\2\2\u0574\u013a\3\2\2\2\u0575\u0576\7,\2"+ + "\2\u0576\u0577\7,\2\2\u0577\u0578\7?\2\2\u0578\u013c\3\2\2\2\u0579\u057a"+ + "\7>\2\2\u057a\u057b\7?\2\2\u057b\u057c\7@\2\2\u057c\u013e\3\2\2\2\u057d"+ + "\u057e\7?\2\2\u057e\u057f\7?\2\2\u057f\u0580\7?\2\2\u0580\u0140\3\2\2"+ + "\2\u0581\u0582\7#\2\2\u0582\u0583\7?\2\2\u0583\u0584\7?\2\2\u0584\u0142"+ + "\3\2\2\2\u0585\u0586\7/\2\2\u0586\u0587\7@\2\2\u0587\u0144\3\2\2\2\u0588"+ + "\u0589\7#\2\2\u0589\u058a\7k\2\2\u058a\u058b\7p\2\2\u058b\u058c\7u\2\2"+ + "\u058c\u058d\7v\2\2\u058d\u058e\7c\2\2\u058e\u058f\7p\2\2\u058f\u0590"+ + "\7e\2\2\u0590\u0591\7g\2\2\u0591\u0592\7q\2\2\u0592\u0593\7h\2\2\u0593"+ + "\u0594\3\2\2\2\u0594\u0595\6\u00a0\r\2\u0595\u0146\3\2\2\2\u0596\u0597"+ + "\7#\2\2\u0597\u0598\7k\2\2\u0598\u0599\7p\2\2\u0599\u059a\3\2\2\2\u059a"+ + "\u059b\6\u00a1\16\2\u059b\u0148\3\2\2\2\u059c\u059d\7*\2\2\u059d\u059e"+ + "\b\u00a2\26\2\u059e\u059f\3\2\2\2\u059f\u05a0\b\u00a2\16\2\u05a0\u014a"+ + "\3\2\2\2\u05a1\u05a2\7+\2\2\u05a2\u05a3\b\u00a3\27\2\u05a3\u05a4\3\2\2"+ + "\2\u05a4\u05a5\b\u00a3\b\2\u05a5\u014c\3\2\2\2\u05a6\u05a7\7}\2\2\u05a7"+ + "\u05a8\b\u00a4\30\2\u05a8\u05a9\3\2\2\2\u05a9\u05aa\b\u00a4\16\2\u05aa"+ + "\u014e\3\2\2\2\u05ab\u05ac\7\177\2\2\u05ac\u05ad\b\u00a5\31\2\u05ad\u05ae"+ + "\3\2\2\2\u05ae\u05af\b\u00a5\b\2\u05af\u0150\3\2\2\2\u05b0\u05b1\7]\2"+ + "\2\u05b1\u05b2\b\u00a6\32\2\u05b2\u05b3\3\2\2\2\u05b3\u05b4\b\u00a6\16"+ + "\2\u05b4\u0152\3\2\2\2\u05b5\u05b6\7_\2\2\u05b6\u05b7\b\u00a7\33\2\u05b7"+ + "\u05b8\3\2\2\2\u05b8\u05b9\b\u00a7\b\2\u05b9\u0154\3\2\2\2\u05ba\u05bb"+ + "\7=\2\2\u05bb\u0156\3\2\2\2\u05bc\u05bd\7.\2\2\u05bd\u0158\3\2\2\2\u05be"+ + "\u05bf\5\u00fb{\2\u05bf\u015a\3\2\2\2\u05c0\u05c1\7?\2\2\u05c1\u015c\3"+ + "\2\2\2\u05c2\u05c3\7@\2\2\u05c3\u015e\3\2\2\2\u05c4\u05c5\7>\2\2\u05c5"+ + "\u0160\3\2\2\2\u05c6\u05c7\7#\2\2\u05c7\u0162\3\2\2\2\u05c8\u05c9\7\u0080"+ + "\2\2\u05c9\u0164\3\2\2\2\u05ca\u05cb\7A\2\2\u05cb\u0166\3\2\2\2\u05cc"+ + "\u05cd\7<\2\2\u05cd\u0168\3\2\2\2\u05ce\u05cf\7?\2\2\u05cf\u05d0\7?\2"+ + "\2\u05d0\u016a\3\2\2\2\u05d1\u05d2\7>\2\2\u05d2\u05d3\7?\2\2\u05d3\u016c"+ + "\3\2\2\2\u05d4\u05d5\7@\2\2\u05d5\u05d6\7?\2\2\u05d6\u016e\3\2\2\2\u05d7"+ + "\u05d8\7#\2\2\u05d8\u05d9\7?\2\2\u05d9\u0170\3\2\2\2\u05da\u05db\7(\2"+ + "\2\u05db\u05dc\7(\2\2\u05dc\u0172\3\2\2\2\u05dd\u05de\7~\2\2\u05de\u05df"+ + "\7~\2\2\u05df\u0174\3\2\2\2\u05e0\u05e1\7-\2\2\u05e1\u05e2\7-\2\2\u05e2"+ + "\u0176\3\2\2\2\u05e3\u05e4\7/\2\2\u05e4\u05e5\7/\2\2\u05e5\u0178\3\2\2"+ + "\2\u05e6\u05e7\7-\2\2\u05e7\u017a\3\2\2\2\u05e8\u05e9\7/\2\2\u05e9\u017c"+ + "\3\2\2\2\u05ea\u05eb\7,\2\2\u05eb\u017e\3\2\2\2\u05ec\u05ed\5\u010f\u0085"+ + "\2\u05ed\u0180\3\2\2\2\u05ee\u05ef\7(\2\2\u05ef\u0182\3\2\2\2\u05f0\u05f1"+ + "\7~\2\2\u05f1\u0184\3\2\2\2\u05f2\u05f3\7`\2\2\u05f3\u0186\3\2\2\2\u05f4"+ + "\u05f5\7\'\2\2\u05f5\u0188\3\2\2\2\u05f6\u05f7\7-\2\2\u05f7\u05f8\7?\2"+ + "\2\u05f8\u018a\3\2\2\2\u05f9\u05fa\7/\2\2\u05fa\u05fb\7?\2\2\u05fb\u018c"+ + "\3\2\2\2\u05fc\u05fd\7,\2\2\u05fd\u05fe\7?\2\2\u05fe\u018e\3\2\2\2\u05ff"+ + "\u0600\7\61\2\2\u0600\u0601\7?\2\2\u0601\u0190\3\2\2\2\u0602\u0603\7("+ + "\2\2\u0603\u0604\7?\2\2\u0604\u0192\3\2\2\2\u0605\u0606\7~\2\2\u0606\u0607"+ + "\7?\2\2\u0607\u0194\3\2\2\2\u0608\u0609\7`\2\2\u0609\u060a\7?\2\2\u060a"+ + "\u0196\3\2\2\2\u060b\u060c\7\'\2\2\u060c\u060d\7?\2\2\u060d\u0198\3\2"+ + "\2\2\u060e\u060f\7>\2\2\u060f\u0610\7>\2\2\u0610\u0611\7?\2\2\u0611\u019a"+ + "\3\2\2\2\u0612\u0613\7@\2\2\u0613\u0614\7@\2\2\u0614\u0615\7?\2\2\u0615"+ + "\u019c\3\2\2\2\u0616\u0617\7@\2\2\u0617\u0618\7@\2\2\u0618\u0619\7@\2"+ + "\2\u0619\u061a\7?\2\2\u061a\u019e\3\2\2\2\u061b\u061c\7A\2\2\u061c\u061d"+ + "\7?\2\2\u061d\u01a0\3\2\2\2\u061e\u0622\t\25\2\2\u061f\u0621\5\u01ad\u00d4"+ + "\2\u0620\u061f\3\2\2\2\u0621\u0624\3\2\2\2\u0622\u0620\3\2\2\2\u0622\u0623"+ + "\3\2\2\2\u0623\u01a2\3\2\2\2\u0624\u0622\3\2\2\2\u0625\u0629\5\u01ab\u00d3"+ + "\2\u0626\u0628\5\u01ad\u00d4\2\u0627\u0626\3\2\2\2\u0628\u062b\3\2\2\2"+ + "\u0629\u0627\3\2\2\2\u0629\u062a\3\2\2\2\u062a\u01a4\3\2\2\2\u062b\u0629"+ + "\3\2\2\2\u062c\u0630\5\u01a7\u00d1\2\u062d\u062f\5\u01a9\u00d2\2\u062e"+ + "\u062d\3\2\2\2\u062f\u0632\3\2\2\2\u0630\u062e\3\2\2\2\u0630\u0631\3\2"+ + "\2\2\u0631\u01a6\3\2\2\2\u0632\u0630\3\2\2\2\u0633\u063a\t\26\2\2\u0634"+ + "\u0635\n\27\2\2\u0635\u063a\6\u00d1\17\2\u0636\u0637\t\30\2\2\u0637\u0638"+ + "\t\31\2\2\u0638\u063a\6\u00d1\20\2\u0639\u0633\3\2\2\2\u0639\u0634\3\2"+ + "\2\2\u0639\u0636\3\2\2\2\u063a\u01a8\3\2\2\2\u063b\u0642\t\32\2\2\u063c"+ + "\u063d\n\27\2\2\u063d\u0642\6\u00d2\21\2\u063e\u063f\t\30\2\2\u063f\u0640"+ + "\t\31\2\2\u0640\u0642\6\u00d2\22\2\u0641\u063b\3\2\2\2\u0641\u063c\3\2"+ + "\2\2\u0641\u063e\3\2\2\2\u0642\u01aa\3\2\2\2\u0643\u064a\t\33\2\2\u0644"+ + "\u0645\n\27\2\2\u0645\u064a\6\u00d3\23\2\u0646\u0647\t\30\2\2\u0647\u0648"+ + "\t\31\2\2\u0648\u064a\6\u00d3\24\2\u0649\u0643\3\2\2\2\u0649\u0644\3\2"+ + "\2\2\u0649\u0646\3\2\2\2\u064a\u01ac\3\2\2\2\u064b\u0652\t\34\2\2\u064c"+ + "\u064d\n\27\2\2\u064d\u0652\6\u00d4\25\2\u064e\u064f\t\30\2\2\u064f\u0650"+ + "\t\31\2\2\u0650\u0652\6\u00d4\26\2\u0651\u064b\3\2\2\2\u0651\u064c\3\2"+ + "\2\2\u0651\u064e\3\2\2\2\u0652\u01ae\3\2\2\2\u0653\u0654\7B\2\2\u0654"+ + "\u01b0\3\2\2\2\u0655\u0656\7\60\2\2\u0656\u0657\7\60\2\2\u0657\u0658\7"+ + "\60\2\2\u0658\u01b2\3\2\2\2\u0659\u065b\t\35\2\2\u065a\u0659\3\2\2\2\u065b"+ + "\u065c\3\2\2\2\u065c\u065a\3\2\2\2\u065c\u065d\3\2\2\2\u065d\u0664\3\2"+ + "\2\2\u065e\u0660\5\u0109\u0082\2\u065f\u065e\3\2\2\2\u0660\u0661\3\2\2"+ + "\2\u0661\u065f\3\2\2\2\u0661\u0662\3\2\2\2\u0662\u0664\3\2\2\2\u0663\u065a"+ + "\3\2\2\2\u0663\u065f\3\2\2\2\u0664\u0665\3\2\2\2\u0665\u0666\b\u00d7\34"+ + "\2\u0666\u01b4\3\2\2\2\u0667\u0669\7\17\2\2\u0668\u0667\3\2\2\2\u0668"+ + "\u0669\3\2\2\2\u0669\u066a\3\2\2\2\u066a\u066b\7\f\2\2\u066b\u066c\b\u00d8"+ + "\35\2\u066c\u01b6\3\2\2\2\u066d\u066e\7\61\2\2\u066e\u066f\7,\2\2\u066f"+ + "\u0673\3\2\2\2\u0670\u0672\13\2\2\2\u0671\u0670\3\2\2\2\u0672\u0675\3"+ + "\2\2\2\u0673\u0674\3\2\2\2\u0673\u0671\3\2\2\2\u0674\u0676\3\2\2\2\u0675"+ + "\u0673\3\2\2\2\u0676\u0677\7,\2\2\u0677\u0678\7\61\2\2\u0678\u0679\3\2"+ + "\2\2\u0679\u067a\b\u00d9\36\2\u067a\u067b\3\2\2\2\u067b\u067c\b\u00d9"+ + "\37\2\u067c\u01b8\3\2\2\2\u067d\u067e\7\61\2\2\u067e\u067f\7\61\2\2\u067f"+ + "\u0683\3\2\2\2\u0680\u0682\n\36\2\2\u0681\u0680\3\2\2\2\u0682\u0685\3"+ + "\2\2\2\u0683\u0681\3\2\2\2\u0683\u0684\3\2\2\2\u0684\u0686\3\2\2\2\u0685"+ + "\u0683\3\2\2\2\u0686\u0687\b\u00da \2\u0687\u0688\3\2\2\2\u0688\u0689"+ + "\b\u00da\37\2\u0689\u01ba\3\2\2\2\u068a\u068b\7%\2\2\u068b\u068c\7#\2"+ + "\2\u068c\u068d\3\2\2\2\u068d\u0691\b\u00db!\2\u068e\u0690\n\36\2\2\u068f"+ + "\u068e\3\2\2\2\u0690\u0693\3\2\2\2\u0691\u068f\3\2\2\2\u0691\u0692\3\2"+ + "\2\2\u0692\u0694\3\2\2\2\u0693\u0691\3\2\2\2\u0694\u0695\b\u00db\34\2"+ + "\u0695\u01bc\3\2\2\2\u0696\u0697\13\2\2\2\u0697\u01be\3\2\2\2T\2\3\4\5"+ + "\6\7\b\u01c3\u01cc\u01d6\u01de\u01e7\u01f0\u01f4\u01fa\u0206\u0214\u0222"+ + "\u0247\u027e\u0282\u0289\u0290\u0297\u02a3\u02cc\u0425\u042a\u0431\u0435"+ + "\u0437\u043d\u0441\u0445\u0449\u0450\u0455\u0457\u045d\u0461\u0465\u046b"+ + "\u0470\u047c\u0480\u0486\u048a\u0492\u0496\u049c\u04a6\u04aa\u04b0\u04b4"+ + "\u04b9\u04bf\u04c2\u04c7\u04cc\u04d4\u04df\u04e3\u04e8\u04ed\u04ff\u0508"+ + "\u0516\u0526\u0622\u0629\u0630\u0639\u0641\u0649\u0651\u065c\u0661\u0663"+ + "\u0668\u0673\u0683\u0691\"\7\3\2\7\7\2\t\4\2\7\4\2\7\5\2\7\6\2\6\2\2\5"+ + "\2\2\t\5\2\t\6\2\3\23\2\tR\2\7\2\2\t}\2\7\b\2\3\26\3\3V\4\3V\5\3V\6\3"+ + "p\7\3\u00a2\b\3\u00a3\t\3\u00a4\n\3\u00a5\13\3\u00a6\f\3\u00a7\r\b\2\2"+ + "\3\u00d8\16\3\u00d9\17\t\u0081\2\3\u00da\20\3\u00db\21"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + } +} \ No newline at end of file diff --git a/base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/GroovyLexer.tokens b/base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/GroovyLexer.tokens similarity index 100% rename from base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/GroovyLexer.tokens rename to base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/GroovyLexer.tokens diff --git a/base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/GroovyParser.java b/base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/GroovyParser.java similarity index 86% rename from base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/GroovyParser.java rename to base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/GroovyParser.java index a695e31547..62b184ca29 100644 --- a/base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/GroovyParser.java +++ b/base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/GroovyParser.java @@ -2,9 +2,7 @@ package org.apache.groovy.parser.antlr4; import java.util.Map; - import org.codehaus.groovy.util.ListHashMap; import org.codehaus.groovy.ast.NodeMetaDataHandler; - import org.codehaus.groovy.ast.NodeMetaDataHandlerHelper; import org.apache.groovy.parser.antlr4.SemanticPredicates; import groovyjarjarantlr4.v4.runtime.atn.*; @@ -212,8 +210,7 @@ public Vocabulary getVocabulary() { public static class GroovyParserRuleContext extends ParserRuleContext implements NodeMetaDataHandler { - private Map metaDataMap = null; - private NodeMetaDataHandlerHelper helper = new NodeMetaDataHandlerHelper(this); + private Map metaDataMap = null; public GroovyParserRuleContext() {} @@ -221,36 +218,6 @@ public GroovyParserRuleContext(ParserRuleContext parent, int invokingStateNumber super(parent, invokingStateNumber); } - @Override - public T getNodeMetaData(Object key) { - return helper.getNodeMetaData(key); - } - - @Override - public void copyNodeMetaData(NodeMetaDataHandler other) { - helper.copyNodeMetaData(other); - } - - @Override - public void setNodeMetaData(Object key, Object value) { - helper.setNodeMetaData(key, value); - } - - @Override - public Object putNodeMetaData(Object key, Object value) { - return helper.putNodeMetaData(key, value); - } - - @Override - public void removeNodeMetaData(Object key) { - helper.removeNodeMetaData(key); - } - - @Override - public Map getNodeMetaData() { - return helper.getNodeMetaData(); - } - @Override public Map getMetaDataMap() { return this.metaDataMap; @@ -8093,17 +8060,6 @@ public void copyFrom(StatementExpressionContext ctx) { super.copyFrom(ctx); } } - public static class NormalExprAltContext extends StatementExpressionContext { - public ExpressionContext expression() { - return getRuleContext(ExpressionContext.class,0); - } - public NormalExprAltContext(StatementExpressionContext ctx) { copyFrom(ctx); } - @Override - public Result accept(ParseTreeVisitor visitor) { - if ( visitor instanceof GroovyParserVisitor ) return ((GroovyParserVisitor)visitor).visitNormalExprAlt(this); - else return visitor.visitChildren(this); - } - } public static class CommandExprAltContext extends StatementExpressionContext { public CommandExpressionContext commandExpression() { return getRuleContext(CommandExpressionContext.class,0); @@ -8121,26 +8077,11 @@ public final StatementExpressionContext statementExpression() throws Recognition StatementExpressionContext _localctx = new StatementExpressionContext(_ctx, getState()); enterRule(_localctx, 224, RULE_statementExpression); try { - setState(1245); - _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,137,_ctx) ) { - case 1: - _localctx = new NormalExprAltContext(_localctx); - enterOuterAlt(_localctx, 1); - { - setState(1243); - expression(0); - } - break; - - case 2: - _localctx = new CommandExprAltContext(_localctx); - enterOuterAlt(_localctx, 2); - { - setState(1244); - commandExpression(); - } - break; + _localctx = new CommandExprAltContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(1243); + commandExpression(); } } catch (RecognitionException re) { @@ -8180,14 +8121,14 @@ public final PostfixExpressionContext postfixExpression() throws RecognitionExce try { enterOuterAlt(_localctx, 1); { - setState(1247); + setState(1245); pathExpression(); - setState(1249); + setState(1247); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,138,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,137,_ctx) ) { case 1: { - setState(1248); + setState(1246); _localctx.op = _input.LT(1); _la = _input.LA(1); if ( !(_la==INC || _la==DEC) ) { @@ -8701,18 +8642,18 @@ private ExpressionContext expression(int _p) throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(1268); + setState(1266); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,139,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,138,_ctx) ) { case 1: { _localctx = new CastExprAltContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(1252); + setState(1250); castParExpression(); - setState(1253); + setState(1251); expression(20); } break; @@ -8722,7 +8663,7 @@ private ExpressionContext expression(int _p) throws RecognitionException { _localctx = new PostfixExprAltContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(1255); + setState(1253); postfixExpression(); } break; @@ -8732,7 +8673,7 @@ private ExpressionContext expression(int _p) throws RecognitionException { _localctx = new UnaryNotExprAltContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(1256); + setState(1254); _la = _input.LA(1); if ( !(_la==NOT || _la==BITNOT) ) { _errHandler.recoverInline(this); @@ -8744,9 +8685,9 @@ private ExpressionContext expression(int _p) throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(1257); + setState(1255); nls(); - setState(1258); + setState(1256); expression(18); } break; @@ -8756,7 +8697,7 @@ private ExpressionContext expression(int _p) throws RecognitionException { _localctx = new UnaryAddExprAltContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(1260); + setState(1258); ((UnaryAddExprAltContext)_localctx).op = _input.LT(1); _la = _input.LA(1); if ( !(((((_la - 100)) & ~0x3f) == 0 && ((1L << (_la - 100)) & ((1L << (INC - 100)) | (1L << (DEC - 100)) | (1L << (ADD - 100)) | (1L << (SUB - 100)))) != 0)) ) { @@ -8769,7 +8710,7 @@ private ExpressionContext expression(int _p) throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(1261); + setState(1259); expression(16); } break; @@ -8779,43 +8720,43 @@ private ExpressionContext expression(int _p) throws RecognitionException { _localctx = new MultipleAssignmentExprAltContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(1262); + setState(1260); ((MultipleAssignmentExprAltContext)_localctx).left = variableNames(); - setState(1263); + setState(1261); nls(); - setState(1264); + setState(1262); ((MultipleAssignmentExprAltContext)_localctx).op = match(ASSIGN); - setState(1265); + setState(1263); nls(); - setState(1266); + setState(1264); ((MultipleAssignmentExprAltContext)_localctx).right = statementExpression(); } break; } _ctx.stop = _input.LT(-1); - setState(1380); + setState(1378); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,144,_ctx); + _alt = getInterpreter().adaptivePredict(_input,143,_ctx); while ( _alt!=2 && _alt!=groovyjarjarantlr4.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { if ( _parseListeners!=null ) triggerExitRuleEvent(); _prevctx = _localctx; { - setState(1378); + setState(1376); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,143,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,142,_ctx) ) { case 1: { _localctx = new PowerExprAltContext(new ExpressionContext(_parentctx, _parentState)); ((PowerExprAltContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_expression); - setState(1270); + setState(1268); if (!(precpred(_ctx, 17))) throw new FailedPredicateException(this, "precpred(_ctx, 17)"); - setState(1271); + setState(1269); ((PowerExprAltContext)_localctx).op = match(POWER); - setState(1272); + setState(1270); nls(); - setState(1273); + setState(1271); ((PowerExprAltContext)_localctx).right = expression(18); } break; @@ -8825,11 +8766,11 @@ private ExpressionContext expression(int _p) throws RecognitionException { _localctx = new MultiplicativeExprAltContext(new ExpressionContext(_parentctx, _parentState)); ((MultiplicativeExprAltContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_expression); - setState(1275); + setState(1273); if (!(precpred(_ctx, 15))) throw new FailedPredicateException(this, "precpred(_ctx, 15)"); - setState(1276); + setState(1274); nls(); - setState(1277); + setState(1275); ((MultiplicativeExprAltContext)_localctx).op = _input.LT(1); _la = _input.LA(1); if ( !(((((_la - 104)) & ~0x3f) == 0 && ((1L << (_la - 104)) & ((1L << (MUL - 104)) | (1L << (DIV - 104)) | (1L << (MOD - 104)))) != 0)) ) { @@ -8842,9 +8783,9 @@ private ExpressionContext expression(int _p) throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(1278); + setState(1276); nls(); - setState(1279); + setState(1277); ((MultiplicativeExprAltContext)_localctx).right = expression(16); } break; @@ -8854,9 +8795,9 @@ private ExpressionContext expression(int _p) throws RecognitionException { _localctx = new AdditiveExprAltContext(new ExpressionContext(_parentctx, _parentState)); ((AdditiveExprAltContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_expression); - setState(1281); + setState(1279); if (!(precpred(_ctx, 14))) throw new FailedPredicateException(this, "precpred(_ctx, 14)"); - setState(1282); + setState(1280); ((AdditiveExprAltContext)_localctx).op = _input.LT(1); _la = _input.LA(1); if ( !(_la==ADD || _la==SUB) ) { @@ -8869,9 +8810,9 @@ private ExpressionContext expression(int _p) throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(1283); + setState(1281); nls(); - setState(1284); + setState(1282); ((AdditiveExprAltContext)_localctx).right = expression(15); } break; @@ -8881,44 +8822,44 @@ private ExpressionContext expression(int _p) throws RecognitionException { _localctx = new ShiftExprAltContext(new ExpressionContext(_parentctx, _parentState)); ((ShiftExprAltContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_expression); - setState(1286); + setState(1284); if (!(precpred(_ctx, 13))) throw new FailedPredicateException(this, "precpred(_ctx, 13)"); - setState(1287); + setState(1285); nls(); - setState(1298); + setState(1296); _errHandler.sync(this); switch (_input.LA(1)) { case GT: case LT: { - setState(1295); + setState(1293); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,140,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,139,_ctx) ) { case 1: { - setState(1288); + setState(1286); ((ShiftExprAltContext)_localctx).dlOp = match(LT); - setState(1289); + setState(1287); match(LT); } break; case 2: { - setState(1290); + setState(1288); ((ShiftExprAltContext)_localctx).tgOp = match(GT); - setState(1291); + setState(1289); match(GT); - setState(1292); + setState(1290); match(GT); } break; case 3: { - setState(1293); + setState(1291); ((ShiftExprAltContext)_localctx).dgOp = match(GT); - setState(1294); + setState(1292); match(GT); } break; @@ -8928,7 +8869,7 @@ private ExpressionContext expression(int _p) throws RecognitionException { case RANGE_INCLUSIVE: case RANGE_EXCLUSIVE: { - setState(1297); + setState(1295); ((ShiftExprAltContext)_localctx).rangeOp = _input.LT(1); _la = _input.LA(1); if ( !(_la==RANGE_INCLUSIVE || _la==RANGE_EXCLUSIVE) ) { @@ -8946,9 +8887,9 @@ private ExpressionContext expression(int _p) throws RecognitionException { default: throw new NoViableAltException(this); } - setState(1300); + setState(1298); nls(); - setState(1301); + setState(1299); ((ShiftExprAltContext)_localctx).right = expression(14); } break; @@ -8958,11 +8899,11 @@ private ExpressionContext expression(int _p) throws RecognitionException { _localctx = new RelationalExprAltContext(new ExpressionContext(_parentctx, _parentState)); ((RelationalExprAltContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_expression); - setState(1303); + setState(1301); if (!(precpred(_ctx, 11))) throw new FailedPredicateException(this, "precpred(_ctx, 11)"); - setState(1304); + setState(1302); nls(); - setState(1305); + setState(1303); ((RelationalExprAltContext)_localctx).op = _input.LT(1); _la = _input.LA(1); if ( !(_la==IN || ((((_la - 77)) & ~0x3f) == 0 && ((1L << (_la - 77)) & ((1L << (NOT_IN - 77)) | (1L << (GT - 77)) | (1L << (LT - 77)) | (1L << (LE - 77)) | (1L << (GE - 77)))) != 0)) ) { @@ -8975,9 +8916,9 @@ private ExpressionContext expression(int _p) throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(1306); + setState(1304); nls(); - setState(1307); + setState(1305); ((RelationalExprAltContext)_localctx).right = expression(12); } break; @@ -8987,11 +8928,11 @@ private ExpressionContext expression(int _p) throws RecognitionException { _localctx = new EqualityExprAltContext(new ExpressionContext(_parentctx, _parentState)); ((EqualityExprAltContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_expression); - setState(1309); + setState(1307); if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)"); - setState(1310); + setState(1308); nls(); - setState(1311); + setState(1309); ((EqualityExprAltContext)_localctx).op = _input.LT(1); _la = _input.LA(1); if ( !(((((_la - 72)) & ~0x3f) == 0 && ((1L << (_la - 72)) & ((1L << (SPACESHIP - 72)) | (1L << (IDENTICAL - 72)) | (1L << (NOT_IDENTICAL - 72)) | (1L << (EQUAL - 72)) | (1L << (NOTEQUAL - 72)))) != 0)) ) { @@ -9004,9 +8945,9 @@ private ExpressionContext expression(int _p) throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(1312); + setState(1310); nls(); - setState(1313); + setState(1311); ((EqualityExprAltContext)_localctx).right = expression(11); } break; @@ -9016,11 +8957,11 @@ private ExpressionContext expression(int _p) throws RecognitionException { _localctx = new RegexExprAltContext(new ExpressionContext(_parentctx, _parentState)); ((RegexExprAltContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_expression); - setState(1315); + setState(1313); if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)"); - setState(1316); + setState(1314); nls(); - setState(1317); + setState(1315); ((RegexExprAltContext)_localctx).op = _input.LT(1); _la = _input.LA(1); if ( !(_la==REGEX_FIND || _la==REGEX_MATCH) ) { @@ -9033,9 +8974,9 @@ private ExpressionContext expression(int _p) throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(1318); + setState(1316); nls(); - setState(1319); + setState(1317); ((RegexExprAltContext)_localctx).right = expression(10); } break; @@ -9045,15 +8986,15 @@ private ExpressionContext expression(int _p) throws RecognitionException { _localctx = new AndExprAltContext(new ExpressionContext(_parentctx, _parentState)); ((AndExprAltContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_expression); - setState(1321); + setState(1319); if (!(precpred(_ctx, 8))) throw new FailedPredicateException(this, "precpred(_ctx, 8)"); - setState(1322); + setState(1320); nls(); - setState(1323); + setState(1321); ((AndExprAltContext)_localctx).op = match(BITAND); - setState(1324); + setState(1322); nls(); - setState(1325); + setState(1323); ((AndExprAltContext)_localctx).right = expression(9); } break; @@ -9063,15 +9004,15 @@ private ExpressionContext expression(int _p) throws RecognitionException { _localctx = new ExclusiveOrExprAltContext(new ExpressionContext(_parentctx, _parentState)); ((ExclusiveOrExprAltContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_expression); - setState(1327); + setState(1325); if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)"); - setState(1328); + setState(1326); nls(); - setState(1329); + setState(1327); ((ExclusiveOrExprAltContext)_localctx).op = match(XOR); - setState(1330); + setState(1328); nls(); - setState(1331); + setState(1329); ((ExclusiveOrExprAltContext)_localctx).right = expression(8); } break; @@ -9081,15 +9022,15 @@ private ExpressionContext expression(int _p) throws RecognitionException { _localctx = new InclusiveOrExprAltContext(new ExpressionContext(_parentctx, _parentState)); ((InclusiveOrExprAltContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_expression); - setState(1333); + setState(1331); if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)"); - setState(1334); + setState(1332); nls(); - setState(1335); + setState(1333); ((InclusiveOrExprAltContext)_localctx).op = match(BITOR); - setState(1336); + setState(1334); nls(); - setState(1337); + setState(1335); ((InclusiveOrExprAltContext)_localctx).right = expression(7); } break; @@ -9099,15 +9040,15 @@ private ExpressionContext expression(int _p) throws RecognitionException { _localctx = new LogicalAndExprAltContext(new ExpressionContext(_parentctx, _parentState)); ((LogicalAndExprAltContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_expression); - setState(1339); + setState(1337); if (!(precpred(_ctx, 5))) throw new FailedPredicateException(this, "precpred(_ctx, 5)"); - setState(1340); + setState(1338); nls(); - setState(1341); + setState(1339); ((LogicalAndExprAltContext)_localctx).op = match(AND); - setState(1342); + setState(1340); nls(); - setState(1343); + setState(1341); ((LogicalAndExprAltContext)_localctx).right = expression(6); } break; @@ -9117,15 +9058,15 @@ private ExpressionContext expression(int _p) throws RecognitionException { _localctx = new LogicalOrExprAltContext(new ExpressionContext(_parentctx, _parentState)); ((LogicalOrExprAltContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_expression); - setState(1345); + setState(1343); if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)"); - setState(1346); + setState(1344); nls(); - setState(1347); + setState(1345); ((LogicalOrExprAltContext)_localctx).op = match(OR); - setState(1348); + setState(1346); nls(); - setState(1349); + setState(1347); ((LogicalOrExprAltContext)_localctx).right = expression(5); } break; @@ -9135,41 +9076,41 @@ private ExpressionContext expression(int _p) throws RecognitionException { _localctx = new ConditionalExprAltContext(new ExpressionContext(_parentctx, _parentState)); ((ConditionalExprAltContext)_localctx).con = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_expression); - setState(1351); + setState(1349); if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)"); - setState(1352); + setState(1350); nls(); - setState(1362); + setState(1360); _errHandler.sync(this); switch (_input.LA(1)) { case QUESTION: { - setState(1353); + setState(1351); match(QUESTION); - setState(1354); + setState(1352); nls(); - setState(1355); + setState(1353); ((ConditionalExprAltContext)_localctx).tb = expression(0); - setState(1356); + setState(1354); nls(); - setState(1357); + setState(1355); match(COLON); - setState(1358); + setState(1356); nls(); } break; case ELVIS: { - setState(1360); + setState(1358); match(ELVIS); - setState(1361); + setState(1359); nls(); } break; default: throw new NoViableAltException(this); } - setState(1364); + setState(1362); ((ConditionalExprAltContext)_localctx).fb = expression(3); } break; @@ -9179,11 +9120,11 @@ private ExpressionContext expression(int _p) throws RecognitionException { _localctx = new RelationalExprAltContext(new ExpressionContext(_parentctx, _parentState)); ((RelationalExprAltContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_expression); - setState(1366); + setState(1364); if (!(precpred(_ctx, 12))) throw new FailedPredicateException(this, "precpred(_ctx, 12)"); - setState(1367); + setState(1365); nls(); - setState(1368); + setState(1366); ((RelationalExprAltContext)_localctx).op = _input.LT(1); _la = _input.LA(1); if ( !(_la==AS || _la==INSTANCEOF || _la==NOT_INSTANCEOF) ) { @@ -9196,9 +9137,9 @@ private ExpressionContext expression(int _p) throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(1369); + setState(1367); nls(); - setState(1370); + setState(1368); type(); } break; @@ -9208,11 +9149,11 @@ private ExpressionContext expression(int _p) throws RecognitionException { _localctx = new AssignmentExprAltContext(new ExpressionContext(_parentctx, _parentState)); ((AssignmentExprAltContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_expression); - setState(1372); + setState(1370); if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); - setState(1373); + setState(1371); nls(); - setState(1374); + setState(1372); ((AssignmentExprAltContext)_localctx).op = _input.LT(1); _la = _input.LA(1); if ( !(((((_la - 71)) & ~0x3f) == 0 && ((1L << (_la - 71)) & ((1L << (POWER_ASSIGN - 71)) | (1L << (ASSIGN - 71)) | (1L << (ADD_ASSIGN - 71)) | (1L << (SUB_ASSIGN - 71)) | (1L << (MUL_ASSIGN - 71)) | (1L << (DIV_ASSIGN - 71)) | (1L << (AND_ASSIGN - 71)) | (1L << (OR_ASSIGN - 71)) | (1L << (XOR_ASSIGN - 71)) | (1L << (MOD_ASSIGN - 71)) | (1L << (LSHIFT_ASSIGN - 71)) | (1L << (RSHIFT_ASSIGN - 71)) | (1L << (URSHIFT_ASSIGN - 71)) | (1L << (ELVIS_ASSIGN - 71)))) != 0)) ) { @@ -9225,18 +9166,18 @@ private ExpressionContext expression(int _p) throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(1375); + setState(1373); nls(); - setState(1376); + setState(1374); enhancedStatementExpression(); } break; } } } - setState(1382); + setState(1380); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,144,_ctx); + _alt = getInterpreter().adaptivePredict(_input,143,_ctx); } } } @@ -9252,9 +9193,9 @@ private ExpressionContext expression(int _p) throws RecognitionException { } public static class CommandExpressionContext extends GroovyParserRuleContext { - public PathExpressionContext pathExpression; - public PathExpressionContext pathExpression() { - return getRuleContext(PathExpressionContext.class,0); + public ExpressionContext expression; + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); } public EnhancedArgumentListContext enhancedArgumentList() { return getRuleContext(EnhancedArgumentListContext.class,0); @@ -9284,16 +9225,16 @@ public final CommandExpressionContext commandExpression() throws RecognitionExce int _alt; enterOuterAlt(_localctx, 1); { - setState(1383); - _localctx.pathExpression = pathExpression(); - setState(1387); + setState(1381); + _localctx.expression = expression(0); + setState(1385); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,145,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,144,_ctx) ) { case 1: { - setState(1384); - if (!( SemanticPredicates.isFollowingMethodName(_localctx.pathExpression.t) )) throw new FailedPredicateException(this, " SemanticPredicates.isFollowingMethodName($pathExpression.t) "); - setState(1385); + setState(1382); + if (!( !SemanticPredicates.isFollowingArgumentsOrClosure(_localctx.expression) )) throw new FailedPredicateException(this, " !SemanticPredicates.isFollowingArgumentsOrClosure($expression.ctx) "); + setState(1383); argumentList(); } break; @@ -9303,21 +9244,21 @@ public final CommandExpressionContext commandExpression() throws RecognitionExce } break; } - setState(1392); + setState(1390); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,146,_ctx); + _alt = getInterpreter().adaptivePredict(_input,145,_ctx); while ( _alt!=2 && _alt!=groovyjarjarantlr4.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(1389); + setState(1387); commandArgument(); } } } - setState(1394); + setState(1392); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,146,_ctx); + _alt = getInterpreter().adaptivePredict(_input,145,_ctx); } } } @@ -9364,14 +9305,14 @@ public final CommandArgumentContext commandArgument() throws RecognitionExceptio int _alt; enterOuterAlt(_localctx, 1); { - setState(1395); + setState(1393); primary(); - setState(1402); + setState(1400); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,148,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,147,_ctx) ) { case 1: { - setState(1397); + setState(1395); _errHandler.sync(this); _alt = 1; do { @@ -9379,7 +9320,7 @@ public final CommandArgumentContext commandArgument() throws RecognitionExceptio case 1: { { - setState(1396); + setState(1394); pathElement(); } } @@ -9387,16 +9328,16 @@ public final CommandArgumentContext commandArgument() throws RecognitionExceptio default: throw new NoViableAltException(this); } - setState(1399); + setState(1397); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,147,_ctx); + _alt = getInterpreter().adaptivePredict(_input,146,_ctx); } while ( _alt!=2 && _alt!=groovyjarjarantlr4.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); } break; case 2: { - setState(1401); + setState(1399); argumentList(); } break; @@ -9445,24 +9386,24 @@ public final PathExpressionContext pathExpression() throws RecognitionException int _alt; enterOuterAlt(_localctx, 1); { - setState(1404); + setState(1402); primary(); - setState(1410); + setState(1408); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,149,_ctx); + _alt = getInterpreter().adaptivePredict(_input,148,_ctx); while ( _alt!=2 && _alt!=groovyjarjarantlr4.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(1405); + setState(1403); _localctx.pathElement = pathElement(); _localctx.t = _localctx.pathElement.t; } } } - setState(1412); + setState(1410); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,149,_ctx); + _alt = getInterpreter().adaptivePredict(_input,148,_ctx); } } } @@ -9531,15 +9472,15 @@ public final PathElementContext pathElement() throws RecognitionException { enterRule(_localctx, 236, RULE_pathElement); int _la; try { - setState(1448); + setState(1447); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,152,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,151,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(1413); + setState(1411); nls(); - setState(1424); + setState(1422); _errHandler.sync(this); switch (_input.LA(1)) { case SPREAD_DOT: @@ -9547,7 +9488,7 @@ public final PathElementContext pathElement() throws RecognitionException { case SAFE_CHAIN_DOT: case DOT: { - setState(1414); + setState(1412); _la = _input.LA(1); if ( !(((((_la - 62)) & ~0x3f) == 0 && ((1L << (_la - 62)) & ((1L << (SPREAD_DOT - 62)) | (1L << (SAFE_DOT - 62)) | (1L << (SAFE_CHAIN_DOT - 62)) | (1L << (DOT - 62)))) != 0)) ) { _errHandler.recoverInline(this); @@ -9559,21 +9500,21 @@ public final PathElementContext pathElement() throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(1415); + setState(1413); nls(); - setState(1418); + setState(1416); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,150,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,149,_ctx) ) { case 1: { - setState(1416); + setState(1414); match(AT); } break; case 2: { - setState(1417); + setState(1415); nonWildcardTypeArguments(); } break; @@ -9582,24 +9523,24 @@ public final PathElementContext pathElement() throws RecognitionException { break; case METHOD_POINTER: { - setState(1420); + setState(1418); match(METHOD_POINTER); - setState(1421); + setState(1419); nls(); } break; case METHOD_REFERENCE: { - setState(1422); + setState(1420); match(METHOD_REFERENCE); - setState(1423); + setState(1421); nls(); } break; default: throw new NoViableAltException(this); } - setState(1426); + setState(1424); namePart(); _localctx.t = 1; } @@ -9608,13 +9549,15 @@ public final PathElementContext pathElement() throws RecognitionException { case 2: enterOuterAlt(_localctx, 2); { - setState(1429); + setState(1427); + nls(); + setState(1428); match(DOT); - setState(1430); + setState(1429); nls(); - setState(1431); + setState(1430); match(NEW); - setState(1432); + setState(1431); creator(1); _localctx.t = 6; } @@ -9623,7 +9566,7 @@ public final PathElementContext pathElement() throws RecognitionException { case 3: enterOuterAlt(_localctx, 3); { - setState(1435); + setState(1434); arguments(); _localctx.t = 2; } @@ -9632,9 +9575,9 @@ public final PathElementContext pathElement() throws RecognitionException { case 4: enterOuterAlt(_localctx, 4); { - setState(1438); + setState(1437); nls(); - setState(1439); + setState(1438); closure(); _localctx.t = 3; } @@ -9643,7 +9586,7 @@ public final PathElementContext pathElement() throws RecognitionException { case 5: enterOuterAlt(_localctx, 5); { - setState(1442); + setState(1441); indexPropertyArgs(); _localctx.t = 4; } @@ -9652,7 +9595,7 @@ public final PathElementContext pathElement() throws RecognitionException { case 6: enterOuterAlt(_localctx, 6); { - setState(1445); + setState(1444); namedPropertyArgs(); _localctx.t = 5; } @@ -9701,33 +9644,33 @@ public final NamePartContext namePart() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(1454); + setState(1453); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,153,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,152,_ctx) ) { case 1: { - setState(1450); + setState(1449); identifier(); } break; case 2: { - setState(1451); + setState(1450); stringLiteral(); } break; case 3: { - setState(1452); + setState(1451); dynamicMemberName(); } break; case 4: { - setState(1453); + setState(1452); keywords(); } break; @@ -9768,20 +9711,20 @@ public final DynamicMemberNameContext dynamicMemberName() throws RecognitionExce DynamicMemberNameContext _localctx = new DynamicMemberNameContext(_ctx, getState()); enterRule(_localctx, 240, RULE_dynamicMemberName); try { - setState(1458); + setState(1457); _errHandler.sync(this); switch (_input.LA(1)) { case LPAREN: enterOuterAlt(_localctx, 1); { - setState(1456); + setState(1455); parExpression(); } break; case GStringBegin: enterOuterAlt(_localctx, 2); { - setState(1457); + setState(1456); gstring(); } break; @@ -9826,29 +9769,29 @@ public final IndexPropertyArgsContext indexPropertyArgs() throws RecognitionExce try { enterOuterAlt(_localctx, 1); { - setState(1461); + setState(1460); _errHandler.sync(this); _la = _input.LA(1); if (_la==QUESTION) { { - setState(1460); + setState(1459); match(QUESTION); } } - setState(1463); + setState(1462); match(LBRACK); - setState(1465); + setState(1464); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,156,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,155,_ctx) ) { case 1: { - setState(1464); + setState(1463); expressionList(true); } break; } - setState(1467); + setState(1466); match(RBRACK); } } @@ -9865,10 +9808,12 @@ public final IndexPropertyArgsContext indexPropertyArgs() throws RecognitionExce public static class NamedPropertyArgsContext extends GroovyParserRuleContext { public TerminalNode LBRACK() { return getToken(GroovyParser.LBRACK, 0); } + public TerminalNode RBRACK() { return getToken(GroovyParser.RBRACK, 0); } public MapEntryListContext mapEntryList() { return getRuleContext(MapEntryListContext.class,0); } - public TerminalNode RBRACK() { return getToken(GroovyParser.RBRACK, 0); } + public TerminalNode COLON() { return getToken(GroovyParser.COLON, 0); } + public TerminalNode QUESTION() { return getToken(GroovyParser.QUESTION, 0); } public NamedPropertyArgsContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } @@ -9884,14 +9829,40 @@ public Result accept(ParseTreeVisitor visitor) { public final NamedPropertyArgsContext namedPropertyArgs() throws RecognitionException { NamedPropertyArgsContext _localctx = new NamedPropertyArgsContext(_ctx, getState()); enterRule(_localctx, 244, RULE_namedPropertyArgs); + int _la; try { enterOuterAlt(_localctx, 1); { setState(1469); - match(LBRACK); - setState(1470); - mapEntryList(); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==QUESTION) { + { + setState(1468); + match(QUESTION); + } + } + setState(1471); + match(LBRACK); + setState(1474); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,157,_ctx) ) { + case 1: + { + setState(1472); + mapEntryList(); + } + break; + + case 2: + { + setState(1473); + match(COLON); + } + break; + } + setState(1476); match(RBRACK); } } @@ -10058,21 +10029,21 @@ public final PrimaryContext primary() throws RecognitionException { PrimaryContext _localctx = new PrimaryContext(_ctx, getState()); enterRule(_localctx, 246, RULE_primary); try { - setState(1491); + setState(1496); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,158,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,159,_ctx) ) { case 1: _localctx = new IdentifierPrmrAltContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(1473); + setState(1478); identifier(); - setState(1475); + setState(1480); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,157,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,158,_ctx) ) { case 1: { - setState(1474); + setState(1479); typeArguments(); } break; @@ -10084,7 +10055,7 @@ public final PrimaryContext primary() throws RecognitionException { _localctx = new LiteralPrmrAltContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(1477); + setState(1482); literal(); } break; @@ -10093,7 +10064,7 @@ public final PrimaryContext primary() throws RecognitionException { _localctx = new GstringPrmrAltContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(1478); + setState(1483); gstring(); } break; @@ -10102,11 +10073,11 @@ public final PrimaryContext primary() throws RecognitionException { _localctx = new NewPrmrAltContext(_localctx); enterOuterAlt(_localctx, 4); { - setState(1479); + setState(1484); match(NEW); - setState(1480); + setState(1485); nls(); - setState(1481); + setState(1486); creator(0); } break; @@ -10115,7 +10086,7 @@ public final PrimaryContext primary() throws RecognitionException { _localctx = new ThisPrmrAltContext(_localctx); enterOuterAlt(_localctx, 5); { - setState(1483); + setState(1488); match(THIS); } break; @@ -10124,7 +10095,7 @@ public final PrimaryContext primary() throws RecognitionException { _localctx = new SuperPrmrAltContext(_localctx); enterOuterAlt(_localctx, 6); { - setState(1484); + setState(1489); match(SUPER); } break; @@ -10133,7 +10104,7 @@ public final PrimaryContext primary() throws RecognitionException { _localctx = new ParenPrmrAltContext(_localctx); enterOuterAlt(_localctx, 7); { - setState(1485); + setState(1490); parExpression(); } break; @@ -10142,7 +10113,7 @@ public final PrimaryContext primary() throws RecognitionException { _localctx = new ClosurePrmrAltContext(_localctx); enterOuterAlt(_localctx, 8); { - setState(1486); + setState(1491); closure(); } break; @@ -10151,7 +10122,7 @@ public final PrimaryContext primary() throws RecognitionException { _localctx = new LambdaPrmrAltContext(_localctx); enterOuterAlt(_localctx, 9); { - setState(1487); + setState(1492); lambdaExpression(); } break; @@ -10160,7 +10131,7 @@ public final PrimaryContext primary() throws RecognitionException { _localctx = new ListPrmrAltContext(_localctx); enterOuterAlt(_localctx, 10); { - setState(1488); + setState(1493); list(); } break; @@ -10169,7 +10140,7 @@ public final PrimaryContext primary() throws RecognitionException { _localctx = new MapPrmrAltContext(_localctx); enterOuterAlt(_localctx, 11); { - setState(1489); + setState(1494); map(); } break; @@ -10178,7 +10149,7 @@ public final PrimaryContext primary() throws RecognitionException { _localctx = new BuiltInTypePrmrAltContext(_localctx); enterOuterAlt(_localctx, 12); { - setState(1490); + setState(1495); builtInType(); } break; @@ -10221,29 +10192,29 @@ public final ListContext list() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(1493); + setState(1498); match(LBRACK); - setState(1495); + setState(1500); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,159,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,160,_ctx) ) { case 1: { - setState(1494); + setState(1499); expressionList(true); } break; } - setState(1498); + setState(1503); _errHandler.sync(this); _la = _input.LA(1); if (_la==COMMA) { { - setState(1497); + setState(1502); match(COMMA); } } - setState(1500); + setState(1505); match(RBRACK); } } @@ -10285,21 +10256,21 @@ public final MapContext map() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(1502); + setState(1507); match(LBRACK); - setState(1508); + setState(1513); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,162,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,163,_ctx) ) { case 1: { - setState(1503); + setState(1508); mapEntryList(); - setState(1505); + setState(1510); _errHandler.sync(this); _la = _input.LA(1); if (_la==COMMA) { { - setState(1504); + setState(1509); match(COMMA); } } @@ -10309,12 +10280,12 @@ public final MapContext map() throws RecognitionException { case 2: { - setState(1507); + setState(1512); match(COLON); } break; } - setState(1510); + setState(1515); match(RBRACK); } } @@ -10359,25 +10330,25 @@ public final MapEntryListContext mapEntryList() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(1512); - mapEntry(); setState(1517); + mapEntry(); + setState(1522); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,163,_ctx); + _alt = getInterpreter().adaptivePredict(_input,164,_ctx); while ( _alt!=2 && _alt!=groovyjarjarantlr4.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(1513); + setState(1518); match(COMMA); - setState(1514); + setState(1519); mapEntry(); } } } - setState(1519); + setState(1524); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,163,_ctx); + _alt = getInterpreter().adaptivePredict(_input,164,_ctx); } } } @@ -10420,19 +10391,19 @@ public final MapEntryContext mapEntry() throws RecognitionException { MapEntryContext _localctx = new MapEntryContext(_ctx, getState()); enterRule(_localctx, 254, RULE_mapEntry); try { - setState(1530); + setState(1535); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,164,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,165,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(1520); + setState(1525); mapEntryLabel(); - setState(1521); + setState(1526); match(COLON); - setState(1522); + setState(1527); nls(); - setState(1523); + setState(1528); expression(0); } break; @@ -10440,13 +10411,13 @@ public final MapEntryContext mapEntry() throws RecognitionException { case 2: enterOuterAlt(_localctx, 2); { - setState(1525); + setState(1530); match(MUL); - setState(1526); + setState(1531); match(COLON); - setState(1527); + setState(1532); nls(); - setState(1528); + setState(1533); expression(0); } break; @@ -10486,13 +10457,13 @@ public final MapEntryLabelContext mapEntryLabel() throws RecognitionException { MapEntryLabelContext _localctx = new MapEntryLabelContext(_ctx, getState()); enterRule(_localctx, 256, RULE_mapEntryLabel); try { - setState(1534); + setState(1539); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,165,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,166,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(1532); + setState(1537); keywords(); } break; @@ -10500,7 +10471,7 @@ public final MapEntryLabelContext mapEntryLabel() throws RecognitionException { case 2: enterOuterAlt(_localctx, 2); { - setState(1533); + setState(1538); primary(); } break; @@ -10581,25 +10552,25 @@ public final CreatorContext creator(int t) throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(1536); + setState(1541); createdName(); - setState(1560); + setState(1565); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,168,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,169,_ctx) ) { case 1: { - setState(1537); + setState(1542); if (!(0 == _localctx.t || 1 == _localctx.t)) throw new FailedPredicateException(this, "0 == $t || 1 == $t"); - setState(1538); + setState(1543); nls(); - setState(1539); + setState(1544); arguments(); - setState(1541); + setState(1546); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,166,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,167,_ctx) ) { case 1: { - setState(1540); + setState(1545); anonymousInnerClassDeclaration(0); } break; @@ -10609,9 +10580,9 @@ public final CreatorContext creator(int t) throws RecognitionException { case 2: { - setState(1543); + setState(1548); if (!(0 == _localctx.t)) throw new FailedPredicateException(this, "0 == $t"); - setState(1549); + setState(1554); _errHandler.sync(this); _alt = 1; do { @@ -10619,13 +10590,13 @@ public final CreatorContext creator(int t) throws RecognitionException { case 1: { { - setState(1544); + setState(1549); annotationsOpt(); - setState(1545); + setState(1550); match(LBRACK); - setState(1546); + setState(1551); expression(0); - setState(1547); + setState(1552); match(RBRACK); } } @@ -10633,24 +10604,24 @@ public final CreatorContext creator(int t) throws RecognitionException { default: throw new NoViableAltException(this); } - setState(1551); + setState(1556); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,167,_ctx); + _alt = getInterpreter().adaptivePredict(_input,168,_ctx); } while ( _alt!=2 && _alt!=groovyjarjarantlr4.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); - setState(1553); + setState(1558); dimsOpt(); } break; case 3: { - setState(1555); + setState(1560); if (!(0 == _localctx.t)) throw new FailedPredicateException(this, "0 == $t"); - setState(1556); + setState(1561); dims(); - setState(1557); + setState(1562); nls(); - setState(1558); + setState(1563); arrayInitializer(); } break; @@ -10698,23 +10669,23 @@ public final ArrayInitializerContext arrayInitializer() throws RecognitionExcept try { enterOuterAlt(_localctx, 1); { - setState(1562); + setState(1567); match(LBRACE); - setState(1563); + setState(1568); nls(); - setState(1565); + setState(1570); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,169,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,170,_ctx) ) { case 1: { - setState(1564); + setState(1569); variableInitializers(); } break; } - setState(1567); + setState(1572); nls(); - setState(1568); + setState(1573); match(RBRACE); } } @@ -10754,7 +10725,7 @@ public final AnonymousInnerClassDeclarationContext anonymousInnerClassDeclaratio try { enterOuterAlt(_localctx, 1); { - setState(1570); + setState(1575); classBody(0); } } @@ -10800,28 +10771,28 @@ public final CreatedNameContext createdName() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(1572); + setState(1577); annotationsOpt(); - setState(1578); + setState(1583); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,171,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,172,_ctx) ) { case 1: { - setState(1573); + setState(1578); primitiveType(); } break; case 2: { - setState(1574); + setState(1579); qualifiedClassName(); - setState(1576); + setState(1581); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,170,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,171,_ctx) ) { case 1: { - setState(1575); + setState(1580); typeArgumentsOrDiamond(); } break; @@ -10872,15 +10843,15 @@ public final NonWildcardTypeArgumentsContext nonWildcardTypeArguments() throws R try { enterOuterAlt(_localctx, 1); { - setState(1580); + setState(1585); match(LT); - setState(1581); + setState(1586); nls(); - setState(1582); + setState(1587); typeList(); - setState(1583); + setState(1588); nls(); - setState(1584); + setState(1589); match(GT); } } @@ -10917,15 +10888,15 @@ public final TypeArgumentsOrDiamondContext typeArgumentsOrDiamond() throws Recog TypeArgumentsOrDiamondContext _localctx = new TypeArgumentsOrDiamondContext(_ctx, getState()); enterRule(_localctx, 268, RULE_typeArgumentsOrDiamond); try { - setState(1589); + setState(1594); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,172,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,173,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(1586); + setState(1591); match(LT); - setState(1587); + setState(1592); match(GT); } break; @@ -10933,7 +10904,7 @@ public final TypeArgumentsOrDiamondContext typeArgumentsOrDiamond() throws Recog case 2: enterOuterAlt(_localctx, 2); { - setState(1588); + setState(1593); typeArguments(); } break; @@ -10977,29 +10948,29 @@ public final ArgumentsContext arguments() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(1591); + setState(1596); match(LPAREN); - setState(1593); + setState(1598); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,173,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,174,_ctx) ) { case 1: { - setState(1592); + setState(1597); enhancedArgumentList(); } break; } - setState(1596); + setState(1601); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,174,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,175,_ctx) ) { case 1: { - setState(1595); + setState(1600); match(COMMA); } break; } - setState(1598); + setState(1603); rparen(); } } @@ -11023,27 +10994,27 @@ public final EnhancedArgumentListContext argumentList() throws RecognitionExcept int _alt; enterOuterAlt(_localctx, 1); { - setState(1600); + setState(1605); argumentListElement(); - setState(1607); + setState(1612); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,175,_ctx); + _alt = getInterpreter().adaptivePredict(_input,176,_ctx); while ( _alt!=2 && _alt!=groovyjarjarantlr4.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(1601); + setState(1606); match(COMMA); - setState(1602); + setState(1607); nls(); - setState(1603); + setState(1608); argumentListElement(); } } } - setState(1609); + setState(1614); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,175,_ctx); + _alt = getInterpreter().adaptivePredict(_input,176,_ctx); } } } @@ -11094,27 +11065,27 @@ public final EnhancedArgumentListContext enhancedArgumentList() throws Recogniti int _alt; enterOuterAlt(_localctx, 1); { - setState(1610); + setState(1615); enhancedArgumentListElement(); - setState(1617); + setState(1622); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,176,_ctx); + _alt = getInterpreter().adaptivePredict(_input,177,_ctx); while ( _alt!=2 && _alt!=groovyjarjarantlr4.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(1611); + setState(1616); match(COMMA); - setState(1612); + setState(1617); nls(); - setState(1613); + setState(1618); enhancedArgumentListElement(); } } } - setState(1619); + setState(1624); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,176,_ctx); + _alt = getInterpreter().adaptivePredict(_input,177,_ctx); } } } @@ -11135,13 +11106,13 @@ public final EnhancedArgumentListElementContext argumentListElement() throws Rec EnhancedArgumentListElementContext _localctx = new EnhancedArgumentListElementContext(_ctx, getState()); enterRule(_localctx, 276, RULE_argumentListElement); try { - setState(1622); + setState(1627); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,177,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,178,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(1620); + setState(1625); expressionListElement(true); } break; @@ -11149,7 +11120,7 @@ public final EnhancedArgumentListElementContext argumentListElement() throws Rec case 2: enterOuterAlt(_localctx, 2); { - setState(1621); + setState(1626); mapEntry(); } break; @@ -11192,13 +11163,13 @@ public final EnhancedArgumentListElementContext enhancedArgumentListElement() th EnhancedArgumentListElementContext _localctx = new EnhancedArgumentListElementContext(_ctx, getState()); enterRule(_localctx, 278, RULE_enhancedArgumentListElement); try { - setState(1627); + setState(1632); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,178,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,179,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(1624); + setState(1629); expressionListElement(true); } break; @@ -11206,7 +11177,7 @@ public final EnhancedArgumentListElementContext enhancedArgumentListElement() th case 2: enterOuterAlt(_localctx, 2); { - setState(1625); + setState(1630); standardLambdaExpression(); } break; @@ -11214,7 +11185,7 @@ public final EnhancedArgumentListElementContext enhancedArgumentListElement() th case 3: enterOuterAlt(_localctx, 3); { - setState(1626); + setState(1631); mapEntry(); } break; @@ -11251,7 +11222,7 @@ public final StringLiteralContext stringLiteral() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(1629); + setState(1634); match(StringLiteral); } } @@ -11286,7 +11257,7 @@ public final ClassNameContext className() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(1631); + setState(1636); match(CapitalizedIdentifier); } } @@ -11306,6 +11277,9 @@ public static class IdentifierContext extends GroovyParserRuleContext { public TerminalNode CapitalizedIdentifier() { return getToken(GroovyParser.CapitalizedIdentifier, 0); } public TerminalNode VAR() { return getToken(GroovyParser.VAR, 0); } public TerminalNode STATIC() { return getToken(GroovyParser.STATIC, 0); } + public TerminalNode IN() { return getToken(GroovyParser.IN, 0); } + public TerminalNode TRAIT() { return getToken(GroovyParser.TRAIT, 0); } + public TerminalNode AS() { return getToken(GroovyParser.AS, 0); } public IdentifierContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } @@ -11322,13 +11296,13 @@ public final IdentifierContext identifier() throws RecognitionException { IdentifierContext _localctx = new IdentifierContext(_ctx, getState()); enterRule(_localctx, 284, RULE_identifier); try { - setState(1638); + setState(1646); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,179,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,180,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(1633); + setState(1638); match(Identifier); } break; @@ -11336,7 +11310,7 @@ public final IdentifierContext identifier() throws RecognitionException { case 2: enterOuterAlt(_localctx, 2); { - setState(1634); + setState(1639); match(CapitalizedIdentifier); } break; @@ -11344,7 +11318,7 @@ public final IdentifierContext identifier() throws RecognitionException { case 3: enterOuterAlt(_localctx, 3); { - setState(1635); + setState(1640); match(VAR); } break; @@ -11352,12 +11326,36 @@ public final IdentifierContext identifier() throws RecognitionException { case 4: enterOuterAlt(_localctx, 4); { - setState(1636); + setState(1641); if (!( DOT == _input.LT(2).getType() )) throw new FailedPredicateException(this, " DOT == _input.LT(2).getType() "); - setState(1637); + setState(1642); match(STATIC); } break; + + case 5: + enterOuterAlt(_localctx, 5); + { + setState(1643); + match(IN); + } + break; + + case 6: + enterOuterAlt(_localctx, 6); + { + setState(1644); + match(TRAIT); + } + break; + + case 7: + enterOuterAlt(_localctx, 7); + { + setState(1645); + match(AS); + } + break; } } catch (RecognitionException re) { @@ -11393,7 +11391,7 @@ public final BuiltInTypeContext builtInType() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(1640); + setState(1648); _la = _input.LA(1); if ( !(_la==BuiltInPrimitiveType || _la==VOID) ) { _errHandler.recoverInline(this); @@ -11489,7 +11487,7 @@ public final KeywordsContext keywords() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(1642); + setState(1650); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << AS) | (1L << DEF) | (1L << IN) | (1L << TRAIT) | (1L << THREADSAFE) | (1L << VAR) | (1L << BuiltInPrimitiveType) | (1L << ABSTRACT) | (1L << ASSERT) | (1L << BREAK) | (1L << CASE) | (1L << CATCH) | (1L << CLASS) | (1L << CONST) | (1L << CONTINUE) | (1L << DEFAULT) | (1L << DO) | (1L << ELSE) | (1L << ENUM) | (1L << EXTENDS) | (1L << FINAL) | (1L << FINALLY) | (1L << FOR) | (1L << IF) | (1L << GOTO) | (1L << IMPLEMENTS) | (1L << IMPORT) | (1L << INSTANCEOF) | (1L << INTERFACE) | (1L << NATIVE) | (1L << NEW) | (1L << PACKAGE) | (1L << PRIVATE) | (1L << PROTECTED) | (1L << PUBLIC) | (1L << RETURN) | (1L << STATIC) | (1L << STRICTFP) | (1L << SUPER) | (1L << SWITCH) | (1L << SYNCHRONIZED) | (1L << THIS) | (1L << THROW) | (1L << THROWS) | (1L << TRANSIENT) | (1L << TRY) | (1L << VOID) | (1L << VOLATILE) | (1L << WHILE) | (1L << BooleanLiteral) | (1L << NullLiteral))) != 0)) ) { _errHandler.recoverInline(this); @@ -11532,13 +11530,13 @@ public final RparenContext rparen() throws RecognitionException { RparenContext _localctx = new RparenContext(_ctx, getState()); enterRule(_localctx, 290, RULE_rparen); try { - setState(1646); + setState(1654); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,180,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,181,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(1644); + setState(1652); match(RPAREN); } break; @@ -11586,21 +11584,21 @@ public final NlsContext nls() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(1651); + setState(1659); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,181,_ctx); + _alt = getInterpreter().adaptivePredict(_input,182,_ctx); while ( _alt!=2 && _alt!=groovyjarjarantlr4.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(1648); + setState(1656); match(NL); } } } - setState(1653); + setState(1661); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,181,_ctx); + _alt = getInterpreter().adaptivePredict(_input,182,_ctx); } } } @@ -11644,7 +11642,7 @@ public final SepContext sep() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(1655); + setState(1663); _errHandler.sync(this); _alt = 1; do { @@ -11652,7 +11650,7 @@ public final SepContext sep() throws RecognitionException { case 1: { { - setState(1654); + setState(1662); _la = _input.LA(1); if ( !(_la==SEMI || _la==NL) ) { _errHandler.recoverInline(this); @@ -11670,9 +11668,9 @@ public final SepContext sep() throws RecognitionException { default: throw new NoViableAltException(this); } - setState(1657); + setState(1665); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,182,_ctx); + _alt = getInterpreter().adaptivePredict(_input,183,_ctx); } while ( _alt!=2 && _alt!=groovyjarjarantlr4.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); } } @@ -11837,7 +11835,7 @@ private boolean expression_sempred(ExpressionContext _localctx, int predIndex) { private boolean commandExpression_sempred(CommandExpressionContext _localctx, int predIndex) { switch (predIndex) { case 26: - return SemanticPredicates.isFollowingMethodName(_localctx.pathExpression.t) ; + return !SemanticPredicates.isFollowingArgumentsOrClosure(_localctx.expression) ; } return true; } @@ -11863,7 +11861,7 @@ private boolean identifier_sempred(IdentifierContext _localctx, int predIndex) { } public static final String _serializedATN = - "\3\uc91d\ucaba\u058d\uafba\u4f53\u0607\uea8b\uc241\3\u0083\u067e\4\2\t"+ + "\3\uc91d\ucaba\u058d\uafba\u4f53\u0607\uea8b\uc241\3\u0083\u0686\4\2\t"+ "\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+ "\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ @@ -11947,341 +11945,342 @@ private boolean identifier_sempred(IdentifierContext _localctx, int predIndex) { "f\3f\3f\5f\u04a2\nf\3g\3g\5g\u04a6\ng\3h\3h\5h\u04aa\nh\3h\3h\3h\3h\3"+ "i\5i\u04b1\ni\3i\3i\5i\u04b5\ni\3i\3i\5i\u04b9\ni\3j\3j\5j\u04bd\nj\3"+ "k\3k\3l\3l\3l\3l\3m\3m\3n\3n\3n\3n\3o\3o\3o\7o\u04ce\no\fo\16o\u04d1\13"+ - "o\3p\3p\3p\5p\u04d6\np\3p\3p\3q\3q\5q\u04dc\nq\3r\3r\5r\u04e0\nr\3s\3"+ - "s\5s\u04e4\ns\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\5t\u04f7"+ - "\nt\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t"+ - "\3t\3t\3t\5t\u0512\nt\3t\5t\u0515\nt\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t"+ - "\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t"+ - "\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t"+ - "\3t\3t\3t\3t\3t\5t\u0555\nt\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t"+ - "\7t\u0565\nt\ft\16t\u0568\13t\3u\3u\3u\3u\5u\u056e\nu\3u\7u\u0571\nu\f"+ - "u\16u\u0574\13u\3v\3v\6v\u0578\nv\rv\16v\u0579\3v\5v\u057d\nv\3w\3w\3"+ - "w\3w\7w\u0583\nw\fw\16w\u0586\13w\3x\3x\3x\3x\3x\5x\u058d\nx\3x\3x\3x"+ - "\3x\5x\u0593\nx\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x"+ - "\3x\3x\3x\3x\5x\u05ab\nx\3y\3y\3y\3y\5y\u05b1\ny\3z\3z\5z\u05b5\nz\3{"+ - "\5{\u05b8\n{\3{\3{\5{\u05bc\n{\3{\3{\3|\3|\3|\3|\3}\3}\5}\u05c6\n}\3}"+ - "\3}\3}\3}\3}\3}\3}\3}\3}\3}\3}\3}\3}\3}\5}\u05d6\n}\3~\3~\5~\u05da\n~"+ - "\3~\5~\u05dd\n~\3~\3~\3\177\3\177\3\177\5\177\u05e4\n\177\3\177\5\177"+ - "\u05e7\n\177\3\177\3\177\3\u0080\3\u0080\3\u0080\7\u0080\u05ee\n\u0080"+ - "\f\u0080\16\u0080\u05f1\13\u0080\3\u0081\3\u0081\3\u0081\3\u0081\3\u0081"+ - "\3\u0081\3\u0081\3\u0081\3\u0081\3\u0081\5\u0081\u05fd\n\u0081\3\u0082"+ - "\3\u0082\5\u0082\u0601\n\u0082\3\u0083\3\u0083\3\u0083\3\u0083\3\u0083"+ - "\5\u0083\u0608\n\u0083\3\u0083\3\u0083\3\u0083\3\u0083\3\u0083\3\u0083"+ - "\6\u0083\u0610\n\u0083\r\u0083\16\u0083\u0611\3\u0083\3\u0083\3\u0083"+ - "\3\u0083\3\u0083\3\u0083\3\u0083\5\u0083\u061b\n\u0083\3\u0084\3\u0084"+ - "\3\u0084\5\u0084\u0620\n\u0084\3\u0084\3\u0084\3\u0084\3\u0085\3\u0085"+ - "\3\u0086\3\u0086\3\u0086\3\u0086\5\u0086\u062b\n\u0086\5\u0086\u062d\n"+ - "\u0086\3\u0087\3\u0087\3\u0087\3\u0087\3\u0087\3\u0087\3\u0088\3\u0088"+ - "\3\u0088\5\u0088\u0638\n\u0088\3\u0089\3\u0089\5\u0089\u063c\n\u0089\3"+ - "\u0089\5\u0089\u063f\n\u0089\3\u0089\3\u0089\3\u008a\3\u008a\3\u008a\3"+ - "\u008a\3\u008a\7\u008a\u0648\n\u008a\f\u008a\16\u008a\u064b\13\u008a\3"+ - "\u008b\3\u008b\3\u008b\3\u008b\3\u008b\7\u008b\u0652\n\u008b\f\u008b\16"+ - "\u008b\u0655\13\u008b\3\u008c\3\u008c\5\u008c\u0659\n\u008c\3\u008d\3"+ - "\u008d\3\u008d\5\u008d\u065e\n\u008d\3\u008e\3\u008e\3\u008f\3\u008f\3"+ - "\u0090\3\u0090\3\u0090\3\u0090\3\u0090\5\u0090\u0669\n\u0090\3\u0091\3"+ - "\u0091\3\u0092\3\u0092\3\u0093\3\u0093\5\u0093\u0671\n\u0093\3\u0094\7"+ - "\u0094\u0674\n\u0094\f\u0094\16\u0094\u0677\13\u0094\3\u0095\6\u0095\u067a"+ - "\n\u0095\r\u0095\16\u0095\u067b\3\u0095\2\2\3\u00e6\u0096\2\2\4\2\6\2"+ - "\b\2\n\2\f\2\16\2\20\2\22\2\24\2\26\2\30\2\32\2\34\2\36\2 \2\"\2$\2&\2"+ - "(\2*\2,\2.\2\60\2\62\2\64\2\66\28\2:\2<\2>\2@\2B\2D\2F\2H\2J\2L\2N\2P"+ - "\2R\2T\2V\2X\2Z\2\\\2^\2`\2b\2d\2f\2h\2j\2l\2n\2p\2r\2t\2v\2x\2z\2|\2"+ - "~\2\u0080\2\u0082\2\u0084\2\u0086\2\u0088\2\u008a\2\u008c\2\u008e\2\u0090"+ - "\2\u0092\2\u0094\2\u0096\2\u0098\2\u009a\2\u009c\2\u009e\2\u00a0\2\u00a2"+ - "\2\u00a4\2\u00a6\2\u00a8\2\u00aa\2\u00ac\2\u00ae\2\u00b0\2\u00b2\2\u00b4"+ - "\2\u00b6\2\u00b8\2\u00ba\2\u00bc\2\u00be\2\u00c0\2\u00c2\2\u00c4\2\u00c6"+ - "\2\u00c8\2\u00ca\2\u00cc\2\u00ce\2\u00d0\2\u00d2\2\u00d4\2\u00d6\2\u00d8"+ - "\2\u00da\2\u00dc\2\u00de\2\u00e0\2\u00e2\2\u00e4\2\u00e6\2\u00e8\2\u00ea"+ - "\2\u00ec\2\u00ee\2\u00f0\2\u00f2\2\u00f4\2\u00f6\2\u00f8\2\u00fa\2\u00fc"+ - "\2\u00fe\2\u0100\2\u0102\2\u0104\2\u0106\2\u0108\2\u010a\2\u010c\2\u010e"+ - "\2\u0110\2\u0112\2\u0114\2\u0116\2\u0118\2\u011a\2\u011c\2\u011e\2\u0120"+ - "\2\u0122\2\u0124\2\u0126\2\u0128\2\2\27\b\2\n\n\16\16&&\61\61\65\6588"+ - "\7\2\20\20\30\30\35\35)+-.\b\2\n\n\16\16\20\20\35\35)+-.\4\2\34\34//\4"+ - "\2WW__\4\2\13\13__\3\2fg\3\2\\]\3\2fi\4\2jkoo\3\2hi\3\2>?\6\2\13\13OO"+ - "Z[ab\5\2JL``cc\3\2FG\5\2\t\t$$NN\5\2IIYYp{\4\2@BXX\4\2\17\17\67\67\4\2"+ - "\t9<=\4\2VV\u0081\u0081\2\u06e7\2\u012a\3\2\2\2\4\u0136\3\2\2\2\6\u0142"+ - "\3\2\2\2\b\u0146\3\2\2\2\n\u0152\3\2\2\2\f\u0157\3\2\2\2\16\u015a\3\2"+ - "\2\2\20\u015f\3\2\2\2\22\u0164\3\2\2\2\24\u0169\3\2\2\2\26\u016f\3\2\2"+ - "\2\30\u0173\3\2\2\2\32\u0176\3\2\2\2\34\u017b\3\2\2\2\36\u017f\3\2\2\2"+ - " \u018e\3\2\2\2\"\u0195\3\2\2\2$\u019f\3\2\2\2&\u01b4\3\2\2\2(\u01dc\3"+ - "\2\2\2*\u01f8\3\2\2\2,\u0208\3\2\2\2.\u0217\3\2\2\2\60\u021e\3\2\2\2\62"+ - "\u023f\3\2\2\2\64\u0243\3\2\2\2\66\u0248\3\2\2\28\u024a\3\2\2\2:\u024c"+ - "\3\2\2\2<\u0256\3\2\2\2>\u025e\3\2\2\2@\u0260\3\2\2\2B\u0262\3\2\2\2D"+ - "\u0276\3\2\2\2F\u027b\3\2\2\2H\u027d\3\2\2\2J\u0284\3\2\2\2L\u0290\3\2"+ - "\2\2N\u0295\3\2\2\2P\u0299\3\2\2\2R\u029d\3\2\2\2T\u029f\3\2\2\2V\u02b7"+ - "\3\2\2\2X\u02b9\3\2\2\2Z\u02bc\3\2\2\2\\\u02c6\3\2\2\2^\u02ce\3\2\2\2"+ - "`\u02d9\3\2\2\2b\u02dc\3\2\2\2d\u02eb\3\2\2\2f\u02ed\3\2\2\2h\u02fa\3"+ - "\2\2\2j\u0301\3\2\2\2l\u0304\3\2\2\2n\u0307\3\2\2\2p\u0315\3\2\2\2r\u0317"+ - "\3\2\2\2t\u0329\3\2\2\2v\u032b\3\2\2\2x\u0332\3\2\2\2z\u0338\3\2\2\2|"+ - "\u033e\3\2\2\2~\u0342\3\2\2\2\u0080\u0346\3\2\2\2\u0082\u0348\3\2\2\2"+ - "\u0084\u0357\3\2\2\2\u0086\u0359\3\2\2\2\u0088\u036a\3\2\2\2\u008a\u036d"+ - "\3\2\2\2\u008c\u0378\3\2\2\2\u008e\u037a\3\2\2\2\u0090\u037c\3\2\2\2\u0092"+ - "\u0384\3\2\2\2\u0094\u038c\3\2\2\2\u0096\u0391\3\2\2\2\u0098\u0393\3\2"+ - "\2\2\u009a\u03a3\3\2\2\2\u009c\u03b2\3\2\2\2\u009e\u03b4\3\2\2\2\u00a0"+ - "\u03bb\3\2\2\2\u00a2\u03d1\3\2\2\2\u00a4\u03d3\3\2\2\2\u00a6\u03df\3\2"+ - "\2\2\u00a8\u03e3\3\2\2\2\u00aa\u03ef\3\2\2\2\u00ac\u03f1\3\2\2\2\u00ae"+ - "\u03ff\3\2\2\2\u00b0\u0420\3\2\2\2\u00b2\u0422\3\2\2\2\u00b4\u0426\3\2"+ - "\2\2\u00b6\u042a\3\2\2\2\u00b8\u043d\3\2\2\2\u00ba\u0464\3\2\2\2\u00bc"+ - "\u0466\3\2\2\2\u00be\u0471\3\2\2\2\u00c0\u0479\3\2\2\2\u00c2\u047d\3\2"+ - "\2\2\u00c4\u0485\3\2\2\2\u00c6\u0490\3\2\2\2\u00c8\u0495\3\2\2\2\u00ca"+ - "\u04a1\3\2\2\2\u00cc\u04a5\3\2\2\2\u00ce\u04a7\3\2\2\2\u00d0\u04b0\3\2"+ - "\2\2\u00d2\u04bc\3\2\2\2\u00d4\u04be\3\2\2\2\u00d6\u04c0\3\2\2\2\u00d8"+ - "\u04c4\3\2\2\2\u00da\u04c6\3\2\2\2\u00dc\u04ca\3\2\2\2\u00de\u04d5\3\2"+ - "\2\2\u00e0\u04db\3\2\2\2\u00e2\u04df\3\2\2\2\u00e4\u04e1\3\2\2\2\u00e6"+ - "\u04f6\3\2\2\2\u00e8\u0569\3\2\2\2\u00ea\u0575\3\2\2\2\u00ec\u057e\3\2"+ - "\2\2\u00ee\u05aa\3\2\2\2\u00f0\u05b0\3\2\2\2\u00f2\u05b4\3\2\2\2\u00f4"+ - "\u05b7\3\2\2\2\u00f6\u05bf\3\2\2\2\u00f8\u05d5\3\2\2\2\u00fa\u05d7\3\2"+ - "\2\2\u00fc\u05e0\3\2\2\2\u00fe\u05ea\3\2\2\2\u0100\u05fc\3\2\2\2\u0102"+ - "\u0600\3\2\2\2\u0104\u0602\3\2\2\2\u0106\u061c\3\2\2\2\u0108\u0624\3\2"+ - "\2\2\u010a\u0626\3\2\2\2\u010c\u062e\3\2\2\2\u010e\u0637\3\2\2\2\u0110"+ - "\u0639\3\2\2\2\u0112\u0642\3\2\2\2\u0114\u064c\3\2\2\2\u0116\u0658\3\2"+ - "\2\2\u0118\u065d\3\2\2\2\u011a\u065f\3\2\2\2\u011c\u0661\3\2\2\2\u011e"+ - "\u0668\3\2\2\2\u0120\u066a\3\2\2\2\u0122\u066c\3\2\2\2\u0124\u0670\3\2"+ - "\2\2\u0126\u0675\3\2\2\2\u0128\u0679\3\2\2\2\u012a\u012c\5\u0126\u0094"+ - "\2\u012b\u012d\5\6\4\2\u012c\u012b\3\2\2\2\u012c\u012d\3\2\2\2\u012d\u012f"+ - "\3\2\2\2\u012e\u0130\5\u0128\u0095\2\u012f\u012e\3\2\2\2\u012f\u0130\3"+ - "\2\2\2\u0130\u0132\3\2\2\2\u0131\u0133\5\4\3\2\u0132\u0131\3\2\2\2\u0132"+ - "\u0133\3\2\2\2\u0133\u0134\3\2\2\2\u0134\u0135\7\2\2\3\u0135\3\3\2\2\2"+ - "\u0136\u013c\5\u00ba^\2\u0137\u0138\5\u0128\u0095\2\u0138\u0139\5\u00ba"+ - "^\2\u0139\u013b\3\2\2\2\u013a\u0137\3\2\2\2\u013b\u013e\3\2\2\2\u013c"+ - "\u013a\3\2\2\2\u013c\u013d\3\2\2\2\u013d\u0140\3\2\2\2\u013e\u013c\3\2"+ - "\2\2\u013f\u0141\5\u0128\u0095\2\u0140\u013f\3\2\2\2\u0140\u0141\3\2\2"+ - "\2\u0141\5\3\2\2\2\u0142\u0143\5\u0088E\2\u0143\u0144\7(\2\2\u0144\u0145"+ - "\5f\64\2\u0145\7\3\2\2\2\u0146\u0147\5\u0088E\2\u0147\u0149\7#\2\2\u0148"+ - "\u014a\7-\2\2\u0149\u0148\3\2\2\2\u0149\u014a\3\2\2\2\u014a\u014b\3\2"+ - "\2\2\u014b\u0150\5f\64\2\u014c\u014d\7X\2\2\u014d\u0151\7j\2\2\u014e\u014f"+ - "\7\t\2\2\u014f\u0151\5\u011e\u0090\2\u0150\u014c\3\2\2\2\u0150\u014e\3"+ - "\2\2\2\u0150\u0151\3\2\2\2\u0151\t\3\2\2\2\u0152\u0153\5\22\n\2\u0153"+ - "\u0154\5&\24\2\u0154\13\3\2\2\2\u0155\u0158\5\26\f\2\u0156\u0158\t\2\2"+ - "\2\u0157\u0155\3\2\2\2\u0157\u0156\3\2\2\2\u0158\r\3\2\2\2\u0159\u015b"+ - "\5\20\t\2\u015a\u0159\3\2\2\2\u015a\u015b\3\2\2\2\u015b\17\3\2\2\2\u015c"+ - "\u015d\5\f\7\2\u015d\u015e\5\u0126\u0094\2\u015e\u0160\3\2\2\2\u015f\u015c"+ - "\3\2\2\2\u0160\u0161\3\2\2\2\u0161\u015f\3\2\2\2\u0161\u0162\3\2\2\2\u0162"+ - "\21\3\2\2\2\u0163\u0165\5\24\13\2\u0164\u0163\3\2\2\2\u0164\u0165\3\2"+ - "\2\2\u0165\23\3\2\2\2\u0166\u0167\5\26\f\2\u0167\u0168\5\u0126\u0094\2"+ - "\u0168\u016a\3\2\2\2\u0169\u0166\3\2\2\2\u016a\u016b\3\2\2\2\u016b\u0169"+ - "\3\2\2\2\u016b\u016c\3\2\2\2\u016c\25\3\2\2\2\u016d\u0170\5\u008aF\2\u016e"+ - "\u0170\t\3\2\2\u016f\u016d\3\2\2\2\u016f\u016e\3\2\2\2\u0170\27\3\2\2"+ - "\2\u0171\u0174\5\u008aF\2\u0172\u0174\t\4\2\2\u0173\u0171\3\2\2\2\u0173"+ - "\u0172\3\2\2\2\u0174\31\3\2\2\2\u0175\u0177\5\34\17\2\u0176\u0175\3\2"+ - "\2\2\u0176\u0177\3\2\2\2\u0177\33\3\2\2\2\u0178\u0179\5\30\r\2\u0179\u017a"+ - "\5\u0126\u0094\2\u017a\u017c\3\2\2\2\u017b\u0178\3\2\2\2\u017c\u017d\3"+ - "\2\2\2\u017d\u017b\3\2\2\2\u017d\u017e\3\2\2\2\u017e\35\3\2\2\2\u017f"+ - "\u0180\7[\2\2\u0180\u0181\5\u0126\u0094\2\u0181\u0188\5 \21\2\u0182\u0183"+ - "\7W\2\2\u0183\u0184\5\u0126\u0094\2\u0184\u0185\5 \21\2\u0185\u0187\3"+ - "\2\2\2\u0186\u0182\3\2\2\2\u0187\u018a\3\2\2\2\u0188\u0186\3\2\2\2\u0188"+ - "\u0189\3\2\2\2\u0189\u018b\3\2\2\2\u018a\u0188\3\2\2\2\u018b\u018c\5\u0126"+ - "\u0094\2\u018c\u018d\7Z\2\2\u018d\37\3\2\2\2\u018e\u0193\5\u011c\u008f"+ - "\2\u018f\u0190\7\34\2\2\u0190\u0191\5\u0126\u0094\2\u0191\u0192\5\"\22"+ - "\2\u0192\u0194\3\2\2\2\u0193\u018f\3\2\2\2\u0193\u0194\3\2\2\2\u0194!"+ - "\3\2\2\2\u0195\u019c\5J&\2\u0196\u0197\7l\2\2\u0197\u0198\5\u0126\u0094"+ - "\2\u0198\u0199\5J&\2\u0199\u019b\3\2\2\2\u019a\u0196\3\2\2\2\u019b\u019e"+ - "\3\2\2\2\u019c\u019a\3\2\2\2\u019c\u019d\3\2\2\2\u019d#\3\2\2\2\u019e"+ - "\u019c\3\2\2\2\u019f\u01a6\5J&\2\u01a0\u01a1\7W\2\2\u01a1\u01a2\5\u0126"+ - "\u0094\2\u01a2\u01a3\5J&\2\u01a3\u01a5\3\2\2\2\u01a4\u01a0\3\2\2\2\u01a5"+ - "\u01a8\3\2\2\2\u01a6\u01a4\3\2\2\2\u01a6\u01a7\3\2\2\2\u01a7%\3\2\2\2"+ - "\u01a8\u01a6\3\2\2\2\u01a9\u01aa\7\25\2\2\u01aa\u01b5\b\24\1\2\u01ab\u01ac"+ - "\7%\2\2\u01ac\u01b5\b\24\1\2\u01ad\u01ae\7\33\2\2\u01ae\u01b5\b\24\1\2"+ - "\u01af\u01b0\7~\2\2\u01b0\u01b1\7%\2\2\u01b1\u01b5\b\24\1\2\u01b2\u01b3"+ - "\7\f\2\2\u01b3\u01b5\b\24\1\2\u01b4\u01a9\3\2\2\2\u01b4\u01ab\3\2\2\2"+ - "\u01b4\u01ad\3\2\2\2\u01b4\u01af\3\2\2\2\u01b4\u01b2\3\2\2\2\u01b5\u01b6"+ - "\3\2\2\2\u01b6\u01b7\5\u011e\u0090\2\u01b7\u01d8\5\u0126\u0094\2\u01b8"+ - "\u01ba\6\24\2\3\u01b9\u01bb\5\36\20\2\u01ba\u01b9\3\2\2\2\u01ba\u01bb"+ - "\3\2\2\2\u01bb\u01bc\3\2\2\2\u01bc\u01ca\5\u0126\u0094\2\u01bd\u01c7\6"+ - "\24\3\3\u01be\u01bf\7\34\2\2\u01bf\u01c3\5\u0126\u0094\2\u01c0\u01c1\6"+ - "\24\4\3\u01c1\u01c4\5$\23\2\u01c2\u01c4\5J&\2\u01c3\u01c0\3\2\2\2\u01c3"+ - "\u01c2\3\2\2\2\u01c4\u01c5\3\2\2\2\u01c5\u01c6\5\u0126\u0094\2\u01c6\u01c8"+ - "\3\2\2\2\u01c7\u01be\3\2\2\2\u01c7\u01c8\3\2\2\2\u01c8\u01cb\3\2\2\2\u01c9"+ - "\u01cb\3\2\2\2\u01ca\u01bd\3\2\2\2\u01ca\u01c9\3\2\2\2\u01cb\u01d5\3\2"+ - "\2\2\u01cc\u01d2\6\24\5\3\u01cd\u01ce\7\"\2\2\u01ce\u01cf\5\u0126\u0094"+ - "\2\u01cf\u01d0\5$\23\2\u01d0\u01d1\5\u0126\u0094\2\u01d1\u01d3\3\2\2\2"+ - "\u01d2\u01cd\3\2\2\2\u01d2\u01d3\3\2\2\2\u01d3\u01d6\3\2\2\2\u01d4\u01d6"+ - "\3\2\2\2\u01d5\u01cc\3\2\2\2\u01d5\u01d4\3\2\2\2\u01d6\u01d9\3\2\2\2\u01d7"+ - "\u01d9\3\2\2\2\u01d8\u01b8\3\2\2\2\u01d8\u01d7\3\2\2\2\u01d9\u01da\3\2"+ - "\2\2\u01da\u01db\5(\25\2\u01db\'\3\2\2\2\u01dc\u01dd\7R\2\2\u01dd\u01e6"+ - "\5\u0126\u0094\2\u01de\u01e0\6\25\6\3\u01df\u01e1\5*\26\2\u01e0\u01df"+ - "\3\2\2\2\u01e0\u01e1\3\2\2\2\u01e1\u01e3\3\2\2\2\u01e2\u01e4\5\u0128\u0095"+ - "\2\u01e3\u01e2\3\2\2\2\u01e3\u01e4\3\2\2\2\u01e4\u01e7\3\2\2\2\u01e5\u01e7"+ - "\3\2\2\2\u01e6\u01de\3\2\2\2\u01e6\u01e5\3\2\2\2\u01e7\u01e9\3\2\2\2\u01e8"+ - "\u01ea\5.\30\2\u01e9\u01e8\3\2\2\2\u01e9\u01ea\3\2\2\2\u01ea\u01f0\3\2"+ - "\2\2\u01eb\u01ec\5\u0128\u0095\2\u01ec\u01ed\5.\30\2\u01ed\u01ef\3\2\2"+ - "\2\u01ee\u01eb\3\2\2\2\u01ef\u01f2\3\2\2\2\u01f0\u01ee\3\2\2\2\u01f0\u01f1"+ - "\3\2\2\2\u01f1\u01f4\3\2\2\2\u01f2\u01f0\3\2\2\2\u01f3\u01f5\5\u0128\u0095"+ - "\2\u01f4\u01f3\3\2\2\2\u01f4\u01f5\3\2\2\2\u01f5\u01f6\3\2\2\2\u01f6\u01f7"+ - "\7S\2\2\u01f7)\3\2\2\2\u01f8\u0200\5,\27\2\u01f9\u01fa\5\u0126\u0094\2"+ - "\u01fa\u01fb\7W\2\2\u01fb\u01fc\5\u0126\u0094\2\u01fc\u01fd\5,\27\2\u01fd"+ - "\u01ff\3\2\2\2\u01fe\u01f9\3\2\2\2\u01ff\u0202\3\2\2\2\u0200\u01fe\3\2"+ - "\2\2\u0200\u0201\3\2\2\2\u0201\u0206\3\2\2\2\u0202\u0200\3\2\2\2\u0203"+ - "\u0204\5\u0126\u0094\2\u0204\u0205\7W\2\2\u0205\u0207\3\2\2\2\u0206\u0203"+ - "\3\2\2\2\u0206\u0207\3\2\2\2\u0207+\3\2\2\2\u0208\u0209\5\u0088E\2\u0209"+ - "\u020b\5\u011e\u0090\2\u020a\u020c\5\u0110\u0089\2\u020b\u020a\3\2\2\2"+ - "\u020b\u020c\3\2\2\2\u020c\u020e\3\2\2\2\u020d\u020f\5\u0108\u0085\2\u020e"+ - "\u020d\3\2\2\2\u020e\u020f\3\2\2\2\u020f-\3\2\2\2\u0210\u0218\7V\2\2\u0211"+ - "\u0212\7-\2\2\u0212\u0214\5\u0126\u0094\2\u0213\u0211\3\2\2\2\u0213\u0214"+ - "\3\2\2\2\u0214\u0215\3\2\2\2\u0215\u0218\5\u009aN\2\u0216\u0218\5\60\31"+ - "\2\u0217\u0210\3\2\2\2\u0217\u0213\3\2\2\2\u0217\u0216\3\2\2\2\u0218/"+ - "\3\2\2\2\u0219\u021f\5\62\32\2\u021a\u021f\58\35\2\u021b\u021c\5\16\b"+ - "\2\u021c\u021d\5&\24\2\u021d\u021f\3\2\2\2\u021e\u0219\3\2\2\2\u021e\u021a"+ - "\3\2\2\2\u021e\u021b\3\2\2\2\u021f\61\3\2\2\2\u0220\u0221\6\32\7\3\u0221"+ - "\u0222\5\66\34\2\u0222\u0223\5\64\33\2\u0223\u0224\7P\2\2\u0224\u0229"+ - "\5\u0124\u0093\2\u0225\u0226\7\30\2\2\u0226\u0227\5\u0126\u0094\2\u0227"+ - "\u0228\5\u0096L\2\u0228\u022a\3\2\2\2\u0229\u0225\3\2\2\2\u0229\u022a"+ - "\3\2\2\2\u022a\u0240\3\2\2\2\u022b\u022d\5\16\b\2\u022c\u022e\5\36\20"+ - "\2\u022d\u022c\3\2\2\2\u022d\u022e\3\2\2\2\u022e\u0230\3\2\2\2\u022f\u0231"+ - "\5\66\34\2\u0230\u022f\3\2\2\2\u0230\u0231\3\2\2\2\u0231\u0232\3\2\2\2"+ - "\u0232\u0233\5\64\33\2\u0233\u0239\5\\/\2\u0234\u0235\5\u0126\u0094\2"+ - "\u0235\u0236\7\64\2\2\u0236\u0237\5\u0126\u0094\2\u0237\u0238\5Z.\2\u0238"+ - "\u023a\3\2\2\2\u0239\u0234\3\2\2\2\u0239\u023a\3\2\2\2\u023a\u023b\3\2"+ - "\2\2\u023b\u023d\5\u0126\u0094\2\u023c\u023e\5d\63\2\u023d\u023c\3\2\2"+ - "\2\u023d\u023e\3\2\2\2\u023e\u0240\3\2\2\2\u023f\u0220\3\2\2\2\u023f\u022b"+ - "\3\2\2\2\u0240\63\3\2\2\2\u0241\u0244\5\u011e\u0090\2\u0242\u0244\5\u011a"+ - "\u008e\2\u0243\u0241\3\2\2\2\u0243\u0242\3\2\2\2\u0244\65\3\2\2\2\u0245"+ - "\u0249\5H%\2\u0246\u0247\6\34\b\3\u0247\u0249\7\67\2\2\u0248\u0245\3\2"+ - "\2\2\u0248\u0246\3\2\2\2\u0249\67\3\2\2\2\u024a\u024b\5\u00a2R\2\u024b"+ - "9\3\2\2\2\u024c\u0253\5<\37\2\u024d\u024e\7W\2\2\u024e\u024f\5\u0126\u0094"+ - "\2\u024f\u0250\5<\37\2\u0250\u0252\3\2\2\2\u0251\u024d\3\2\2\2\u0252\u0255"+ - "\3\2\2\2\u0253\u0251\3\2\2\2\u0253\u0254\3\2\2\2\u0254;\3\2\2\2\u0255"+ - "\u0253\3\2\2\2\u0256\u025c\5> \2\u0257\u0258\5\u0126\u0094\2\u0258\u0259"+ - "\7Y\2\2\u0259\u025a\5\u0126\u0094\2\u025a\u025b\5@!\2\u025b\u025d\3\2"+ - "\2\2\u025c\u0257\3\2\2\2\u025c\u025d\3\2\2\2\u025d=\3\2\2\2\u025e\u025f"+ - "\5\u011e\u0090\2\u025f?\3\2\2\2\u0260\u0261\5\u00e0q\2\u0261A\3\2\2\2"+ - "\u0262\u0263\5@!\2\u0263\u026b\5\u0126\u0094\2\u0264\u0265\7W\2\2\u0265"+ - "\u0266\5\u0126\u0094\2\u0266\u0267\5@!\2\u0267\u0268\5\u0126\u0094\2\u0268"+ - "\u026a\3\2\2\2\u0269\u0264\3\2\2\2\u026a\u026d\3\2\2\2\u026b\u0269\3\2"+ - "\2\2\u026b\u026c\3\2\2\2\u026c\u026e\3\2\2\2\u026d\u026b\3\2\2\2\u026e"+ - "\u0270\5\u0126\u0094\2\u026f\u0271\7W\2\2\u0270\u026f\3\2\2\2\u0270\u0271"+ - "\3\2\2\2\u0271C\3\2\2\2\u0272\u0273\5\u0088E\2\u0273\u0274\7T\2\2\u0274"+ - "\u0275\7U\2\2\u0275\u0277\3\2\2\2\u0276\u0272\3\2\2\2\u0277\u0278\3\2"+ - "\2\2\u0278\u0276\3\2\2\2\u0278\u0279\3\2\2\2\u0279E\3\2\2\2\u027a\u027c"+ - "\5D#\2\u027b\u027a\3\2\2\2\u027b\u027c\3\2\2\2\u027cG\3\2\2\2\u027d\u0280"+ - "\5\u0088E\2\u027e\u0281\5R*\2\u027f\u0281\5P)\2\u0280\u027e\3\2\2\2\u0280"+ - "\u027f\3\2\2\2\u0281\u0282\3\2\2\2\u0282\u0283\5F$\2\u0283I\3\2\2\2\u0284"+ - "\u028a\5\u0088E\2\u0285\u0288\5R*\2\u0286\u0288\7\67\2\2\u0287\u0285\3"+ - "\2\2\2\u0287\u0286\3\2\2\2\u0288\u028b\3\2\2\2\u0289\u028b\5N(\2\u028a"+ - "\u0287\3\2\2\2\u028a\u0289\3\2\2\2\u028b\u028c\3\2\2\2\u028c\u028d\5F"+ - "$\2\u028dK\3\2\2\2\u028e\u0291\5l\67\2\u028f\u0291\5n8\2\u0290\u028e\3"+ - "\2\2\2\u0290\u028f\3\2\2\2\u0291\u0293\3\2\2\2\u0292\u0294\5T+\2\u0293"+ - "\u0292\3\2\2\2\u0293\u0294\3\2\2\2\u0294M\3\2\2\2\u0295\u0297\5l\67\2"+ - "\u0296\u0298\5T+\2\u0297\u0296\3\2\2\2\u0297\u0298\3\2\2\2\u0298O\3\2"+ - "\2\2\u0299\u029b\5n8\2\u029a\u029c\5T+\2\u029b\u029a\3\2\2\2\u029b\u029c"+ - "\3\2\2\2\u029cQ\3\2\2\2\u029d\u029e\7\17\2\2\u029eS\3\2\2\2\u029f\u02a0"+ - "\7[\2\2\u02a0\u02a1\5\u0126\u0094\2\u02a1\u02a8\5V,\2\u02a2\u02a3\7W\2"+ - "\2\u02a3\u02a4\5\u0126\u0094\2\u02a4\u02a5\5V,\2\u02a5\u02a7\3\2\2\2\u02a6"+ - "\u02a2\3\2\2\2\u02a7\u02aa\3\2\2\2\u02a8\u02a6\3\2\2\2\u02a8\u02a9\3\2"+ - "\2\2\u02a9\u02ab\3\2\2\2\u02aa\u02a8\3\2\2\2\u02ab\u02ac\5\u0126\u0094"+ - "\2\u02ac\u02ad\7Z\2\2\u02adU\3\2\2\2\u02ae\u02b8\5J&\2\u02af\u02b0\5\u0088"+ - "E\2\u02b0\u02b5\7^\2\2\u02b1\u02b2\t\5\2\2\u02b2\u02b3\5\u0126\u0094\2"+ - "\u02b3\u02b4\5J&\2\u02b4\u02b6\3\2\2\2\u02b5\u02b1\3\2\2\2\u02b5\u02b6"+ - "\3\2\2\2\u02b6\u02b8\3\2\2\2\u02b7\u02ae\3\2\2\2\u02b7\u02af\3\2\2\2\u02b8"+ - "W\3\2\2\2\u02b9\u02ba\5\u0088E\2\u02ba\u02bb\5l\67\2\u02bbY\3\2\2\2\u02bc"+ - "\u02c3\5X-\2\u02bd\u02be\7W\2\2\u02be\u02bf\5\u0126\u0094\2\u02bf\u02c0"+ - "\5X-\2\u02c0\u02c2\3\2\2\2\u02c1\u02bd\3\2\2\2\u02c2\u02c5\3\2\2\2\u02c3"+ - "\u02c1\3\2\2\2\u02c3\u02c4\3\2\2\2\u02c4[\3\2\2\2\u02c5\u02c3\3\2\2\2"+ - "\u02c6\u02c8\7P\2\2\u02c7\u02c9\5^\60\2\u02c8\u02c7\3\2\2\2\u02c8\u02c9"+ - "\3\2\2\2\u02c9\u02ca\3\2\2\2\u02ca\u02cb\5\u0124\u0093\2\u02cb]\3\2\2"+ - "\2\u02cc\u02cf\5b\62\2\u02cd\u02cf\5`\61\2\u02ce\u02cc\3\2\2\2\u02ce\u02cd"+ - "\3\2\2\2\u02cf\u02d6\3\2\2\2\u02d0\u02d1\7W\2\2\u02d1\u02d2\5\u0126\u0094"+ - "\2\u02d2\u02d3\5b\62\2\u02d3\u02d5\3\2\2\2\u02d4\u02d0\3\2\2\2\u02d5\u02d8"+ - "\3\2\2\2\u02d6\u02d4\3\2\2\2\u02d6\u02d7\3\2\2\2\u02d7_\3\2\2\2\u02d8"+ - "\u02d6\3\2\2\2\u02d9\u02da\5J&\2\u02da\u02db\7\62\2\2\u02dba\3\2\2\2\u02dc"+ - "\u02de\5\32\16\2\u02dd\u02df\5J&\2\u02de\u02dd\3\2\2\2\u02de\u02df\3\2"+ - "\2\2\u02df\u02e1\3\2\2\2\u02e0\u02e2\7\177\2\2\u02e1\u02e0\3\2\2\2\u02e1"+ - "\u02e2\3\2\2\2\u02e2\u02e3\3\2\2\2\u02e3\u02e9\5> \2\u02e4\u02e5\5\u0126"+ - "\u0094\2\u02e5\u02e6\7Y\2\2\u02e6\u02e7\5\u0126\u0094\2\u02e7\u02e8\5"+ - "\u00e6t\2\u02e8\u02ea\3\2\2\2\u02e9\u02e4\3\2\2\2\u02e9\u02ea\3\2\2\2"+ - "\u02eac\3\2\2\2\u02eb\u02ec\5\u009aN\2\u02ece\3\2\2\2\u02ed\u02f2\5h\65"+ - "\2\u02ee\u02ef\7X\2\2\u02ef\u02f1\5h\65\2\u02f0\u02ee\3\2\2\2\u02f1\u02f4"+ - "\3\2\2\2\u02f2\u02f0\3\2\2\2\u02f2\u02f3\3\2\2\2\u02f3g\3\2\2\2\u02f4"+ - "\u02f2\3\2\2\2\u02f5\u02fb\5\u011e\u0090\2\u02f6\u02fb\7\n\2\2\u02f7\u02fb"+ - "\7\13\2\2\u02f8\u02fb\7\t\2\2\u02f9\u02fb\7\f\2\2\u02fa\u02f5\3\2\2\2"+ - "\u02fa\u02f6\3\2\2\2\u02fa\u02f7\3\2\2\2\u02fa\u02f8\3\2\2\2\u02fa\u02f9"+ - "\3\2\2\2\u02fbi\3\2\2\2\u02fc\u02fd\5h\65\2\u02fd\u02fe\7X\2\2\u02fe\u0300"+ - "\3\2\2\2\u02ff\u02fc\3\2\2\2\u0300\u0303\3\2\2\2\u0301\u02ff\3\2\2\2\u0301"+ - "\u0302\3\2\2\2\u0302k\3\2\2\2\u0303\u0301\3\2\2\2\u0304\u0305\5j\66\2"+ - "\u0305\u0306\5\u011e\u0090\2\u0306m\3\2\2\2\u0307\u0308\5j\66\2\u0308"+ - "\u030d\5\u011c\u008f\2\u0309\u030a\7X\2\2\u030a\u030c\5\u011c\u008f\2"+ - "\u030b\u0309\3\2\2\2\u030c\u030f\3\2\2\2\u030d\u030b\3\2\2\2\u030d\u030e"+ - "\3\2\2\2\u030eo\3\2\2\2\u030f\u030d\3\2\2\2\u0310\u0316\7:\2\2\u0311\u0316"+ - "\7;\2\2\u0312\u0316\5\u011a\u008e\2\u0313\u0316\7<\2\2\u0314\u0316\7="+ - "\2\2\u0315\u0310\3\2\2\2\u0315\u0311\3\2\2\2\u0315\u0312\3\2\2\2\u0315"+ - "\u0313\3\2\2\2\u0315\u0314\3\2\2\2\u0316q\3\2\2\2\u0317\u0318\7\4\2\2"+ - "\u0318\u031d\5t;\2\u0319\u031a\7\6\2\2\u031a\u031c\5t;\2\u031b\u0319\3"+ - "\2\2\2\u031c\u031f\3\2\2\2\u031d\u031b\3\2\2\2\u031d\u031e\3\2\2\2\u031e"+ - "\u0320\3\2\2\2\u031f\u031d\3\2\2\2\u0320\u0321\7\5\2\2\u0321s\3\2\2\2"+ - "\u0322\u032a\5v<\2\u0323\u0325\7R\2\2\u0324\u0326\5\u00e2r\2\u0325\u0324"+ - "\3\2\2\2\u0325\u0326\3\2\2\2\u0326\u0327\3\2\2\2\u0327\u032a\7S\2\2\u0328"+ - "\u032a\5\u0082B\2\u0329\u0322\3\2\2\2\u0329\u0323\3\2\2\2\u0329\u0328"+ - "\3\2\2\2\u032au\3\2\2\2\u032b\u032f\5\u011e\u0090\2\u032c\u032e\7\7\2"+ - "\2\u032d\u032c\3\2\2\2\u032e\u0331\3\2\2\2\u032f\u032d\3\2\2\2\u032f\u0330"+ - "\3\2\2\2\u0330w\3\2\2\2\u0331\u032f\3\2\2\2\u0332\u0333\5|?\2\u0333\u0334"+ - "\5\u0126\u0094\2\u0334\u0335\7M\2\2\u0335\u0336\5\u0126\u0094\2\u0336"+ - "\u0337\5\u0080A\2\u0337y\3\2\2\2\u0338\u0339\5~@\2\u0339\u033a\5\u0126"+ - "\u0094\2\u033a\u033b\7M\2\2\u033b\u033c\5\u0126\u0094\2\u033c\u033d\5"+ - "\u0080A\2\u033d{\3\2\2\2\u033e\u033f\5\\/\2\u033f}\3\2\2\2\u0340\u0343"+ - "\5\\/\2\u0341\u0343\5> \2\u0342\u0340\3\2\2\2\u0342\u0341\3\2\2\2\u0343"+ - "\177\3\2\2\2\u0344\u0347\5\u009aN\2\u0345\u0347\5\u00e2r\2\u0346\u0344"+ - "\3\2\2\2\u0346\u0345\3\2\2\2\u0347\u0081\3\2\2\2\u0348\u0349\7R\2\2\u0349"+ - "\u0351\5\u0126\u0094\2\u034a\u034c\5^\60\2\u034b\u034a\3\2\2\2\u034b\u034c"+ - "\3\2\2\2\u034c\u034d\3\2\2\2\u034d\u034e\5\u0126\u0094\2\u034e\u034f\7"+ - "M\2\2\u034f\u0350\5\u0126\u0094\2\u0350\u0352\3\2\2\2\u0351\u034b\3\2"+ - "\2\2\u0351\u0352\3\2\2\2\u0352\u0353\3\2\2\2\u0353\u0354\5\u0084C\2\u0354"+ - "\u0355\7S\2\2\u0355\u0083\3\2\2\2\u0356\u0358\5\u0086D\2\u0357\u0356\3"+ - "\2\2\2\u0357\u0358\3\2\2\2\u0358\u0085\3\2\2\2\u0359\u035f\5\u009cO\2"+ - "\u035a\u035b\5\u0128\u0095\2\u035b\u035c\5\u009cO\2\u035c\u035e\3\2\2"+ - "\2\u035d\u035a\3\2\2\2\u035e\u0361\3\2\2\2\u035f\u035d\3\2\2\2\u035f\u0360"+ - "\3\2\2\2\u0360\u0363\3\2\2\2\u0361\u035f\3\2\2\2\u0362\u0364\5\u0128\u0095"+ - "\2\u0363\u0362\3\2\2\2\u0363\u0364\3\2\2\2\u0364\u0087\3\2\2\2\u0365\u0366"+ - "\5\u008aF\2\u0366\u0367\5\u0126\u0094\2\u0367\u0369\3\2\2\2\u0368\u0365"+ - "\3\2\2\2\u0369\u036c\3\2\2\2\u036a\u0368\3\2\2\2\u036a\u036b\3\2\2\2\u036b"+ - "\u0089\3\2\2\2\u036c\u036a\3\2\2\2\u036d\u036e\7~\2\2\u036e\u0374\5\u008e"+ - "H\2\u036f\u0371\7P\2\2\u0370\u0372\5\u008cG\2\u0371\u0370\3\2\2\2\u0371"+ - "\u0372\3\2\2\2\u0372\u0373\3\2\2\2\u0373\u0375\5\u0124\u0093\2\u0374\u036f"+ - "\3\2\2\2\u0374\u0375\3\2\2\2\u0375\u008b\3\2\2\2\u0376\u0379\5\u0090I"+ - "\2\u0377\u0379\5\u0096L\2\u0378\u0376\3\2\2\2\u0378\u0377\3\2\2\2\u0379"+ - "\u008d\3\2\2\2\u037a\u037b\5l\67\2\u037b\u008f\3\2\2\2\u037c\u0381\5\u0092"+ - "J\2\u037d\u037e\7W\2\2\u037e\u0380\5\u0092J\2\u037f\u037d\3\2\2\2\u0380"+ - "\u0383\3\2\2\2\u0381\u037f\3\2\2\2\u0381\u0382\3\2\2\2\u0382\u0091\3\2"+ - "\2\2\u0383\u0381\3\2\2\2\u0384\u0385\5\u0094K\2\u0385\u0386\5\u0126\u0094"+ - "\2\u0386\u0387\7Y\2\2\u0387\u0388\5\u0126\u0094\2\u0388\u0389\5\u0096"+ - "L\2\u0389\u0093\3\2\2\2\u038a\u038d\5\u011e\u0090\2\u038b\u038d\5\u0122"+ - "\u0092\2\u038c\u038a\3\2\2\2\u038c\u038b\3\2\2\2\u038d\u0095\3\2\2\2\u038e"+ - "\u0392\5\u0098M\2\u038f\u0392\5\u008aF\2\u0390\u0392\5\u00e6t\2\u0391"+ - "\u038e\3\2\2\2\u0391\u038f\3\2\2\2\u0391\u0390\3\2\2\2\u0392\u0097\3\2"+ - "\2\2\u0393\u039c\7T\2\2\u0394\u0399\5\u0096L\2\u0395\u0396\7W\2\2\u0396"+ - "\u0398\5\u0096L\2\u0397\u0395\3\2\2\2\u0398\u039b\3\2\2\2\u0399\u0397"+ - "\3\2\2\2\u0399\u039a\3\2\2\2\u039a\u039d\3\2\2\2\u039b\u0399\3\2\2\2\u039c"+ - "\u0394\3\2\2\2\u039c\u039d\3\2\2\2\u039d\u039f\3\2\2\2\u039e\u03a0\7W"+ - "\2\2\u039f\u039e\3\2\2\2\u039f\u03a0\3\2\2\2\u03a0\u03a1\3\2\2\2\u03a1"+ - "\u03a2\7U\2\2\u03a2\u0099\3\2\2\2\u03a3\u03ab\7R\2\2\u03a4\u03ac\5\u0126"+ - "\u0094\2\u03a5\u03a7\5\u0128\u0095\2\u03a6\u03a5\3\2\2\2\u03a7\u03aa\3"+ - "\2\2\2\u03a8\u03a6\3\2\2\2\u03a8\u03a9\3\2\2\2\u03a9\u03ac\3\2\2\2\u03aa"+ - "\u03a8\3\2\2\2\u03ab\u03a4\3\2\2\2\u03ab\u03a8\3\2\2\2\u03ac\u03ad\3\2"+ - "\2\2\u03ad\u03ae\5\u0084C\2\u03ae\u03af\7S\2\2\u03af\u009b\3\2\2\2\u03b0"+ - "\u03b3\5\u009eP\2\u03b1\u03b3\5\u00ba^\2\u03b2\u03b0\3\2\2\2\u03b2\u03b1"+ - "\3\2\2\2\u03b3\u009d\3\2\2\2\u03b4\u03b5\6P\t\2\u03b5\u03b6\5\u00a2R\2"+ - "\u03b6\u009f\3\2\2\2\u03b7\u03b8\6Q\n\3\u03b8\u03bc\5\34\17\2\u03b9\u03ba"+ - "\6Q\13\3\u03ba\u03bc\5\20\t\2\u03bb\u03b7\3\2\2\2\u03bb\u03b9\3\2\2\2"+ - "\u03bc\u00a1\3\2\2\2\u03bd\u03c8\5\u00a0Q\2\u03be\u03c0\5J&\2\u03bf\u03be"+ - "\3\2\2\2\u03bf\u03c0\3\2\2\2\u03c0\u03c1\3\2\2\2\u03c1\u03c9\5:\36\2\u03c2"+ - "\u03c3\5\u00a4S\2\u03c3\u03c4\5\u0126\u0094\2\u03c4\u03c5\7Y\2\2\u03c5"+ - "\u03c6\5\u0126\u0094\2\u03c6\u03c7\5@!\2\u03c7\u03c9\3\2\2\2\u03c8\u03bf"+ - "\3\2\2\2\u03c8\u03c2\3\2\2\2\u03c9\u03d2\3\2\2\2\u03ca\u03cb\5\u00a0Q"+ - "\2\u03cb\u03cc\5J&\2\u03cc\u03cd\5:\36\2\u03cd\u03d2\3\2\2\2\u03ce\u03cf"+ - "\5J&\2\u03cf\u03d0\5:\36\2\u03d0\u03d2\3\2\2\2\u03d1\u03bd\3\2\2\2\u03d1"+ - "\u03ca\3\2\2\2\u03d1\u03ce\3\2\2\2\u03d2\u00a3\3\2\2\2\u03d3\u03d4\7P"+ - "\2\2\u03d4\u03d9\5\u00a6T\2\u03d5\u03d6\7W\2\2\u03d6\u03d8\5\u00a6T\2"+ - "\u03d7\u03d5\3\2\2\2\u03d8\u03db\3\2\2\2\u03d9\u03d7\3\2\2\2\u03d9\u03da"+ - "\3\2\2\2\u03da\u03dc\3\2\2\2\u03db\u03d9\3\2\2\2\u03dc\u03dd\5\u0124\u0093"+ - "\2\u03dd\u00a5\3\2\2\2\u03de\u03e0\5J&\2\u03df\u03de\3\2\2\2\u03df\u03e0"+ - "\3\2\2\2\u03e0\u03e1\3\2\2\2\u03e1\u03e2\5> \2\u03e2\u00a7\3\2\2\2\u03e3"+ - "\u03e4\7P\2\2\u03e4\u03e7\5> \2\u03e5\u03e6\7W\2\2\u03e6\u03e8\5> \2\u03e7"+ - "\u03e5\3\2\2\2\u03e8\u03e9\3\2\2\2\u03e9\u03e7\3\2\2\2\u03e9\u03ea\3\2"+ - "\2\2\u03ea\u03eb\3\2\2\2\u03eb\u03ec\5\u0124\u0093\2\u03ec\u00a9\3\2\2"+ - "\2\u03ed\u03f0\5\u00acW\2\u03ee\u03f0\5\u00aeX\2\u03ef\u03ed\3\2\2\2\u03ef"+ - "\u03ee\3\2\2\2\u03f0\u00ab\3\2\2\2\u03f1\u03f2\7 \2\2\u03f2\u03f3\5\u00da"+ - "n\2\u03f3\u03f4\5\u0126\u0094\2\u03f4\u03fd\5\u00ba^\2\u03f5\u03f8\5\u0126"+ - "\u0094\2\u03f6\u03f8\5\u0128\u0095\2\u03f7\u03f5\3\2\2\2\u03f7\u03f6\3"+ - "\2\2\2\u03f8\u03f9\3\2\2\2\u03f9\u03fa\7\32\2\2\u03fa\u03fb\5\u0126\u0094"+ - "\2\u03fb\u03fc\5\u00ba^\2\u03fc\u03fe\3\2\2\2\u03fd\u03f7\3\2\2\2\u03fd"+ + "o\3p\3p\3p\5p\u04d6\np\3p\3p\3q\3q\5q\u04dc\nq\3r\3r\3s\3s\5s\u04e2\n"+ + "s\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\5t\u04f5\nt\3t\3"+ + "t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3"+ + "t\5t\u0510\nt\3t\5t\u0513\nt\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3"+ + "t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3"+ + "t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3"+ + "t\3t\3t\5t\u0553\nt\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\3t\7t\u0563"+ + "\nt\ft\16t\u0566\13t\3u\3u\3u\3u\5u\u056c\nu\3u\7u\u056f\nu\fu\16u\u0572"+ + "\13u\3v\3v\6v\u0576\nv\rv\16v\u0577\3v\5v\u057b\nv\3w\3w\3w\3w\7w\u0581"+ + "\nw\fw\16w\u0584\13w\3x\3x\3x\3x\3x\5x\u058b\nx\3x\3x\3x\3x\5x\u0591\n"+ + "x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3x\3"+ + "x\5x\u05aa\nx\3y\3y\3y\3y\5y\u05b0\ny\3z\3z\5z\u05b4\nz\3{\5{\u05b7\n"+ + "{\3{\3{\5{\u05bb\n{\3{\3{\3|\5|\u05c0\n|\3|\3|\3|\5|\u05c5\n|\3|\3|\3"+ + "}\3}\5}\u05cb\n}\3}\3}\3}\3}\3}\3}\3}\3}\3}\3}\3}\3}\3}\3}\5}\u05db\n"+ + "}\3~\3~\5~\u05df\n~\3~\5~\u05e2\n~\3~\3~\3\177\3\177\3\177\5\177\u05e9"+ + "\n\177\3\177\5\177\u05ec\n\177\3\177\3\177\3\u0080\3\u0080\3\u0080\7\u0080"+ + "\u05f3\n\u0080\f\u0080\16\u0080\u05f6\13\u0080\3\u0081\3\u0081\3\u0081"+ + "\3\u0081\3\u0081\3\u0081\3\u0081\3\u0081\3\u0081\3\u0081\5\u0081\u0602"+ + "\n\u0081\3\u0082\3\u0082\5\u0082\u0606\n\u0082\3\u0083\3\u0083\3\u0083"+ + "\3\u0083\3\u0083\5\u0083\u060d\n\u0083\3\u0083\3\u0083\3\u0083\3\u0083"+ + "\3\u0083\3\u0083\6\u0083\u0615\n\u0083\r\u0083\16\u0083\u0616\3\u0083"+ + "\3\u0083\3\u0083\3\u0083\3\u0083\3\u0083\3\u0083\5\u0083\u0620\n\u0083"+ + "\3\u0084\3\u0084\3\u0084\5\u0084\u0625\n\u0084\3\u0084\3\u0084\3\u0084"+ + "\3\u0085\3\u0085\3\u0086\3\u0086\3\u0086\3\u0086\5\u0086\u0630\n\u0086"+ + "\5\u0086\u0632\n\u0086\3\u0087\3\u0087\3\u0087\3\u0087\3\u0087\3\u0087"+ + "\3\u0088\3\u0088\3\u0088\5\u0088\u063d\n\u0088\3\u0089\3\u0089\5\u0089"+ + "\u0641\n\u0089\3\u0089\5\u0089\u0644\n\u0089\3\u0089\3\u0089\3\u008a\3"+ + "\u008a\3\u008a\3\u008a\3\u008a\7\u008a\u064d\n\u008a\f\u008a\16\u008a"+ + "\u0650\13\u008a\3\u008b\3\u008b\3\u008b\3\u008b\3\u008b\7\u008b\u0657"+ + "\n\u008b\f\u008b\16\u008b\u065a\13\u008b\3\u008c\3\u008c\5\u008c\u065e"+ + "\n\u008c\3\u008d\3\u008d\3\u008d\5\u008d\u0663\n\u008d\3\u008e\3\u008e"+ + "\3\u008f\3\u008f\3\u0090\3\u0090\3\u0090\3\u0090\3\u0090\3\u0090\3\u0090"+ + "\3\u0090\5\u0090\u0671\n\u0090\3\u0091\3\u0091\3\u0092\3\u0092\3\u0093"+ + "\3\u0093\5\u0093\u0679\n\u0093\3\u0094\7\u0094\u067c\n\u0094\f\u0094\16"+ + "\u0094\u067f\13\u0094\3\u0095\6\u0095\u0682\n\u0095\r\u0095\16\u0095\u0683"+ + "\3\u0095\2\2\3\u00e6\u0096\2\2\4\2\6\2\b\2\n\2\f\2\16\2\20\2\22\2\24\2"+ + "\26\2\30\2\32\2\34\2\36\2 \2\"\2$\2&\2(\2*\2,\2.\2\60\2\62\2\64\2\66\2"+ + "8\2:\2<\2>\2@\2B\2D\2F\2H\2J\2L\2N\2P\2R\2T\2V\2X\2Z\2\\\2^\2`\2b\2d\2"+ + "f\2h\2j\2l\2n\2p\2r\2t\2v\2x\2z\2|\2~\2\u0080\2\u0082\2\u0084\2\u0086"+ + "\2\u0088\2\u008a\2\u008c\2\u008e\2\u0090\2\u0092\2\u0094\2\u0096\2\u0098"+ + "\2\u009a\2\u009c\2\u009e\2\u00a0\2\u00a2\2\u00a4\2\u00a6\2\u00a8\2\u00aa"+ + "\2\u00ac\2\u00ae\2\u00b0\2\u00b2\2\u00b4\2\u00b6\2\u00b8\2\u00ba\2\u00bc"+ + "\2\u00be\2\u00c0\2\u00c2\2\u00c4\2\u00c6\2\u00c8\2\u00ca\2\u00cc\2\u00ce"+ + "\2\u00d0\2\u00d2\2\u00d4\2\u00d6\2\u00d8\2\u00da\2\u00dc\2\u00de\2\u00e0"+ + "\2\u00e2\2\u00e4\2\u00e6\2\u00e8\2\u00ea\2\u00ec\2\u00ee\2\u00f0\2\u00f2"+ + "\2\u00f4\2\u00f6\2\u00f8\2\u00fa\2\u00fc\2\u00fe\2\u0100\2\u0102\2\u0104"+ + "\2\u0106\2\u0108\2\u010a\2\u010c\2\u010e\2\u0110\2\u0112\2\u0114\2\u0116"+ + "\2\u0118\2\u011a\2\u011c\2\u011e\2\u0120\2\u0122\2\u0124\2\u0126\2\u0128"+ + "\2\2\27\b\2\n\n\16\16&&\61\61\65\6588\7\2\20\20\30\30\35\35)+-.\b\2\n"+ + "\n\16\16\20\20\35\35)+-.\4\2\34\34//\4\2WW__\4\2\13\13__\3\2fg\3\2\\]"+ + "\3\2fi\4\2jkoo\3\2hi\3\2>?\6\2\13\13OOZ[ab\5\2JL``cc\3\2FG\5\2\t\t$$N"+ + "N\5\2IIYYp{\4\2@BXX\4\2\17\17\67\67\4\2\t9<=\4\2VV\u0081\u0081\2\u06f3"+ + "\2\u012a\3\2\2\2\4\u0136\3\2\2\2\6\u0142\3\2\2\2\b\u0146\3\2\2\2\n\u0152"+ + "\3\2\2\2\f\u0157\3\2\2\2\16\u015a\3\2\2\2\20\u015f\3\2\2\2\22\u0164\3"+ + "\2\2\2\24\u0169\3\2\2\2\26\u016f\3\2\2\2\30\u0173\3\2\2\2\32\u0176\3\2"+ + "\2\2\34\u017b\3\2\2\2\36\u017f\3\2\2\2 \u018e\3\2\2\2\"\u0195\3\2\2\2"+ + "$\u019f\3\2\2\2&\u01b4\3\2\2\2(\u01dc\3\2\2\2*\u01f8\3\2\2\2,\u0208\3"+ + "\2\2\2.\u0217\3\2\2\2\60\u021e\3\2\2\2\62\u023f\3\2\2\2\64\u0243\3\2\2"+ + "\2\66\u0248\3\2\2\28\u024a\3\2\2\2:\u024c\3\2\2\2<\u0256\3\2\2\2>\u025e"+ + "\3\2\2\2@\u0260\3\2\2\2B\u0262\3\2\2\2D\u0276\3\2\2\2F\u027b\3\2\2\2H"+ + "\u027d\3\2\2\2J\u0284\3\2\2\2L\u0290\3\2\2\2N\u0295\3\2\2\2P\u0299\3\2"+ + "\2\2R\u029d\3\2\2\2T\u029f\3\2\2\2V\u02b7\3\2\2\2X\u02b9\3\2\2\2Z\u02bc"+ + "\3\2\2\2\\\u02c6\3\2\2\2^\u02ce\3\2\2\2`\u02d9\3\2\2\2b\u02dc\3\2\2\2"+ + "d\u02eb\3\2\2\2f\u02ed\3\2\2\2h\u02fa\3\2\2\2j\u0301\3\2\2\2l\u0304\3"+ + "\2\2\2n\u0307\3\2\2\2p\u0315\3\2\2\2r\u0317\3\2\2\2t\u0329\3\2\2\2v\u032b"+ + "\3\2\2\2x\u0332\3\2\2\2z\u0338\3\2\2\2|\u033e\3\2\2\2~\u0342\3\2\2\2\u0080"+ + "\u0346\3\2\2\2\u0082\u0348\3\2\2\2\u0084\u0357\3\2\2\2\u0086\u0359\3\2"+ + "\2\2\u0088\u036a\3\2\2\2\u008a\u036d\3\2\2\2\u008c\u0378\3\2\2\2\u008e"+ + "\u037a\3\2\2\2\u0090\u037c\3\2\2\2\u0092\u0384\3\2\2\2\u0094\u038c\3\2"+ + "\2\2\u0096\u0391\3\2\2\2\u0098\u0393\3\2\2\2\u009a\u03a3\3\2\2\2\u009c"+ + "\u03b2\3\2\2\2\u009e\u03b4\3\2\2\2\u00a0\u03bb\3\2\2\2\u00a2\u03d1\3\2"+ + "\2\2\u00a4\u03d3\3\2\2\2\u00a6\u03df\3\2\2\2\u00a8\u03e3\3\2\2\2\u00aa"+ + "\u03ef\3\2\2\2\u00ac\u03f1\3\2\2\2\u00ae\u03ff\3\2\2\2\u00b0\u0420\3\2"+ + "\2\2\u00b2\u0422\3\2\2\2\u00b4\u0426\3\2\2\2\u00b6\u042a\3\2\2\2\u00b8"+ + "\u043d\3\2\2\2\u00ba\u0464\3\2\2\2\u00bc\u0466\3\2\2\2\u00be\u0471\3\2"+ + "\2\2\u00c0\u0479\3\2\2\2\u00c2\u047d\3\2\2\2\u00c4\u0485\3\2\2\2\u00c6"+ + "\u0490\3\2\2\2\u00c8\u0495\3\2\2\2\u00ca\u04a1\3\2\2\2\u00cc\u04a5\3\2"+ + "\2\2\u00ce\u04a7\3\2\2\2\u00d0\u04b0\3\2\2\2\u00d2\u04bc\3\2\2\2\u00d4"+ + "\u04be\3\2\2\2\u00d6\u04c0\3\2\2\2\u00d8\u04c4\3\2\2\2\u00da\u04c6\3\2"+ + "\2\2\u00dc\u04ca\3\2\2\2\u00de\u04d5\3\2\2\2\u00e0\u04db\3\2\2\2\u00e2"+ + "\u04dd\3\2\2\2\u00e4\u04df\3\2\2\2\u00e6\u04f4\3\2\2\2\u00e8\u0567\3\2"+ + "\2\2\u00ea\u0573\3\2\2\2\u00ec\u057c\3\2\2\2\u00ee\u05a9\3\2\2\2\u00f0"+ + "\u05af\3\2\2\2\u00f2\u05b3\3\2\2\2\u00f4\u05b6\3\2\2\2\u00f6\u05bf\3\2"+ + "\2\2\u00f8\u05da\3\2\2\2\u00fa\u05dc\3\2\2\2\u00fc\u05e5\3\2\2\2\u00fe"+ + "\u05ef\3\2\2\2\u0100\u0601\3\2\2\2\u0102\u0605\3\2\2\2\u0104\u0607\3\2"+ + "\2\2\u0106\u0621\3\2\2\2\u0108\u0629\3\2\2\2\u010a\u062b\3\2\2\2\u010c"+ + "\u0633\3\2\2\2\u010e\u063c\3\2\2\2\u0110\u063e\3\2\2\2\u0112\u0647\3\2"+ + "\2\2\u0114\u0651\3\2\2\2\u0116\u065d\3\2\2\2\u0118\u0662\3\2\2\2\u011a"+ + "\u0664\3\2\2\2\u011c\u0666\3\2\2\2\u011e\u0670\3\2\2\2\u0120\u0672\3\2"+ + "\2\2\u0122\u0674\3\2\2\2\u0124\u0678\3\2\2\2\u0126\u067d\3\2\2\2\u0128"+ + "\u0681\3\2\2\2\u012a\u012c\5\u0126\u0094\2\u012b\u012d\5\6\4\2\u012c\u012b"+ + "\3\2\2\2\u012c\u012d\3\2\2\2\u012d\u012f\3\2\2\2\u012e\u0130\5\u0128\u0095"+ + "\2\u012f\u012e\3\2\2\2\u012f\u0130\3\2\2\2\u0130\u0132\3\2\2\2\u0131\u0133"+ + "\5\4\3\2\u0132\u0131\3\2\2\2\u0132\u0133\3\2\2\2\u0133\u0134\3\2\2\2\u0134"+ + "\u0135\7\2\2\3\u0135\3\3\2\2\2\u0136\u013c\5\u00ba^\2\u0137\u0138\5\u0128"+ + "\u0095\2\u0138\u0139\5\u00ba^\2\u0139\u013b\3\2\2\2\u013a\u0137\3\2\2"+ + "\2\u013b\u013e\3\2\2\2\u013c\u013a\3\2\2\2\u013c\u013d\3\2\2\2\u013d\u0140"+ + "\3\2\2\2\u013e\u013c\3\2\2\2\u013f\u0141\5\u0128\u0095\2\u0140\u013f\3"+ + "\2\2\2\u0140\u0141\3\2\2\2\u0141\5\3\2\2\2\u0142\u0143\5\u0088E\2\u0143"+ + "\u0144\7(\2\2\u0144\u0145\5f\64\2\u0145\7\3\2\2\2\u0146\u0147\5\u0088"+ + "E\2\u0147\u0149\7#\2\2\u0148\u014a\7-\2\2\u0149\u0148\3\2\2\2\u0149\u014a"+ + "\3\2\2\2\u014a\u014b\3\2\2\2\u014b\u0150\5f\64\2\u014c\u014d\7X\2\2\u014d"+ + "\u0151\7j\2\2\u014e\u014f\7\t\2\2\u014f\u0151\5\u011e\u0090\2\u0150\u014c"+ + "\3\2\2\2\u0150\u014e\3\2\2\2\u0150\u0151\3\2\2\2\u0151\t\3\2\2\2\u0152"+ + "\u0153\5\22\n\2\u0153\u0154\5&\24\2\u0154\13\3\2\2\2\u0155\u0158\5\26"+ + "\f\2\u0156\u0158\t\2\2\2\u0157\u0155\3\2\2\2\u0157\u0156\3\2\2\2\u0158"+ + "\r\3\2\2\2\u0159\u015b\5\20\t\2\u015a\u0159\3\2\2\2\u015a\u015b\3\2\2"+ + "\2\u015b\17\3\2\2\2\u015c\u015d\5\f\7\2\u015d\u015e\5\u0126\u0094\2\u015e"+ + "\u0160\3\2\2\2\u015f\u015c\3\2\2\2\u0160\u0161\3\2\2\2\u0161\u015f\3\2"+ + "\2\2\u0161\u0162\3\2\2\2\u0162\21\3\2\2\2\u0163\u0165\5\24\13\2\u0164"+ + "\u0163\3\2\2\2\u0164\u0165\3\2\2\2\u0165\23\3\2\2\2\u0166\u0167\5\26\f"+ + "\2\u0167\u0168\5\u0126\u0094\2\u0168\u016a\3\2\2\2\u0169\u0166\3\2\2\2"+ + "\u016a\u016b\3\2\2\2\u016b\u0169\3\2\2\2\u016b\u016c\3\2\2\2\u016c\25"+ + "\3\2\2\2\u016d\u0170\5\u008aF\2\u016e\u0170\t\3\2\2\u016f\u016d\3\2\2"+ + "\2\u016f\u016e\3\2\2\2\u0170\27\3\2\2\2\u0171\u0174\5\u008aF\2\u0172\u0174"+ + "\t\4\2\2\u0173\u0171\3\2\2\2\u0173\u0172\3\2\2\2\u0174\31\3\2\2\2\u0175"+ + "\u0177\5\34\17\2\u0176\u0175\3\2\2\2\u0176\u0177\3\2\2\2\u0177\33\3\2"+ + "\2\2\u0178\u0179\5\30\r\2\u0179\u017a\5\u0126\u0094\2\u017a\u017c\3\2"+ + "\2\2\u017b\u0178\3\2\2\2\u017c\u017d\3\2\2\2\u017d\u017b\3\2\2\2\u017d"+ + "\u017e\3\2\2\2\u017e\35\3\2\2\2\u017f\u0180\7[\2\2\u0180\u0181\5\u0126"+ + "\u0094\2\u0181\u0188\5 \21\2\u0182\u0183\7W\2\2\u0183\u0184\5\u0126\u0094"+ + "\2\u0184\u0185\5 \21\2\u0185\u0187\3\2\2\2\u0186\u0182\3\2\2\2\u0187\u018a"+ + "\3\2\2\2\u0188\u0186\3\2\2\2\u0188\u0189\3\2\2\2\u0189\u018b\3\2\2\2\u018a"+ + "\u0188\3\2\2\2\u018b\u018c\5\u0126\u0094\2\u018c\u018d\7Z\2\2\u018d\37"+ + "\3\2\2\2\u018e\u0193\5\u011c\u008f\2\u018f\u0190\7\34\2\2\u0190\u0191"+ + "\5\u0126\u0094\2\u0191\u0192\5\"\22\2\u0192\u0194\3\2\2\2\u0193\u018f"+ + "\3\2\2\2\u0193\u0194\3\2\2\2\u0194!\3\2\2\2\u0195\u019c\5J&\2\u0196\u0197"+ + "\7l\2\2\u0197\u0198\5\u0126\u0094\2\u0198\u0199\5J&\2\u0199\u019b\3\2"+ + "\2\2\u019a\u0196\3\2\2\2\u019b\u019e\3\2\2\2\u019c\u019a\3\2\2\2\u019c"+ + "\u019d\3\2\2\2\u019d#\3\2\2\2\u019e\u019c\3\2\2\2\u019f\u01a6\5J&\2\u01a0"+ + "\u01a1\7W\2\2\u01a1\u01a2\5\u0126\u0094\2\u01a2\u01a3\5J&\2\u01a3\u01a5"+ + "\3\2\2\2\u01a4\u01a0\3\2\2\2\u01a5\u01a8\3\2\2\2\u01a6\u01a4\3\2\2\2\u01a6"+ + "\u01a7\3\2\2\2\u01a7%\3\2\2\2\u01a8\u01a6\3\2\2\2\u01a9\u01aa\7\25\2\2"+ + "\u01aa\u01b5\b\24\1\2\u01ab\u01ac\7%\2\2\u01ac\u01b5\b\24\1\2\u01ad\u01ae"+ + "\7\33\2\2\u01ae\u01b5\b\24\1\2\u01af\u01b0\7~\2\2\u01b0\u01b1\7%\2\2\u01b1"+ + "\u01b5\b\24\1\2\u01b2\u01b3\7\f\2\2\u01b3\u01b5\b\24\1\2\u01b4\u01a9\3"+ + "\2\2\2\u01b4\u01ab\3\2\2\2\u01b4\u01ad\3\2\2\2\u01b4\u01af\3\2\2\2\u01b4"+ + "\u01b2\3\2\2\2\u01b5\u01b6\3\2\2\2\u01b6\u01b7\5\u011e\u0090\2\u01b7\u01d8"+ + "\5\u0126\u0094\2\u01b8\u01ba\6\24\2\3\u01b9\u01bb\5\36\20\2\u01ba\u01b9"+ + "\3\2\2\2\u01ba\u01bb\3\2\2\2\u01bb\u01bc\3\2\2\2\u01bc\u01ca\5\u0126\u0094"+ + "\2\u01bd\u01c7\6\24\3\3\u01be\u01bf\7\34\2\2\u01bf\u01c3\5\u0126\u0094"+ + "\2\u01c0\u01c1\6\24\4\3\u01c1\u01c4\5$\23\2\u01c2\u01c4\5J&\2\u01c3\u01c0"+ + "\3\2\2\2\u01c3\u01c2\3\2\2\2\u01c4\u01c5\3\2\2\2\u01c5\u01c6\5\u0126\u0094"+ + "\2\u01c6\u01c8\3\2\2\2\u01c7\u01be\3\2\2\2\u01c7\u01c8\3\2\2\2\u01c8\u01cb"+ + "\3\2\2\2\u01c9\u01cb\3\2\2\2\u01ca\u01bd\3\2\2\2\u01ca\u01c9\3\2\2\2\u01cb"+ + "\u01d5\3\2\2\2\u01cc\u01d2\6\24\5\3\u01cd\u01ce\7\"\2\2\u01ce\u01cf\5"+ + "\u0126\u0094\2\u01cf\u01d0\5$\23\2\u01d0\u01d1\5\u0126\u0094\2\u01d1\u01d3"+ + "\3\2\2\2\u01d2\u01cd\3\2\2\2\u01d2\u01d3\3\2\2\2\u01d3\u01d6\3\2\2\2\u01d4"+ + "\u01d6\3\2\2\2\u01d5\u01cc\3\2\2\2\u01d5\u01d4\3\2\2\2\u01d6\u01d9\3\2"+ + "\2\2\u01d7\u01d9\3\2\2\2\u01d8\u01b8\3\2\2\2\u01d8\u01d7\3\2\2\2\u01d9"+ + "\u01da\3\2\2\2\u01da\u01db\5(\25\2\u01db\'\3\2\2\2\u01dc\u01dd\7R\2\2"+ + "\u01dd\u01e6\5\u0126\u0094\2\u01de\u01e0\6\25\6\3\u01df\u01e1\5*\26\2"+ + "\u01e0\u01df\3\2\2\2\u01e0\u01e1\3\2\2\2\u01e1\u01e3\3\2\2\2\u01e2\u01e4"+ + "\5\u0128\u0095\2\u01e3\u01e2\3\2\2\2\u01e3\u01e4\3\2\2\2\u01e4\u01e7\3"+ + "\2\2\2\u01e5\u01e7\3\2\2\2\u01e6\u01de\3\2\2\2\u01e6\u01e5\3\2\2\2\u01e7"+ + "\u01e9\3\2\2\2\u01e8\u01ea\5.\30\2\u01e9\u01e8\3\2\2\2\u01e9\u01ea\3\2"+ + "\2\2\u01ea\u01f0\3\2\2\2\u01eb\u01ec\5\u0128\u0095\2\u01ec\u01ed\5.\30"+ + "\2\u01ed\u01ef\3\2\2\2\u01ee\u01eb\3\2\2\2\u01ef\u01f2\3\2\2\2\u01f0\u01ee"+ + "\3\2\2\2\u01f0\u01f1\3\2\2\2\u01f1\u01f4\3\2\2\2\u01f2\u01f0\3\2\2\2\u01f3"+ + "\u01f5\5\u0128\u0095\2\u01f4\u01f3\3\2\2\2\u01f4\u01f5\3\2\2\2\u01f5\u01f6"+ + "\3\2\2\2\u01f6\u01f7\7S\2\2\u01f7)\3\2\2\2\u01f8\u0200\5,\27\2\u01f9\u01fa"+ + "\5\u0126\u0094\2\u01fa\u01fb\7W\2\2\u01fb\u01fc\5\u0126\u0094\2\u01fc"+ + "\u01fd\5,\27\2\u01fd\u01ff\3\2\2\2\u01fe\u01f9\3\2\2\2\u01ff\u0202\3\2"+ + "\2\2\u0200\u01fe\3\2\2\2\u0200\u0201\3\2\2\2\u0201\u0206\3\2\2\2\u0202"+ + "\u0200\3\2\2\2\u0203\u0204\5\u0126\u0094\2\u0204\u0205\7W\2\2\u0205\u0207"+ + "\3\2\2\2\u0206\u0203\3\2\2\2\u0206\u0207\3\2\2\2\u0207+\3\2\2\2\u0208"+ + "\u0209\5\u0088E\2\u0209\u020b\5\u011e\u0090\2\u020a\u020c\5\u0110\u0089"+ + "\2\u020b\u020a\3\2\2\2\u020b\u020c\3\2\2\2\u020c\u020e\3\2\2\2\u020d\u020f"+ + "\5\u0108\u0085\2\u020e\u020d\3\2\2\2\u020e\u020f\3\2\2\2\u020f-\3\2\2"+ + "\2\u0210\u0218\7V\2\2\u0211\u0212\7-\2\2\u0212\u0214\5\u0126\u0094\2\u0213"+ + "\u0211\3\2\2\2\u0213\u0214\3\2\2\2\u0214\u0215\3\2\2\2\u0215\u0218\5\u009a"+ + "N\2\u0216\u0218\5\60\31\2\u0217\u0210\3\2\2\2\u0217\u0213\3\2\2\2\u0217"+ + "\u0216\3\2\2\2\u0218/\3\2\2\2\u0219\u021f\5\62\32\2\u021a\u021f\58\35"+ + "\2\u021b\u021c\5\16\b\2\u021c\u021d\5&\24\2\u021d\u021f\3\2\2\2\u021e"+ + "\u0219\3\2\2\2\u021e\u021a\3\2\2\2\u021e\u021b\3\2\2\2\u021f\61\3\2\2"+ + "\2\u0220\u0221\6\32\7\3\u0221\u0222\5\66\34\2\u0222\u0223\5\64\33\2\u0223"+ + "\u0224\7P\2\2\u0224\u0229\5\u0124\u0093\2\u0225\u0226\7\30\2\2\u0226\u0227"+ + "\5\u0126\u0094\2\u0227\u0228\5\u0096L\2\u0228\u022a\3\2\2\2\u0229\u0225"+ + "\3\2\2\2\u0229\u022a\3\2\2\2\u022a\u0240\3\2\2\2\u022b\u022d\5\16\b\2"+ + "\u022c\u022e\5\36\20\2\u022d\u022c\3\2\2\2\u022d\u022e\3\2\2\2\u022e\u0230"+ + "\3\2\2\2\u022f\u0231\5\66\34\2\u0230\u022f\3\2\2\2\u0230\u0231\3\2\2\2"+ + "\u0231\u0232\3\2\2\2\u0232\u0233\5\64\33\2\u0233\u0239\5\\/\2\u0234\u0235"+ + "\5\u0126\u0094\2\u0235\u0236\7\64\2\2\u0236\u0237\5\u0126\u0094\2\u0237"+ + "\u0238\5Z.\2\u0238\u023a\3\2\2\2\u0239\u0234\3\2\2\2\u0239\u023a\3\2\2"+ + "\2\u023a\u023b\3\2\2\2\u023b\u023d\5\u0126\u0094\2\u023c\u023e\5d\63\2"+ + "\u023d\u023c\3\2\2\2\u023d\u023e\3\2\2\2\u023e\u0240\3\2\2\2\u023f\u0220"+ + "\3\2\2\2\u023f\u022b\3\2\2\2\u0240\63\3\2\2\2\u0241\u0244\5\u011e\u0090"+ + "\2\u0242\u0244\5\u011a\u008e\2\u0243\u0241\3\2\2\2\u0243\u0242\3\2\2\2"+ + "\u0244\65\3\2\2\2\u0245\u0249\5H%\2\u0246\u0247\6\34\b\3\u0247\u0249\7"+ + "\67\2\2\u0248\u0245\3\2\2\2\u0248\u0246\3\2\2\2\u0249\67\3\2\2\2\u024a"+ + "\u024b\5\u00a2R\2\u024b9\3\2\2\2\u024c\u0253\5<\37\2\u024d\u024e\7W\2"+ + "\2\u024e\u024f\5\u0126\u0094\2\u024f\u0250\5<\37\2\u0250\u0252\3\2\2\2"+ + "\u0251\u024d\3\2\2\2\u0252\u0255\3\2\2\2\u0253\u0251\3\2\2\2\u0253\u0254"+ + "\3\2\2\2\u0254;\3\2\2\2\u0255\u0253\3\2\2\2\u0256\u025c\5> \2\u0257\u0258"+ + "\5\u0126\u0094\2\u0258\u0259\7Y\2\2\u0259\u025a\5\u0126\u0094\2\u025a"+ + "\u025b\5@!\2\u025b\u025d\3\2\2\2\u025c\u0257\3\2\2\2\u025c\u025d\3\2\2"+ + "\2\u025d=\3\2\2\2\u025e\u025f\5\u011e\u0090\2\u025f?\3\2\2\2\u0260\u0261"+ + "\5\u00e0q\2\u0261A\3\2\2\2\u0262\u0263\5@!\2\u0263\u026b\5\u0126\u0094"+ + "\2\u0264\u0265\7W\2\2\u0265\u0266\5\u0126\u0094\2\u0266\u0267\5@!\2\u0267"+ + "\u0268\5\u0126\u0094\2\u0268\u026a\3\2\2\2\u0269\u0264\3\2\2\2\u026a\u026d"+ + "\3\2\2\2\u026b\u0269\3\2\2\2\u026b\u026c\3\2\2\2\u026c\u026e\3\2\2\2\u026d"+ + "\u026b\3\2\2\2\u026e\u0270\5\u0126\u0094\2\u026f\u0271\7W\2\2\u0270\u026f"+ + "\3\2\2\2\u0270\u0271\3\2\2\2\u0271C\3\2\2\2\u0272\u0273\5\u0088E\2\u0273"+ + "\u0274\7T\2\2\u0274\u0275\7U\2\2\u0275\u0277\3\2\2\2\u0276\u0272\3\2\2"+ + "\2\u0277\u0278\3\2\2\2\u0278\u0276\3\2\2\2\u0278\u0279\3\2\2\2\u0279E"+ + "\3\2\2\2\u027a\u027c\5D#\2\u027b\u027a\3\2\2\2\u027b\u027c\3\2\2\2\u027c"+ + "G\3\2\2\2\u027d\u0280\5\u0088E\2\u027e\u0281\5R*\2\u027f\u0281\5P)\2\u0280"+ + "\u027e\3\2\2\2\u0280\u027f\3\2\2\2\u0281\u0282\3\2\2\2\u0282\u0283\5F"+ + "$\2\u0283I\3\2\2\2\u0284\u028a\5\u0088E\2\u0285\u0288\5R*\2\u0286\u0288"+ + "\7\67\2\2\u0287\u0285\3\2\2\2\u0287\u0286\3\2\2\2\u0288\u028b\3\2\2\2"+ + "\u0289\u028b\5N(\2\u028a\u0287\3\2\2\2\u028a\u0289\3\2\2\2\u028b\u028c"+ + "\3\2\2\2\u028c\u028d\5F$\2\u028dK\3\2\2\2\u028e\u0291\5l\67\2\u028f\u0291"+ + "\5n8\2\u0290\u028e\3\2\2\2\u0290\u028f\3\2\2\2\u0291\u0293\3\2\2\2\u0292"+ + "\u0294\5T+\2\u0293\u0292\3\2\2\2\u0293\u0294\3\2\2\2\u0294M\3\2\2\2\u0295"+ + "\u0297\5l\67\2\u0296\u0298\5T+\2\u0297\u0296\3\2\2\2\u0297\u0298\3\2\2"+ + "\2\u0298O\3\2\2\2\u0299\u029b\5n8\2\u029a\u029c\5T+\2\u029b\u029a\3\2"+ + "\2\2\u029b\u029c\3\2\2\2\u029cQ\3\2\2\2\u029d\u029e\7\17\2\2\u029eS\3"+ + "\2\2\2\u029f\u02a0\7[\2\2\u02a0\u02a1\5\u0126\u0094\2\u02a1\u02a8\5V,"+ + "\2\u02a2\u02a3\7W\2\2\u02a3\u02a4\5\u0126\u0094\2\u02a4\u02a5\5V,\2\u02a5"+ + "\u02a7\3\2\2\2\u02a6\u02a2\3\2\2\2\u02a7\u02aa\3\2\2\2\u02a8\u02a6\3\2"+ + "\2\2\u02a8\u02a9\3\2\2\2\u02a9\u02ab\3\2\2\2\u02aa\u02a8\3\2\2\2\u02ab"+ + "\u02ac\5\u0126\u0094\2\u02ac\u02ad\7Z\2\2\u02adU\3\2\2\2\u02ae\u02b8\5"+ + "J&\2\u02af\u02b0\5\u0088E\2\u02b0\u02b5\7^\2\2\u02b1\u02b2\t\5\2\2\u02b2"+ + "\u02b3\5\u0126\u0094\2\u02b3\u02b4\5J&\2\u02b4\u02b6\3\2\2\2\u02b5\u02b1"+ + "\3\2\2\2\u02b5\u02b6\3\2\2\2\u02b6\u02b8\3\2\2\2\u02b7\u02ae\3\2\2\2\u02b7"+ + "\u02af\3\2\2\2\u02b8W\3\2\2\2\u02b9\u02ba\5\u0088E\2\u02ba\u02bb\5l\67"+ + "\2\u02bbY\3\2\2\2\u02bc\u02c3\5X-\2\u02bd\u02be\7W\2\2\u02be\u02bf\5\u0126"+ + "\u0094\2\u02bf\u02c0\5X-\2\u02c0\u02c2\3\2\2\2\u02c1\u02bd\3\2\2\2\u02c2"+ + "\u02c5\3\2\2\2\u02c3\u02c1\3\2\2\2\u02c3\u02c4\3\2\2\2\u02c4[\3\2\2\2"+ + "\u02c5\u02c3\3\2\2\2\u02c6\u02c8\7P\2\2\u02c7\u02c9\5^\60\2\u02c8\u02c7"+ + "\3\2\2\2\u02c8\u02c9\3\2\2\2\u02c9\u02ca\3\2\2\2\u02ca\u02cb\5\u0124\u0093"+ + "\2\u02cb]\3\2\2\2\u02cc\u02cf\5b\62\2\u02cd\u02cf\5`\61\2\u02ce\u02cc"+ + "\3\2\2\2\u02ce\u02cd\3\2\2\2\u02cf\u02d6\3\2\2\2\u02d0\u02d1\7W\2\2\u02d1"+ + "\u02d2\5\u0126\u0094\2\u02d2\u02d3\5b\62\2\u02d3\u02d5\3\2\2\2\u02d4\u02d0"+ + "\3\2\2\2\u02d5\u02d8\3\2\2\2\u02d6\u02d4\3\2\2\2\u02d6\u02d7\3\2\2\2\u02d7"+ + "_\3\2\2\2\u02d8\u02d6\3\2\2\2\u02d9\u02da\5J&\2\u02da\u02db\7\62\2\2\u02db"+ + "a\3\2\2\2\u02dc\u02de\5\32\16\2\u02dd\u02df\5J&\2\u02de\u02dd\3\2\2\2"+ + "\u02de\u02df\3\2\2\2\u02df\u02e1\3\2\2\2\u02e0\u02e2\7\177\2\2\u02e1\u02e0"+ + "\3\2\2\2\u02e1\u02e2\3\2\2\2\u02e2\u02e3\3\2\2\2\u02e3\u02e9\5> \2\u02e4"+ + "\u02e5\5\u0126\u0094\2\u02e5\u02e6\7Y\2\2\u02e6\u02e7\5\u0126\u0094\2"+ + "\u02e7\u02e8\5\u00e6t\2\u02e8\u02ea\3\2\2\2\u02e9\u02e4\3\2\2\2\u02e9"+ + "\u02ea\3\2\2\2\u02eac\3\2\2\2\u02eb\u02ec\5\u009aN\2\u02ece\3\2\2\2\u02ed"+ + "\u02f2\5h\65\2\u02ee\u02ef\7X\2\2\u02ef\u02f1\5h\65\2\u02f0\u02ee\3\2"+ + "\2\2\u02f1\u02f4\3\2\2\2\u02f2\u02f0\3\2\2\2\u02f2\u02f3\3\2\2\2\u02f3"+ + "g\3\2\2\2\u02f4\u02f2\3\2\2\2\u02f5\u02fb\5\u011e\u0090\2\u02f6\u02fb"+ + "\7\n\2\2\u02f7\u02fb\7\13\2\2\u02f8\u02fb\7\t\2\2\u02f9\u02fb\7\f\2\2"+ + "\u02fa\u02f5\3\2\2\2\u02fa\u02f6\3\2\2\2\u02fa\u02f7\3\2\2\2\u02fa\u02f8"+ + "\3\2\2\2\u02fa\u02f9\3\2\2\2\u02fbi\3\2\2\2\u02fc\u02fd\5h\65\2\u02fd"+ + "\u02fe\7X\2\2\u02fe\u0300\3\2\2\2\u02ff\u02fc\3\2\2\2\u0300\u0303\3\2"+ + "\2\2\u0301\u02ff\3\2\2\2\u0301\u0302\3\2\2\2\u0302k\3\2\2\2\u0303\u0301"+ + "\3\2\2\2\u0304\u0305\5j\66\2\u0305\u0306\5\u011e\u0090\2\u0306m\3\2\2"+ + "\2\u0307\u0308\5j\66\2\u0308\u030d\5\u011c\u008f\2\u0309\u030a\7X\2\2"+ + "\u030a\u030c\5\u011c\u008f\2\u030b\u0309\3\2\2\2\u030c\u030f\3\2\2\2\u030d"+ + "\u030b\3\2\2\2\u030d\u030e\3\2\2\2\u030eo\3\2\2\2\u030f\u030d\3\2\2\2"+ + "\u0310\u0316\7:\2\2\u0311\u0316\7;\2\2\u0312\u0316\5\u011a\u008e\2\u0313"+ + "\u0316\7<\2\2\u0314\u0316\7=\2\2\u0315\u0310\3\2\2\2\u0315\u0311\3\2\2"+ + "\2\u0315\u0312\3\2\2\2\u0315\u0313\3\2\2\2\u0315\u0314\3\2\2\2\u0316q"+ + "\3\2\2\2\u0317\u0318\7\4\2\2\u0318\u031d\5t;\2\u0319\u031a\7\6\2\2\u031a"+ + "\u031c\5t;\2\u031b\u0319\3\2\2\2\u031c\u031f\3\2\2\2\u031d\u031b\3\2\2"+ + "\2\u031d\u031e\3\2\2\2\u031e\u0320\3\2\2\2\u031f\u031d\3\2\2\2\u0320\u0321"+ + "\7\5\2\2\u0321s\3\2\2\2\u0322\u032a\5v<\2\u0323\u0325\7R\2\2\u0324\u0326"+ + "\5\u00e2r\2\u0325\u0324\3\2\2\2\u0325\u0326\3\2\2\2\u0326\u0327\3\2\2"+ + "\2\u0327\u032a\7S\2\2\u0328\u032a\5\u0082B\2\u0329\u0322\3\2\2\2\u0329"+ + "\u0323\3\2\2\2\u0329\u0328\3\2\2\2\u032au\3\2\2\2\u032b\u032f\5\u011e"+ + "\u0090\2\u032c\u032e\7\7\2\2\u032d\u032c\3\2\2\2\u032e\u0331\3\2\2\2\u032f"+ + "\u032d\3\2\2\2\u032f\u0330\3\2\2\2\u0330w\3\2\2\2\u0331\u032f\3\2\2\2"+ + "\u0332\u0333\5|?\2\u0333\u0334\5\u0126\u0094\2\u0334\u0335\7M\2\2\u0335"+ + "\u0336\5\u0126\u0094\2\u0336\u0337\5\u0080A\2\u0337y\3\2\2\2\u0338\u0339"+ + "\5~@\2\u0339\u033a\5\u0126\u0094\2\u033a\u033b\7M\2\2\u033b\u033c\5\u0126"+ + "\u0094\2\u033c\u033d\5\u0080A\2\u033d{\3\2\2\2\u033e\u033f\5\\/\2\u033f"+ + "}\3\2\2\2\u0340\u0343\5\\/\2\u0341\u0343\5> \2\u0342\u0340\3\2\2\2\u0342"+ + "\u0341\3\2\2\2\u0343\177\3\2\2\2\u0344\u0347\5\u009aN\2\u0345\u0347\5"+ + "\u00e2r\2\u0346\u0344\3\2\2\2\u0346\u0345\3\2\2\2\u0347\u0081\3\2\2\2"+ + "\u0348\u0349\7R\2\2\u0349\u0351\5\u0126\u0094\2\u034a\u034c\5^\60\2\u034b"+ + "\u034a\3\2\2\2\u034b\u034c\3\2\2\2\u034c\u034d\3\2\2\2\u034d\u034e\5\u0126"+ + "\u0094\2\u034e\u034f\7M\2\2\u034f\u0350\5\u0126\u0094\2\u0350\u0352\3"+ + "\2\2\2\u0351\u034b\3\2\2\2\u0351\u0352\3\2\2\2\u0352\u0353\3\2\2\2\u0353"+ + "\u0354\5\u0084C\2\u0354\u0355\7S\2\2\u0355\u0083\3\2\2\2\u0356\u0358\5"+ + "\u0086D\2\u0357\u0356\3\2\2\2\u0357\u0358\3\2\2\2\u0358\u0085\3\2\2\2"+ + "\u0359\u035f\5\u009cO\2\u035a\u035b\5\u0128\u0095\2\u035b\u035c\5\u009c"+ + "O\2\u035c\u035e\3\2\2\2\u035d\u035a\3\2\2\2\u035e\u0361\3\2\2\2\u035f"+ + "\u035d\3\2\2\2\u035f\u0360\3\2\2\2\u0360\u0363\3\2\2\2\u0361\u035f\3\2"+ + "\2\2\u0362\u0364\5\u0128\u0095\2\u0363\u0362\3\2\2\2\u0363\u0364\3\2\2"+ + "\2\u0364\u0087\3\2\2\2\u0365\u0366\5\u008aF\2\u0366\u0367\5\u0126\u0094"+ + "\2\u0367\u0369\3\2\2\2\u0368\u0365\3\2\2\2\u0369\u036c\3\2\2\2\u036a\u0368"+ + "\3\2\2\2\u036a\u036b\3\2\2\2\u036b\u0089\3\2\2\2\u036c\u036a\3\2\2\2\u036d"+ + "\u036e\7~\2\2\u036e\u0374\5\u008eH\2\u036f\u0371\7P\2\2\u0370\u0372\5"+ + "\u008cG\2\u0371\u0370\3\2\2\2\u0371\u0372\3\2\2\2\u0372\u0373\3\2\2\2"+ + "\u0373\u0375\5\u0124\u0093\2\u0374\u036f\3\2\2\2\u0374\u0375\3\2\2\2\u0375"+ + "\u008b\3\2\2\2\u0376\u0379\5\u0090I\2\u0377\u0379\5\u0096L\2\u0378\u0376"+ + "\3\2\2\2\u0378\u0377\3\2\2\2\u0379\u008d\3\2\2\2\u037a\u037b\5l\67\2\u037b"+ + "\u008f\3\2\2\2\u037c\u0381\5\u0092J\2\u037d\u037e\7W\2\2\u037e\u0380\5"+ + "\u0092J\2\u037f\u037d\3\2\2\2\u0380\u0383\3\2\2\2\u0381\u037f\3\2\2\2"+ + "\u0381\u0382\3\2\2\2\u0382\u0091\3\2\2\2\u0383\u0381\3\2\2\2\u0384\u0385"+ + "\5\u0094K\2\u0385\u0386\5\u0126\u0094\2\u0386\u0387\7Y\2\2\u0387\u0388"+ + "\5\u0126\u0094\2\u0388\u0389\5\u0096L\2\u0389\u0093\3\2\2\2\u038a\u038d"+ + "\5\u011e\u0090\2\u038b\u038d\5\u0122\u0092\2\u038c\u038a\3\2\2\2\u038c"+ + "\u038b\3\2\2\2\u038d\u0095\3\2\2\2\u038e\u0392\5\u0098M\2\u038f\u0392"+ + "\5\u008aF\2\u0390\u0392\5\u00e6t\2\u0391\u038e\3\2\2\2\u0391\u038f\3\2"+ + "\2\2\u0391\u0390\3\2\2\2\u0392\u0097\3\2\2\2\u0393\u039c\7T\2\2\u0394"+ + "\u0399\5\u0096L\2\u0395\u0396\7W\2\2\u0396\u0398\5\u0096L\2\u0397\u0395"+ + "\3\2\2\2\u0398\u039b\3\2\2\2\u0399\u0397\3\2\2\2\u0399\u039a\3\2\2\2\u039a"+ + "\u039d\3\2\2\2\u039b\u0399\3\2\2\2\u039c\u0394\3\2\2\2\u039c\u039d\3\2"+ + "\2\2\u039d\u039f\3\2\2\2\u039e\u03a0\7W\2\2\u039f\u039e\3\2\2\2\u039f"+ + "\u03a0\3\2\2\2\u03a0\u03a1\3\2\2\2\u03a1\u03a2\7U\2\2\u03a2\u0099\3\2"+ + "\2\2\u03a3\u03ab\7R\2\2\u03a4\u03ac\5\u0126\u0094\2\u03a5\u03a7\5\u0128"+ + "\u0095\2\u03a6\u03a5\3\2\2\2\u03a7\u03aa\3\2\2\2\u03a8\u03a6\3\2\2\2\u03a8"+ + "\u03a9\3\2\2\2\u03a9\u03ac\3\2\2\2\u03aa\u03a8\3\2\2\2\u03ab\u03a4\3\2"+ + "\2\2\u03ab\u03a8\3\2\2\2\u03ac\u03ad\3\2\2\2\u03ad\u03ae\5\u0084C\2\u03ae"+ + "\u03af\7S\2\2\u03af\u009b\3\2\2\2\u03b0\u03b3\5\u009eP\2\u03b1\u03b3\5"+ + "\u00ba^\2\u03b2\u03b0\3\2\2\2\u03b2\u03b1\3\2\2\2\u03b3\u009d\3\2\2\2"+ + "\u03b4\u03b5\6P\t\2\u03b5\u03b6\5\u00a2R\2\u03b6\u009f\3\2\2\2\u03b7\u03b8"+ + "\6Q\n\3\u03b8\u03bc\5\34\17\2\u03b9\u03ba\6Q\13\3\u03ba\u03bc\5\20\t\2"+ + "\u03bb\u03b7\3\2\2\2\u03bb\u03b9\3\2\2\2\u03bc\u00a1\3\2\2\2\u03bd\u03c8"+ + "\5\u00a0Q\2\u03be\u03c0\5J&\2\u03bf\u03be\3\2\2\2\u03bf\u03c0\3\2\2\2"+ + "\u03c0\u03c1\3\2\2\2\u03c1\u03c9\5:\36\2\u03c2\u03c3\5\u00a4S\2\u03c3"+ + "\u03c4\5\u0126\u0094\2\u03c4\u03c5\7Y\2\2\u03c5\u03c6\5\u0126\u0094\2"+ + "\u03c6\u03c7\5@!\2\u03c7\u03c9\3\2\2\2\u03c8\u03bf\3\2\2\2\u03c8\u03c2"+ + "\3\2\2\2\u03c9\u03d2\3\2\2\2\u03ca\u03cb\5\u00a0Q\2\u03cb\u03cc\5J&\2"+ + "\u03cc\u03cd\5:\36\2\u03cd\u03d2\3\2\2\2\u03ce\u03cf\5J&\2\u03cf\u03d0"+ + "\5:\36\2\u03d0\u03d2\3\2\2\2\u03d1\u03bd\3\2\2\2\u03d1\u03ca\3\2\2\2\u03d1"+ + "\u03ce\3\2\2\2\u03d2\u00a3\3\2\2\2\u03d3\u03d4\7P\2\2\u03d4\u03d9\5\u00a6"+ + "T\2\u03d5\u03d6\7W\2\2\u03d6\u03d8\5\u00a6T\2\u03d7\u03d5\3\2\2\2\u03d8"+ + "\u03db\3\2\2\2\u03d9\u03d7\3\2\2\2\u03d9\u03da\3\2\2\2\u03da\u03dc\3\2"+ + "\2\2\u03db\u03d9\3\2\2\2\u03dc\u03dd\5\u0124\u0093\2\u03dd\u00a5\3\2\2"+ + "\2\u03de\u03e0\5J&\2\u03df\u03de\3\2\2\2\u03df\u03e0\3\2\2\2\u03e0\u03e1"+ + "\3\2\2\2\u03e1\u03e2\5> \2\u03e2\u00a7\3\2\2\2\u03e3\u03e4\7P\2\2\u03e4"+ + "\u03e7\5> \2\u03e5\u03e6\7W\2\2\u03e6\u03e8\5> \2\u03e7\u03e5\3\2\2\2"+ + "\u03e8\u03e9\3\2\2\2\u03e9\u03e7\3\2\2\2\u03e9\u03ea\3\2\2\2\u03ea\u03eb"+ + "\3\2\2\2\u03eb\u03ec\5\u0124\u0093\2\u03ec\u00a9\3\2\2\2\u03ed\u03f0\5"+ + "\u00acW\2\u03ee\u03f0\5\u00aeX\2\u03ef\u03ed\3\2\2\2\u03ef\u03ee\3\2\2"+ + "\2\u03f0\u00ab\3\2\2\2\u03f1\u03f2\7 \2\2\u03f2\u03f3\5\u00dan\2\u03f3"+ + "\u03f4\5\u0126\u0094\2\u03f4\u03fd\5\u00ba^\2\u03f5\u03f8\5\u0126\u0094"+ + "\2\u03f6\u03f8\5\u0128\u0095\2\u03f7\u03f5\3\2\2\2\u03f7\u03f6\3\2\2\2"+ + "\u03f8\u03f9\3\2\2\2\u03f9\u03fa\7\32\2\2\u03fa\u03fb\5\u0126\u0094\2"+ + "\u03fb\u03fc\5\u00ba^\2\u03fc\u03fe\3\2\2\2\u03fd\u03f7\3\2\2\2\u03fd"+ "\u03fe\3\2\2\2\u03fe\u00ad\3\2\2\2\u03ff\u0400\7\60\2\2\u0400\u0401\5"+ "\u00dan\2\u0401\u0402\5\u0126\u0094\2\u0402\u0403\7R\2\2\u0403\u0407\5"+ "\u0126\u0094\2\u0404\u0406\5\u00c8e\2\u0405\u0404\3\2\2\2\u0406\u0409"+ @@ -12362,175 +12361,179 @@ private boolean identifier_sempred(IdentifierContext _localctx, int predIndex) { "\2\2\u04d2\u04d3\7j\2\2\u04d3\u04d6\bp\1\2\u04d4\u04d6\3\2\2\2\u04d5\u04d2"+ "\3\2\2\2\u04d5\u04d4\3\2\2\2\u04d6\u04d7\3\2\2\2\u04d7\u04d8\5\u00e6t"+ "\2\u04d8\u00df\3\2\2\2\u04d9\u04dc\5\u00e2r\2\u04da\u04dc\5z>\2\u04db"+ - "\u04d9\3\2\2\2\u04db\u04da\3\2\2\2\u04dc\u00e1\3\2\2\2\u04dd\u04e0\5\u00e6"+ - "t\2\u04de\u04e0\5\u00e8u\2\u04df\u04dd\3\2\2\2\u04df\u04de\3\2\2\2\u04e0"+ - "\u00e3\3\2\2\2\u04e1\u04e3\5\u00ecw\2\u04e2\u04e4\t\b\2\2\u04e3\u04e2"+ - "\3\2\2\2\u04e3\u04e4\3\2\2\2\u04e4\u00e5\3\2\2\2\u04e5\u04e6\bt\1\2\u04e6"+ - "\u04e7\5\u00d6l\2\u04e7\u04e8\5\u00e6t\26\u04e8\u04f7\3\2\2\2\u04e9\u04f7"+ - "\5\u00e4s\2\u04ea\u04eb\t\t\2\2\u04eb\u04ec\5\u0126\u0094\2\u04ec\u04ed"+ - "\5\u00e6t\24\u04ed\u04f7\3\2\2\2\u04ee\u04ef\t\n\2\2\u04ef\u04f7\5\u00e6"+ - "t\22\u04f0\u04f1\5\u00a8U\2\u04f1\u04f2\5\u0126\u0094\2\u04f2\u04f3\7"+ - "Y\2\2\u04f3\u04f4\5\u0126\u0094\2\u04f4\u04f5\5\u00e2r\2\u04f5\u04f7\3"+ - "\2\2\2\u04f6\u04e5\3\2\2\2\u04f6\u04e9\3\2\2\2\u04f6\u04ea\3\2\2\2\u04f6"+ - "\u04ee\3\2\2\2\u04f6\u04f0\3\2\2\2\u04f7\u0566\3\2\2\2\u04f8\u04f9\f\23"+ - "\2\2\u04f9\u04fa\7H\2\2\u04fa\u04fb\5\u0126\u0094\2\u04fb\u04fc\5\u00e6"+ - "t\24\u04fc\u0565\3\2\2\2\u04fd\u04fe\f\21\2\2\u04fe\u04ff\5\u0126\u0094"+ - "\2\u04ff\u0500\t\13\2\2\u0500\u0501\5\u0126\u0094\2\u0501\u0502\5\u00e6"+ - "t\22\u0502\u0565\3\2\2\2\u0503\u0504\f\20\2\2\u0504\u0505\t\f\2\2\u0505"+ - "\u0506\5\u0126\u0094\2\u0506\u0507\5\u00e6t\21\u0507\u0565\3\2\2\2\u0508"+ - "\u0509\f\17\2\2\u0509\u0514\5\u0126\u0094\2\u050a\u050b\7[\2\2\u050b\u0512"+ - "\7[\2\2\u050c\u050d\7Z\2\2\u050d\u050e\7Z\2\2\u050e\u0512\7Z\2\2\u050f"+ - "\u0510\7Z\2\2\u0510\u0512\7Z\2\2\u0511\u050a\3\2\2\2\u0511\u050c\3\2\2"+ - "\2\u0511\u050f\3\2\2\2\u0512\u0515\3\2\2\2\u0513\u0515\t\r\2\2\u0514\u0511"+ - "\3\2\2\2\u0514\u0513\3\2\2\2\u0515\u0516\3\2\2\2\u0516\u0517\5\u0126\u0094"+ - "\2\u0517\u0518\5\u00e6t\20\u0518\u0565\3\2\2\2\u0519\u051a\f\r\2\2\u051a"+ - "\u051b\5\u0126\u0094\2\u051b\u051c\t\16\2\2\u051c\u051d\5\u0126\u0094"+ - "\2\u051d\u051e\5\u00e6t\16\u051e\u0565\3\2\2\2\u051f\u0520\f\f\2\2\u0520"+ - "\u0521\5\u0126\u0094\2\u0521\u0522\t\17\2\2\u0522\u0523\5\u0126\u0094"+ - "\2\u0523\u0524\5\u00e6t\r\u0524\u0565\3\2\2\2\u0525\u0526\f\13\2\2\u0526"+ - "\u0527\5\u0126\u0094\2\u0527\u0528\t\20\2\2\u0528\u0529\5\u0126\u0094"+ - "\2\u0529\u052a\5\u00e6t\f\u052a\u0565\3\2\2\2\u052b\u052c\f\n\2\2\u052c"+ - "\u052d\5\u0126\u0094\2\u052d\u052e\7l\2\2\u052e\u052f\5\u0126\u0094\2"+ - "\u052f\u0530\5\u00e6t\13\u0530\u0565\3\2\2\2\u0531\u0532\f\t\2\2\u0532"+ - "\u0533\5\u0126\u0094\2\u0533\u0534\7n\2\2\u0534\u0535\5\u0126\u0094\2"+ - "\u0535\u0536\5\u00e6t\n\u0536\u0565\3\2\2\2\u0537\u0538\f\b\2\2\u0538"+ - "\u0539\5\u0126\u0094\2\u0539\u053a\7m\2\2\u053a\u053b\5\u0126\u0094\2"+ - "\u053b\u053c\5\u00e6t\t\u053c\u0565\3\2\2\2\u053d\u053e\f\7\2\2\u053e"+ - "\u053f\5\u0126\u0094\2\u053f\u0540\7d\2\2\u0540\u0541\5\u0126\u0094\2"+ - "\u0541\u0542\5\u00e6t\b\u0542\u0565\3\2\2\2\u0543\u0544\f\6\2\2\u0544"+ - "\u0545\5\u0126\u0094\2\u0545\u0546\7e\2\2\u0546\u0547\5\u0126\u0094\2"+ - "\u0547\u0548\5\u00e6t\7\u0548\u0565\3\2\2\2\u0549\u054a\f\5\2\2\u054a"+ - "\u0554\5\u0126\u0094\2\u054b\u054c\7^\2\2\u054c\u054d\5\u0126\u0094\2"+ - "\u054d\u054e\5\u00e6t\2\u054e\u054f\5\u0126\u0094\2\u054f\u0550\7_\2\2"+ - "\u0550\u0551\5\u0126\u0094\2\u0551\u0555\3\2\2\2\u0552\u0553\7C\2\2\u0553"+ - "\u0555\5\u0126\u0094\2\u0554\u054b\3\2\2\2\u0554\u0552\3\2\2\2\u0555\u0556"+ - "\3\2\2\2\u0556\u0557\5\u00e6t\5\u0557\u0565\3\2\2\2\u0558\u0559\f\16\2"+ - "\2\u0559\u055a\5\u0126\u0094\2\u055a\u055b\t\21\2\2\u055b\u055c\5\u0126"+ - "\u0094\2\u055c\u055d\5J&\2\u055d\u0565\3\2\2\2\u055e\u055f\f\3\2\2\u055f"+ - "\u0560\5\u0126\u0094\2\u0560\u0561\t\22\2\2\u0561\u0562\5\u0126\u0094"+ - "\2\u0562\u0563\5\u00e0q\2\u0563\u0565\3\2\2\2\u0564\u04f8\3\2\2\2\u0564"+ - "\u04fd\3\2\2\2\u0564\u0503\3\2\2\2\u0564\u0508\3\2\2\2\u0564\u0519\3\2"+ - "\2\2\u0564\u051f\3\2\2\2\u0564\u0525\3\2\2\2\u0564\u052b\3\2\2\2\u0564"+ - "\u0531\3\2\2\2\u0564\u0537\3\2\2\2\u0564\u053d\3\2\2\2\u0564\u0543\3\2"+ - "\2\2\u0564\u0549\3\2\2\2\u0564\u0558\3\2\2\2\u0564\u055e\3\2\2\2\u0565"+ - "\u0568\3\2\2\2\u0566\u0564\3\2\2\2\u0566\u0567\3\2\2\2\u0567\u00e7\3\2"+ - "\2\2\u0568\u0566\3\2\2\2\u0569\u056d\5\u00ecw\2\u056a\u056b\6u\34\3\u056b"+ - "\u056e\5\u0112\u008a\2\u056c\u056e\3\2\2\2\u056d\u056a\3\2\2\2\u056d\u056c"+ - "\3\2\2\2\u056e\u0572\3\2\2\2\u056f\u0571\5\u00eav\2\u0570\u056f\3\2\2"+ - "\2\u0571\u0574\3\2\2\2\u0572\u0570\3\2\2\2\u0572\u0573\3\2\2\2\u0573\u00e9"+ - "\3\2\2\2\u0574\u0572\3\2\2\2\u0575\u057c\5\u00f8}\2\u0576\u0578\5\u00ee"+ - "x\2\u0577\u0576\3\2\2\2\u0578\u0579\3\2\2\2\u0579\u0577\3\2\2\2\u0579"+ - "\u057a\3\2\2\2\u057a\u057d\3\2\2\2\u057b\u057d\5\u0112\u008a\2\u057c\u0577"+ - "\3\2\2\2\u057c\u057b\3\2\2\2\u057c\u057d\3\2\2\2\u057d\u00eb\3\2\2\2\u057e"+ - "\u0584\5\u00f8}\2\u057f\u0580\5\u00eex\2\u0580\u0581\bw\1\2\u0581\u0583"+ - "\3\2\2\2\u0582\u057f\3\2\2\2\u0583\u0586\3\2\2\2\u0584\u0582\3\2\2\2\u0584"+ - "\u0585\3\2\2\2\u0585\u00ed\3\2\2\2\u0586\u0584\3\2\2\2\u0587\u0592\5\u0126"+ - "\u0094\2\u0588\u0589\t\23\2\2\u0589\u058c\5\u0126\u0094\2\u058a\u058d"+ - "\7~\2\2\u058b\u058d\5\u010c\u0087\2\u058c\u058a\3\2\2\2\u058c\u058b\3"+ - "\2\2\2\u058c\u058d\3\2\2\2\u058d\u0593\3\2\2\2\u058e\u058f\7D\2\2\u058f"+ - "\u0593\5\u0126\u0094\2\u0590\u0591\7E\2\2\u0591\u0593\5\u0126\u0094\2"+ - "\u0592\u0588\3\2\2\2\u0592\u058e\3\2\2\2\u0592\u0590\3\2\2\2\u0593\u0594"+ - "\3\2\2\2\u0594\u0595\5\u00f0y\2\u0595\u0596\bx\1\2\u0596\u05ab\3\2\2\2"+ - "\u0597\u0598\7X\2\2\u0598\u0599\5\u0126\u0094\2\u0599\u059a\7\'\2\2\u059a"+ - "\u059b\5\u0104\u0083\2\u059b\u059c\bx\1\2\u059c\u05ab\3\2\2\2\u059d\u059e"+ - "\5\u0110\u0089\2\u059e\u059f\bx\1\2\u059f\u05ab\3\2\2\2\u05a0\u05a1\5"+ - "\u0126\u0094\2\u05a1\u05a2\5\u0082B\2\u05a2\u05a3\bx\1\2\u05a3\u05ab\3"+ - "\2\2\2\u05a4\u05a5\5\u00f4{\2\u05a5\u05a6\bx\1\2\u05a6\u05ab\3\2\2\2\u05a7"+ - "\u05a8\5\u00f6|\2\u05a8\u05a9\bx\1\2\u05a9\u05ab\3\2\2\2\u05aa\u0587\3"+ - "\2\2\2\u05aa\u0597\3\2\2\2\u05aa\u059d\3\2\2\2\u05aa\u05a0\3\2\2\2\u05aa"+ - "\u05a4\3\2\2\2\u05aa\u05a7\3\2\2\2\u05ab\u00ef\3\2\2\2\u05ac\u05b1\5\u011e"+ - "\u0090\2\u05ad\u05b1\5\u011a\u008e\2\u05ae\u05b1\5\u00f2z\2\u05af\u05b1"+ - "\5\u0122\u0092\2\u05b0\u05ac\3\2\2\2\u05b0\u05ad\3\2\2\2\u05b0\u05ae\3"+ - "\2\2\2\u05b0\u05af\3\2\2\2\u05b1\u00f1\3\2\2\2\u05b2\u05b5\5\u00d8m\2"+ - "\u05b3\u05b5\5r:\2\u05b4\u05b2\3\2\2\2\u05b4\u05b3\3\2\2\2\u05b5\u00f3"+ - "\3\2\2\2\u05b6\u05b8\7^\2\2\u05b7\u05b6\3\2\2\2\u05b7\u05b8\3\2\2\2\u05b8"+ - "\u05b9\3\2\2\2\u05b9\u05bb\7T\2\2\u05ba\u05bc\5\u00dco\2\u05bb\u05ba\3"+ - "\2\2\2\u05bb\u05bc\3\2\2\2\u05bc\u05bd\3\2\2\2\u05bd\u05be\7U\2\2\u05be"+ - "\u00f5\3\2\2\2\u05bf\u05c0\7T\2\2\u05c0\u05c1\5\u00fe\u0080\2\u05c1\u05c2"+ - "\7U\2\2\u05c2\u00f7\3\2\2\2\u05c3\u05c5\5\u011e\u0090\2\u05c4\u05c6\5"+ - "T+\2\u05c5\u05c4\3\2\2\2\u05c5\u05c6\3\2\2\2\u05c6\u05d6\3\2\2\2\u05c7"+ - "\u05d6\5p9\2\u05c8\u05d6\5r:\2\u05c9\u05ca\7\'\2\2\u05ca\u05cb\5\u0126"+ - "\u0094\2\u05cb\u05cc\5\u0104\u0083\2\u05cc\u05d6\3\2\2\2\u05cd\u05d6\7"+ - "\62\2\2\u05ce\u05d6\7/\2\2\u05cf\u05d6\5\u00d8m\2\u05d0\u05d6\5\u0082"+ - "B\2\u05d1\u05d6\5x=\2\u05d2\u05d6\5\u00fa~\2\u05d3\u05d6\5\u00fc\177\2"+ - "\u05d4\u05d6\5\u0120\u0091\2\u05d5\u05c3\3\2\2\2\u05d5\u05c7\3\2\2\2\u05d5"+ - "\u05c8\3\2\2\2\u05d5\u05c9\3\2\2\2\u05d5\u05cd\3\2\2\2\u05d5\u05ce\3\2"+ - "\2\2\u05d5\u05cf\3\2\2\2\u05d5\u05d0\3\2\2\2\u05d5\u05d1\3\2\2\2\u05d5"+ - "\u05d2\3\2\2\2\u05d5\u05d3\3\2\2\2\u05d5\u05d4\3\2\2\2\u05d6\u00f9\3\2"+ - "\2\2\u05d7\u05d9\7T\2\2\u05d8\u05da\5\u00dco\2\u05d9\u05d8\3\2\2\2\u05d9"+ - "\u05da\3\2\2\2\u05da\u05dc\3\2\2\2\u05db\u05dd\7W\2\2\u05dc\u05db\3\2"+ - "\2\2\u05dc\u05dd\3\2\2\2\u05dd\u05de\3\2\2\2\u05de\u05df\7U\2\2\u05df"+ - "\u00fb\3\2\2\2\u05e0\u05e6\7T\2\2\u05e1\u05e3\5\u00fe\u0080\2\u05e2\u05e4"+ - "\7W\2\2\u05e3\u05e2\3\2\2\2\u05e3\u05e4\3\2\2\2\u05e4\u05e7\3\2\2\2\u05e5"+ - "\u05e7\7_\2\2\u05e6\u05e1\3\2\2\2\u05e6\u05e5\3\2\2\2\u05e7\u05e8\3\2"+ - "\2\2\u05e8\u05e9\7U\2\2\u05e9\u00fd\3\2\2\2\u05ea\u05ef\5\u0100\u0081"+ - "\2\u05eb\u05ec\7W\2\2\u05ec\u05ee\5\u0100\u0081\2\u05ed\u05eb\3\2\2\2"+ - "\u05ee\u05f1\3\2\2\2\u05ef\u05ed\3\2\2\2\u05ef\u05f0\3\2\2\2\u05f0\u00ff"+ - "\3\2\2\2\u05f1\u05ef\3\2\2\2\u05f2\u05f3\5\u0102\u0082\2\u05f3\u05f4\7"+ - "_\2\2\u05f4\u05f5\5\u0126\u0094\2\u05f5\u05f6\5\u00e6t\2\u05f6\u05fd\3"+ - "\2\2\2\u05f7\u05f8\7j\2\2\u05f8\u05f9\7_\2\2\u05f9\u05fa\5\u0126\u0094"+ - "\2\u05fa\u05fb\5\u00e6t\2\u05fb\u05fd\3\2\2\2\u05fc\u05f2\3\2\2\2\u05fc"+ - "\u05f7\3\2\2\2\u05fd\u0101\3\2\2\2\u05fe\u0601\5\u0122\u0092\2\u05ff\u0601"+ - "\5\u00f8}\2\u0600\u05fe\3\2\2\2\u0600\u05ff\3\2\2\2\u0601\u0103\3\2\2"+ - "\2\u0602\u061a\5\u010a\u0086\2\u0603\u0604\6\u0083\35\3\u0604\u0605\5"+ - "\u0126\u0094\2\u0605\u0607\5\u0110\u0089\2\u0606\u0608\5\u0108\u0085\2"+ - "\u0607\u0606\3\2\2\2\u0607\u0608\3\2\2\2\u0608\u061b\3\2\2\2\u0609\u060f"+ - "\6\u0083\36\3\u060a\u060b\5\u0088E\2\u060b\u060c\7T\2\2\u060c\u060d\5"+ - "\u00e6t\2\u060d\u060e\7U\2\2\u060e\u0610\3\2\2\2\u060f\u060a\3\2\2\2\u0610"+ - "\u0611\3\2\2\2\u0611\u060f\3\2\2\2\u0611\u0612\3\2\2\2\u0612\u0613\3\2"+ - "\2\2\u0613\u0614\5F$\2\u0614\u061b\3\2\2\2\u0615\u0616\6\u0083\37\3\u0616"+ - "\u0617\5D#\2\u0617\u0618\5\u0126\u0094\2\u0618\u0619\5\u0106\u0084\2\u0619"+ - "\u061b\3\2\2\2\u061a\u0603\3\2\2\2\u061a\u0609\3\2\2\2\u061a\u0615\3\2"+ - "\2\2\u061b\u0105\3\2\2\2\u061c\u061d\7R\2\2\u061d\u061f\5\u0126\u0094"+ - "\2\u061e\u0620\5B\"\2\u061f\u061e\3\2\2\2\u061f\u0620\3\2\2\2\u0620\u0621"+ - "\3\2\2\2\u0621\u0622\5\u0126\u0094\2\u0622\u0623\7S\2\2\u0623\u0107\3"+ - "\2\2\2\u0624\u0625\5(\25\2\u0625\u0109\3\2\2\2\u0626\u062c\5\u0088E\2"+ - "\u0627\u062d\5R*\2\u0628\u062a\5l\67\2\u0629\u062b\5\u010e\u0088\2\u062a"+ - "\u0629\3\2\2\2\u062a\u062b\3\2\2\2\u062b\u062d\3\2\2\2\u062c\u0627\3\2"+ - "\2\2\u062c\u0628\3\2\2\2\u062d\u010b\3\2\2\2\u062e\u062f\7[\2\2\u062f"+ - "\u0630\5\u0126\u0094\2\u0630\u0631\5$\23\2\u0631\u0632\5\u0126\u0094\2"+ - "\u0632\u0633\7Z\2\2\u0633\u010d\3\2\2\2\u0634\u0635\7[\2\2\u0635\u0638"+ - "\7Z\2\2\u0636\u0638\5T+\2\u0637\u0634\3\2\2\2\u0637\u0636\3\2\2\2\u0638"+ - "\u010f\3\2\2\2\u0639\u063b\7P\2\2\u063a\u063c\5\u0114\u008b\2\u063b\u063a"+ - "\3\2\2\2\u063b\u063c\3\2\2\2\u063c\u063e\3\2\2\2\u063d\u063f\7W\2\2\u063e"+ - "\u063d\3\2\2\2\u063e\u063f\3\2\2\2\u063f\u0640\3\2\2\2\u0640\u0641\5\u0124"+ - "\u0093\2\u0641\u0111\3\2\2\2\u0642\u0649\5\u0116\u008c\2\u0643\u0644\7"+ - "W\2\2\u0644\u0645\5\u0126\u0094\2\u0645\u0646\5\u0116\u008c\2\u0646\u0648"+ - "\3\2\2\2\u0647\u0643\3\2\2\2\u0648\u064b\3\2\2\2\u0649\u0647\3\2\2\2\u0649"+ - "\u064a\3\2\2\2\u064a\u0113\3\2\2\2\u064b\u0649\3\2\2\2\u064c\u0653\5\u0118"+ - "\u008d\2\u064d\u064e\7W\2\2\u064e\u064f\5\u0126\u0094\2\u064f\u0650\5"+ - "\u0118\u008d\2\u0650\u0652\3\2\2\2\u0651\u064d\3\2\2\2\u0652\u0655\3\2"+ - "\2\2\u0653\u0651\3\2\2\2\u0653\u0654\3\2\2\2\u0654\u0115\3\2\2\2\u0655"+ - "\u0653\3\2\2\2\u0656\u0659\5\u00dep\2\u0657\u0659\5\u0100\u0081\2\u0658"+ - "\u0656\3\2\2\2\u0658\u0657\3\2\2\2\u0659\u0117\3\2\2\2\u065a\u065e\5\u00de"+ - "p\2\u065b\u065e\5z>\2\u065c\u065e\5\u0100\u0081\2\u065d\u065a\3\2\2\2"+ - "\u065d\u065b\3\2\2\2\u065d\u065c\3\2\2\2\u065e\u0119\3\2\2\2\u065f\u0660"+ - "\7\3\2\2\u0660\u011b\3\2\2\2\u0661\u0662\7|\2\2\u0662\u011d\3\2\2\2\u0663"+ - "\u0669\7}\2\2\u0664\u0669\7|\2\2\u0665\u0669\7\16\2\2\u0666\u0667\6\u0090"+ - " \2\u0667\u0669\7-\2\2\u0668\u0663\3\2\2\2\u0668\u0664\3\2\2\2\u0668\u0665"+ - "\3\2\2\2\u0668\u0666\3\2\2\2\u0669\u011f\3\2\2\2\u066a\u066b\t\24\2\2"+ - "\u066b\u0121\3\2\2\2\u066c\u066d\t\25\2\2\u066d\u0123\3\2\2\2\u066e\u0671"+ - "\7Q\2\2\u066f\u0671\b\u0093\1\2\u0670\u066e\3\2\2\2\u0670\u066f\3\2\2"+ - "\2\u0671\u0125\3\2\2\2\u0672\u0674\7\u0081\2\2\u0673\u0672\3\2\2\2\u0674"+ - "\u0677\3\2\2\2\u0675\u0673\3\2\2\2\u0675\u0676\3\2\2\2\u0676\u0127\3\2"+ - "\2\2\u0677\u0675\3\2\2\2\u0678\u067a\t\26\2\2\u0679\u0678\3\2\2\2\u067a"+ - "\u067b\3\2\2\2\u067b\u0679\3\2\2\2\u067b\u067c\3\2\2\2\u067c\u0129\3\2"+ - "\2\2\u00b9\u012c\u012f\u0132\u013c\u0140\u0149\u0150\u0157\u015a\u0161"+ - "\u0164\u016b\u016f\u0173\u0176\u017d\u0188\u0193\u019c\u01a6\u01b4\u01ba"+ - "\u01c3\u01c7\u01ca\u01d2\u01d5\u01d8\u01e0\u01e3\u01e6\u01e9\u01f0\u01f4"+ - "\u0200\u0206\u020b\u020e\u0213\u0217\u021e\u0229\u022d\u0230\u0239\u023d"+ - "\u023f\u0243\u0248\u0253\u025c\u026b\u0270\u0278\u027b\u0280\u0287\u028a"+ - "\u0290\u0293\u0297\u029b\u02a8\u02b5\u02b7\u02c3\u02c8\u02ce\u02d6\u02de"+ - "\u02e1\u02e9\u02f2\u02fa\u0301\u030d\u0315\u031d\u0325\u0329\u032f\u0342"+ - "\u0346\u034b\u0351\u0357\u035f\u0363\u036a\u0371\u0374\u0378\u0381\u038c"+ - "\u0391\u0399\u039c\u039f\u03a8\u03ab\u03b2\u03bb\u03bf\u03c8\u03d1\u03d9"+ - "\u03df\u03e9\u03ef\u03f7\u03fd\u0407\u0420\u0424\u0428\u042c\u0435\u043b"+ - "\u0444\u0451\u0464\u046a\u0476\u0481\u048b\u0490\u0497\u04a1\u04a5\u04a9"+ - "\u04b0\u04b4\u04b8\u04bc\u04cf\u04d5\u04db\u04df\u04e3\u04f6\u0511\u0514"+ - "\u0554\u0564\u0566\u056d\u0572\u0579\u057c\u0584\u058c\u0592\u05aa\u05b0"+ - "\u05b4\u05b7\u05bb\u05c5\u05d5\u05d9\u05dc\u05e3\u05e6\u05ef\u05fc\u0600"+ - "\u0607\u0611\u061a\u061f\u062a\u062c\u0637\u063b\u063e\u0649\u0653\u0658"+ - "\u065d\u0668\u0670\u0675\u067b"; + "\u04d9\3\2\2\2\u04db\u04da\3\2\2\2\u04dc\u00e1\3\2\2\2\u04dd\u04de\5\u00e8"+ + "u\2\u04de\u00e3\3\2\2\2\u04df\u04e1\5\u00ecw\2\u04e0\u04e2\t\b\2\2\u04e1"+ + "\u04e0\3\2\2\2\u04e1\u04e2\3\2\2\2\u04e2\u00e5\3\2\2\2\u04e3\u04e4\bt"+ + "\1\2\u04e4\u04e5\5\u00d6l\2\u04e5\u04e6\5\u00e6t\26\u04e6\u04f5\3\2\2"+ + "\2\u04e7\u04f5\5\u00e4s\2\u04e8\u04e9\t\t\2\2\u04e9\u04ea\5\u0126\u0094"+ + "\2\u04ea\u04eb\5\u00e6t\24\u04eb\u04f5\3\2\2\2\u04ec\u04ed\t\n\2\2\u04ed"+ + "\u04f5\5\u00e6t\22\u04ee\u04ef\5\u00a8U\2\u04ef\u04f0\5\u0126\u0094\2"+ + "\u04f0\u04f1\7Y\2\2\u04f1\u04f2\5\u0126\u0094\2\u04f2\u04f3\5\u00e2r\2"+ + "\u04f3\u04f5\3\2\2\2\u04f4\u04e3\3\2\2\2\u04f4\u04e7\3\2\2\2\u04f4\u04e8"+ + "\3\2\2\2\u04f4\u04ec\3\2\2\2\u04f4\u04ee\3\2\2\2\u04f5\u0564\3\2\2\2\u04f6"+ + "\u04f7\f\23\2\2\u04f7\u04f8\7H\2\2\u04f8\u04f9\5\u0126\u0094\2\u04f9\u04fa"+ + "\5\u00e6t\24\u04fa\u0563\3\2\2\2\u04fb\u04fc\f\21\2\2\u04fc\u04fd\5\u0126"+ + "\u0094\2\u04fd\u04fe\t\13\2\2\u04fe\u04ff\5\u0126\u0094\2\u04ff\u0500"+ + "\5\u00e6t\22\u0500\u0563\3\2\2\2\u0501\u0502\f\20\2\2\u0502\u0503\t\f"+ + "\2\2\u0503\u0504\5\u0126\u0094\2\u0504\u0505\5\u00e6t\21\u0505\u0563\3"+ + "\2\2\2\u0506\u0507\f\17\2\2\u0507\u0512\5\u0126\u0094\2\u0508\u0509\7"+ + "[\2\2\u0509\u0510\7[\2\2\u050a\u050b\7Z\2\2\u050b\u050c\7Z\2\2\u050c\u0510"+ + "\7Z\2\2\u050d\u050e\7Z\2\2\u050e\u0510\7Z\2\2\u050f\u0508\3\2\2\2\u050f"+ + "\u050a\3\2\2\2\u050f\u050d\3\2\2\2\u0510\u0513\3\2\2\2\u0511\u0513\t\r"+ + "\2\2\u0512\u050f\3\2\2\2\u0512\u0511\3\2\2\2\u0513\u0514\3\2\2\2\u0514"+ + "\u0515\5\u0126\u0094\2\u0515\u0516\5\u00e6t\20\u0516\u0563\3\2\2\2\u0517"+ + "\u0518\f\r\2\2\u0518\u0519\5\u0126\u0094\2\u0519\u051a\t\16\2\2\u051a"+ + "\u051b\5\u0126\u0094\2\u051b\u051c\5\u00e6t\16\u051c\u0563\3\2\2\2\u051d"+ + "\u051e\f\f\2\2\u051e\u051f\5\u0126\u0094\2\u051f\u0520\t\17\2\2\u0520"+ + "\u0521\5\u0126\u0094\2\u0521\u0522\5\u00e6t\r\u0522\u0563\3\2\2\2\u0523"+ + "\u0524\f\13\2\2\u0524\u0525\5\u0126\u0094\2\u0525\u0526\t\20\2\2\u0526"+ + "\u0527\5\u0126\u0094\2\u0527\u0528\5\u00e6t\f\u0528\u0563\3\2\2\2\u0529"+ + "\u052a\f\n\2\2\u052a\u052b\5\u0126\u0094\2\u052b\u052c\7l\2\2\u052c\u052d"+ + "\5\u0126\u0094\2\u052d\u052e\5\u00e6t\13\u052e\u0563\3\2\2\2\u052f\u0530"+ + "\f\t\2\2\u0530\u0531\5\u0126\u0094\2\u0531\u0532\7n\2\2\u0532\u0533\5"+ + "\u0126\u0094\2\u0533\u0534\5\u00e6t\n\u0534\u0563\3\2\2\2\u0535\u0536"+ + "\f\b\2\2\u0536\u0537\5\u0126\u0094\2\u0537\u0538\7m\2\2\u0538\u0539\5"+ + "\u0126\u0094\2\u0539\u053a\5\u00e6t\t\u053a\u0563\3\2\2\2\u053b\u053c"+ + "\f\7\2\2\u053c\u053d\5\u0126\u0094\2\u053d\u053e\7d\2\2\u053e\u053f\5"+ + "\u0126\u0094\2\u053f\u0540\5\u00e6t\b\u0540\u0563\3\2\2\2\u0541\u0542"+ + "\f\6\2\2\u0542\u0543\5\u0126\u0094\2\u0543\u0544\7e\2\2\u0544\u0545\5"+ + "\u0126\u0094\2\u0545\u0546\5\u00e6t\7\u0546\u0563\3\2\2\2\u0547\u0548"+ + "\f\5\2\2\u0548\u0552\5\u0126\u0094\2\u0549\u054a\7^\2\2\u054a\u054b\5"+ + "\u0126\u0094\2\u054b\u054c\5\u00e6t\2\u054c\u054d\5\u0126\u0094\2\u054d"+ + "\u054e\7_\2\2\u054e\u054f\5\u0126\u0094\2\u054f\u0553\3\2\2\2\u0550\u0551"+ + "\7C\2\2\u0551\u0553\5\u0126\u0094\2\u0552\u0549\3\2\2\2\u0552\u0550\3"+ + "\2\2\2\u0553\u0554\3\2\2\2\u0554\u0555\5\u00e6t\5\u0555\u0563\3\2\2\2"+ + "\u0556\u0557\f\16\2\2\u0557\u0558\5\u0126\u0094\2\u0558\u0559\t\21\2\2"+ + "\u0559\u055a\5\u0126\u0094\2\u055a\u055b\5J&\2\u055b\u0563\3\2\2\2\u055c"+ + "\u055d\f\3\2\2\u055d\u055e\5\u0126\u0094\2\u055e\u055f\t\22\2\2\u055f"+ + "\u0560\5\u0126\u0094\2\u0560\u0561\5\u00e0q\2\u0561\u0563\3\2\2\2\u0562"+ + "\u04f6\3\2\2\2\u0562\u04fb\3\2\2\2\u0562\u0501\3\2\2\2\u0562\u0506\3\2"+ + "\2\2\u0562\u0517\3\2\2\2\u0562\u051d\3\2\2\2\u0562\u0523\3\2\2\2\u0562"+ + "\u0529\3\2\2\2\u0562\u052f\3\2\2\2\u0562\u0535\3\2\2\2\u0562\u053b\3\2"+ + "\2\2\u0562\u0541\3\2\2\2\u0562\u0547\3\2\2\2\u0562\u0556\3\2\2\2\u0562"+ + "\u055c\3\2\2\2\u0563\u0566\3\2\2\2\u0564\u0562\3\2\2\2\u0564\u0565\3\2"+ + "\2\2\u0565\u00e7\3\2\2\2\u0566\u0564\3\2\2\2\u0567\u056b\5\u00e6t\2\u0568"+ + "\u0569\6u\34\3\u0569\u056c\5\u0112\u008a\2\u056a\u056c\3\2\2\2\u056b\u0568"+ + "\3\2\2\2\u056b\u056a\3\2\2\2\u056c\u0570\3\2\2\2\u056d\u056f\5\u00eav"+ + "\2\u056e\u056d\3\2\2\2\u056f\u0572\3\2\2\2\u0570\u056e\3\2\2\2\u0570\u0571"+ + "\3\2\2\2\u0571\u00e9\3\2\2\2\u0572\u0570\3\2\2\2\u0573\u057a\5\u00f8}"+ + "\2\u0574\u0576\5\u00eex\2\u0575\u0574\3\2\2\2\u0576\u0577\3\2\2\2\u0577"+ + "\u0575\3\2\2\2\u0577\u0578\3\2\2\2\u0578\u057b\3\2\2\2\u0579\u057b\5\u0112"+ + "\u008a\2\u057a\u0575\3\2\2\2\u057a\u0579\3\2\2\2\u057a\u057b\3\2\2\2\u057b"+ + "\u00eb\3\2\2\2\u057c\u0582\5\u00f8}\2\u057d\u057e\5\u00eex\2\u057e\u057f"+ + "\bw\1\2\u057f\u0581\3\2\2\2\u0580\u057d\3\2\2\2\u0581\u0584\3\2\2\2\u0582"+ + "\u0580\3\2\2\2\u0582\u0583\3\2\2\2\u0583\u00ed\3\2\2\2\u0584\u0582\3\2"+ + "\2\2\u0585\u0590\5\u0126\u0094\2\u0586\u0587\t\23\2\2\u0587\u058a\5\u0126"+ + "\u0094\2\u0588\u058b\7~\2\2\u0589\u058b\5\u010c\u0087\2\u058a\u0588\3"+ + "\2\2\2\u058a\u0589\3\2\2\2\u058a\u058b\3\2\2\2\u058b\u0591\3\2\2\2\u058c"+ + "\u058d\7D\2\2\u058d\u0591\5\u0126\u0094\2\u058e\u058f\7E\2\2\u058f\u0591"+ + "\5\u0126\u0094\2\u0590\u0586\3\2\2\2\u0590\u058c\3\2\2\2\u0590\u058e\3"+ + "\2\2\2\u0591\u0592\3\2\2\2\u0592\u0593\5\u00f0y\2\u0593\u0594\bx\1\2\u0594"+ + "\u05aa\3\2\2\2\u0595\u0596\5\u0126\u0094\2\u0596\u0597\7X\2\2\u0597\u0598"+ + "\5\u0126\u0094\2\u0598\u0599\7\'\2\2\u0599\u059a\5\u0104\u0083\2\u059a"+ + "\u059b\bx\1\2\u059b\u05aa\3\2\2\2\u059c\u059d\5\u0110\u0089\2\u059d\u059e"+ + "\bx\1\2\u059e\u05aa\3\2\2\2\u059f\u05a0\5\u0126\u0094\2\u05a0\u05a1\5"+ + "\u0082B\2\u05a1\u05a2\bx\1\2\u05a2\u05aa\3\2\2\2\u05a3\u05a4\5\u00f4{"+ + "\2\u05a4\u05a5\bx\1\2\u05a5\u05aa\3\2\2\2\u05a6\u05a7\5\u00f6|\2\u05a7"+ + "\u05a8\bx\1\2\u05a8\u05aa\3\2\2\2\u05a9\u0585\3\2\2\2\u05a9\u0595\3\2"+ + "\2\2\u05a9\u059c\3\2\2\2\u05a9\u059f\3\2\2\2\u05a9\u05a3\3\2\2\2\u05a9"+ + "\u05a6\3\2\2\2\u05aa\u00ef\3\2\2\2\u05ab\u05b0\5\u011e\u0090\2\u05ac\u05b0"+ + "\5\u011a\u008e\2\u05ad\u05b0\5\u00f2z\2\u05ae\u05b0\5\u0122\u0092\2\u05af"+ + "\u05ab\3\2\2\2\u05af\u05ac\3\2\2\2\u05af\u05ad\3\2\2\2\u05af\u05ae\3\2"+ + "\2\2\u05b0\u00f1\3\2\2\2\u05b1\u05b4\5\u00d8m\2\u05b2\u05b4\5r:\2\u05b3"+ + "\u05b1\3\2\2\2\u05b3\u05b2\3\2\2\2\u05b4\u00f3\3\2\2\2\u05b5\u05b7\7^"+ + "\2\2\u05b6\u05b5\3\2\2\2\u05b6\u05b7\3\2\2\2\u05b7\u05b8\3\2\2\2\u05b8"+ + "\u05ba\7T\2\2\u05b9\u05bb\5\u00dco\2\u05ba\u05b9\3\2\2\2\u05ba\u05bb\3"+ + "\2\2\2\u05bb\u05bc\3\2\2\2\u05bc\u05bd\7U\2\2\u05bd\u00f5\3\2\2\2\u05be"+ + "\u05c0\7^\2\2\u05bf\u05be\3\2\2\2\u05bf\u05c0\3\2\2\2\u05c0\u05c1\3\2"+ + "\2\2\u05c1\u05c4\7T\2\2\u05c2\u05c5\5\u00fe\u0080\2\u05c3\u05c5\7_\2\2"+ + "\u05c4\u05c2\3\2\2\2\u05c4\u05c3\3\2\2\2\u05c5\u05c6\3\2\2\2\u05c6\u05c7"+ + "\7U\2\2\u05c7\u00f7\3\2\2\2\u05c8\u05ca\5\u011e\u0090\2\u05c9\u05cb\5"+ + "T+\2\u05ca\u05c9\3\2\2\2\u05ca\u05cb\3\2\2\2\u05cb\u05db\3\2\2\2\u05cc"+ + "\u05db\5p9\2\u05cd\u05db\5r:\2\u05ce\u05cf\7\'\2\2\u05cf\u05d0\5\u0126"+ + "\u0094\2\u05d0\u05d1\5\u0104\u0083\2\u05d1\u05db\3\2\2\2\u05d2\u05db\7"+ + "\62\2\2\u05d3\u05db\7/\2\2\u05d4\u05db\5\u00d8m\2\u05d5\u05db\5\u0082"+ + "B\2\u05d6\u05db\5x=\2\u05d7\u05db\5\u00fa~\2\u05d8\u05db\5\u00fc\177\2"+ + "\u05d9\u05db\5\u0120\u0091\2\u05da\u05c8\3\2\2\2\u05da\u05cc\3\2\2\2\u05da"+ + "\u05cd\3\2\2\2\u05da\u05ce\3\2\2\2\u05da\u05d2\3\2\2\2\u05da\u05d3\3\2"+ + "\2\2\u05da\u05d4\3\2\2\2\u05da\u05d5\3\2\2\2\u05da\u05d6\3\2\2\2\u05da"+ + "\u05d7\3\2\2\2\u05da\u05d8\3\2\2\2\u05da\u05d9\3\2\2\2\u05db\u00f9\3\2"+ + "\2\2\u05dc\u05de\7T\2\2\u05dd\u05df\5\u00dco\2\u05de\u05dd\3\2\2\2\u05de"+ + "\u05df\3\2\2\2\u05df\u05e1\3\2\2\2\u05e0\u05e2\7W\2\2\u05e1\u05e0\3\2"+ + "\2\2\u05e1\u05e2\3\2\2\2\u05e2\u05e3\3\2\2\2\u05e3\u05e4\7U\2\2\u05e4"+ + "\u00fb\3\2\2\2\u05e5\u05eb\7T\2\2\u05e6\u05e8\5\u00fe\u0080\2\u05e7\u05e9"+ + "\7W\2\2\u05e8\u05e7\3\2\2\2\u05e8\u05e9\3\2\2\2\u05e9\u05ec\3\2\2\2\u05ea"+ + "\u05ec\7_\2\2\u05eb\u05e6\3\2\2\2\u05eb\u05ea\3\2\2\2\u05ec\u05ed\3\2"+ + "\2\2\u05ed\u05ee\7U\2\2\u05ee\u00fd\3\2\2\2\u05ef\u05f4\5\u0100\u0081"+ + "\2\u05f0\u05f1\7W\2\2\u05f1\u05f3\5\u0100\u0081\2\u05f2\u05f0\3\2\2\2"+ + "\u05f3\u05f6\3\2\2\2\u05f4\u05f2\3\2\2\2\u05f4\u05f5\3\2\2\2\u05f5\u00ff"+ + "\3\2\2\2\u05f6\u05f4\3\2\2\2\u05f7\u05f8\5\u0102\u0082\2\u05f8\u05f9\7"+ + "_\2\2\u05f9\u05fa\5\u0126\u0094\2\u05fa\u05fb\5\u00e6t\2\u05fb\u0602\3"+ + "\2\2\2\u05fc\u05fd\7j\2\2\u05fd\u05fe\7_\2\2\u05fe\u05ff\5\u0126\u0094"+ + "\2\u05ff\u0600\5\u00e6t\2\u0600\u0602\3\2\2\2\u0601\u05f7\3\2\2\2\u0601"+ + "\u05fc\3\2\2\2\u0602\u0101\3\2\2\2\u0603\u0606\5\u0122\u0092\2\u0604\u0606"+ + "\5\u00f8}\2\u0605\u0603\3\2\2\2\u0605\u0604\3\2\2\2\u0606\u0103\3\2\2"+ + "\2\u0607\u061f\5\u010a\u0086\2\u0608\u0609\6\u0083\35\3\u0609\u060a\5"+ + "\u0126\u0094\2\u060a\u060c\5\u0110\u0089\2\u060b\u060d\5\u0108\u0085\2"+ + "\u060c\u060b\3\2\2\2\u060c\u060d\3\2\2\2\u060d\u0620\3\2\2\2\u060e\u0614"+ + "\6\u0083\36\3\u060f\u0610\5\u0088E\2\u0610\u0611\7T\2\2\u0611\u0612\5"+ + "\u00e6t\2\u0612\u0613\7U\2\2\u0613\u0615\3\2\2\2\u0614\u060f\3\2\2\2\u0615"+ + "\u0616\3\2\2\2\u0616\u0614\3\2\2\2\u0616\u0617\3\2\2\2\u0617\u0618\3\2"+ + "\2\2\u0618\u0619\5F$\2\u0619\u0620\3\2\2\2\u061a\u061b\6\u0083\37\3\u061b"+ + "\u061c\5D#\2\u061c\u061d\5\u0126\u0094\2\u061d\u061e\5\u0106\u0084\2\u061e"+ + "\u0620\3\2\2\2\u061f\u0608\3\2\2\2\u061f\u060e\3\2\2\2\u061f\u061a\3\2"+ + "\2\2\u0620\u0105\3\2\2\2\u0621\u0622\7R\2\2\u0622\u0624\5\u0126\u0094"+ + "\2\u0623\u0625\5B\"\2\u0624\u0623\3\2\2\2\u0624\u0625\3\2\2\2\u0625\u0626"+ + "\3\2\2\2\u0626\u0627\5\u0126\u0094\2\u0627\u0628\7S\2\2\u0628\u0107\3"+ + "\2\2\2\u0629\u062a\5(\25\2\u062a\u0109\3\2\2\2\u062b\u0631\5\u0088E\2"+ + "\u062c\u0632\5R*\2\u062d\u062f\5l\67\2\u062e\u0630\5\u010e\u0088\2\u062f"+ + "\u062e\3\2\2\2\u062f\u0630\3\2\2\2\u0630\u0632\3\2\2\2\u0631\u062c\3\2"+ + "\2\2\u0631\u062d\3\2\2\2\u0632\u010b\3\2\2\2\u0633\u0634\7[\2\2\u0634"+ + "\u0635\5\u0126\u0094\2\u0635\u0636\5$\23\2\u0636\u0637\5\u0126\u0094\2"+ + "\u0637\u0638\7Z\2\2\u0638\u010d\3\2\2\2\u0639\u063a\7[\2\2\u063a\u063d"+ + "\7Z\2\2\u063b\u063d\5T+\2\u063c\u0639\3\2\2\2\u063c\u063b\3\2\2\2\u063d"+ + "\u010f\3\2\2\2\u063e\u0640\7P\2\2\u063f\u0641\5\u0114\u008b\2\u0640\u063f"+ + "\3\2\2\2\u0640\u0641\3\2\2\2\u0641\u0643\3\2\2\2\u0642\u0644\7W\2\2\u0643"+ + "\u0642\3\2\2\2\u0643\u0644\3\2\2\2\u0644\u0645\3\2\2\2\u0645\u0646\5\u0124"+ + "\u0093\2\u0646\u0111\3\2\2\2\u0647\u064e\5\u0116\u008c\2\u0648\u0649\7"+ + "W\2\2\u0649\u064a\5\u0126\u0094\2\u064a\u064b\5\u0116\u008c\2\u064b\u064d"+ + "\3\2\2\2\u064c\u0648\3\2\2\2\u064d\u0650\3\2\2\2\u064e\u064c\3\2\2\2\u064e"+ + "\u064f\3\2\2\2\u064f\u0113\3\2\2\2\u0650\u064e\3\2\2\2\u0651\u0658\5\u0118"+ + "\u008d\2\u0652\u0653\7W\2\2\u0653\u0654\5\u0126\u0094\2\u0654\u0655\5"+ + "\u0118\u008d\2\u0655\u0657\3\2\2\2\u0656\u0652\3\2\2\2\u0657\u065a\3\2"+ + "\2\2\u0658\u0656\3\2\2\2\u0658\u0659\3\2\2\2\u0659\u0115\3\2\2\2\u065a"+ + "\u0658\3\2\2\2\u065b\u065e\5\u00dep\2\u065c\u065e\5\u0100\u0081\2\u065d"+ + "\u065b\3\2\2\2\u065d\u065c\3\2\2\2\u065e\u0117\3\2\2\2\u065f\u0663\5\u00de"+ + "p\2\u0660\u0663\5z>\2\u0661\u0663\5\u0100\u0081\2\u0662\u065f\3\2\2\2"+ + "\u0662\u0660\3\2\2\2\u0662\u0661\3\2\2\2\u0663\u0119\3\2\2\2\u0664\u0665"+ + "\7\3\2\2\u0665\u011b\3\2\2\2\u0666\u0667\7|\2\2\u0667\u011d\3\2\2\2\u0668"+ + "\u0671\7}\2\2\u0669\u0671\7|\2\2\u066a\u0671\7\16\2\2\u066b\u066c\6\u0090"+ + " \2\u066c\u0671\7-\2\2\u066d\u0671\7\13\2\2\u066e\u0671\7\f\2\2\u066f"+ + "\u0671\7\t\2\2\u0670\u0668\3\2\2\2\u0670\u0669\3\2\2\2\u0670\u066a\3\2"+ + "\2\2\u0670\u066b\3\2\2\2\u0670\u066d\3\2\2\2\u0670\u066e\3\2\2\2\u0670"+ + "\u066f\3\2\2\2\u0671\u011f\3\2\2\2\u0672\u0673\t\24\2\2\u0673\u0121\3"+ + "\2\2\2\u0674\u0675\t\25\2\2\u0675\u0123\3\2\2\2\u0676\u0679\7Q\2\2\u0677"+ + "\u0679\b\u0093\1\2\u0678\u0676\3\2\2\2\u0678\u0677\3\2\2\2\u0679\u0125"+ + "\3\2\2\2\u067a\u067c\7\u0081\2\2\u067b\u067a\3\2\2\2\u067c\u067f\3\2\2"+ + "\2\u067d\u067b\3\2\2\2\u067d\u067e\3\2\2\2\u067e\u0127\3\2\2\2\u067f\u067d"+ + "\3\2\2\2\u0680\u0682\t\26\2\2\u0681\u0680\3\2\2\2\u0682\u0683\3\2\2\2"+ + "\u0683\u0681\3\2\2\2\u0683\u0684\3\2\2\2\u0684\u0129\3\2\2\2\u00ba\u012c"+ + "\u012f\u0132\u013c\u0140\u0149\u0150\u0157\u015a\u0161\u0164\u016b\u016f"+ + "\u0173\u0176\u017d\u0188\u0193\u019c\u01a6\u01b4\u01ba\u01c3\u01c7\u01ca"+ + "\u01d2\u01d5\u01d8\u01e0\u01e3\u01e6\u01e9\u01f0\u01f4\u0200\u0206\u020b"+ + "\u020e\u0213\u0217\u021e\u0229\u022d\u0230\u0239\u023d\u023f\u0243\u0248"+ + "\u0253\u025c\u026b\u0270\u0278\u027b\u0280\u0287\u028a\u0290\u0293\u0297"+ + "\u029b\u02a8\u02b5\u02b7\u02c3\u02c8\u02ce\u02d6\u02de\u02e1\u02e9\u02f2"+ + "\u02fa\u0301\u030d\u0315\u031d\u0325\u0329\u032f\u0342\u0346\u034b\u0351"+ + "\u0357\u035f\u0363\u036a\u0371\u0374\u0378\u0381\u038c\u0391\u0399\u039c"+ + "\u039f\u03a8\u03ab\u03b2\u03bb\u03bf\u03c8\u03d1\u03d9\u03df\u03e9\u03ef"+ + "\u03f7\u03fd\u0407\u0420\u0424\u0428\u042c\u0435\u043b\u0444\u0451\u0464"+ + "\u046a\u0476\u0481\u048b\u0490\u0497\u04a1\u04a5\u04a9\u04b0\u04b4\u04b8"+ + "\u04bc\u04cf\u04d5\u04db\u04e1\u04f4\u050f\u0512\u0552\u0562\u0564\u056b"+ + "\u0570\u0577\u057a\u0582\u058a\u0590\u05a9\u05af\u05b3\u05b6\u05ba\u05bf"+ + "\u05c4\u05ca\u05da\u05de\u05e1\u05e8\u05eb\u05f4\u0601\u0605\u060c\u0616"+ + "\u061f\u0624\u062f\u0631\u063c\u0640\u0643\u064e\u0658\u065d\u0662\u0670"+ + "\u0678\u067d\u0683"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/GroovyParser.tokens b/base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/GroovyParser.tokens similarity index 100% rename from base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/GroovyParser.tokens rename to base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/GroovyParser.tokens diff --git a/base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/GroovyParserBaseVisitor.java b/base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/GroovyParserBaseVisitor.java similarity index 96% rename from base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/GroovyParserBaseVisitor.java rename to base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/GroovyParserBaseVisitor.java index 0c4261121d..7483d39902 100644 --- a/base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/GroovyParserBaseVisitor.java +++ b/base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/GroovyParserBaseVisitor.java @@ -2,9 +2,7 @@ package org.apache.groovy.parser.antlr4; import java.util.Map; - import org.codehaus.groovy.util.ListHashMap; import org.codehaus.groovy.ast.NodeMetaDataHandler; - import org.codehaus.groovy.ast.NodeMetaDataHandlerHelper; import org.apache.groovy.parser.antlr4.SemanticPredicates; import groovyjarjarantlr4.v4.runtime.Token; @@ -444,14 +442,6 @@ public class GroovyParserBaseVisitor extends AbstractParseTreeVisitorThe default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

    - */ - @Override public Result visitNormalExprAlt(@NotNull GroovyParser.NormalExprAltContext ctx) { return visitChildren(ctx); } - /** * {@inheritDoc} * diff --git a/base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/GroovyParserVisitor.java b/base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/GroovyParserVisitor.java similarity index 96% rename from base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/GroovyParserVisitor.java rename to base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/GroovyParserVisitor.java index 85005d4a74..dd88e43a59 100644 --- a/base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/GroovyParserVisitor.java +++ b/base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/GroovyParserVisitor.java @@ -2,9 +2,7 @@ package org.apache.groovy.parser.antlr4; import java.util.Map; - import org.codehaus.groovy.util.ListHashMap; import org.codehaus.groovy.ast.NodeMetaDataHandler; - import org.codehaus.groovy.ast.NodeMetaDataHandlerHelper; import org.apache.groovy.parser.antlr4.SemanticPredicates; import groovyjarjarantlr4.v4.runtime.Token; @@ -443,14 +441,6 @@ public interface GroovyParserVisitor extends ParseTreeVisitor { */ Result visitEmptyStmtAlt(@NotNull GroovyParser.EmptyStmtAltContext ctx); - /** - * Visit a parse tree produced by the {@code normalExprAlt} - * labeled alternative in {@link GroovyParser#statementExpression}. - * @param ctx the parse tree - * @return the visitor result - */ - Result visitNormalExprAlt(@NotNull GroovyParser.NormalExprAltContext ctx); - /** * Visit a parse tree produced by the {@code commandExprAlt} * labeled alternative in {@link GroovyParser#statementExpression}. diff --git a/base/org.codehaus.groovy26/src/org/codehaus/greclipse/GroovyTokenTypeBridge.java b/base/org.codehaus.groovy30/src/org/codehaus/greclipse/GroovyTokenTypeBridge.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/greclipse/GroovyTokenTypeBridge.java rename to base/org.codehaus.groovy30/src/org/codehaus/greclipse/GroovyTokenTypeBridge.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/activator/GroovyActivator.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/activator/GroovyActivator.java similarity index 94% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/activator/GroovyActivator.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/activator/GroovyActivator.java index 0b25d70957..6ef8fd2d70 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/activator/GroovyActivator.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/activator/GroovyActivator.java @@ -30,7 +30,7 @@ public class GroovyActivator extends Plugin { public static final String PLUGIN_ID = "org.codehaus.groovy"; - public static final String GROOVY_JAR = "lib/groovy-2.6.0-indy.jar"; + public static final String GROOVY_JAR = "lib/groovy-3.0.0-indy.jar"; public static URL GROOVY_JAR_URL; @@ -67,6 +67,9 @@ public void start(BundleContext context) throws Exception { System.out.println("------------"); } + // disable long-lived PARAMETERIZED_TYPE_CACHE in GenericsUtils + System.setProperty("groovy.enable.parameterized.type.cache", "false"); + super.start(context); try { initialize(); diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java similarity index 99% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java index 9e2023d94d..f5cd55f7dc 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java @@ -75,7 +75,6 @@ import org.codehaus.groovy.ast.expr.ListExpression; import org.codehaus.groovy.ast.expr.MapEntryExpression; import org.codehaus.groovy.ast.expr.MapExpression; -import org.codehaus.groovy.ast.expr.MethodCall; import org.codehaus.groovy.ast.expr.MethodCallExpression; import org.codehaus.groovy.ast.expr.MethodPointerExpression; import org.codehaus.groovy.ast.expr.NamedArgumentListExpression; diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/ErrorRecoveredCSTParserPlugin.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/ErrorRecoveredCSTParserPlugin.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/ErrorRecoveredCSTParserPlugin.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/ErrorRecoveredCSTParserPlugin.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/ErrorRecoveredCSTParserPluginFactory.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/ErrorRecoveredCSTParserPluginFactory.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/ErrorRecoveredCSTParserPluginFactory.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/ErrorRecoveredCSTParserPluginFactory.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/ICSTReporter.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/ICSTReporter.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/ICSTReporter.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/ICSTReporter.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/LocationSupport.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/LocationSupport.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/LocationSupport.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/LocationSupport.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/SourceBuffer.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/SourceBuffer.java similarity index 99% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/SourceBuffer.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/SourceBuffer.java index 061564ee83..179f036f6e 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/SourceBuffer.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/SourceBuffer.java @@ -158,8 +158,6 @@ public void setUnescaper(UnicodeEscapingReader unicodeEscapingReader) { /** * GRECLIPSE-805: Support for unicode escape sequences - * @author Andrew Eisenberg - * @created Mar 3, 2011 */ class NoEscaper extends UnicodeEscapingReader { public NoEscaper() { diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/UnicodeEscapingReader.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/UnicodeEscapingReader.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/UnicodeEscapingReader.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/UnicodeEscapingReader.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/groovy.g b/base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/groovy.g similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/groovy.g rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/groovy.g diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/parser/GroovyLexer.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/parser/GroovyLexer.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/parser/GroovyLexer.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/parser/GroovyLexer.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/parser/GroovyLexer.smap b/base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/parser/GroovyLexer.smap similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/parser/GroovyLexer.smap rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/parser/GroovyLexer.smap diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/parser/GroovyRecognizer.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/parser/GroovyRecognizer.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/parser/GroovyRecognizer.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/parser/GroovyRecognizer.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/parser/GroovyRecognizer.smap b/base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/parser/GroovyRecognizer.smap similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/parser/GroovyRecognizer.smap rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/parser/GroovyRecognizer.smap diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/parser/GroovyTokenTypes.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/parser/GroovyTokenTypes.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/parser/GroovyTokenTypes.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/parser/GroovyTokenTypes.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/parser/GroovyTokenTypes.txt b/base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/parser/GroovyTokenTypes.txt similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/parser/GroovyTokenTypes.txt rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/parser/GroovyTokenTypes.txt diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/ASTNode.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ASTNode.java similarity index 78% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/ASTNode.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ASTNode.java index 1fcd69031b..b5b68511e8 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/ASTNode.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ASTNode.java @@ -18,9 +18,6 @@ */ package org.codehaus.groovy.ast; -import org.codehaus.groovy.GroovyBugError; -import org.codehaus.groovy.util.ListHashMap; - import java.util.Map; import java.util.Objects; @@ -56,7 +53,6 @@ public class ASTNode implements NodeMetaDataHandler { private final int[] offsets = new int[2]; // GRECLIPSE end private Map metaDataMap; - private final NodeMetaDataHandlerHelper helper = new NodeMetaDataHandlerHelper(this); public void visit(GroovyCodeVisitor visitor) { throw new RuntimeException("No visit() method implemented for class: " + getClass().getName()); @@ -144,52 +140,12 @@ public void copyNodeMetaData(ASTNode other) { } @Override - public void copyNodeMetaData(NodeMetaDataHandler other) { - helper.copyNodeMetaData(other); - } - - @Override - public T getNodeMetaData(Object key) { - return helper.getNodeMetaData(key); - } - - // GRECLIPSE add - public T getNodeMetaData(Object key, java.util.function.Function valFn) { - if (key == null) throw new GroovyBugError("Tried to get/set meta data with null key on " + this + "."); - if (metaDataMap == null) { - setMetaDataMap(new ListHashMap()); - } - return (T) metaDataMap.computeIfAbsent(key, valFn); - } - // GRECLIPSE end - - @Override - public void setNodeMetaData(Object key, Object value) { - helper.setNodeMetaData(key, value); - } - - @Override - public Object putNodeMetaData(Object key, Object value) { - return helper.putNodeMetaData(key, value); - } - - @Override - public void removeNodeMetaData(Object key) { - helper.removeNodeMetaData(key); - } - - @Override - public Map getNodeMetaData() { - return helper.getNodeMetaData(); - } - - @Override - public Map getMetaDataMap() { + public Map getMetaDataMap() { return metaDataMap; } @Override - public void setMetaDataMap(Map metaDataMap) { + public void setMetaDataMap(Map metaDataMap) { this.metaDataMap = metaDataMap; } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/AnnotatedNode.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/AnnotatedNode.java similarity index 96% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/AnnotatedNode.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/AnnotatedNode.java index 4d2503a795..256a5cbd29 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/AnnotatedNode.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/AnnotatedNode.java @@ -117,6 +117,17 @@ public void setHasNoRealSourcePosition(boolean value) { this.hasNoRealSourcePositionFlag = value; } + @Override + public Groovydoc getGroovydoc() { + Groovydoc groovydoc = getNodeMetaData(DOC_COMMENT); + return (groovydoc != null ? groovydoc : Groovydoc.EMPTY_GROOVYDOC); + } + + @Override + public AnnotatedNode getInstance() { + return this; + } + // GRECLIPSE add public int getNameStart() { return nameStart; @@ -144,16 +155,4 @@ public void setSourcePosition(ASTNode node) { } } // GRECLIPSE end - - @Override - public Groovydoc getGroovydoc() { - Groovydoc groovydoc = this.getNodeMetaData(DOC_COMMENT); - - return null == groovydoc ? Groovydoc.EMPTY_GROOVYDOC : groovydoc; - } - - @Override - public AnnotatedNode getInstance() { - return this; - } } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/ClassCodeVisitorSupport.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ClassCodeVisitorSupport.java similarity index 99% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/ClassCodeVisitorSupport.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ClassCodeVisitorSupport.java index ccdce9c1c9..85bfaad997 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/ClassCodeVisitorSupport.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ClassCodeVisitorSupport.java @@ -120,7 +120,7 @@ protected void visitAnnotation(AnnotationNode node) { } public void visitConstantExpression(ConstantExpression expression) { - // check for inlined constant (see ResolveVisitor.transformInlineConstants) + // check for inlined constant (see ExpressionUtils.transformInlineConstants) Expression original = expression.getNodeMetaData(ORIGINAL_EXPRESSION); if (original != null) { original.visit(this); diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/ClassHelper.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ClassHelper.java similarity index 95% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/ClassHelper.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ClassHelper.java index 4a164dbcc5..09b3dddf5b 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/ClassHelper.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ClassHelper.java @@ -28,6 +28,24 @@ import groovy.lang.Range; import groovy.lang.Reference; import groovy.lang.Script; +import groovy.lang.Tuple; +import groovy.lang.Tuple0; +import groovy.lang.Tuple1; +import groovy.lang.Tuple10; +import groovy.lang.Tuple11; +import groovy.lang.Tuple12; +import groovy.lang.Tuple13; +import groovy.lang.Tuple14; +import groovy.lang.Tuple15; +import groovy.lang.Tuple16; +import groovy.lang.Tuple2; +import groovy.lang.Tuple3; +import groovy.lang.Tuple4; +import groovy.lang.Tuple5; +import groovy.lang.Tuple6; +import groovy.lang.Tuple7; +import groovy.lang.Tuple8; +import groovy.lang.Tuple9; import org.apache.groovy.util.Maps; import org.codehaus.groovy.classgen.asm.util.TypeUtil; import org.codehaus.groovy.runtime.GeneratedClosure; @@ -72,6 +90,12 @@ public class ClassHelper { Iterator.class, GeneratedClosure.class, GeneratedLambda.class, GroovyObjectSupport.class }; + public static final Class[] TUPLE_CLASSES = new Class[] { + Tuple0.class, Tuple1.class, Tuple2.class, Tuple3.class, Tuple4.class, Tuple5.class, Tuple6.class, + Tuple7.class, Tuple8.class, Tuple9.class, Tuple10.class, Tuple11.class, Tuple12.class, Tuple13.class, + Tuple14.class, Tuple15.class, Tuple16.class + }; + @SuppressWarnings("unused") private static final String[] primitiveClassNames = new String[]{ "", "boolean", "char", "byte", "short", @@ -80,8 +104,10 @@ public class ClassHelper { public static final ClassNode DYNAMIC_TYPE = makeCached(Object.class), OBJECT_TYPE = DYNAMIC_TYPE, - VOID_TYPE = makeCached(Void.TYPE), CLOSURE_TYPE = makeCached(Closure.class), + VOID_TYPE = makeCached(Void.TYPE), + CLOSURE_TYPE = makeCached(Closure.class), GSTRING_TYPE = makeCached(GString.class), LIST_TYPE = makeWithoutCaching(List.class), + TUPLE_TYPE = makeWithoutCaching(Tuple.class), MAP_TYPE = makeWithoutCaching(Map.class), RANGE_TYPE = makeCached(Range.class), PATTERN_TYPE = makeCached(Pattern.class), STRING_TYPE = makeCached(String.class), SCRIPT_TYPE = makeCached(Script.class), REFERENCE_TYPE = makeWithoutCaching(Reference.class), diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/ClassNode.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ClassNode.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/ClassNode.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ClassNode.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/Comment.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/Comment.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/Comment.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/Comment.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/CompileUnit.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/CompileUnit.java similarity index 96% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/CompileUnit.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/CompileUnit.java index a3ecb72fbd..2bee649640 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/CompileUnit.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/CompileUnit.java @@ -39,10 +39,8 @@ *

    * It's attached to MethodNodes and ClassNodes and is used to find fully qualified names of classes, * resolve imports, and that sort of thing. - * - * @author James Strachan */ -public class CompileUnit { +public class CompileUnit implements NodeMetaDataHandler { private final List modules = new ArrayList(); private final Map classes = new HashMap(); @@ -57,6 +55,7 @@ public class CompileUnit { private final Map classesToCompile = new HashMap(); private final Map classNameToSource = new HashMap(); private final Map generatedInnerClasses = new HashMap(); + private Map metaDataMap; public CompileUnit(GroovyClassLoader classLoader, CompilerConfiguration config) { this(classLoader, null, config); @@ -198,4 +197,14 @@ public void addGeneratedInnerClass(InnerClassNode icn) { public Map getGeneratedInnerClasses() { return Collections.unmodifiableMap(generatedInnerClasses); } + + @Override + public Map getMetaDataMap() { + return metaDataMap; + } + + @Override + public void setMetaDataMap(Map metaDataMap) { + this.metaDataMap = metaDataMap; + } } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/ConstructorNode.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ConstructorNode.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/ConstructorNode.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ConstructorNode.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/GenericsType.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/GenericsType.java similarity index 90% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/GenericsType.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/GenericsType.java index 2e96ed9ded..1ae4b2636b 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/GenericsType.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/GenericsType.java @@ -24,6 +24,7 @@ import java.lang.reflect.Modifier; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.Set; import static org.codehaus.groovy.ast.ClassHelper.GROOVY_OBJECT_TYPE; @@ -387,18 +388,19 @@ private boolean compareGenericsWithBound(final ClassNode classNode, final ClassN return true; } GenericsType[] redirectBoundGenericTypes = bound.redirect().getGenericsTypes(); - Map classNodePlaceholders = GenericsUtils.extractPlaceholders(classNode); - Map boundPlaceHolders = GenericsUtils.extractPlaceholders(bound); + Map classNodePlaceholders = GenericsUtils.extractPlaceholders(classNode); + Map boundPlaceHolders = GenericsUtils.extractPlaceholders(bound); boolean match = true; for (int i = 0; redirectBoundGenericTypes!=null && i < redirectBoundGenericTypes.length && match; i++) { GenericsType redirectBoundType = redirectBoundGenericTypes[i]; GenericsType classNodeType = cnTypes[i]; if (classNodeType.isPlaceholder()) { - String name = classNodeType.getName(); + GenericsTypeName name = new GenericsTypeName(classNodeType.getName()); if (redirectBoundType.isPlaceholder()) { - match = name.equals(redirectBoundType.getName()); + GenericsTypeName gtn = new GenericsTypeName(redirectBoundType.getName()); + match = name.equals(gtn); if (!match) { - GenericsType genericsType = boundPlaceHolders.get(redirectBoundType.getName()); + GenericsType genericsType = boundPlaceHolders.get(gtn); match = false; if (genericsType!=null) { if (genericsType.isPlaceholder()) { @@ -424,7 +426,7 @@ private boolean compareGenericsWithBound(final ClassNode classNode, final ClassN if (classNodeType.isPlaceholder()) { match = classNodeType.getName().equals(redirectBoundType.getName()); } else { - String name = redirectBoundType.getName(); + GenericsTypeName name = new GenericsTypeName(redirectBoundType.getName()); if (boundPlaceHolders.containsKey(name)) { redirectBoundType = boundPlaceHolders.get(name); boolean wildcard = redirectBoundType.isWildcard(); @@ -439,8 +441,9 @@ private boolean compareGenericsWithBound(final ClassNode classNode, final ClassN if (gt.isPlaceholder()) { // check for recursive generic typedef, like in // > - if (classNodePlaceholders.containsKey(gt.getName())) { - gt = classNodePlaceholders.get(gt.getName()); + GenericsTypeName gtn = new GenericsTypeName(gt.getName()); + if (classNodePlaceholders.containsKey(gtn)) { + gt = classNodePlaceholders.get(gtn); } } match = implementsInterfaceOrIsSubclassOf(gt.getType(), classNodeType.getType()); @@ -451,8 +454,9 @@ private boolean compareGenericsWithBound(final ClassNode classNode, final ClassN if (gt.isPlaceholder()) { // check for recursive generic typedef, like in // > - if (classNodePlaceholders.containsKey(gt.getName())) { - gt = classNodePlaceholders.get(gt.getName()); + GenericsTypeName gtn = new GenericsTypeName(gt.getName()); + if (classNodePlaceholders.containsKey(gtn)) { + gt = classNodePlaceholders.get(gtn); } } match = implementsInterfaceOrIsSubclassOf(classNodeType.getType(), gt.getType()) @@ -513,4 +517,46 @@ private static ClassNode getParameterizedSuperClass(ClassNode classNode) { } return superClass; } + + /** + * Represents GenericsType name + * TODO In order to distinguish GenericsType with same name(See GROOVY-8409), we should add a property to keep the declaring class. + * + * fixing GROOVY-8409 steps: + * 1) change the signature of constructor GenericsTypeName to `GenericsTypeName(String name, ClassNode declaringClass)` + * 2) try to fix all compilation errors(if `GenericsType` has declaringClass property, the step would be a bit easy to fix...) + * 3) run all tests to see whether the change breaks anything + * 4) if all tests pass, congratulations! but if some tests are broken, try to debug and find why... + * + * We should find a way to set declaring class for `GenericsType` first, it can be completed at the resolving phase. + */ + public static class GenericsTypeName { + private String name; + + public GenericsTypeName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + GenericsTypeName that = (GenericsTypeName) o; + return Objects.equals(name, that.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } + + @Override + public String toString() { + return name; + } + } } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/GroovyCodeVisitor.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/GroovyCodeVisitor.java similarity index 91% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/GroovyCodeVisitor.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/GroovyCodeVisitor.java index e37ed67fd0..9e204ca19e 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/GroovyCodeVisitor.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/GroovyCodeVisitor.java @@ -33,6 +33,7 @@ import org.codehaus.groovy.ast.expr.DeclarationExpression; import org.codehaus.groovy.ast.expr.ElvisOperatorExpression; import org.codehaus.groovy.ast.expr.EmptyExpression; +import org.codehaus.groovy.ast.expr.Expression; import org.codehaus.groovy.ast.expr.FieldExpression; import org.codehaus.groovy.ast.expr.GStringExpression; import org.codehaus.groovy.ast.expr.LambdaExpression; @@ -72,6 +73,8 @@ import org.codehaus.groovy.ast.stmt.WhileStatement; import org.codehaus.groovy.classgen.BytecodeExpression; +import java.util.List; + /** * An implementation of the visitor pattern for working with ASTNodes * @@ -140,7 +143,9 @@ public interface GroovyCodeVisitor { void visitClosureExpression(ClosureExpression expression); - void visitLambdaExpression(LambdaExpression expression); + default void visitLambdaExpression(LambdaExpression expression) { + visitClosureExpression(expression); + } void visitTupleExpression(TupleExpression expression); @@ -195,4 +200,18 @@ public interface GroovyCodeVisitor { // GRECLIPSE add default void visitEmptyExpression(EmptyExpression expression) {} // GRECLIPSE end + + default void visitListOfExpressions(List list) { + if (list == null) return; + for (Expression expression : list) { + // GRECLIPSE edit + //if (expression instanceof SpreadExpression) { + // Expression spread = ((SpreadExpression) expression).getExpression(); + // spread.visit(this); + //} else { + expression.visit(this); + //} + // GRECLIPSE end + } + } } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/ImmutableClassNode.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ImmutableClassNode.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/ImmutableClassNode.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ImmutableClassNode.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/ImportNode.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ImportNode.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/ImportNode.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ImportNode.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/MethodNode.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/MethodNode.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/MethodNode.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/MethodNode.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/ModuleNode.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ModuleNode.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/ModuleNode.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ModuleNode.java diff --git a/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/NodeMetaDataHandler.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/NodeMetaDataHandler.java new file mode 100644 index 0000000000..7f004b7892 --- /dev/null +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/NodeMetaDataHandler.java @@ -0,0 +1,148 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.ast; + +import org.codehaus.groovy.GroovyBugError; +import org.codehaus.groovy.util.ListHashMap; + +import java.util.Collections; +import java.util.Map; + +/** + * An interface to mark a node being able to handle metadata + */ +public interface NodeMetaDataHandler { + /** + * Gets the node meta data. + * + * @param key - the meta data key + * @return the node meta data value for this key + */ + default T getNodeMetaData(Object key) { + Map metaDataMap = this.getMetaDataMap(); + if (metaDataMap == null) { + return (T) null; + } + return (T) metaDataMap.get(key); + } + + // GRECLIPSE add + default T getNodeMetaData(Object key, java.util.function.Function valFn) { + if (key == null) throw new GroovyBugError("Tried to get/set meta data with null key on " + this + "."); + + Map metaDataMap = this.getMetaDataMap(); + if (metaDataMap == null) { + metaDataMap = new ListHashMap(); + this.setMetaDataMap(metaDataMap); + } + return (T) metaDataMap.computeIfAbsent(key, valFn); + } + // GRECLIPSE end + + /** + * Copies all node meta data from the other node to this one + * + * @param other - the other node + */ + default void copyNodeMetaData(NodeMetaDataHandler other) { + Map otherMetaDataMap = other.getMetaDataMap(); + if (otherMetaDataMap == null) { + return; + } + Map metaDataMap = this.getMetaDataMap(); + if (metaDataMap == null) { + metaDataMap = new ListHashMap(); + this.setMetaDataMap(metaDataMap); + } + + metaDataMap.putAll(otherMetaDataMap); + } + + /** + * Sets the node meta data. + * + * @param key - the meta data key + * @param value - the meta data value + * @throws GroovyBugError if key is null or there is already meta + * data under that key + */ + default void setNodeMetaData(Object key, Object value) { + if (key == null) throw new GroovyBugError("Tried to set meta data with null key on " + this + "."); + + Map metaDataMap = this.getMetaDataMap(); + if (metaDataMap == null) { + metaDataMap = new ListHashMap(); + this.setMetaDataMap(metaDataMap); + } + Object old = metaDataMap.put(key, value); + if (old != null) throw new GroovyBugError("Tried to overwrite existing meta data " + this + "."); + } + + /** + * Sets the node meta data but allows overwriting values. + * + * @param key - the meta data key + * @param value - the meta data value + * @return the old node meta data value for this key + * @throws GroovyBugError if key is null + */ + default Object putNodeMetaData(Object key, Object value) { + if (key == null) throw new GroovyBugError("Tried to set meta data with null key on " + this + "."); + + Map metaDataMap = this.getMetaDataMap(); + if (metaDataMap == null) { + metaDataMap = new ListHashMap(); + this.setMetaDataMap(metaDataMap); + } + return metaDataMap.put(key, value); + } + + /** + * Removes a node meta data entry. + * + * @param key - the meta data key + * @throws GroovyBugError if the key is null + */ + default void removeNodeMetaData(Object key) { + if (key == null) throw new GroovyBugError("Tried to remove meta data with null key " + this + "."); + + Map metaDataMap = this.getMetaDataMap(); + if (metaDataMap == null) { + return; + } + metaDataMap.remove(key); + } + + /** + * Returns an unmodifiable view of the current node metadata. + * + * @return the node metadata. Always not null. + */ + default Map getNodeMetaData() { + Map metaDataMap = this.getMetaDataMap(); + if (metaDataMap == null) { + return Collections.emptyMap(); + } + return Collections.unmodifiableMap(metaDataMap); + } + + Map getMetaDataMap(); + + void setMetaDataMap(Map metaDataMap); +} diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/Parameter.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/Parameter.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/Parameter.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/Parameter.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/TaskEntry.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/TaskEntry.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/TaskEntry.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/TaskEntry.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/expr/ClassExpression.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/expr/ClassExpression.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/expr/ClassExpression.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/expr/ClassExpression.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/expr/ConstantExpression.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/expr/ConstantExpression.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/expr/ConstantExpression.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/expr/ConstantExpression.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/expr/EmptyExpression.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/expr/EmptyExpression.java similarity index 98% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/expr/EmptyExpression.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/expr/EmptyExpression.java index 944a870e82..9829d88fb5 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/expr/EmptyExpression.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/expr/EmptyExpression.java @@ -130,7 +130,7 @@ public void removeNodeMetaData(Object key) { } @Override - public void setMetaDataMap(Map metaDataMap) { + public void setMetaDataMap(Map metaDataMap) { throw createUnsupportedOperationException(); } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/expr/MethodCallExpression.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/expr/MethodCallExpression.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/expr/MethodCallExpression.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/expr/MethodCallExpression.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/expr/StaticMethodCallExpression.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/expr/StaticMethodCallExpression.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/expr/StaticMethodCallExpression.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/expr/StaticMethodCallExpression.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/stmt/EmptyStatement.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/stmt/EmptyStatement.java similarity index 98% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/stmt/EmptyStatement.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/stmt/EmptyStatement.java index 2203091651..db23e4210d 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/stmt/EmptyStatement.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/stmt/EmptyStatement.java @@ -86,7 +86,7 @@ public void removeNodeMetaData(Object key) { } @Override - public void setMetaDataMap(Map metaDataMap) { + public void setMetaDataMap(Map metaDataMap) { throw createUnsupportedOperationException(); } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/tools/GenericsUtils.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/tools/GenericsUtils.java similarity index 77% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/tools/GenericsUtils.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/tools/GenericsUtils.java index 4d9b84f353..c06cd434ca 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/ast/tools/GenericsUtils.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/tools/GenericsUtils.java @@ -20,6 +20,7 @@ import groovyjarjarantlr.RecognitionException; import groovyjarjarantlr.TokenStreamException; +import groovy.lang.Tuple2; import groovy.transform.stc.IncorrectTypeHintException; import org.codehaus.groovy.GroovyBugError; import org.codehaus.groovy.antlr.AntlrParserPlugin; @@ -44,6 +45,7 @@ import java.io.StringReader; import java.lang.ref.SoftReference; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; @@ -52,7 +54,10 @@ import java.util.Map; import java.util.Objects; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Predicate; +import static groovy.lang.Tuple.tuple; +import static org.codehaus.groovy.ast.GenericsType.GenericsTypeName; import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.getCorrectedClassNode; import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf; @@ -139,8 +144,8 @@ public static GenericsType buildWildcardType(final ClassNode... types) { return gt; } - public static Map extractPlaceholders(ClassNode cn) { - Map ret = new HashMap(); + public static Map extractPlaceholders(ClassNode cn) { + Map ret = new HashMap<>(); extractPlaceholders(cn, ret); return ret; } @@ -152,7 +157,7 @@ public static Map extractPlaceholders(ClassNode cn) { * @param node the class node to check * @param map the generics type information collector */ - public static void extractPlaceholders(ClassNode node, Map map) { + public static void extractPlaceholders(ClassNode node, Map map) { if (node == null) return; if (node.isArray()) { @@ -178,7 +183,7 @@ public static void extractPlaceholders(ClassNode node, Map for (int i = 0; i < redirectGenericsTypes.length; i++) { GenericsType redirectType = redirectGenericsTypes[i]; if (redirectType.isPlaceholder()) { - String name = redirectType.getName(); + GenericsTypeName name = new GenericsTypeName(redirectType.getName()); if (!map.containsKey(name)) { GenericsType value = parameterized[i]; map.put(name, value); @@ -457,7 +462,26 @@ public static Map addMethodGenerics(MethodNode current, Map sr = PARAMETERIZED_TYPE_CACHE.getAndPut(new ParameterizedTypeCacheKey(genericsClass, actualType), new EvictableCache.ValueProvider>() { - @Override - public SoftReference provide(ParameterizedTypeCacheKey key) { - return new SoftReference<>(findParameterizedType(key.getGenericsClass(), key.getActualType())); - } - }); + public static ClassNode findParameterizedTypeFromCache(final ClassNode genericsClass, final ClassNode actualType, boolean tryToFindExactType) { + if (!PARAMETERIZED_TYPE_CACHE_ENABLED) { + return findParameterizedType(genericsClass, actualType, tryToFindExactType); + } + + SoftReference sr = PARAMETERIZED_TYPE_CACHE.getAndPut(new ParameterizedTypeCacheKey(genericsClass, actualType), key -> new SoftReference<>(findParameterizedType(key.getGenericsClass(), key.getActualType(), tryToFindExactType))); return null == sr ? null : sr.get(); } /** * Get the parameterized type by search the whole class hierarchy according to generics class and actual receiver. - * {@link #findParameterizedTypeFromCache(ClassNode, ClassNode)} is strongly recommended for better performance. + * {@link #findParameterizedTypeFromCache(ClassNode, ClassNode, boolean)} is strongly recommended for better performance. * * @param genericsClass the generics class * @param actualType the actual type + * @param tryToFindExactType whether to try to find exact type * @return the parameterized type */ - public static ClassNode findParameterizedType(ClassNode genericsClass, ClassNode actualType) { + public static ClassNode findParameterizedType(ClassNode genericsClass, ClassNode actualType, boolean tryToFindExactType) { ClassNode parameterizedType = null; if (null == genericsClass.getGenericsTypes()) { @@ -703,12 +726,18 @@ public static ClassNode findParameterizedType(ClassNode genericsClass, ClassNode List classNodeList = new LinkedList<>(getAllSuperClassesAndInterfaces(actualType)); classNodeList.add(0, actualType); + LinkedList parameterizedTypeCandidateList = new LinkedList<>(); + for (ClassNode cn : classNodeList) { if (cn == genericsClass) { continue; } - if (!genericsClass.equals(cn.redirect())) { + if (tryToFindExactType && null != cn.getGenericsTypes() && hasNonPlaceHolders(cn)) { + parameterizedTypeCandidateList.add(cn); + } + + if (!(genericsClass.equals(cn.redirect()))) { continue; } @@ -718,6 +747,12 @@ public static ClassNode findParameterizedType(ClassNode genericsClass, ClassNode } } + if (null == parameterizedType) { + if (!parameterizedTypeCandidateList.isEmpty()) { + parameterizedType = parameterizedTypeCandidateList.getLast(); + } + } + return parameterizedType; } @@ -750,6 +785,14 @@ private static List getAllUnresolvedSuperClasses(ClassNode actualRece private static final EvictableCache> PARAMETERIZED_TYPE_CACHE = new ConcurrentSoftCache<>(64); + /** + * Clear the parameterized type cache + * It is useful to IDE as the type being compiled are continuously being edited/altered, see GROOVY-8675 + */ + public static void clearParameterizedTypeCache() { + PARAMETERIZED_TYPE_CACHE.clearAll(); + } + /** * map declaring generics type to actual generics type, e.g. GROOVY-7204: * declaring generics types: T, S extends Serializable @@ -764,28 +807,189 @@ private static List getAllUnresolvedSuperClasses(ClassNode actualRece * so we need actual types: T: String, S: Long */ public static Map makeDeclaringAndActualGenericsTypeMap(ClassNode declaringClass, ClassNode actualReceiver) { - ClassNode parameterizedType = findParameterizedTypeFromCache(declaringClass, actualReceiver); + return doMakeDeclaringAndActualGenericsTypeMap(declaringClass, actualReceiver, false).getV1(); + } + + /** + * The method is similar with {@link GenericsUtils#makeDeclaringAndActualGenericsTypeMap(ClassNode, ClassNode)}, + * The main difference is that the method will try to map all placeholders found to the relevant exact types, + * but the other will not try even if the parameterized type has placeholders + * + * @param declaringClass the generics class node declaring the generics types + * @param actualReceiver the sub-class class node + * @return the placeholder-to-actualtype mapping + * @since 3.0.0 + */ + public static Map makeDeclaringAndActualGenericsTypeMapOfExactType(ClassNode declaringClass, ClassNode actualReceiver) { + List parameterizedTypeList = new LinkedList<>(); + + Map result = makeDeclaringAndActualGenericsTypeMapOfExactType(declaringClass, actualReceiver, parameterizedTypeList); + + return connectGenericsTypes(result); + } + + private static Map makeDeclaringAndActualGenericsTypeMapOfExactType(ClassNode declaringClass, ClassNode actualReceiver, List parameterizedTypeList) { + Tuple2, ClassNode> resultAndParameterizedTypeTuple = doMakeDeclaringAndActualGenericsTypeMap(declaringClass, actualReceiver, true); + ClassNode parameterizedType = resultAndParameterizedTypeTuple.getV2(); + Map result = resultAndParameterizedTypeTuple.getV1(); + + if (hasPlaceHolders(parameterizedType) && !parameterizedTypeList.contains(parameterizedType)) { + parameterizedTypeList.add(parameterizedType); + result.putAll(makeDeclaringAndActualGenericsTypeMapOfExactType(parameterizedType, actualReceiver, parameterizedTypeList)); + } + + return connectGenericsTypes(result); + } + + private static Tuple2, ClassNode> doMakeDeclaringAndActualGenericsTypeMap(ClassNode declaringClass, ClassNode actualReceiver, boolean tryToFindExactType) { + ClassNode parameterizedType = findParameterizedTypeFromCache(declaringClass, actualReceiver, tryToFindExactType); if (null == parameterizedType) { + return tuple(Collections.emptyMap(), parameterizedType); + } + + Map result = new LinkedHashMap<>(); + + result.putAll(makePlaceholderAndParameterizedTypeMap(declaringClass)); + result.putAll(makePlaceholderAndParameterizedTypeMap(parameterizedType)); + + result = connectGenericsTypes(result); + + return tuple(result, parameterizedType); + } + + private static Map makePlaceholderAndParameterizedTypeMap(ClassNode declaringClass) { + if (null == declaringClass) { return Collections.emptyMap(); } + Map result = new LinkedHashMap<>(); + + ClassNode redirectDeclaringClass = declaringClass.redirect(); GenericsType[] declaringGenericsTypes = declaringClass.getGenericsTypes(); - GenericsType[] actualGenericsTypes = parameterizedType.getGenericsTypes(); + GenericsType[] redirectDeclaringGenericsTypes = redirectDeclaringClass.getGenericsTypes(); + + if (null != declaringGenericsTypes && null != redirectDeclaringGenericsTypes) { + for (int i = 0, n = declaringGenericsTypes.length; i < n; i++) { + result.put(redirectDeclaringGenericsTypes[i], declaringGenericsTypes[i]); + } + } + + return result; + } + private static Map connectGenericsTypes(Map genericsTypeMap) { Map result = new LinkedHashMap<>(); - for (int i = 0, n = declaringGenericsTypes.length; i < n; i++) { - result.put(declaringGenericsTypes[i], actualGenericsTypes[i]); + + outter: + for (Map.Entry entry : genericsTypeMap.entrySet()) { + GenericsType key = entry.getKey(); + GenericsType value = entry.getValue(); + + if (value.isPlaceholder()) { + for (Map.Entry genericsTypeMapEntry : genericsTypeMap.entrySet()) { + GenericsType genericsTypeMapEntryValue = genericsTypeMapEntry.getValue(); + if (!genericsTypeMapEntryValue.isPlaceholder() && (genericsTypeMapEntry.getKey().getName().equals(value.getName()))) { + result.put(key, genericsTypeMapEntryValue); // connected to actual type + continue outter; + } + } + } + + result.put(key, value); } return result; } + /** + * Check whether the ClassNode has non generics placeholders, aka not placeholder + * + * @param parameterizedType the class node + * @return the result + * @since 3.0.0 + */ + public static boolean hasNonPlaceHolders(ClassNode parameterizedType) { + return checkPlaceHolders(parameterizedType, genericsType -> !genericsType.isPlaceholder()); + } + + /** + * Check whether the ClassNode has generics placeholders + * @param parameterizedType the class node + * @return the result + * @since 3.0.0 + */ + public static boolean hasPlaceHolders(ClassNode parameterizedType) { + return checkPlaceHolders(parameterizedType, genericsType -> genericsType.isPlaceholder()); + } + + private static boolean checkPlaceHolders(ClassNode parameterizedType, Predicate p) { + if (null == parameterizedType) return false; + + GenericsType[] genericsTypes = parameterizedType.getGenericsTypes(); + + if (null == genericsTypes) return false; + + for (GenericsType genericsType : genericsTypes) { + if (p.test(genericsType)) { + return true; + } + } + + return false; + } + + /** + * Get the parameter and return types of the abstract method of SAM + * + * If the abstract method is not parameterized, we will get generics placeholders, e.g. T, U + * For example, the abstract method of {@link java.util.function.Function} is + *

    +     *      R apply(T t);
    +     * 
    + * + * We parameterize the above interface as {@code Function}, then the abstract method will be + *
    +     *      Integer apply(String t);
    +     * 
    + * + * When we call {@code parameterizeSAM} on the ClassNode {@code Function}, + * we can get parameter types and return type of the above abstract method, + * i.e. ClassNode {@code ClassHelper.STRING_TYPE} and {@code ClassHelper.Integer_TYPE} + * + * @param sam the class node which contains only one abstract method + * @return the parameter and return types + * @since 3.0.0 + * + */ + public static Tuple2 parameterizeSAM(ClassNode sam) { + MethodNode methodNode = ClassHelper.findSAM(sam); + final Map map = makeDeclaringAndActualGenericsTypeMapOfExactType(methodNode.getDeclaringClass(), sam); + + ClassNode[] parameterTypes = + Arrays.stream(methodNode.getParameters()) + .map(e -> { + ClassNode originalParameterType = e.getType(); + return originalParameterType.isGenericsPlaceHolder() + ? findActualTypeByGenericsPlaceholderName(originalParameterType.getUnresolvedName(), map) + : originalParameterType; + }) + .toArray(ClassNode[]::new); + + ClassNode originalReturnType = methodNode.getReturnType(); + ClassNode returnType = + originalReturnType.isGenericsPlaceHolder() + ? findActualTypeByGenericsPlaceholderName(originalReturnType.getUnresolvedName(), map) + : originalReturnType; + + return tuple(parameterTypes, returnType); + } + /** * Get the actual type according to the placeholder name * * @param placeholderName the placeholder name, e.g. T, E - * @param genericsPlaceholderAndTypeMap the result of {@link #makeDeclaringAndActualGenericsTypeMap(ClassNode, ClassNode} + * @param genericsPlaceholderAndTypeMap the result of {@link #makeDeclaringAndActualGenericsTypeMap(ClassNode, ClassNode)} * @return the actual type */ public static ClassNode findActualTypeByGenericsPlaceholderName(String placeholderName, Map genericsPlaceholderAndTypeMap) { diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/AnnotationVisitor.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/AnnotationVisitor.java similarity index 86% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/AnnotationVisitor.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/AnnotationVisitor.java index d70f36e3c3..84f2c9adf8 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/AnnotationVisitor.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/AnnotationVisitor.java @@ -40,11 +40,11 @@ import org.codehaus.groovy.syntax.SyntaxException; import org.codehaus.groovy.vmplugin.VMPluginFactory; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; import java.util.List; import java.util.Map; +import static org.apache.groovy.ast.tools.ExpressionUtils.transformInlineConstants; + /** * An Annotation visitor responsible for: *
      @@ -90,9 +90,9 @@ public AnnotationNode visit(AnnotationNode node) { Map attributes = node.getMembers(); for (Map.Entry entry : attributes.entrySet()) { String attrName = entry.getKey(); - Expression attrExpr = transformInlineConstants(entry.getValue()); - entry.setValue(attrExpr); ClassNode attrType = getAttributeType(node, attrName); + Expression attrExpr = transformInlineConstants(entry.getValue(), attrType); + entry.setValue(attrExpr); visitExpression(attrName, attrExpr, attrType); } VMPluginFactory.getPlugin().configureAnnotation(node); @@ -133,50 +133,6 @@ private boolean validateEnumConstant(Expression exp) { return true; } - private Expression transformInlineConstants(Expression exp) { - if (exp instanceof PropertyExpression) { - PropertyExpression pe = (PropertyExpression) exp; - if (pe.getObjectExpression() instanceof ClassExpression) { - ClassExpression ce = (ClassExpression) pe.getObjectExpression(); - ClassNode type = ce.getType(); - if (type.isEnum() || !type.isResolved()) - return exp; - - try { - // GRECLIPSE add - if (type.hasClass()) { - // GRECLIPSE end - Field field = type.getTypeClass().getField(pe.getPropertyAsString()); - if (field != null && Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers())) { - return new ConstantExpression(field.get(null)); - } - // GRECLIPSE add - } else { - FieldNode fieldNode = type.getField(pe.getPropertyAsString()); - if (fieldNode != null && Modifier.isStatic(fieldNode.getModifiers()) && Modifier.isFinal(fieldNode.getModifiers())) { - Expression e = fieldNode.getInitialExpression(); - return e; - } - } - // GRECLIPSE end - } catch(Exception e) { - // ignore, leave property expression in place and we'll report later - } - } - } else if (exp instanceof ListExpression) { - ListExpression le = (ListExpression) exp; - ListExpression result = new ListExpression(); - for (Expression e : le.getExpressions()) { - result.addExpression(transformInlineConstants(e)); - } - // GRECLIPSE edd - result.setSourcePosition(exp); - // GRECLIPSE end - return result; - } - return exp; - } - private boolean checkIfMandatoryAnnotationValuesPassed(AnnotationNode node) { boolean ok = true; /* GRECLIPSE edit -- temp hack; can't rely on getCode() @@ -271,8 +227,12 @@ public void checkReturnType(ClassNode attrType, ASTNode node) { } private ConstantExpression getConstantExpression(Expression exp, ClassNode attrType) { - if (exp instanceof ConstantExpression) { - return (ConstantExpression) exp; + Expression result = exp; + if (!(result instanceof ConstantExpression)) { + result = transformInlineConstants(result, attrType); + } + if (result instanceof ConstantExpression) { + return (ConstantExpression) result; } String base = "Expected '" + exp.getText() + "' to be an inline constant of type " + attrType.getName(); if (exp instanceof PropertyExpression) { diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/AsmClassGenerator.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/AsmClassGenerator.java similarity index 99% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/AsmClassGenerator.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/AsmClassGenerator.java index aee8bdb8da..6cbd4daef7 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/AsmClassGenerator.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/AsmClassGenerator.java @@ -102,7 +102,6 @@ import org.codehaus.groovy.classgen.asm.WriterController; import org.codehaus.groovy.classgen.asm.WriterControllerFactory; import org.codehaus.groovy.control.SourceUnit; -import org.codehaus.groovy.runtime.MetaClassHelper; import org.codehaus.groovy.runtime.ScriptBytecodeAdapter; import org.codehaus.groovy.syntax.RuntimeParserException; import groovyjarjarasm.asm.AnnotationVisitor; @@ -124,6 +123,8 @@ import java.util.List; import java.util.Map; +import static org.apache.groovy.util.BeanUtils.capitalize; + /** * Generates Java class versions of Groovy classes using ASM. * @@ -1031,7 +1032,7 @@ && isThisExpression(objectExpression) } else { prefix = "get"; } - String propName = prefix + MetaClassHelper.capitalize(name); + String propName = prefix + capitalize(name); visitMethodCallExpression(new MethodCallExpression(objectExpression, propName, MethodCallExpression.NO_ARGUMENTS)); return; } @@ -1067,6 +1068,10 @@ && isThisExpression(objectExpression) iterType = iterType.getOuterClass(); if (thisField == null) { // closure within inner class + while (iterType.isDerivedFrom(ClassHelper.CLOSURE_TYPE)) { + // GROOVY-8881: cater for closures within closures - getThisObject is already outer class of all closures + iterType = iterType.getOuterClass(); + } mv.visitMethodInsn(INVOKEVIRTUAL, BytecodeHelper.getClassInternalName(ClassHelper.CLOSURE_TYPE), "getThisObject", "()Ljava/lang/Object;", false); mv.visitTypeInsn(CHECKCAST, BytecodeHelper.getClassInternalName(iterType)); } else { @@ -1140,13 +1145,13 @@ private boolean getterAndSetterExists(MethodNode setter, MethodNode getter) { } private MethodNode findSetterOfSuperClass(ClassNode classNode, FieldNode fieldNode) { - String setterMethodName = "set" + MetaClassHelper.capitalize(fieldNode.getName()); + String setterMethodName = "set" + capitalize(fieldNode.getName()); return classNode.getSuperClass().getSetterMethod(setterMethodName); } private MethodNode findGetterOfSuperClass(ClassNode classNode, FieldNode fieldNode) { - String getterMethodName = "get" + MetaClassHelper.capitalize(fieldNode.getName()); + String getterMethodName = "get" + capitalize(fieldNode.getName()); return classNode.getSuperClass().getGetterMethod(getterMethodName); } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/ClassCompletionVerifier.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/ClassCompletionVerifier.java similarity index 99% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/ClassCompletionVerifier.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/ClassCompletionVerifier.java index f0928a0e43..71a17552d4 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/ClassCompletionVerifier.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/ClassCompletionVerifier.java @@ -43,7 +43,6 @@ import org.codehaus.groovy.ast.stmt.CatchStatement; import org.codehaus.groovy.ast.tools.GeneralUtils; import org.codehaus.groovy.control.SourceUnit; -import org.codehaus.groovy.runtime.MetaClassHelper; import org.codehaus.groovy.syntax.Types; import org.codehaus.groovy.transform.trait.Traits; @@ -62,6 +61,7 @@ import static java.lang.reflect.Modifier.isSynchronized; import static java.lang.reflect.Modifier.isTransient; import static java.lang.reflect.Modifier.isVolatile; +import static org.apache.groovy.util.BeanUtils.capitalize; import static org.codehaus.groovy.ast.ClassHelper.VOID_TYPE; import static groovyjarjarasm.asm.Opcodes.ACC_ABSTRACT; import static groovyjarjarasm.asm.Opcodes.ACC_FINAL; @@ -545,11 +545,11 @@ public void visitProperty(PropertyNode node) { private void checkDuplicateProperties(PropertyNode node) { ClassNode cn = node.getDeclaringClass(); String name = node.getName(); - String getterName = "get" + MetaClassHelper.capitalize(name); + String getterName = "get" + capitalize(name); if (Character.isUpperCase(name.charAt(0))) { for (PropertyNode propNode : cn.getProperties()) { String otherName = propNode.getField().getName(); - String otherGetterName = "get" + MetaClassHelper.capitalize(otherName); + String otherGetterName = "get" + capitalize(otherName); if (node != propNode && getterName.equals(otherGetterName)) { String msg = "The field " + name + " and " + otherName + " on the class " + cn.getName() + " will result in duplicate JavaBean properties, which is not allowed"; diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/EnumVisitor.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/EnumVisitor.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/EnumVisitor.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/EnumVisitor.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/ExtendedVerifier.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/ExtendedVerifier.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/ExtendedVerifier.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/ExtendedVerifier.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/VariableScopeVisitor.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/VariableScopeVisitor.java similarity index 93% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/VariableScopeVisitor.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/VariableScopeVisitor.java index 827b4cc575..fe16d7aab3 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/VariableScopeVisitor.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/VariableScopeVisitor.java @@ -53,8 +53,8 @@ import java.util.Iterator; import java.util.LinkedList; -import static java.beans.Introspector.decapitalize; import static java.lang.reflect.Modifier.isFinal; +import static org.apache.groovy.ast.tools.MethodNodeUtils.getPropertyName; /** * goes through an AST and initializes the scopes @@ -184,17 +184,16 @@ private Variable findClassMember(ClassNode cn, String name) { for (MethodNode mn : cn.getMethods()) { String pName = getPropertyName(mn); - // GRECLIPSE edit - //if (pName != null && pName.equals(name)) - // return new PropertyNode(pName, mn.getModifiers(), ClassHelper.OBJECT_TYPE, cn, null, null, null); if (name.equals(pName)) { + // GRECLIPSE edit + //PropertyNode property = new PropertyNode(name, mn.getModifiers(), ClassHelper.OBJECT_TYPE, cn, null, null, null); PropertyNode property = new PropertyNode(name, mn.getModifiers(), getPropertyType(mn), cn, null, null, null); + // GRECLIPSE end property.getField().setHasNoRealSourcePosition(true); property.getField().setSynthetic(true); property.getField().setDeclaringClass(cn); property.setDeclaringClass(cn); return property; } - // GRECLIPSE end } for (PropertyNode pn : cn.getProperties()) { @@ -206,39 +205,6 @@ private Variable findClassMember(ClassNode cn, String name) { return findClassMember(cn.getOuterClass(), name); } - private static String getPropertyName(MethodNode m) { - String name = m.getName(); - /* GRECLIPSE edit - if (!(name.startsWith("set") || name.startsWith("get"))) return null; - String pname = name.substring(3); - if (pname.length() == 0) return null; - pname = java.beans.Introspector.decapitalize(pname); - - if (name.startsWith("get") && (m.getReturnType() == ClassHelper.VOID_TYPE || m.getParameters().length != 0)) { - return null; - } - if (name.startsWith("set") && m.getParameters().length != 1) { - return null; - } - return pname; - */ - if (name.startsWith("set") || name.startsWith("get") || name.startsWith("is")) { - String pname = decapitalize(name.substring(name.startsWith("is") ? 2 : 3)); - if (!pname.isEmpty()) { - if (name.startsWith("set")) { - if (m.getParameters().length == 1) { - return pname; - } - } else if (m.getParameters().length == 0 && !ClassHelper.VOID_TYPE.equals(m.getReturnType())) { - if (name.startsWith("get") || ClassHelper.boolean_TYPE.equals(m.getReturnType())) { - return pname; - } - } - } - } - return null; - } - // GRECLIPSE add private static ClassNode getPropertyType(MethodNode m) { if (ClassHelper.VOID_TYPE.equals(m.getReturnType())) { diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/Verifier.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/Verifier.java similarity index 97% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/Verifier.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/Verifier.java index 7362ccf779..24a340e93a 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/Verifier.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/Verifier.java @@ -22,7 +22,9 @@ import groovy.lang.GroovyObject; import groovy.lang.MetaClass; import groovy.transform.Generated; +import groovy.transform.Internal; import org.apache.groovy.ast.tools.ClassNodeUtils; +import org.apache.groovy.util.BeanUtils; import org.codehaus.groovy.GroovyBugError; import org.codehaus.groovy.ast.AnnotationNode; import org.codehaus.groovy.ast.ClassHelper; @@ -62,7 +64,6 @@ import org.codehaus.groovy.classgen.asm.WriterController; import org.codehaus.groovy.reflection.ClassInfo; import org.codehaus.groovy.runtime.DefaultGroovyMethods; -import org.codehaus.groovy.runtime.MetaClassHelper; import org.codehaus.groovy.syntax.RuntimeParserException; import org.codehaus.groovy.syntax.Token; import org.codehaus.groovy.syntax.Types; @@ -84,11 +85,12 @@ import java.util.Map; import java.util.Set; -import static java.lang.reflect.Modifier.isAbstract; import static java.lang.reflect.Modifier.isFinal; import static java.lang.reflect.Modifier.isPrivate; import static java.lang.reflect.Modifier.isPublic; import static java.lang.reflect.Modifier.isStatic; +import static org.apache.groovy.ast.tools.AnnotatedNodeUtils.markAsGenerated; +import static org.apache.groovy.ast.tools.ExpressionUtils.transformInlineConstants; import static org.apache.groovy.ast.tools.MethodNodeUtils.methodDescriptorWithoutReturnType; import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpec; import static org.codehaus.groovy.ast.tools.GenericsUtils.createGenericsSpec; @@ -141,6 +143,7 @@ public class Verifier implements GroovyClassVisitor, Opcodes { }; private static final Class GENERATED_ANNOTATION = Generated.class; + private static final Class INTERNAL_ANNOTATION = Internal.class; private ClassNode classNode; private MethodNode methodNode; @@ -411,10 +414,11 @@ protected void addGroovyObjectInterfaceAndMethods(ClassNode node, final String c boolean shouldAnnotate = classNode.getModule().getContext() != null; AnnotationNode generatedAnnotation = shouldAnnotate ? new AnnotationNode(ClassHelper.make(GENERATED_ANNOTATION)) : null; + AnnotationNode internalAnnotation = shouldAnnotate ? new AnnotationNode(ClassHelper.make(INTERNAL_ANNOTATION)) : null; if (!node.hasMethod("getMetaClass", Parameter.EMPTY_ARRAY)) { metaClassField = setMetaClassFieldIfNotExists(node, metaClassField); - MethodNode methodNode = addMethod(node, !isAbstract(node.getModifiers()), + MethodNode methodNode = addMethod(node, !shouldAnnotate, "getMetaClass", ACC_PUBLIC, ClassHelper.METACLASS_TYPE, @@ -453,7 +457,10 @@ public void visit(MethodVisitor mv) { } }) ); - if (shouldAnnotate) methodNode.addAnnotation(generatedAnnotation); + if (shouldAnnotate) { + methodNode.addAnnotation(generatedAnnotation); + methodNode.addAnnotation(internalAnnotation); + } } Parameter[] parameters = new Parameter[]{new Parameter(ClassHelper.METACLASS_TYPE, "mc")}; @@ -482,13 +489,16 @@ public void visit(MethodVisitor mv) { setMetaClassCode = new BytecodeSequence(list); } - MethodNode methodNode = addMethod(node, !isAbstract(node.getModifiers()), + MethodNode methodNode = addMethod(node, !shouldAnnotate, "setMetaClass", ACC_PUBLIC, ClassHelper.VOID_TYPE, SET_METACLASS_PARAMS, ClassNode.EMPTY_ARRAY, setMetaClassCode ); - if (shouldAnnotate) methodNode.addAnnotation(generatedAnnotation); + if (shouldAnnotate) { + methodNode.addAnnotation(generatedAnnotation); + methodNode.addAnnotation(internalAnnotation); + } } if (!node.hasMethod("invokeMethod", INVOKE_METHOD_PARAMS)) { @@ -498,7 +508,7 @@ public void visit(MethodVisitor mv) { blockScope.putReferencedLocalVariable(vMethods); blockScope.putReferencedLocalVariable(vArguments); - MethodNode methodNode = addMethod(node, !isAbstract(node.getModifiers()), + MethodNode methodNode = addMethod(node, !shouldAnnotate, "invokeMethod", ACC_PUBLIC, ClassHelper.OBJECT_TYPE, INVOKE_METHOD_PARAMS, @@ -515,11 +525,14 @@ public void visit(MethodVisitor mv) { } }) ); - if (shouldAnnotate) methodNode.addAnnotation(generatedAnnotation); + if (shouldAnnotate) { + methodNode.addAnnotation(generatedAnnotation); + methodNode.addAnnotation(internalAnnotation); + } } if (!node.hasMethod("getProperty", GET_PROPERTY_PARAMS)) { - MethodNode methodNode = addMethod(node, !isAbstract(node.getModifiers()), + MethodNode methodNode = addMethod(node, !shouldAnnotate, "getProperty", ACC_PUBLIC, ClassHelper.OBJECT_TYPE, @@ -536,11 +549,14 @@ public void visit(MethodVisitor mv) { } }) ); - if (shouldAnnotate) methodNode.addAnnotation(generatedAnnotation); + if (shouldAnnotate) { + methodNode.addAnnotation(generatedAnnotation); + methodNode.addAnnotation(internalAnnotation); + } } if (!node.hasMethod("setProperty", SET_PROPERTY_PARAMS)) { - MethodNode methodNode = addMethod(node, !isAbstract(node.getModifiers()), + MethodNode methodNode = addMethod(node, !shouldAnnotate, "setProperty", ACC_PUBLIC, ClassHelper.VOID_TYPE, @@ -558,7 +574,10 @@ public void visit(MethodVisitor mv) { } }) ); - if (shouldAnnotate) methodNode.addAnnotation(generatedAnnotation); + if (shouldAnnotate) { + methodNode.addAnnotation(generatedAnnotation); + methodNode.addAnnotation(internalAnnotation); + } } } @@ -758,7 +777,7 @@ private void visitGetter(PropertyNode node, Statement getterBlock, int getterMod protected void addPropertyMethod(MethodNode method) { classNode.addMethod(method); - method.addAnnotation(new AnnotationNode(ClassHelper.make(GENERATED_ANNOTATION))); + markAsGenerated(classNode, method); // GROOVY-4415 / GROOVY-4645: check that there's no abstract method which corresponds to this one List abstractMethods = classNode.getAbstractMethods(); if (abstractMethods == null) return; @@ -894,7 +913,8 @@ public void call(ArgumentListExpression arguments, Parameter[] newParams, Method } protected void addConstructor(Parameter[] newParams, ConstructorNode ctor, Statement code, ClassNode node) { - node.addConstructor(ctor.getModifiers(), newParams, ctor.getExceptions(), code); + ConstructorNode genConstructor = node.addConstructor(ctor.getModifiers(), newParams, ctor.getExceptions(), code); + markAsGenerated(node, genConstructor); } /** @@ -957,9 +977,7 @@ protected void addDefaultParameters(DefaultArgsAction action, MethodNode method) } for (Parameter parameter : parameters) { - // GRECLIPSE add - if (!parameter.hasInitialExpression()) continue; - // GRECLIPSE end + if (!parameter.hasInitialExpression()) continue; // GROOVY-8728 make idempotent // remove default expression and store it as node metadata parameter.putNodeMetaData(Verifier.INITIAL_EXPRESSION, parameter.getInitialExpression()); parameter.setInitialExpression(null); @@ -1154,10 +1172,12 @@ protected void addFieldInitialization(List list, List staticList, FieldNode fiel // GROOVY-3311: pre-defined constants added by groovy compiler for numbers/characters should be // initialized first so that code dependent on it does not see their values as empty Expression initialValueExpression = fieldNode.getInitialValueExpression(); - if (initialValueExpression instanceof ConstantExpression) { - ConstantExpression cexp = (ConstantExpression) initialValueExpression; + Expression transformed = transformInlineConstants(initialValueExpression, fieldNode.getType()); + if (transformed instanceof ConstantExpression) { + ConstantExpression cexp = (ConstantExpression) transformed; cexp = transformToPrimitiveConstantIfPossible(cexp); if (fieldNode.isFinal() && ClassHelper.isStaticConstantInitializerType(cexp.getType()) && cexp.getType().equals(fieldNode.getType())) { + fieldNode.setInitialValueExpression(transformed); return; // GROOVY-5150: primitive type constants will be initialized directly } staticList.add(0, statement); @@ -1186,7 +1206,7 @@ protected void addFieldInitialization(List list, List staticList, FieldNode fiel * Capitalizes the start of the given bean property name */ public static String capitalize(String name) { - return MetaClassHelper.capitalize(name); + return BeanUtils.capitalize(name); } protected Statement createGetterBlock(PropertyNode propertyNode, final FieldNode field) { diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/asm/BytecodeHelper.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/BytecodeHelper.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/asm/BytecodeHelper.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/BytecodeHelper.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/asm/CompileStack.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/CompileStack.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/asm/CompileStack.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/CompileStack.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/asm/StatementWriter.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/StatementWriter.java similarity index 99% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/asm/StatementWriter.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/StatementWriter.java index 647c67030f..e822798d67 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/asm/StatementWriter.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/StatementWriter.java @@ -92,13 +92,12 @@ public void writeBlockStatement(BlockStatement block) { } compileStack.pop(); - // GRECLIPSE add + // GROOVY-7647 if (block.getLastLineNumber() > 0) { MethodVisitor mv = controller.getMethodVisitor(); Label blockEnd = new Label(); mv.visitLabel(blockEnd); mv.visitLineNumber(block.getLastLineNumber(), blockEnd); } - // GRECLIPSE end controller.getOperandStack().popDownTo(mark); } @@ -166,9 +165,7 @@ protected void writeForInLoop(ForStatement loop) { private void visitExpressionOfLoopStatement(Expression expression) { if (expression instanceof ClosureListExpression) { - for (Expression e : ((ClosureListExpression) expression).getExpressions()) { - visitExpressionOrStatement(e); - } + ((ClosureListExpression) expression).getExpressions().forEach(this::visitExpressionOrStatement); } else { visitExpressionOrStatement(expression); } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/asm/WriterController.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/WriterController.java similarity index 97% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/asm/WriterController.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/WriterController.java index 9bc4de3dc7..d6da5fccd6 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/asm/WriterController.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/WriterController.java @@ -72,7 +72,7 @@ public class WriterController { private StatementWriter statementWriter; private boolean fastPath = false; private TypeChooser typeChooser; - private int bytecodeVersion = Opcodes.V1_5; + private int bytecodeVersion = Opcodes.V1_8; private int lineNumber = -1; private int helperMethodIndex = 0; private List superMethodNames = new ArrayList(); @@ -149,14 +149,11 @@ private ClassVisitor createClassVisitor(ClassVisitor cv) { } private static int chooseBytecodeVersion(final boolean invokedynamic, final String targetBytecode) { - if (invokedynamic) { - if (CompilerConfiguration.JDK8.equals(targetBytecode)) { - return Opcodes.V1_8; - } - return Opcodes.V1_7; - } else { - Integer bytecodeVersion = CompilerConfiguration.JDK_TO_BYTECODE_VERSION_MAP.get(targetBytecode); + Integer bytecodeVersion = CompilerConfiguration.JDK_TO_BYTECODE_VERSION_MAP.get(targetBytecode); + if (invokedynamic && bytecodeVersion < Opcodes.V1_8) { + return Opcodes.V1_8; + } else { if (null != bytecodeVersion) { return bytecodeVersion; } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/asm/sc/StaticPropertyAccessHelper.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/sc/StaticPropertyAccessHelper.java similarity index 99% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/asm/sc/StaticPropertyAccessHelper.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/sc/StaticPropertyAccessHelper.java index fa67bfaae2..307c3c77b1 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/asm/sc/StaticPropertyAccessHelper.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/sc/StaticPropertyAccessHelper.java @@ -32,7 +32,7 @@ /** * Contains helper methods aimed at facilitating the generation of statically compiled bytecode for property access. * - * @author Cédric Champeau + * @author Cédric Champeau * @since 2.4.0 */ public abstract class StaticPropertyAccessHelper { diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/CompilationUnit.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/control/CompilationUnit.java similarity index 98% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/control/CompilationUnit.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/control/CompilationUnit.java index 67d4f9b18f..b915d5383b 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/CompilationUnit.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/control/CompilationUnit.java @@ -185,12 +185,26 @@ public CompilationUnit(CompilerConfiguration configuration, CodeSource security, this.staticImportVisitor = new StaticImportVisitor(); this.optimizer = new OptimizerVisitor(this); - phaseOperations = new LinkedList[Phases.ALL + 1]; - newPhaseOperations = new LinkedList[Phases.ALL + 1]; + initPhaseOperations(); + addPhaseOperations(); + + applyCompilationCustomizers(configuration); + + this.classgenCallback = null; + this.classNodeResolver = new ClassNodeResolver(); + } + + private void initPhaseOperations() { + int cnt = Phases.ALL + 1; + phaseOperations = new LinkedList[cnt]; + newPhaseOperations = new LinkedList[cnt]; for (int i = 0; i < phaseOperations.length; i++) { phaseOperations[i] = new LinkedList(); newPhaseOperations[i] = new LinkedList(); } + } + + private void addPhaseOperations() { addPhaseOperation(new SourceUnitOperation() { public void call(SourceUnit source) throws CompilationFailedException { source.parse(); @@ -277,7 +291,9 @@ public void call(SourceUnit source, GeneratorContext context, } } }, Phases.INSTRUCTION_SELECTION); + } + private void applyCompilationCustomizers(CompilerConfiguration configuration) { // apply configuration customizers if any if (configuration != null) { final List customizers = configuration.getCompilationCustomizers(); @@ -288,8 +304,6 @@ public void call(SourceUnit source, GeneratorContext context, addPhaseOperation(customizer, customizer.getPhase().getPhaseNumber()); } } - this.classgenCallback = null; - this.classNodeResolver = new ClassNodeResolver(); } /** @@ -302,17 +316,21 @@ public GroovyClassLoader getTransformLoader() { public void addPhaseOperation(SourceUnitOperation op, int phase) { - if (phase < 0 || phase > Phases.ALL) throw new IllegalArgumentException("phase " + phase + " is unknown"); + validatePhase(phase); phaseOperations[phase].add(op); } public void addPhaseOperation(PrimaryClassNodeOperation op, int phase) { - if (phase < 0 || phase > Phases.ALL) throw new IllegalArgumentException("phase " + phase + " is unknown"); + validatePhase(phase); phaseOperations[phase].add(op); } - public void addFirstPhaseOperation(PrimaryClassNodeOperation op, int phase) { + private static void validatePhase(int phase) { if (phase < 0 || phase > Phases.ALL) throw new IllegalArgumentException("phase " + phase + " is unknown"); + } + + public void addFirstPhaseOperation(PrimaryClassNodeOperation op, int phase) { + validatePhase(phase); phaseOperations[phase].add(0, op); } @@ -321,7 +339,7 @@ public void addPhaseOperation(GroovyClassOperation op) { } public void addNewPhaseOperation(SourceUnitOperation op, int phase) { - if (phase < 0 || phase > Phases.ALL) throw new IllegalArgumentException("phase " + phase + " is unknown"); + validatePhase(phase); newPhaseOperations[phase].add(op); } @@ -744,20 +762,10 @@ public void call(GroovyClass gclass) throws CompilationFailedException { // byte[] bytes = gclass.getBytes(); - FileOutputStream stream = null; - try { - stream = new FileOutputStream(path); + try (FileOutputStream stream = new FileOutputStream(path)) { stream.write(bytes, 0, bytes.length); } catch (IOException e) { getErrorCollector().addError(Message.create(e.getMessage(), CompilationUnit.this)); - } finally { - if (stream != null) { - try { - stream.close(); - } catch (Exception e) { - // Ignore - } - } } } }; @@ -1154,12 +1162,10 @@ public void applyToPrimaryClassNodes(PrimaryClassNodeOperation body) throws Comp } catch (GroovyBugError e) { changeBugText(e, context); throw e; - } catch (NoClassDefFoundError e) { + } catch (NoClassDefFoundError | Exception e) { // effort to get more logging in case a dependency of a class is loaded // although it shouldn't have convertUncaughtExceptionToCompilationError(e); - } catch (Exception e) { - convertUncaughtExceptionToCompilationError(e); } } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/CompilerConfiguration.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/control/CompilerConfiguration.java similarity index 91% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/control/CompilerConfiguration.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/control/CompilerConfiguration.java index 0988135ee5..1459537cdb 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/CompilerConfiguration.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/control/CompilerConfiguration.java @@ -50,6 +50,12 @@ public class CompilerConfiguration { /** This ("indy") is the Optimization Option value for enabling invokedynamic compilation. */ public static final String INVOKEDYNAMIC = "indy"; + /** This ("groovydoc") is the Optimization Option value for enabling attaching groovydoc as AST node metadata. */ + public static final String GROOVYDOC = "groovydoc"; + + /** This ("runtimeGroovydoc") is the Optimization Option value for enabling attaching {@link groovy.lang.Groovydoc} annotation*/ + public static final String RUNTIME_GROOVYDOC = "runtimeGroovydoc"; + /** This ("1.4") is the value for targetBytecode to compile for a JDK 1.4. **/ public static final String JDK4 = "1.4"; /** This ("1.5") is the value for targetBytecode to compile for a JDK 1.5. **/ @@ -62,6 +68,12 @@ public class CompilerConfiguration { public static final String JDK8 = "1.8"; /** This ("9") is the value for targetBytecode to compile for a JDK 9. **/ public static final String JDK9 = "9"; + /** This ("10") is the value for targetBytecode to compile for a JDK 10. **/ + public static final String JDK10 = "10"; + /** This ("11") is the value for targetBytecode to compile for a JDK 11. **/ + public static final String JDK11 = "11"; + /** This ("12") is the value for targetBytecode to compile for a JDK 12. **/ + public static final String JDK12 = "12"; /** * This constant is for comparing targetBytecode to ensure it is set to JDK 1.5 or later. @@ -77,20 +89,25 @@ public class CompilerConfiguration { @Deprecated public static final String PRE_JDK5 = JDK4; - /** JDK version to bytecode version mapping */ + /** + * JDK version to bytecode version mapping + */ public static final Map JDK_TO_BYTECODE_VERSION_MAP = Maps.of( JDK4, Opcodes.V1_4, JDK5, Opcodes.V1_5, JDK6, Opcodes.V1_6, JDK7, Opcodes.V1_7, JDK8, Opcodes.V1_8, - JDK9, Opcodes.V9 + JDK9, Opcodes.V9, + JDK10, Opcodes.V10, + JDK11, Opcodes.V11, + JDK12, Opcodes.V12 ); /** An array of the valid targetBytecode values **/ public static final String[] ALLOWED_JDKS = JDK_TO_BYTECODE_VERSION_MAP.keySet().toArray(new String[0]); - public static final int ASM_API_VERSION = Opcodes.ASM6; + public static final int ASM_API_VERSION = Opcodes.ASM7; /** * The default source encoding @@ -196,7 +213,7 @@ public class CompilerConfiguration { /** * Global AST transformations which should not be loaded even if they are - * defined in META-INF/org.codehaus.groovy.transform.ASTTransformation files. + * defined in META-INF/services/org.codehaus.groovy.transform.ASTTransformation files. * By default, none are disabled. */ private Set disabledGlobalASTTransformations; @@ -241,15 +258,23 @@ public CompilerConfiguration() { setTargetDirectory(target); } - boolean indy = getBooleanSafe("groovy.target.indy"); - if (DEFAULT!=null && Boolean.TRUE.equals(DEFAULT.getOptimizationOptions().get(INVOKEDYNAMIC))) { - indy = true; + Map options = new HashMap<>(4); + + handleOptimizationOption(options, INVOKEDYNAMIC, "groovy.target.indy"); + handleOptimizationOption(options, GROOVYDOC, "groovy.attach.groovydoc"); + handleOptimizationOption(options, RUNTIME_GROOVYDOC, "groovy.attach.runtime.groovydoc"); + + setOptimizationOptions(options); + } + + private void handleOptimizationOption(Map options, String optionName, String sysOptionName) { + boolean optionEnabled = getBooleanSafe(sysOptionName); + if (DEFAULT != null && Boolean.TRUE.equals(DEFAULT.getOptimizationOptions().get(optionName))) { + optionEnabled = true; } - Map options = new HashMap(3); - if (indy) { - options.put(INVOKEDYNAMIC, Boolean.TRUE); + if (optionEnabled) { + options.put(optionName, Boolean.TRUE); } - setOptimizationOptions(options); } /** @@ -700,14 +725,14 @@ public ParserPluginFactory getPluginFactory() { /* GRECLIPSE edit pluginFactory = ParserVersion.V_2 == parserVersion ? ParserPluginFactory.antlr2() - : ParserPluginFactory.antlr4(); + : ParserPluginFactory.antlr4(this); */ pluginFactory = new ParserPluginFactory() { @Override public ParserPlugin createParserPlugin() { - return Boolean.getBoolean("groovy.antlr4") - ? ParserPluginFactory.antlr4().createParserPlugin() - : ParserPluginFactory.antlr2().createParserPlugin(); + return !Boolean.getBoolean("groovy.antlr4") + ? ParserPluginFactory.antlr2().createParserPlugin() + : ParserPluginFactory.antlr4(CompilerConfiguration.this).createParserPlugin(); } }; // GRECLIPSE end @@ -785,7 +810,7 @@ public String getTargetBytecode() { } private static String getMinBytecodeVersion() { - return JDK7; + return JDK8; } /** @@ -858,7 +883,7 @@ public Set getDisabledGlobalASTTransformations() { * Disables the specified global AST transformations. In order to avoid class loading side effects, it is not recommended * to use MyASTTransformation.class.getName() by directly use the class name as a string. Disabled AST transformations * only apply to automatically loaded global AST transformations, that is to say transformations defined in a - * META-INF/org.codehaus.groovy.transform.ASTTransformation file. + * META-INF/services/org.codehaus.groovy.transform.ASTTransformation file. * If you explicitly add a global AST transformation * in your compilation process, for example using the {@link org.codehaus.groovy.control.customizers.ASTTransformationCustomizer} or * using a {@link org.codehaus.groovy.control.CompilationUnit.PrimaryClassNodeOperation}, then nothing will prevent @@ -886,4 +911,20 @@ public boolean isIndyEnabled() { Boolean indyEnabled = getOptimizationOptions().get(INVOKEDYNAMIC); return Optional.ofNullable(indyEnabled).orElse(Boolean.FALSE).booleanValue(); } + + /** + * Check if groovydoc enabled. + */ + public boolean isGroovydocEnabled() { + Boolean groovydocEnabled = getOptimizationOptions().get(GROOVYDOC); + return Optional.ofNullable(groovydocEnabled).orElse(Boolean.FALSE).booleanValue(); + } + + /** + * Check if runtime groovydoc enabled. + */ + public boolean isRuntimeGroovydocEnabled() { + Boolean runtimeGroovydocEnabled = getOptimizationOptions().get(RUNTIME_GROOVYDOC); + return Optional.ofNullable(runtimeGroovydocEnabled).orElse(Boolean.FALSE).booleanValue(); + } } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/ErrorCollector.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/control/ErrorCollector.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/control/ErrorCollector.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/control/ErrorCollector.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/GenericsVisitor.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/control/GenericsVisitor.java similarity index 98% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/control/GenericsVisitor.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/control/GenericsVisitor.java index 105e099fd9..df50b79dc0 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/GenericsVisitor.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/control/GenericsVisitor.java @@ -167,8 +167,8 @@ private void checkGenericsUsage(ClassNode n, ClassNode cn, Boolean isAnonInnerCl // GRECLIPSE edit //if (!nType.isDerivedFrom(cnType)) { // if (cnType.isInterface() && nType.implementsInterface(cnType)) continue; - if (!nTypes[0].isWildcard() && !nType.isDerivedFrom(cnType) && - !(cnType.isInterface() && nType.implementsInterface(cnType))) { + if (!nTypes[i].isWildcard() && !nType.isDerivedFrom(cnType) && + !(cnType.isInterface() && nType.implementsInterface(cnType))) { // GRECLIPSE end addError("The type " + nTypes[i].getName() + " is not a valid substitute for the bounded parameter <" + diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/ParserPluginFactory.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/control/ParserPluginFactory.java similarity index 73% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/control/ParserPluginFactory.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/control/ParserPluginFactory.java index 4906d1592e..947319f869 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/ParserPluginFactory.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/control/ParserPluginFactory.java @@ -22,54 +22,32 @@ import org.codehaus.groovy.syntax.ParserException; import org.codehaus.groovy.syntax.Reduction; -import java.io.Reader; - /** * A factory of parser plugin instances * */ public abstract class ParserPluginFactory { - /* GRECLIPSE edit - private static Class ANTLR4_CLASS=null; - */ /** * creates the ANTLR 4 parser * @return the factory for the parser */ - public static ParserPluginFactory antlr4() { + public static ParserPluginFactory antlr4(CompilerConfiguration compilerConfiguration) { /* GRECLIPSE edit - if (ANTLR4_CLASS==null) { - String name = "org.apache.groovy.parser.antlr4.Antlr4PluginFactory"; - try { - ANTLR4_CLASS = - Class.forName(name, false, ParserPluginFactory.class.getClassLoader()); - } catch (Exception e) { - throw new GroovyRuntimeException("Could not find or load parser plugin factory for antlr4", e); - } - } - try { - return AccessController.doPrivileged(new PrivilegedExceptionAction() { - public ParserPluginFactory run() throws Exception { - return (ParserPluginFactory) ANTLR4_CLASS.newInstance(); - } - }); - } catch (PrivilegedActionException e) { - throw new GroovyRuntimeException("Could not create instance of parser plugin factory for antlr4", e.getCause()); - } + return new Antlr4PluginFactory(compilerConfiguration); */ return new ParserPluginFactory() { @Override public ParserPlugin createParserPlugin() { return new ParserPlugin() { @Override - public Reduction parseCST(SourceUnit sourceUnit, Reader reader) throws CompilationFailedException { + public Reduction parseCST(SourceUnit sourceUnit, java.io.Reader reader) throws CompilationFailedException { return null; } @Override public ModuleNode buildAST(SourceUnit sourceUnit, ClassLoader classLoader, Reduction cst) throws ParserException { assert sourceUnit.getSource() != null && sourceUnit.getSource().canReopenSource(); - return new org.apache.groovy.parser.antlr4.AstBuilder(sourceUnit).buildAST(); + return new org.apache.groovy.parser.antlr4.AstBuilder(sourceUnit, compilerConfiguration).buildAST(); } }; } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/ProcessingUnit.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/control/ProcessingUnit.java similarity index 98% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/control/ProcessingUnit.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/control/ProcessingUnit.java index 64ce0c92ed..280a499e42 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/ProcessingUnit.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/control/ProcessingUnit.java @@ -26,8 +26,6 @@ /** * A base class for data structures that can collect messages and errors * during processing. - * - * @author Chris Poirier */ public abstract class ProcessingUnit { diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/ResolveVisitor.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/control/ResolveVisitor.java similarity index 92% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/control/ResolveVisitor.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/control/ResolveVisitor.java index e9d7f25d67..88f4b2af68 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/ResolveVisitor.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/control/ResolveVisitor.java @@ -19,12 +19,12 @@ package org.codehaus.groovy.control; import groovy.lang.Tuple2; +import org.apache.groovy.ast.tools.ExpressionUtils; import org.codehaus.groovy.GroovyBugError; import org.codehaus.groovy.ast.ASTNode; import org.codehaus.groovy.ast.AnnotatedNode; import org.codehaus.groovy.ast.AnnotationNode; import org.codehaus.groovy.ast.ClassCodeExpressionTransformer; -import org.codehaus.groovy.ast.ClassCodeVisitorSupport; import org.codehaus.groovy.ast.ClassHelper; import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.CompileUnit; @@ -60,6 +60,8 @@ import org.codehaus.groovy.ast.stmt.ForStatement; import org.codehaus.groovy.ast.stmt.Statement; import org.codehaus.groovy.control.ClassNodeResolver.LookupResult; +import org.codehaus.groovy.runtime.memoize.EvictableCache; +import org.codehaus.groovy.runtime.memoize.UnlimitedConcurrentCache; import org.codehaus.groovy.syntax.Types; import org.codehaus.groovy.transform.trait.Traits; import groovyjarjarasm.asm.Opcodes; @@ -75,6 +77,7 @@ import java.util.Map; import java.util.Set; +import static org.codehaus.groovy.ast.GenericsType.GenericsTypeName; import static org.codehaus.groovy.ast.tools.GeneralUtils.inSamePackage; import static org.codehaus.groovy.ast.tools.GeneralUtils.isDefaultVisibility; @@ -93,6 +96,7 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer { private static final String BIGINTEGER_STR = "BigInteger"; private static final String BIGDECIMAL_STR = "BigDecimal"; public static final String QUESTION_MARK = "?"; + public static final String[] EMPTY_STRING_ARRAY = new String[0]; // GRECLIPSE private->protected protected ClassNode currentClass; @@ -105,12 +109,12 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer { private boolean inPropertyExpression = false; private boolean inClosure = false; - private Map genericParameterNames = new HashMap(); + private Map genericParameterNames = new HashMap(); private final Set fieldTypesChecked = new HashSet(); // GRECLIPSE add private final Set resolutionFailedCache = new HashSet(); // GRECLIPSE end - private boolean checkingVariableTypeInDeclaration = false; + private boolean checkingVariableTypeInDeclaration; // GRECLIPSE private->protected protected ImportNode currImportNode; private MethodNode currentMethod; @@ -124,23 +128,27 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer { */ private static class ConstructedNestedClass extends ClassNode { final ClassNode knownEnclosingType; + public ConstructedNestedClass(ClassNode outer, String inner) { - super(outer.getName()+"$"+(inner=replacePoints(inner)), Opcodes.ACC_PUBLIC,ClassHelper.OBJECT_TYPE); + super(outer.getName() + "$" + replacePoints(inner), Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE); this.knownEnclosingType = outer; this.isPrimaryNode = false; } + // GRECLIPSE add public String getUnresolvedName() { // outer class (aka knownEnclosingType) may have aliased name that should be reflected here too return super.getUnresolvedName().replace(knownEnclosingType.getName(), knownEnclosingType.getUnresolvedName()); } // GRECLIPSE end + public boolean hasPackageName() { - if (redirect()!=this) return super.hasPackageName(); + if (redirect() != this) return super.hasPackageName(); return knownEnclosingType.hasPackageName(); } + public String setName(String name) { - if (redirect()!=this) { + if (redirect() != this) { return super.setName(name); } else { throw new GroovyBugError("ConstructedNestedClass#setName should not be called"); @@ -233,10 +241,10 @@ public void startResolving(ClassNode node, SourceUnit source) { protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { VariableScope oldScope = currentScope; currentScope = node.getVariableScope(); - Map oldPNames = genericParameterNames; - genericParameterNames = node.isStatic() - ? new HashMap() - : new HashMap(genericParameterNames); + Map oldPNames = genericParameterNames; + genericParameterNames = node.isStatic() && !Traits.isTrait(node.getDeclaringClass()) + ? new HashMap() + : new HashMap(genericParameterNames); resolveGenericsHeader(node.getGenericsTypes()); @@ -270,9 +278,9 @@ public void visitField(FieldNode node) { } public void visitProperty(PropertyNode node) { - Map oldPNames = genericParameterNames; - if (node.isStatic()) { - genericParameterNames = new HashMap(); + Map oldPNames = genericParameterNames; + if (node.isStatic() && !Traits.isTrait(node.getDeclaringClass())) { + genericParameterNames = new HashMap(); } ClassNode t = node.getType(); @@ -292,8 +300,7 @@ protected boolean resolveToInner(ClassNode type) { if (type instanceof ConstructedNestedClass) return false; String name = type.getName(); String saved = name; - while (true) { - if (-1 == name.lastIndexOf('.')) break; + while (-1 != name.lastIndexOf('.')) { name = replaceLastPointWithDollar(name); type.setName(name); if (resolve(type)) return true; @@ -339,11 +346,7 @@ private boolean checkInnerTypeVisibility(ClassNode enclosingType, ClassNode inne } int modifiers = innerClassNode.getModifiers(); - if (Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers)) { - return true; - } - - return false; + return Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers); } private void resolveOrFail(ClassNode type, String msg, ASTNode node) { @@ -400,10 +403,10 @@ protected boolean resolve(ClassNode type, boolean testModuleImports, boolean tes String typeName = type.getName(); - if (genericParameterNames.get(typeName) != null) { - GenericsType gt = genericParameterNames.get(typeName); - type.setRedirect(gt.getType()); - type.setGenericsTypes(new GenericsType[]{ gt }); + GenericsType genericsType = genericParameterNames.get(new GenericsTypeName(typeName)); + if (genericsType != null) { + type.setRedirect(genericsType.getType()); + type.setGenericsTypes(new GenericsType[]{ genericsType }); type.setGenericsPlaceHolder(true); return true; } @@ -586,29 +589,11 @@ protected boolean resolveFromDefaultImports(ClassNode type, boolean testDefaultI // try to resolve against a default import, because we know that the // default packages do not contain classes like these testDefaultImports &= !(type instanceof LowerCaseClass); - final String typeName = type.getName(); if (testDefaultImports) { - for (String packagePrefix : DEFAULT_IMPORTS) { - // We limit the inner class lookups here by using ConstructedClassWithPackage. - // This way only the name will change, the packagePrefix will - // not be included in the lookup. The case where the - // packagePrefix is really a class is handled elsewhere. - // WARNING: This code does not expect a class that has a static - // inner class in DEFAULT_IMPORTS - ConstructedClassWithPackage tmp = new ConstructedClassWithPackage(packagePrefix, typeName); - // GRECLIPSE add - if (resolutionFailedCache.contains(tmp.getName())) continue; - // GRECLIPSE end - if (resolve(tmp, false, false, false)) { - type.setRedirect(tmp.redirect()); - return true; - } - // GRECLIPSE add - resolutionFailedCache.add(tmp.getName()); - // GRECLIPSE end - } + if (resolveFromDefaultImports(type)) return true; + final String typeName = type.getName(); if (BIGINTEGER_STR.equals(typeName)) { type.setRedirect(ClassHelper.BigInteger_TYPE); return true; @@ -620,6 +605,58 @@ protected boolean resolveFromDefaultImports(ClassNode type, boolean testDefaultI return false; } + private boolean resolveFromDefaultImports(ClassNode type) { + final String typeName = type.getName(); + + Set packagePrefixSet = DEFAULT_IMPORT_CLASS_AND_PACKAGES_CACHE.get(typeName); + if (null != packagePrefixSet) { + // if the type name was resolved before, we can try the successfully resolved packages first, which are much less and very likely successful to resolve. + // As a result, we can avoid trying other default import packages and further resolving, which can improve the resolving performance to some extent. + if (resolveFromDefaultImports(type, packagePrefixSet.toArray(EMPTY_STRING_ARRAY))) { + return true; + } + } + + if (resolveFromDefaultImports(type, DEFAULT_IMPORTS)) { + return true; + } + return false; + } + + private static final EvictableCache> DEFAULT_IMPORT_CLASS_AND_PACKAGES_CACHE = new UnlimitedConcurrentCache<>(); + + private boolean resolveFromDefaultImports(final ClassNode type, final String[] packagePrefixes) { + final String typeName = type.getName(); + + for (String packagePrefix : packagePrefixes) { + // We limit the inner class lookups here by using ConstructedClassWithPackage. + // This way only the name will change, the packagePrefix will + // not be included in the lookup. The case where the + // packagePrefix is really a class is handled elsewhere. + // WARNING: This code does not expect a class that has a static + // inner class in DEFAULT_IMPORTS + ConstructedClassWithPackage tmp = new ConstructedClassWithPackage(packagePrefix, typeName); + // GRECLIPSE add + if (resolutionFailedCache.contains(tmp.getName())) continue; + // GRECLIPSE end + if (resolve(tmp, false, false, false)) { + type.setRedirect(tmp.redirect()); + + if (DEFAULT_IMPORTS == packagePrefixes) { // Only the non-cached type and packages should be cached + Set packagePrefixSet = DEFAULT_IMPORT_CLASS_AND_PACKAGES_CACHE.getAndPut(typeName, key -> new HashSet<>(2)); + packagePrefixSet.add(packagePrefix); + } + + return true; + } + // GRECLIPSE add + resolutionFailedCache.add(tmp.getName()); + // GRECLIPSE end + } + + return false; + } + // GRECLIPSE private->protected protected boolean resolveFromCompileUnit(ClassNode type) { // look into the compile unit if there is a class with that name @@ -661,7 +698,7 @@ private boolean resolveAliasFromModule(ClassNode type) { * foo.foo.bar rather than foo.bar. This means to cut at the dot in foo.bar and * foo for import */ - while (true) { + do { pname = name.substring(0, index); ClassNode aliasedNode = null; ImportNode importNode = module.getImport(pname); @@ -701,7 +738,7 @@ private boolean resolveAliasFromModule(ClassNode type) { // completely and use a ConstructedClassWithPackage to prevent lookups against the package. String className = aliasedNode.getNameWithoutPackage() + '$' + name.substring(pname.length() + 1).replace('.', '$'); - ConstructedClassWithPackage tmp = new ConstructedClassWithPackage(aliasedNode.getPackageName()+".", className); + ConstructedClassWithPackage tmp = new ConstructedClassWithPackage(aliasedNode.getPackageName() + ".", className); if (resolve(tmp, true, true, false)) { type.setRedirect(tmp.redirect()); return true; @@ -709,8 +746,7 @@ private boolean resolveAliasFromModule(ClassNode type) { } } index = pname.lastIndexOf('.'); - if (index == -1) break; - } + } while (index != -1); return false; } @@ -851,9 +887,9 @@ protected boolean resolveToOuter(ClassNode type) { } if (currentClass.getModule().hasPackageName() && name.indexOf('.') == -1) return false; - LookupResult lr = null; - lr = classNodeResolver.resolveName(name, compilationUnit); - if (lr!=null) { + + LookupResult lr = classNodeResolver.resolveName(name, compilationUnit); + if (lr != null) { if (lr.isSourceUnit()) { SourceUnit su = lr.getSourceUnit(); currentClass.getCompileUnit().addClassNodeToCompile(type, su); @@ -1129,7 +1165,6 @@ protected Expression transformVariableExpression(VariableExpression ve) { // referencedClassVariables, but must be removed // for each parentscope too for (VariableScope scope = currentScope; scope != null && !scope.isRoot(); scope = scope.getParent()) { - if (scope.isRoot()) break; if (scope.removeReferencedClassVariable(ve.getName()) == null) break; } ClassExpression ce = new ClassExpression(t); @@ -1178,7 +1213,7 @@ protected Expression transformBinaryExpression(BinaryExpression be) { return ce; } else { - // may be we have C[k1:v1, k2:v2] -> should become (C)([k1:v1, k2:v2]) + // maybe we have C[k1:v1, k2:v2] -> should become (C)([k1:v1, k2:v2]) boolean map = true; for (Expression expression : list.getExpressions()) { if(!(expression instanceof MapEntryExpression)) { @@ -1194,6 +1229,7 @@ protected Expression transformBinaryExpression(BinaryExpression be) { } me.setSourcePosition(list); final CastExpression ce = new CastExpression(left.getType(), me); + ce.setCoerce(true); ce.setSourcePosition(be); return ce; } @@ -1202,7 +1238,8 @@ protected Expression transformBinaryExpression(BinaryExpression be) { // we have C[*:map] -> should become (C) map SpreadMapExpression mapExpression = (SpreadMapExpression) be.getRightExpression(); Expression right = transform(mapExpression.getExpression()); - Expression ce = new CastExpression(left.getType(), right); + CastExpression ce = new CastExpression(left.getType(), right); + ce.setCoerce(true); ce.setSourcePosition(be); return ce; } @@ -1233,14 +1270,12 @@ protected Expression transformClosureExpression(ClosureExpression ce) { resolveOrFail(t, ce); visitAnnotations(para); if (para.hasInitialExpression()) { - Object initialVal = para.getInitialExpression(); - if (initialVal instanceof Expression) { - para.setInitialExpression(transform((Expression) initialVal)); - } + para.setInitialExpression(transform(para.getInitialExpression())); } visitAnnotations(para); } } + Statement code = ce.getCode(); if (code != null) code.visit(this); inClosure = oldInClosure; @@ -1254,8 +1289,7 @@ protected Expression transformConstructorCallExpression(ConstructorCallExpressio addError("You cannot create an instance from the abstract " + getDescription(type) + ".", cce); } - Expression ret = cce.transformExpression(this); - return ret; + return cce.transformExpression(this); } private static String getDescription(ClassNode node) { @@ -1341,9 +1375,9 @@ public void visitAnnotations(AnnotatedNode node) { // GRECLIPSE end for (Map.Entry member : an.getMembers().entrySet()) { Expression newValue = transform(member.getValue()); - newValue = transformInlineConstants(newValue); - member.setValue(newValue); - checkAnnotationMemberValue(newValue); + Expression adjusted = transformInlineConstants(newValue); + member.setValue(adjusted); + checkAnnotationMemberValue(adjusted); } /* GRECLIPSE edit -- can't do this if (annType.isResolved()) { @@ -1372,47 +1406,9 @@ private boolean isRepeatable(Class annTypeClass) { return false; } - // resolve constant-looking expressions statically (do here as gets transformed away later) - private Expression transformInlineConstants(Expression exp) { - if (exp instanceof PropertyExpression) { - PropertyExpression pe = (PropertyExpression) exp; - if (pe.getObjectExpression() instanceof ClassExpression) { - ClassExpression ce = (ClassExpression) pe.getObjectExpression(); - ClassNode type = ce.getType(); - if (type.isEnum()) - return exp; - - FieldNode fn = type.getField(pe.getPropertyAsString()); - if (fn != null && !fn.isEnum() && fn.isStatic() && fn.isFinal()) { - if (fn.getInitialValueExpression() instanceof ConstantExpression) { - // GRECLIPSE edit - return cloneConstantExpression(fn.getInitialValueExpression(), exp); - // GRECLIPS end - } - } - } - // GRECLIPSE add - } else if (exp instanceof VariableExpression) { - VariableExpression ve = (VariableExpression) exp; - if (ve.getAccessedVariable() instanceof FieldNode) { - FieldNode fn = (FieldNode) ve.getAccessedVariable(); - if (!fn.isEnum() && fn.isStatic() && fn.isFinal() && - fn.getInitialValueExpression() instanceof ConstantExpression) { - return cloneConstantExpression(fn.getInitialValueExpression(), exp); - } - } - // GRECLIPSE end - } else if (exp instanceof ListExpression) { - ListExpression le = (ListExpression) exp; - ListExpression result = new ListExpression(); - for (Expression e : le.getExpressions()) { - result.addExpression(transformInlineConstants(e)); - } - // GRECLIPSE add - result.setSourcePosition(exp); - // GRECLIPSE end - return result; - } else if (exp instanceof AnnotationConstantExpression) { + // resolve constant-looking expressions statically (do here as they get transformed away later) + private static Expression transformInlineConstants(final Expression exp) { + if (exp instanceof AnnotationConstantExpression) { ConstantExpression ce = (ConstantExpression) exp; if (ce.getValue() instanceof AnnotationNode) { // replicate a little bit of AnnotationVisitor here @@ -1422,20 +1418,12 @@ private Expression transformInlineConstants(Expression exp) { member.setValue(transformInlineConstants(member.getValue())); } } + } else { + return ExpressionUtils.transformInlineConstants(exp); } return exp; } - // GRECLIPSE add - protected static ConstantExpression cloneConstantExpression(Expression val, Expression src) { - ConstantExpression ret = new ConstantExpression(((ConstantExpression) val).getValue()); - ret.setNodeMetaData(ClassCodeVisitorSupport.ORIGINAL_EXPRESSION, src); - // TODO: Copy any other fields or metadata? - // Source position is dropped by design. - return ret; - } - // GRECLIPSE end - private void checkAnnotationMemberValue(Expression newValue) { if (newValue instanceof PropertyExpression) { PropertyExpression pe = (PropertyExpression) newValue; @@ -1460,7 +1448,7 @@ public void visitClass(ClassNode node) { if (node instanceof InnerClassNode) { if (Modifier.isStatic(node.getModifiers())) { - genericParameterNames = new HashMap(); + genericParameterNames = new HashMap(); } InnerClassNode innerClassNode = (InnerClassNode) node; @@ -1471,7 +1459,7 @@ public void visitClass(ClassNode node) { } } } else { - genericParameterNames = new HashMap(); + genericParameterNames = new HashMap(); } resolveGenericsHeader(node.getGenericsTypes()); @@ -1671,9 +1659,10 @@ private void resolveGenericsHeader(GenericsType[] types, GenericsType rootType, ClassNode classNode = type.getType(); String name = type.getName(); + GenericsTypeName gtn = new GenericsTypeName(name); ClassNode[] bounds = type.getUpperBounds(); boolean isWild = QUESTION_MARK.equals(name); - boolean toDealWithGenerics = 0 == level || (level > 0 && null != genericParameterNames.get(name)); + boolean toDealWithGenerics = 0 == level || (level > 0 && null != genericParameterNames.get(gtn)); if (bounds != null) { boolean nameAdded = false; @@ -1681,7 +1670,7 @@ private void resolveGenericsHeader(GenericsType[] types, GenericsType rootType, if (!isWild) { if (!nameAdded && upperBound != null || !resolve(classNode)) { if (toDealWithGenerics) { - genericParameterNames.put(name, type); + genericParameterNames.put(gtn, type); type.setPlaceholder(true); classNode.setRedirect(upperBound); nameAdded = true; @@ -1698,8 +1687,8 @@ private void resolveGenericsHeader(GenericsType[] types, GenericsType rootType, } else { if (!isWild) { if (toDealWithGenerics) { - GenericsType originalGt = genericParameterNames.get(name); - genericParameterNames.put(name, type); + GenericsType originalGt = genericParameterNames.get(gtn); + genericParameterNames.put(gtn, type); type.setPlaceholder(true); if (null == originalGt) { @@ -1730,7 +1719,7 @@ private boolean resolveGenericsType(GenericsType genericsType) { currentClass.setUsingGenerics(true); ClassNode type = genericsType.getType(); // save name before redirect - String name = type.getName(); + GenericsTypeName name = new GenericsTypeName(type.getName()); ClassNode[] bounds = genericsType.getUpperBounds(); if (!genericParameterNames.containsKey(name)) { if (bounds != null) { diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/SourceUnit.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/control/SourceUnit.java similarity index 99% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/control/SourceUnit.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/control/SourceUnit.java index dd5bd4c245..5bc6951763 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/SourceUnit.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/control/SourceUnit.java @@ -319,7 +319,7 @@ public String getSample(int line, int column, Janitor janitor) { int start = column - 30 - 1; int end = (column + 10 > text.length() ? text.length() : column + 10 - 1); sample = " " + text.substring(start, end) + Utilities.eol() + " " + - marker.substring(start, marker.length()); + marker.substring(start); } else { sample = " " + text + Utilities.eol() + " " + marker; } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/StaticImportVisitor.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/control/StaticImportVisitor.java similarity index 88% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/control/StaticImportVisitor.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/control/StaticImportVisitor.java index 5003f4de30..7d70e5de0c 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/StaticImportVisitor.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/control/StaticImportVisitor.java @@ -38,7 +38,6 @@ import org.codehaus.groovy.ast.expr.ConstructorCallExpression; import org.codehaus.groovy.ast.expr.EmptyExpression; import org.codehaus.groovy.ast.expr.Expression; -import org.codehaus.groovy.ast.expr.ListExpression; import org.codehaus.groovy.ast.expr.MapEntryExpression; import org.codehaus.groovy.ast.expr.MethodCall; import org.codehaus.groovy.ast.expr.MethodCallExpression; @@ -50,18 +49,18 @@ import org.codehaus.groovy.ast.stmt.Statement; import org.codehaus.groovy.syntax.Types; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; +import static org.apache.groovy.ast.tools.ClassNodeUtils.getField; import static org.apache.groovy.ast.tools.ClassNodeUtils.getPropNameForAccessor; import static org.apache.groovy.ast.tools.ClassNodeUtils.hasPossibleStaticMethod; import static org.apache.groovy.ast.tools.ClassNodeUtils.hasPossibleStaticProperty; import static org.apache.groovy.ast.tools.ClassNodeUtils.hasStaticProperty; import static org.apache.groovy.ast.tools.ClassNodeUtils.isInnerClass; import static org.apache.groovy.ast.tools.ClassNodeUtils.isValidAccessorName; -import static org.codehaus.groovy.runtime.MetaClassHelper.capitalize; +import static org.apache.groovy.ast.tools.ExpressionUtils.transformInlineConstants; +import static org.apache.groovy.util.BeanUtils.capitalize; /** * Visitor to resolve constants and method calls from static Imports @@ -213,6 +212,17 @@ protected Expression transformVariableExpression(VariableExpression ve) { } return result; } + } else if (v instanceof FieldNode) { + if (inSpecialConstructorCall) { // GROOVY-8819 + FieldNode fn = (FieldNode) v; + ClassNode declaringClass = fn.getDeclaringClass(); + if (fn.isStatic() && currentClass.isDerivedFrom(declaringClass)) { + Expression result = new PropertyExpression(new ClassExpression(declaringClass), v.getName()); + result.setSourcePosition(ve); + + return result; + } + } } return ve; } @@ -230,44 +240,6 @@ private static void setSourcePosition(Expression toSet, Expression origNode) { } } - // resolve constant-looking expressions statically (do here as gets transformed away later) - - private Expression transformInlineConstants(Expression exp) { - if (exp instanceof PropertyExpression) { - PropertyExpression pe = (PropertyExpression) exp; - if (pe.getObjectExpression() instanceof ClassExpression) { - ClassExpression ce = (ClassExpression) pe.getObjectExpression(); - ClassNode type = ce.getType(); - if (type.isEnum()) return exp; - Expression constant = findConstant(getField(type, pe.getPropertyAsString())); - // GRECLIPSE edit - //if (constant != null) return constant; - if (constant != null) { - return ResolveVisitor.cloneConstantExpression(constant, exp); - } - // GRECLIPSE end - } - } else if (exp instanceof ListExpression) { - ListExpression le = (ListExpression) exp; - ListExpression result = new ListExpression(); - for (Expression e : le.getExpressions()) { - result.addExpression(transformInlineConstants(e)); - } - return result; - } - - return exp; - } - - private static Expression findConstant(FieldNode fn) { - if (fn != null && !fn.isEnum() && fn.isStatic() && fn.isFinal()) { - if (fn.getInitialValueExpression() instanceof ConstantExpression) { - return fn.getInitialValueExpression(); - } - } - return null; - } - protected Expression transformMethodCallExpression(MethodCallExpression mce) { Expression args = transform(mce.getArguments()); Expression method = transform(mce.getMethod()); @@ -282,26 +254,28 @@ protected Expression transformMethodCallExpression(MethodCallExpression mce) { if (mce.isImplicitThis() || isExplicitThisOrSuper) { if (mce.isImplicitThis()) { - Expression ret = findStaticMethodImportFromModule(method, args); - if (ret != null) { - // GRECLIPSE add - if (!((MethodCall) ret).getMethodAsString().equals(method.getText())) { - // store the identifier to facilitate organizing static imports - ret.putNodeMetaData("static.import.alias", method.getText()); - } - // GRECLIPSE end - setSourcePosition(ret, mce); - return ret; - } - if (method instanceof ConstantExpression && !inLeftExpression) { - // could be a closure field - String methodName = (String) ((ConstantExpression) method).getValue(); - ret = findStaticFieldOrPropAccessorImportFromModule(methodName); + if (null == currentClass.tryFindPossibleMethod(mce.getMethodAsString(), args)) { + Expression ret = findStaticMethodImportFromModule(method, args); if (ret != null) { - ret = new MethodCallExpression(ret, "call", args); + // GRECLIPSE add + if (!((MethodCall) ret).getMethodAsString().equals(method.getText())) { + // store the identifier to facilitate organizing static imports + ret.putNodeMetaData("static.import.alias", method.getText()); + } + // GRECLIPSE end setSourcePosition(ret, mce); return ret; } + if (method instanceof ConstantExpression && !inLeftExpression) { + // could be a closure field + String methodName = (String) ((ConstantExpression) method).getValue(); + ret = findStaticFieldOrPropAccessorImportFromModule(methodName); + if (ret != null) { + ret = new MethodCallExpression(ret, "call", args); + setSourcePosition(ret, mce); + return ret; + } + } } } else if (currentMethod!=null && currentMethod.isStatic() && isExplicitSuper) { MethodCallExpression ret = new MethodCallExpression(new ClassExpression(currentClass.getSuperClass()), method, args); @@ -342,6 +316,12 @@ protected Expression transformMethodCallExpression(MethodCallExpression mce) { return smce; } } + + if (mce.isImplicitThis() && lookForPossibleStaticMethod && hasPossibleStaticMethod(currentClass, methodName, args, true)) { + StaticMethodCallExpression result = new StaticMethodCallExpression(currentClass, methodName, args); + result.setSourcePosition(mce); + return result; + } } } } @@ -606,24 +586,6 @@ private static Expression findStaticField(ClassNode staticImportType, String fie return null; } - private static FieldNode getField(ClassNode classNode, String fieldName) { - ClassNode node = classNode; - Set visited = new HashSet(); - while (node != null) { - FieldNode fn = node.getDeclaredField(fieldName); - if (fn != null) return fn; - ClassNode[] interfaces = node.getInterfaces(); - for (ClassNode iNode : interfaces) { - if (visited.contains(iNode.getName())) continue; - FieldNode ifn = getField(iNode, fieldName); - visited.add(iNode.getName()); - if (ifn != null) return ifn; - } - node = node.getSuperClass(); - } - return null; - } - private static Expression findStaticMethod(ClassNode staticImportType, String methodName, Expression args) { if (staticImportType.isPrimaryClassNode() || staticImportType.isResolved()) { if (staticImportType.hasPossibleStaticMethod(methodName, args)) { diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/messages/LocatedMessage.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/control/messages/LocatedMessage.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/control/messages/LocatedMessage.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/control/messages/LocatedMessage.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/syntax/PreciseSyntaxException.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/syntax/PreciseSyntaxException.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/syntax/PreciseSyntaxException.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/syntax/PreciseSyntaxException.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/tools/GroovyClass.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/tools/GroovyClass.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/tools/GroovyClass.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/tools/GroovyClass.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/ASTTransformationCollectorCodeVisitor.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/ASTTransformationCollectorCodeVisitor.java similarity index 99% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/ASTTransformationCollectorCodeVisitor.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/ASTTransformationCollectorCodeVisitor.java index da9baaf108..c18a5ec963 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/ASTTransformationCollectorCodeVisitor.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/ASTTransformationCollectorCodeVisitor.java @@ -241,9 +241,7 @@ private void findCollectedAnnotations(AnnotationNode aliasNode, AnnotatedNode or if (klass != null) { try { act = (AnnotationCollectorTransform) klass.newInstance(); - } catch (InstantiationException e) { - source.getErrorCollector().addErrorAndContinue(new ExceptionMessage(e, true, source)); - } catch (IllegalAccessException e) { + } catch (InstantiationException | IllegalAccessException e) { source.getErrorCollector().addErrorAndContinue(new ExceptionMessage(e, true, source)); } } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/ASTTransformationVisitor.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/ASTTransformationVisitor.java similarity index 97% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/ASTTransformationVisitor.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/ASTTransformationVisitor.java index 7142ed510f..dcd078dcf7 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/ASTTransformationVisitor.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/ASTTransformationVisitor.java @@ -147,13 +147,7 @@ public void visitClass(ClassNode classNode) { for (Class transformClass : baseTransforms.keySet()) { try { transformInstances.put(transformClass, transformClass.newInstance()); - } catch (InstantiationException e) { - source.getErrorCollector().addError( - new SimpleMessage( - "Could not instantiate Transformation Processor " + transformClass - , //+ " declared by " + annotation.getClassNode().getName(), - source)); - } catch (IllegalAccessException e) { + } catch (InstantiationException | IllegalAccessException e) { source.getErrorCollector().addError( new SimpleMessage( "Could not instantiate Transformation Processor " + transformClass @@ -288,9 +282,7 @@ private static void doAddGlobalTransforms(ASTTransformationsContext context, boo // GRECLIPSE add -- don't consume our own META-INF entries if (skipManifest(compilationUnit, service)) continue; // GRECLIPSE end - BufferedReader svcIn = null; - try { - svcIn = new BufferedReader(new InputStreamReader(URLStreams.openUncachedStream(service), "UTF-8")); + try (BufferedReader svcIn = new BufferedReader(new InputStreamReader(URLStreams.openUncachedStream(service), "UTF-8"))) { try { className = svcIn.readLine(); } catch (IOException ioe) { @@ -338,9 +330,6 @@ private static void doAddGlobalTransforms(ASTTransformationsContext context, boo continue; } } - } finally { - if (svcIn != null) - svcIn.close(); } } } catch (IOException e) { diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/AnnotationCollectorTransform.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/AnnotationCollectorTransform.java similarity index 83% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/AnnotationCollectorTransform.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/AnnotationCollectorTransform.java index e0d19f47e7..119e45e41a 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/AnnotationCollectorTransform.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/AnnotationCollectorTransform.java @@ -25,6 +25,8 @@ import org.codehaus.groovy.ast.AnnotationNode; import org.codehaus.groovy.ast.ClassHelper; import org.codehaus.groovy.ast.ClassNode; +import org.codehaus.groovy.ast.InnerClassNode; +import org.codehaus.groovy.ast.MethodNode; import org.codehaus.groovy.ast.Parameter; import org.codehaus.groovy.ast.expr.AnnotationConstantExpression; import org.codehaus.groovy.ast.expr.ArrayExpression; @@ -49,6 +51,7 @@ import java.util.Map; import java.util.Set; +import static org.codehaus.groovy.transform.trait.TraitComposer.COMPILESTATIC_CLASSNODE; import static groovyjarjarasm.asm.Opcodes.ACC_ABSTRACT; import static groovyjarjarasm.asm.Opcodes.ACC_ANNOTATION; import static groovyjarjarasm.asm.Opcodes.ACC_ENUM; @@ -97,7 +100,7 @@ public static class ClassChanger { */ public void transformClass(ClassNode cn) { AnnotationNode collector = null; - for (ListIterator it = cn.getAnnotations().listIterator(); it.hasNext();) { + for (ListIterator it = cn.getAnnotations().listIterator(); it.hasNext(); ) { AnnotationNode an = it.next(); if (an.getClassNode().getName().equals(AnnotationCollector.class.getName())) { collector = an; @@ -107,15 +110,31 @@ public void transformClass(ClassNode cn) { if (collector == null) { return; } - // force final class, remove interface, annotation, enum and abstract modifiers - cn.setModifiers((ACC_FINAL+cn.getModifiers()) & ~(ACC_ENUM|ACC_INTERFACE|ACC_ANNOTATION|ACC_ABSTRACT)); - // force Object super class - cn.setSuperClass(ClassHelper.OBJECT_TYPE); - // force no interfaces implemented - cn.setInterfaces(ClassNode.EMPTY_ARRAY); + boolean legacySerialization = false; + final Expression member = collector.getMember("serializeClass"); + if (member instanceof ClassExpression) { + ClassExpression ce = (ClassExpression) member; + legacySerialization = ce.getType().getName().equals(cn.getName()); + } + ClassNode helper = cn; + if (legacySerialization) { + // force final class, remove interface, annotation, enum and abstract modifiers + helper.setModifiers((ACC_FINAL + helper.getModifiers()) & ~(ACC_ENUM | ACC_INTERFACE | ACC_ANNOTATION | ACC_ABSTRACT)); + // force Object super class + helper.setSuperClass(ClassHelper.OBJECT_TYPE); + // force no interfaces implemented + helper.setInterfaces(ClassNode.EMPTY_ARRAY); + } else { + helper = new InnerClassNode(cn.getPlainNodeReference(), cn.getName() + "$CollectorHelper", + ACC_PUBLIC | ACC_STATIC | ACC_FINAL, ClassHelper.OBJECT_TYPE.getPlainNodeReference()); + cn.getModule().addClass(helper); + helper.addAnnotation(new AnnotationNode(COMPILESTATIC_CLASSNODE)); + MethodNode serializeClass = collector.getClassNode().getMethod("serializeClass", Parameter.EMPTY_ARRAY); + collector.setMember("serializeClass", new ClassExpression(helper.getPlainNodeReference())); + } // add static value():Object[][] method - List meta = getMeta(cn); + List meta = getMeta(cn); List outer = new ArrayList(meta.size()); for (AnnotationNode an : meta) { Expression serialized = serialize(an); @@ -124,15 +143,14 @@ public void transformClass(ClassNode cn) { ArrayExpression ae = new ArrayExpression(ClassHelper.OBJECT_TYPE.makeArray(), outer); Statement code = new ReturnStatement(ae); - cn.addMethod( "value", ACC_PUBLIC+ACC_STATIC, - ClassHelper.OBJECT_TYPE.makeArray().makeArray(), - Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, - code); + helper.addMethod("value", ACC_PUBLIC + ACC_STATIC, + ClassHelper.OBJECT_TYPE.makeArray().makeArray(), + Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, code); // remove annotations - for (ListIterator it = cn.getAnnotations().listIterator(); it.hasNext();) { + for (ListIterator it = cn.getAnnotations().listIterator(); it.hasNext(); ) { AnnotationNode an = it.next(); - if (an == collector) { + if (an == collector || "java.lang.annotation".equals(an.getClassNode().getPackageName())) { continue; } it.remove(); @@ -236,7 +254,7 @@ private static List getTargetListFromAnnotations(ClassNode alias List ret = new ArrayList(annotations.size()); for (AnnotationNode an : annotations) { ClassNode type = an.getClassNode(); - if (type.getName().equals(AnnotationCollector.class.getName())) continue; + if (type.getName().equals(AnnotationCollector.class.getName()) || "java.lang.annotation".equals(type.getPackageName())) continue; AnnotationNode toAdd = new AnnotationNode(type); copyMembers(an, toAdd); ret.add(toAdd); @@ -256,6 +274,7 @@ private static void copyMembers(final Map members, final Ann } private static List getTargetListFromClass(ClassNode alias) { + alias = getSerializeClass(alias); Class c = alias.getTypeClass(); Object[][] data; try { @@ -266,7 +285,23 @@ private static List getTargetListFromClass(ClassNode alias) { } return makeListOfAnnotations(data); } - + + // 2.5.3 and above gets from annotation attribute otherwise self + private static ClassNode getSerializeClass(ClassNode alias) { + List annotations = alias.getAnnotations(ClassHelper.make(AnnotationCollector.class)); + if (!annotations.isEmpty()) { + AnnotationNode annotationNode = annotations.get(0); + Expression member = annotationNode.getMember("serializeClass"); + if (member instanceof ClassExpression) { + ClassExpression ce = (ClassExpression) member; + if (!ce.getType().getName().equals(AnnotationCollector.class.getName())) { + alias = ce.getType(); + } + } + } + return alias; + } + private static List makeListOfAnnotations(Object[][] data) { if (data.length == 0) { return Collections.emptyList(); @@ -352,7 +387,7 @@ protected List getTargetAnnotationList(AnnotationNode collector, public List visit(AnnotationNode collector, AnnotationNode aliasAnnotationUsage, AnnotatedNode aliasAnnotated, SourceUnit source) { List ret = getTargetAnnotationList(collector, aliasAnnotationUsage, source); Set unusedNames = new HashSet(aliasAnnotationUsage.getMembers().keySet()); - + for (AnnotationNode an: ret) { for (String name : aliasAnnotationUsage.getMembers().keySet()) { if (an.getClassNode().hasMethod(name, Parameter.EMPTY_ARRAY)) { diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/FieldASTTransformation.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/FieldASTTransformation.java similarity index 97% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/FieldASTTransformation.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/FieldASTTransformation.java index 9e28258a6b..d3fc654bcf 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/FieldASTTransformation.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/FieldASTTransformation.java @@ -46,7 +46,6 @@ import org.codehaus.groovy.classgen.VariableScopeVisitor; import org.codehaus.groovy.control.CompilePhase; import org.codehaus.groovy.control.SourceUnit; -import org.codehaus.groovy.runtime.MetaClassHelper; import groovyjarjarasm.asm.Opcodes; import java.util.ArrayList; @@ -54,6 +53,8 @@ import java.util.Iterator; import java.util.List; +import static org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedConstructor; +import static org.apache.groovy.util.BeanUtils.capitalize; import static org.codehaus.groovy.ast.ClassHelper.make; import static org.codehaus.groovy.ast.tools.GeneralUtils.assignX; import static org.codehaus.groovy.ast.tools.GeneralUtils.block; @@ -122,7 +123,7 @@ public void visit(ASTNode[] nodes, SourceUnit source) { addError("Can't have a final field also annotated with @" + OPTION_TYPE.getNameWithoutPackage(), de); } } else { - String setterName = "set" + MetaClassHelper.capitalize(variableName); + String setterName = "set" + capitalize(variableName); cNode.addMethod(setterName, ACC_PUBLIC | ACC_SYNTHETIC, ClassHelper.VOID_TYPE, params(param(ve.getType(), variableName)), ClassNode.EMPTY_ARRAY, block( stmt(assignX(propX(varX("this"), variableName), varX(variableName))) )); @@ -233,7 +234,7 @@ private void adjustConstructorAndFields(int skipIndex, ClassNode type) { } type.removeConstructor(constructor); // code doesn't mention the removed param at this point, okay to leave as is - type.addConstructor(constructor.getModifiers(), newParams, constructor.getExceptions(), constructor.getCode()); + addGeneratedConstructor(type, constructor.getModifiers(), newParams, constructor.getExceptions(), constructor.getCode()); type.removeField(variableName); } } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/LazyASTTransformation.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/LazyASTTransformation.java similarity index 92% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/LazyASTTransformation.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/LazyASTTransformation.java index fece60e691..e5e7da7553 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/LazyASTTransformation.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/LazyASTTransformation.java @@ -37,10 +37,11 @@ import org.codehaus.groovy.ast.stmt.SynchronizedStatement; import org.codehaus.groovy.control.CompilePhase; import org.codehaus.groovy.control.SourceUnit; -import org.codehaus.groovy.runtime.MetaClassHelper; import java.lang.ref.SoftReference; +import static org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedMethod; +import static org.apache.groovy.util.BeanUtils.capitalize; import static org.codehaus.groovy.ast.ClassHelper.makeWithoutCaching; import static org.codehaus.groovy.ast.tools.GeneralUtils.assignS; import static org.codehaus.groovy.ast.tools.GeneralUtils.assignX; @@ -130,7 +131,7 @@ private static void addHolderClassIdiomBody(BlockStatement body, FieldNode field // (2) keep initExpr within a declaring class method that is only called by the holder class // currently we have gone with (2) for simplicity with only a slight memory footprint increase in the declaring class final String initializeMethodName = (fullName + "_initExpr").replace('.', '_'); - declaringClass.addMethod(initializeMethodName, ACC_PRIVATE | ACC_STATIC | ACC_FINAL, fieldType, + addGeneratedMethod(declaringClass, initializeMethodName, ACC_PRIVATE | ACC_STATIC | ACC_FINAL, fieldType, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, returnS(initExpr)); holderClass.addField(innerFieldName, ACC_PRIVATE | ACC_STATIC | ACC_FINAL, fieldType, callX(declaringClass, initializeMethodName)); @@ -166,10 +167,11 @@ private static void addNonThreadSafeBody(BlockStatement body, FieldNode fieldNod private static void addMethod(FieldNode fieldNode, BlockStatement body, ClassNode type) { int visibility = ACC_PUBLIC; if (fieldNode.isStatic()) visibility |= ACC_STATIC; - String propName = MetaClassHelper.capitalize(fieldNode.getName().substring(1)); - fieldNode.getDeclaringClass().addMethod("get" + propName, visibility, type, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, body); + String propName = capitalize(fieldNode.getName().substring(1)); + ClassNode declaringClass = fieldNode.getDeclaringClass(); + addGeneratedMethod(declaringClass, "get" + propName, visibility, type, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, body); if (ClassHelper.boolean_TYPE.equals(type)) { - fieldNode.getDeclaringClass().addMethod("is" + propName, visibility, type, + addGeneratedMethod(declaringClass, "is" + propName, visibility, type, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, stmt(callThisX("get" + propName))); } } @@ -212,7 +214,7 @@ private static void createSoftGetter(FieldNode fieldNode, Expression initExpr, C private static void createSoftSetter(FieldNode fieldNode, ClassNode type) { final BlockStatement body = new BlockStatement(); final Expression fieldExpr = varX(fieldNode); - final String name = "set" + MetaClassHelper.capitalize(fieldNode.getName().substring(1)); + final String name = "set" + capitalize(fieldNode.getName().substring(1)); final Parameter parameter = param(type, "value"); final Expression paramExpr = varX(parameter); body.addStatement(ifElseS( @@ -222,7 +224,8 @@ private static void createSoftSetter(FieldNode fieldNode, ClassNode type) { )); int visibility = ACC_PUBLIC; if (fieldNode.isStatic()) visibility |= ACC_STATIC; - fieldNode.getDeclaringClass().addMethod(name, visibility, ClassHelper.VOID_TYPE, params(parameter), ClassNode.EMPTY_ARRAY, body); + ClassNode declaringClass = fieldNode.getDeclaringClass(); + addGeneratedMethod(declaringClass, name, visibility, ClassHelper.VOID_TYPE, params(parameter), ClassNode.EMPTY_ARRAY, body); } private static Expression syncTarget(FieldNode fieldNode) { diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/LogASTTransformation.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/LogASTTransformation.java similarity index 78% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/LogASTTransformation.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/LogASTTransformation.java index d381bf5a90..60c96bc566 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/LogASTTransformation.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/LogASTTransformation.java @@ -45,18 +45,12 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import groovyjarjarasm.asm.Opcodes; + +import static org.apache.groovy.ast.tools.VisibilityUtils.getVisibility; + /** * This class provides an AST Transformation to add a log field to a class. - * - * @author Guillaume Laforge - * @author Jochen Theodorou - * @author Dinko Srkoc - * @author Hamlet D'Arcy - * @author Raffaele Cigni - * @author Alberto Vilches Raton - * @author Tomasz Bujok - * @author Martin Ghados - * @author Matthias Cullmann */ @GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS) public class LogASTTransformation extends AbstractASTTransformation implements CompilationUnitAware { @@ -67,8 +61,11 @@ public class LogASTTransformation extends AbstractASTTransformation implements C */ public static final String DEFAULT_CATEGORY_NAME = "##default-category-name##"; + public static final String DEFAULT_ACCESS_MODIFIER = "private"; + private CompilationUnit compilationUnit; + @Override public void visit(ASTNode[] nodes, final SourceUnit source) { init(nodes, source); AnnotatedNode targetClass = (AnnotatedNode) nodes[1]; @@ -82,6 +79,8 @@ public void visit(ASTNode[] nodes, final SourceUnit source) { final String categoryName = lookupCategoryName(logAnnotation); + final int logFieldModifiers = lookupLogFieldModifiers(targetClass, logAnnotation); + if (!(targetClass instanceof ClassNode)) throw new GroovyBugError("Class annotation " + logAnnotation.getClassNode().getName() + " annotated no Class, this must not happen."); @@ -95,6 +94,7 @@ protected SourceUnit getSourceUnit() { return source; } + @Override public Expression transform(Expression exp) { if (exp == null) return null; if (exp instanceof MethodCallExpression) { @@ -114,7 +114,13 @@ public void visitClass(ClassNode node) { } else if (logField != null && !Modifier.isPrivate(logField.getModifiers())) { addError("Class annotated with Log annotation cannot have log field declared because the field exists in the parent class: " + logField.getOwner().getName(), logField); } else { - logNode = loggingStrategy.addLoggerFieldToClass(node, logFieldName, categoryName); + if (loggingStrategy instanceof LoggingStrategyV2) { + LoggingStrategyV2 loggingStrategyV2 = (LoggingStrategyV2) loggingStrategy; + logNode = loggingStrategyV2.addLoggerFieldToClass(node, logFieldName, categoryName, logFieldModifiers); + } else { + // support the old style but they won't be as configurable + logNode = loggingStrategy.addLoggerFieldToClass(node, logFieldName, categoryName); + } } super.visitClass(node); } @@ -196,6 +202,11 @@ private static String lookupCategoryName(AnnotationNode logAnnotation) { return DEFAULT_CATEGORY_NAME; } + private int lookupLogFieldModifiers(AnnotatedNode targetClass, AnnotationNode logAnnotation) { + int modifiers = getVisibility(logAnnotation, targetClass, ClassNode.class, Opcodes.ACC_PRIVATE); + return Opcodes.ACC_FINAL | Opcodes.ACC_TRANSIENT | Opcodes.ACC_STATIC | modifiers; + } + private static LoggingStrategy createLoggingStrategy(AnnotationNode logAnnotation, GroovyClassLoader loader) { String annotationName = logAnnotation.getClassNode().getName(); @@ -221,10 +232,23 @@ private static LoggingStrategy createLoggingStrategy(AnnotationNode logAnnotatio throw new RuntimeException("Could not find default value of method named loggingStrategy on class named " + annotationName); } - if (!LoggingStrategy.class.isAssignableFrom((Class) defaultValue)) { + if (!LoggingStrategy.class.isAssignableFrom((Class) defaultValue) + && !LoggingStrategyV2.class.isAssignableFrom((Class) defaultValue)) { throw new RuntimeException("Default loggingStrategy value on class named " + annotationName + " is not a LoggingStrategy"); } + // try V2 configurable logging strategy + try { + Class strategyClass = (Class) defaultValue; + if (AbstractLoggingStrategy.class.isAssignableFrom(strategyClass)) { + return DefaultGroovyMethods.newInstance(strategyClass, new Object[]{loader}); + } else { + return strategyClass.newInstance(); + } + } catch (Exception e) { + } + + // try legacy logging strategy try { Class strategyClass = (Class) defaultValue; if (AbstractLoggingStrategy.class.isAssignableFrom(strategyClass)) { @@ -262,6 +286,40 @@ public interface LoggingStrategy { Expression wrapLoggingMethodCall(Expression logVariable, String methodName, Expression originalExpression); } + /** + * A LoggingStrategy defines how to wire a new logger instance into an existing class. + * It is meant to be used with the @Log family of annotations to allow you to + * write your own Log annotation provider. + */ + public interface LoggingStrategyV2 extends LoggingStrategy { + /** + * In this method, you are given a ClassNode, a field name and a category name, and you must add a new Field + * onto the class. Return the result of the ClassNode.addField operations. + * + * @param classNode the class that was originally annotated with the Log transformation. + * @param fieldName the name of the logger field + * @param categoryName the name of the logging category + * @param fieldModifiers the modifiers (private, final, et. al.) of the logger field + * @return the FieldNode instance that was created and added to the class + */ + FieldNode addLoggerFieldToClass(ClassNode classNode, String fieldName, String categoryName, int fieldModifiers); + } + + public abstract static class AbstractLoggingStrategyV2 extends AbstractLoggingStrategy implements LoggingStrategyV2 { + protected AbstractLoggingStrategyV2(final GroovyClassLoader loader) { + super(loader); + } + + protected AbstractLoggingStrategyV2() { + this(null); + } + + @Override + public FieldNode addLoggerFieldToClass(ClassNode classNode, String fieldName, String categoryName) { + throw new UnsupportedOperationException("This logger requires a later version of Groovy"); + } + } + public abstract static class AbstractLoggingStrategy implements LoggingStrategy { protected final GroovyClassLoader loader; @@ -273,6 +331,7 @@ protected AbstractLoggingStrategy() { this(null); } + @Override public String getCategoryName(ClassNode classNode, String categoryName) { if (categoryName.equals(DEFAULT_CATEGORY_NAME)) { return classNode.getName(); @@ -296,6 +355,7 @@ protected ClassNode classNode(String name) { } } + @Override public void setCompilationUnit(final CompilationUnit unit) { this.compilationUnit = unit; } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java similarity index 97% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java index 801ae48dd9..30e9f7bbd4 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java @@ -72,6 +72,8 @@ import java.util.Map; import java.util.Set; +import static org.codehaus.groovy.ast.ClassHelper.Character_TYPE; +import static org.codehaus.groovy.ast.ClassHelper.STRING_TYPE; import static org.codehaus.groovy.ast.tools.GenericsUtils.addMethodGenerics; import static org.codehaus.groovy.ast.tools.GenericsUtils.applyGenericsContextToPlaceHolders; import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpecRecurse; @@ -438,7 +440,14 @@ public void visitForLoop(final ForStatement forLoop) { Expression collectionExpression = forLoop.getCollectionExpression(); if (!(collectionExpression instanceof ClosureListExpression)) { final ClassNode collectionType = getType(forLoop.getCollectionExpression()); - ClassNode componentType = inferLoopElementType(collectionType); + ClassNode forLoopVariableType = forLoop.getVariableType(); + ClassNode componentType; + if (Character_TYPE.equals(ClassHelper.getWrapper(forLoopVariableType)) && STRING_TYPE.equals(collectionType)) { + // we allow auto-coercion here + componentType = forLoopVariableType; + } else { + componentType = inferLoopElementType(collectionType); + } forLoop.getVariable().setType(componentType); // GRECLIPSE edit -- preserve origin type for code select //forLoop.getVariable().setOriginType(componentType); diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/sc/transformers/MethodCallExpressionTransformer.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/sc/transformers/MethodCallExpressionTransformer.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/sc/transformers/MethodCallExpressionTransformer.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/sc/transformers/MethodCallExpressionTransformer.java diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java similarity index 94% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index 4df6ed8c37..3ab1a2bddb 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -22,6 +22,9 @@ import groovy.lang.DelegatesTo; import groovy.lang.IntRange; import groovy.lang.Range; +import groovy.lang.Tuple2; +import groovy.transform.NamedParam; +import groovy.transform.NamedParams; import groovy.transform.TypeChecked; import groovy.transform.TypeCheckingMode; import groovy.transform.stc.ClosureParams; @@ -43,6 +46,7 @@ import org.codehaus.groovy.ast.Parameter; import org.codehaus.groovy.ast.PropertyNode; import org.codehaus.groovy.ast.Variable; +import org.codehaus.groovy.ast.expr.AnnotationConstantExpression; import org.codehaus.groovy.ast.expr.ArgumentListExpression; import org.codehaus.groovy.ast.expr.AttributeExpression; import org.codehaus.groovy.ast.expr.BinaryExpression; @@ -63,6 +67,7 @@ import org.codehaus.groovy.ast.expr.MapExpression; import org.codehaus.groovy.ast.expr.MethodCall; import org.codehaus.groovy.ast.expr.MethodCallExpression; +import org.codehaus.groovy.ast.expr.NotExpression; import org.codehaus.groovy.ast.expr.PostfixExpression; import org.codehaus.groovy.ast.expr.PrefixExpression; import org.codehaus.groovy.ast.expr.PropertyExpression; @@ -74,7 +79,6 @@ import org.codehaus.groovy.ast.expr.UnaryMinusExpression; import org.codehaus.groovy.ast.expr.UnaryPlusExpression; import org.codehaus.groovy.ast.expr.VariableExpression; -import org.codehaus.groovy.ast.expr.NotExpression; import org.codehaus.groovy.ast.stmt.BlockStatement; import org.codehaus.groovy.ast.stmt.CaseStatement; import org.codehaus.groovy.ast.stmt.CatchStatement; @@ -89,13 +93,13 @@ import org.codehaus.groovy.ast.tools.GenericsUtils; import org.codehaus.groovy.ast.tools.WideningCategories; import org.codehaus.groovy.classgen.ReturnAdder; +import org.codehaus.groovy.classgen.Verifier; import org.codehaus.groovy.classgen.asm.InvocationWriter; import org.codehaus.groovy.control.CompilationUnit; import org.codehaus.groovy.control.ErrorCollector; import org.codehaus.groovy.control.SourceUnit; import org.codehaus.groovy.control.messages.SyntaxErrorMessage; import org.codehaus.groovy.runtime.DefaultGroovyMethods; -import org.codehaus.groovy.runtime.MetaClassHelper; import org.codehaus.groovy.syntax.SyntaxException; import org.codehaus.groovy.syntax.Token; import org.codehaus.groovy.syntax.TokenUtil; @@ -125,6 +129,8 @@ import java.util.concurrent.atomic.AtomicReference; import static org.apache.groovy.ast.tools.ClassNodeUtils.samePackageName; +import static org.apache.groovy.util.BeanUtils.capitalize; +import static org.apache.groovy.util.BeanUtils.decapitalize; import static org.codehaus.groovy.ast.ClassHelper.BigDecimal_TYPE; import static org.codehaus.groovy.ast.ClassHelper.BigInteger_TYPE; import static org.codehaus.groovy.ast.ClassHelper.Boolean_TYPE; @@ -148,6 +154,7 @@ import static org.codehaus.groovy.ast.ClassHelper.RANGE_TYPE; import static org.codehaus.groovy.ast.ClassHelper.STRING_TYPE; import static org.codehaus.groovy.ast.ClassHelper.Short_TYPE; +import static org.codehaus.groovy.ast.ClassHelper.TUPLE_CLASSES; import static org.codehaus.groovy.ast.ClassHelper.VOID_TYPE; import static org.codehaus.groovy.ast.ClassHelper.boolean_TYPE; import static org.codehaus.groovy.ast.ClassHelper.byte_TYPE; @@ -166,6 +173,7 @@ import static org.codehaus.groovy.ast.ClassHelper.make; import static org.codehaus.groovy.ast.ClassHelper.short_TYPE; import static org.codehaus.groovy.ast.ClassHelper.void_WRAPPER_TYPE; +import static org.codehaus.groovy.ast.GenericsType.GenericsTypeName; import static org.codehaus.groovy.ast.tools.GeneralUtils.args; import static org.codehaus.groovy.ast.tools.GeneralUtils.binX; import static org.codehaus.groovy.ast.tools.GeneralUtils.callX; @@ -281,6 +289,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport { protected static final ClassNode DELEGATES_TO_TARGET = ClassHelper.make(DelegatesTo.Target.class); protected static final ClassNode LINKEDHASHMAP_CLASSNODE = make(LinkedHashMap.class); protected static final ClassNode CLOSUREPARAMS_CLASSNODE = make(ClosureParams.class); + protected static final ClassNode NAMED_PARAMS_CLASSNODE = make(NamedParams.class); protected static final ClassNode MAP_ENTRY_TYPE = make(Map.Entry.class); protected static final ClassNode ENUMERATION_TYPE = make(Enumeration.class); @@ -483,12 +492,36 @@ private static void addPrivateFieldOrMethodAccess(Expression source, ClassNode c * Given a field node, checks if we are accessing or setting a private field from an inner class. */ private void checkOrMarkPrivateAccess(Expression source, FieldNode fn, boolean lhsOfAssignment) { + ClassNode enclosingClassNode = typeCheckingContext.getEnclosingClassNode(); + ClassNode declaringClass = fn.getDeclaringClass(); if (fn != null && Modifier.isPrivate(fn.getModifiers()) && - (fn.getDeclaringClass() != typeCheckingContext.getEnclosingClassNode() || typeCheckingContext.getEnclosingClosure() != null) && - fn.getDeclaringClass().getModule() == typeCheckingContext.getEnclosingClassNode().getModule()) { + (declaringClass != enclosingClassNode || typeCheckingContext.getEnclosingClosure() != null) && + declaringClass.getModule() == enclosingClassNode.getModule()) { + if (!lhsOfAssignment && enclosingClassNode.isDerivedFrom(declaringClass)) { + // check for a public/protected getter since JavaBean getters haven't been recognised as properties + // at this point and we don't want private field access for that case which will be handled later + boolean isPrimBool = fn.getOriginType().equals(ClassHelper.boolean_TYPE); + String suffix = Verifier.capitalize(fn.getName()); + MethodNode getterNode = findValidGetter(enclosingClassNode, "get" + suffix); + if (getterNode == null && isPrimBool) { + getterNode = findValidGetter(enclosingClassNode, "is" + suffix); + } + if (getterNode != null) { + source.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, getterNode.getReturnType()); + return; + } + } StaticTypesMarker marker = lhsOfAssignment ? StaticTypesMarker.PV_FIELDS_MUTATION : StaticTypesMarker.PV_FIELDS_ACCESS; - addPrivateFieldOrMethodAccess(source, fn.getDeclaringClass(), marker, fn); + addPrivateFieldOrMethodAccess(source, declaringClass, marker, fn); + } + } + + private MethodNode findValidGetter(ClassNode classNode, String name) { + MethodNode getterMethod = classNode.getGetterMethod(name); + if (getterMethod != null && (getterMethod.isPublic() || getterMethod.isProtected())) { + return getterMethod; } + return null; } /** @@ -658,7 +691,7 @@ public void visitVariableExpression(VariableExpression vexp) { } if (variable != null) { - ClassNode inferredType = getInferredTypeFromTempInfo(variable, (ClassNode) variable.getNodeMetaData(StaticTypesMarker.INFERRED_TYPE)); + ClassNode inferredType = getInferredTypeFromTempInfo(variable, variable.getNodeMetaData(StaticTypesMarker.INFERRED_TYPE)); // instanceof applies, stash away the type, reusing key used elsewhere if (inferredType != null && !inferredType.getName().equals("java.lang.Object")) { vexp.putNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE, inferredType); @@ -757,15 +790,20 @@ public void visitBinaryExpression(BinaryExpression expression) { int op = expression.getOperation().getType(); leftExpression.visit(this); SetterInfo setterInfo = removeSetterInfo(leftExpression); + ClassNode lType = null; if (setterInfo != null) { if (ensureValidSetter(expression, leftExpression, rightExpression, setterInfo)) { return; } } else { + lType = getType(leftExpression); + inferParameterAndReturnTypesOfClosureOnRHS(lType, rightExpression, op); + rightExpression.visit(this); } - ClassNode lType = getType(leftExpression); + + if (null == lType) lType = getType(leftExpression); ClassNode rType = getType(rightExpression); if (isNullConstant(rightExpression)) { if (!isPrimitiveType(lType)) @@ -909,6 +947,31 @@ && isAssignment(enclosingBinaryExpression.getOperation().getType()) } } + private void inferParameterAndReturnTypesOfClosureOnRHS(ClassNode lType, Expression rightExpression, int op) { + if (ASSIGN == op) { + if (rightExpression instanceof ClosureExpression && ClassHelper.isFunctionalInterface(lType)) { + Tuple2 typeInfo = GenericsUtils.parameterizeSAM(lType); + ClassNode[] paramTypes = typeInfo.getV1(); + ClosureExpression closureExpression = ((ClosureExpression) rightExpression); + Parameter[] closureParameters = closureExpression.getParameters(); + + if (paramTypes.length == closureParameters.length) { + for (int i = 0, n = closureParameters.length; i < n; i++) { + Parameter parameter = closureParameters[i]; + if (parameter.isDynamicTyped()) { + parameter.setType(paramTypes[i]); + parameter.setOriginType(paramTypes[i]); + } + } + } else { + addStaticTypeError("Wrong number of parameters: ", closureExpression); + } + + storeInferredReturnType(rightExpression, typeInfo.getV2()); + } + } + } + /** * Given a binary expression corresponding to an assignment, will check that the type of the RHS matches one * of the possible setters and if not, throw a type checking error. @@ -1051,11 +1114,14 @@ private boolean typeCheckMultipleAssignmentAndContinue(Expression leftExpression // multiple assignment check if (!(leftExpression instanceof TupleExpression)) return true; - if (!(rightExpression instanceof ListExpression)) { + Expression transformedRightExpression = transformRightExpressionToSupportMultipleAssignment(rightExpression); + if (null == transformedRightExpression) { addStaticTypeError("Multiple assignments without list expressions on the right hand side are unsupported in static type checking mode", rightExpression); return false; } + rightExpression = transformedRightExpression; + TupleExpression tuple = (TupleExpression) leftExpression; ListExpression list = (ListExpression) rightExpression; List listExpressions = list.getExpressions(); @@ -1080,6 +1146,44 @@ private boolean typeCheckMultipleAssignmentAndContinue(Expression leftExpression return true; } + private Expression transformRightExpressionToSupportMultipleAssignment(Expression rightExpression) { + if (rightExpression instanceof ListExpression) { + return rightExpression; + } + + ClassNode cn = null; + if (rightExpression instanceof MethodCallExpression || rightExpression instanceof ConstructorCallExpression || rightExpression instanceof VariableExpression) { + ClassNode inferredType = getType(rightExpression); + cn = null == inferredType ? rightExpression.getType() : inferredType; + } + + if (null == cn) { + return null; + } + + for (int i = 0, n = TUPLE_CLASSES.length; i < n; i++) { + Class tcn = TUPLE_CLASSES[i]; + if (tcn.equals(cn.getTypeClass())) { + ListExpression listExpression = new ListExpression(); + GenericsType[] genericsTypes = cn.getGenericsTypes(); + for (int j = 0; j < i; j++) { + // the index of element in tuple starts with 1 + MethodCallExpression mce = new MethodCallExpression(rightExpression, "getV" + (j + 1), ArgumentListExpression.EMPTY_ARGUMENTS); + ClassNode elementType = null != genericsTypes ? genericsTypes[j].getType() : ClassHelper.OBJECT_TYPE; + mce.setType(elementType); + storeType(mce, elementType); + listExpression.addExpression(mce); + } + + listExpression.setSourcePosition(rightExpression); + + return listExpression; + } + } + + return null; + } + private static ClassNode adjustTypeForSpreading(ClassNode inferredRightExpressionType, Expression leftExpression) { // imagine we have: list*.foo = 100 // then the assignment must be checked against [100], not 100 @@ -1255,7 +1359,7 @@ protected void checkGroovyConstructorMap(final Expression receiver, final ClassN " for class: " + receiverType.getName(), receiver); } else { ClassNode valueType = getType(entryExpression.getValueExpression()); - MethodNode setter = receiverType.getSetterMethod("set" + MetaClassHelper.capitalize(pexp.getPropertyAsString()), false); + MethodNode setter = receiverType.getSetterMethod("set" + capitalize(pexp.getPropertyAsString()), false); ClassNode toBeAssignedTo = setter == null ? lookup.get() : setter.getParameters()[0].getType(); if (!isAssignableTo(valueType, toBeAssignedTo) && !extension.handleIncompatibleAssignment(toBeAssignedTo, valueType, entryExpression)) { @@ -1411,7 +1515,7 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re List> owners = makeOwnerList(objectExpression); addReceivers(receivers, owners, pexp.isImplicitThis()); - String capName = MetaClassHelper.capitalize(propertyName); + String capName = capitalize(propertyName); boolean isAttributeExpression = pexp instanceof AttributeExpression; HashSet handledNodes = new HashSet(); for (Receiver receiver : receivers) { @@ -1676,7 +1780,7 @@ private T allowStaticAccessToMember(T member, boolean staticOnly) { private void storeWithResolve(ClassNode typeToResolve, ClassNode receiver, ClassNode declaringClass, boolean isStatic, PropertyExpression expressionToStoreOn) { ClassNode type = typeToResolve; if (getGenericsWithoutArray(type) != null) { - Map resolvedPlaceholders = resolvePlaceHoldersFromDeclaration(receiver, declaringClass, null, isStatic); + Map resolvedPlaceholders = resolvePlaceHoldersFromDeclaration(receiver, declaringClass, null, isStatic); type = resolveGenericsWithContext(resolvedPlaceholders, type); } storeInferredTypeForPropertyExpression(expressionToStoreOn, type); @@ -1726,7 +1830,7 @@ protected SetterInfo hasSetter(final PropertyExpression pexp) { List> owners = makeOwnerList(objectExpression); addReceivers(receivers, owners, pexp.isImplicitThis()); - String capName = MetaClassHelper.capitalize(propertyName); + String capName = capitalize(propertyName); boolean isAttributeExpression = pexp instanceof AttributeExpression; for (Receiver receiver : receivers) { @@ -1809,8 +1913,14 @@ public void visitForLoop(final ForStatement forLoop) { } else { collectionExpression.visit(this); final ClassNode collectionType = getType(collectionExpression); - ClassNode componentType = inferLoopElementType(collectionType); ClassNode forLoopVariableType = forLoop.getVariableType(); + ClassNode componentType; + if (Character_TYPE.equals(ClassHelper.getWrapper(forLoopVariableType)) && STRING_TYPE.equals(collectionType)) { + // we allow auto-coercion here + componentType = forLoopVariableType; + } else { + componentType = inferLoopElementType(collectionType); + } if (ClassHelper.getUnwrapper(componentType) == forLoopVariableType) { // prefer primitive type over boxed type componentType = forLoopVariableType; @@ -1854,7 +1964,7 @@ public static ClassNode inferLoopElementType(final ClassNode collectionType) { componentType = MAP_ENTRY_TYPE.getPlainNodeReference(); componentType.setGenericsTypes(genericsTypes); } else if (STRING_TYPE.equals(collectionType)) { - componentType = ClassHelper.Character_TYPE; + componentType = ClassHelper.STRING_TYPE; } else if (ENUMERATION_TYPE.equals(collectionType)) { // GROOVY-6123 ClassNode intf = GenericsUtils.parameterizeType(collectionType, ENUMERATION_TYPE); @@ -2270,6 +2380,13 @@ public void visitClosureExpression(final ClosureExpression expression) { TypeCheckingContext.EnclosingClosure enclosingClosure = typeCheckingContext.getEnclosingClosure(); if (!enclosingClosure.getReturnTypes().isEmpty()) { ClassNode returnType = lowestUpperBound(enclosingClosure.getReturnTypes()); + + ClassNode expectedReturnType = getInferredReturnType(expression); + // type argument can not be of primitive type, we should convert it to the wrapper type + if (null != expectedReturnType && ClassHelper.isPrimitiveType(returnType) && expectedReturnType.equals(ClassHelper.getWrapper(returnType))) { + returnType = expectedReturnType; + } + storeInferredReturnType(expression, returnType); ClassNode inferredType = wrapClosureType(returnType); storeType(enclosingClosure.getClosureExpression(), inferredType); @@ -2578,6 +2695,86 @@ protected void visitMethodCallArguments(final ClassNode receiver, ArgumentListEx } } } + if (expressions.size() > 0 && expressions.get(0) instanceof MapExpression && params.length > 0) { + checkNamedParamsAnnotation(params[0], (MapExpression) expressions.get(0)); + } + } + + private void checkNamedParamsAnnotation(Parameter param, MapExpression args) { + if (!param.getType().isDerivedFrom(ClassHelper.MAP_TYPE)) return; + List entryExpressions = args.getMapEntryExpressions(); + Map entries = new LinkedHashMap(); + for (MapEntryExpression entry : entryExpressions) { + Object key = entry.getKeyExpression(); + if (key instanceof ConstantExpression) { + key = ((ConstantExpression) key).getValue(); + } + entries.put(key, entry.getValueExpression()); + } + List annotations = param.getAnnotations(NAMED_PARAMS_CLASSNODE); + if (annotations != null && !annotations.isEmpty()) { + AnnotationNode an = null; + for (AnnotationNode next : annotations) { + if (next.getClassNode().getName().equals(NamedParams.class.getName())) { + an = next; + } + } + List collectedNames = new ArrayList(); + if (an != null) { + Expression value = an.getMember("value"); + if (value instanceof AnnotationConstantExpression) { + processNamedParam((AnnotationConstantExpression) value, entries, args, collectedNames); + } else if (value instanceof ListExpression) { + ListExpression le = (ListExpression) value; + for (Expression next : le.getExpressions()) { + if (next instanceof AnnotationConstantExpression) { + processNamedParam((AnnotationConstantExpression) next, entries, args, collectedNames); + } + } + } + for (Map.Entry entry : entries.entrySet()) { + if (!collectedNames.contains(entry.getKey())) { + addStaticTypeError("unexpected named arg: " + entry.getKey(), args); + } + } + } + } + } + + private void processNamedParam(AnnotationConstantExpression value, Map entries, Expression expression, List collectedNames) { + AnnotationNode namedParam = (AnnotationNode) value.getValue(); + if (!namedParam.getClassNode().getName().equals(NamedParam.class.getName())) return; + String name = null; + boolean required = false; + ClassNode expectedType = null; + ConstantExpression constX = (ConstantExpression) namedParam.getMember("value"); + if (constX != null) { + name = (String) constX.getValue(); + collectedNames.add(name); + } + constX = (ConstantExpression) namedParam.getMember("required"); + if (constX != null) { + required = (Boolean) constX.getValue(); + } + ClassExpression typeX = (ClassExpression) namedParam.getMember("type"); + if (typeX != null) { + expectedType = typeX.getType(); + } + if (!entries.keySet().contains(name)) { + if (required) { + addStaticTypeError("required named arg '" + name + "' not found.", expression); + } + } else { + Expression supplied = entries.get(name); + if (isCompatibleType(expectedType, expectedType != null, supplied.getType())) { + addStaticTypeError("parameter for named arg '" + name + "' has type '" + prettyPrintType(supplied.getType()) + + "' but expected '" + prettyPrintType(expectedType) + "'.", expression); + } + } + } + + private boolean isCompatibleType(ClassNode expectedType, boolean b, ClassNode type) { + return b && !isAssignableTo(type, expectedType); } /** @@ -2625,7 +2822,7 @@ private void inferSAMType(Parameter param, ClassNode receiver, MethodNode method // First we try to get as much information about the declaration // class through the receiver - Map targetMethodDeclarationClassConnections = new HashMap(); + Map targetMethodDeclarationClassConnections = new HashMap(); extractGenericsConnections(targetMethodDeclarationClassConnections, receiver, receiver.redirect()); // then we use the method with the SAM parameter to get more information about the declaration Parameter[] parametersOfMethodContainingSAM = methodWithSAMParameter.getParameters(); @@ -2646,7 +2843,7 @@ private void inferSAMType(Parameter param, ClassNode receiver, MethodNode method // to replace the generics in the SAM type parameter of the target // method and than that to make the connections to the SAM type generics ClassNode paramTypeWithReceiverInformation = applyGenericsContext(targetMethodDeclarationClassConnections, param.getOriginType()); - Map SAMTypeConnections = new HashMap(); + Map SAMTypeConnections = new HashMap(); ClassNode classForSAM = paramTypeWithReceiverInformation.redirect(); extractGenericsConnections(SAMTypeConnections, paramTypeWithReceiverInformation, classForSAM); @@ -2685,9 +2882,41 @@ private void inferSAMType(Parameter param, ClassNode receiver, MethodNode method applyGenericsContext(SAMTypeConnections, typeOrNull(parameterTypesForSAM, i)); blockParameterTypes[i] = resolvedParameter; } + + tryToInferUnresolvedBlockParameterType(paramTypeWithReceiverInformation, methodForSAM, blockParameterTypes); + openBlock.putNodeMetaData(StaticTypesMarker.CLOSURE_ARGUMENTS, blockParameterTypes); } + private void tryToInferUnresolvedBlockParameterType(ClassNode paramTypeWithReceiverInformation, MethodNode methodForSAM, ClassNode[] blockParameterTypes) { + List indexList = new LinkedList<>(); + for (int i = 0, n = blockParameterTypes.length; i < n; i++) { + ClassNode blockParameterType = blockParameterTypes[i]; + if (null != blockParameterType && blockParameterType.isGenericsPlaceHolder()) { + indexList.add(i); + } + } + + if (!indexList.isEmpty()) { + // If the parameter type failed to resolve, try to find the parameter type through the class hierarchy + Map genericsTypeMap = GenericsUtils.makeDeclaringAndActualGenericsTypeMapOfExactType(methodForSAM.getDeclaringClass(), paramTypeWithReceiverInformation); + + for (Integer index : indexList) { + for (Map.Entry entry : genericsTypeMap.entrySet()) { + if (entry.getKey().getName().equals(blockParameterTypes[index].getUnresolvedName())) { + ClassNode type = entry.getValue().getType(); + + if (null != type && !type.isGenericsPlaceHolder()) { + blockParameterTypes[index] = type; + } + + break; + } + } + } + } + } + private ClassNode typeOrNull(ClassNode[] parameterTypesForSAM, int i) { return i < parameterTypesForSAM.length ? parameterTypesForSAM[i] : null; } @@ -2704,11 +2933,7 @@ private List getSignaturesFromHint(final ClosureExpression expressi typeCheckingContext.source, typeCheckingContext.compilationUnit, convertToStringArray(options), expression); - } catch (ClassNotFoundException e) { - throw new GroovyBugError(e); - } catch (InstantiationException e) { - throw new GroovyBugError(e); - } catch (IllegalAccessException e) { + } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) { throw new GroovyBugError(e); } return closureSignatures; @@ -2729,11 +2954,7 @@ private List resolveWithResolver(List candidates, Clas typeCheckingContext.source, typeCheckingContext.compilationUnit, convertToStringArray(options)); - } catch (ClassNotFoundException e) { - throw new GroovyBugError(e); - } catch (InstantiationException e) { - throw new GroovyBugError(e); - } catch (IllegalAccessException e) { + } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) { throw new GroovyBugError(e); } } @@ -2755,6 +2976,7 @@ private void doInferClosureParameterTypes(final ClassNode receiver, final Expres // In practice, it could be done differently but it has the main advantage of reusing // existing code, hence reducing the amount of code to debug in case of failure. ClassNode[] inferred = resolveGenericsFromTypeHint(receiver, arguments, selectedMethod, signature); + if (closureParams == null) return; // no-arg closure if (signature.length == closureParams.length // same number of arguments || (signature.length == 1 && closureParams.length == 0) // implicit it || (closureParams.length > signature.length && inferred[inferred.length - 1].isArray())) { // vargs @@ -3245,8 +3467,6 @@ public void visitMethodCallExpression(MethodCallExpression call) { addCategoryMethodCallError(call); } mn = disambiguateMethods(mn, chosenReceiver != null ? chosenReceiver.getType() : null, args, call); - - if (mn.size() == 1) { MethodNode directMethodCallCandidate = mn.get(0); if (call.getNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION) == null && @@ -3951,7 +4171,7 @@ protected void storeType(Expression exp, ClassNode cn) { if (exp instanceof VariableExpression) { VariableExpression var = (VariableExpression) exp; final Variable accessedVariable = var.getAccessedVariable(); - if (accessedVariable != null && accessedVariable != exp && accessedVariable instanceof VariableExpression) { + if (accessedVariable != exp && accessedVariable instanceof VariableExpression) { storeType((Expression) accessedVariable, cn); } if (accessedVariable instanceof Parameter) { @@ -4129,7 +4349,7 @@ private ClassNode inferSAMTypeGenericsInAssignment(ClassNode samUsage, MethodNod if (samGt == null || closureGt == null) return samUsage; // extract the generics from the return type - Map connections = new HashMap(); + Map connections = new HashMap(); extractGenericsConnections(connections, getInferredReturnType(closureExpression), sam.getReturnType()); // next we get the block parameter types and set the generics @@ -4571,8 +4791,8 @@ public static String extractPropertyNameFromMethodName(String prefix, String met if (prefix == null || methodName == null) return null; if (methodName.startsWith(prefix) && prefix.length() < methodName.length()) { String result = methodName.substring(prefix.length()); - String propertyName = java.beans.Introspector.decapitalize(result); - if (result.equals(MetaClassHelper.capitalize(propertyName))) return propertyName; + String propertyName = decapitalize(result); + if (result.equals(capitalize(propertyName))) return propertyName; } return null; } @@ -4617,7 +4837,7 @@ protected ClassNode getType(final ASTNode exp) { checkOrMarkPrivateAccess(vexp, fieldNode, isLHSOfEnclosingAssignment(vexp)); return getType(fieldNode); } - if (variable != null && variable != vexp && variable instanceof VariableExpression) { + if (variable != vexp && variable instanceof VariableExpression) { return getType((Expression) variable); } if (variable instanceof Parameter) { @@ -4743,7 +4963,7 @@ private ClassNode getTypeFromClosureArguments(Parameter parameter, TypeCheckingC */ private ClassNode getGenericsResolvedTypeOfFieldOrProperty(AnnotatedNode an, ClassNode type) { if (!type.isUsingGenerics()) return type; - Map connections = new HashMap(); + Map connections = new HashMap(); //TODO: inner classes mean a different this-type. This is ignored here! extractGenericsConnections(connections, typeCheckingContext.getEnclosingClassNode(), an.getDeclaringClass()); type = applyGenericsContext(connections, type); @@ -4928,7 +5148,7 @@ protected ClassNode inferReturnTypeGenerics( } if (!isUsingGenericsOrIsArrayUsingGenerics(returnType)) return returnType; if (getGenericsWithoutArray(returnType) == null) return returnType; - Map resolvedPlaceholders = resolvePlaceHoldersFromDeclaration(receiver, getDeclaringClass(method, arguments), method, method.isStatic()); + Map resolvedPlaceholders = resolvePlaceHoldersFromDeclaration(receiver, getDeclaringClass(method, arguments), method, method.isStatic()); if (!receiver.isGenericsPlaceHolder()) { GenericsUtils.extractPlaceholders(receiver, resolvedPlaceholders); } @@ -4936,7 +5156,7 @@ protected ClassNode inferReturnTypeGenerics( if (resolvedPlaceholders.isEmpty()) { return boundUnboundedWildcards(returnType); } - Map placeholdersFromContext = extractGenericsParameterMapOfThis(typeCheckingContext.getEnclosingMethod()); + Map placeholdersFromContext = extractGenericsParameterMapOfThis(typeCheckingContext.getEnclosingMethod()); applyGenericsConnections(placeholdersFromContext, resolvedPlaceholders); // then resolve receivers from method arguments @@ -4958,7 +5178,7 @@ protected ClassNode inferReturnTypeGenerics( if (implementsInterfaceOrIsSubclassOf(actualType, CLOSURE_TYPE) && isSAMType(type)) { // implicit closure coercion in action! - Map pholders = applyGenericsContextToParameterClass(resolvedPlaceholders, type); + Map pholders = applyGenericsContextToParameterClass(resolvedPlaceholders, type); actualType = convertClosureTypeToSAMType(expressions.get(i), actualType, type, pholders); } if (isVargs && lastArg && actualType.isArray()) { @@ -4969,7 +5189,7 @@ protected ClassNode inferReturnTypeGenerics( } actualType = wrapTypeIfNecessary(actualType); - Map connections = new HashMap(); + Map connections = new HashMap(); extractGenericsConnections(connections, actualType, type); extractGenericsConnectionsForSuperClassAndInterfaces(resolvedPlaceholders, connections); applyGenericsConnections(connections, resolvedPlaceholders); @@ -4980,20 +5200,20 @@ protected ClassNode inferReturnTypeGenerics( return applyGenericsContext(resolvedPlaceholders, returnType); } - private static void resolvePlaceholdersFromExplicitTypeHints(final MethodNode method, final GenericsType[] explicitTypeHints, final Map resolvedPlaceholders) { + private static void resolvePlaceholdersFromExplicitTypeHints(final MethodNode method, final GenericsType[] explicitTypeHints, final Map resolvedPlaceholders) { if (explicitTypeHints != null) { GenericsType[] methodGenericTypes = method.getGenericsTypes(); if (methodGenericTypes != null && methodGenericTypes.length == explicitTypeHints.length) { for (int i = 0; i < explicitTypeHints.length; i++) { GenericsType methodGenericType = methodGenericTypes[i]; GenericsType explicitTypeHint = explicitTypeHints[i]; - resolvedPlaceholders.put(methodGenericType.getName(), explicitTypeHint); + resolvedPlaceholders.put(new GenericsTypeName(methodGenericType.getName()), explicitTypeHint); } } } } - private static void extractGenericsConnectionsForSuperClassAndInterfaces(final Map resolvedPlaceholders, final Map connections) { + private static void extractGenericsConnectionsForSuperClassAndInterfaces(final Map resolvedPlaceholders, final Map connections) { for (GenericsType value : new HashSet(connections.values())) { if (!value.isPlaceholder() && !value.isWildcard()) { ClassNode valueType = value.getType(); @@ -5041,7 +5261,7 @@ private static void extractGenericsConnectionsForSuperClassAndInterfaces(final M * @param samType the type into which the closure is coerced into * @return same SAM type, but completed with information from the closure node */ - private static ClassNode convertClosureTypeToSAMType(final Expression expression, final ClassNode closureType, final ClassNode samType, final Map placeholders) { + private static ClassNode convertClosureTypeToSAMType(final Expression expression, final ClassNode closureType, final ClassNode samType, final Map placeholders) { if (!samType.isUsingGenerics()) return samType; // use the generics information from the Closure to further specify the type @@ -5057,7 +5277,7 @@ private static ClassNode convertClosureTypeToSAMType(final Expression expression ClassNode unwrapped = closureReturnType.getGenericsTypes()[0].getType(); extractGenericsConnections(placeholders, unwrapped, samReturnType); } else if (samReturnType.isGenericsPlaceHolder()) { - placeholders.put(samReturnType.getGenericsTypes()[0].getName(), closureType.getGenericsTypes()[0]); + placeholders.put(new GenericsTypeName(samReturnType.getGenericsTypes()[0].getName()), closureType.getGenericsTypes()[0]); } // now repeat the same for each parameter given in the ClosureExpression @@ -5088,7 +5308,7 @@ private static ClassNode convertClosureTypeToSAMType(final Expression expression generifiedType = generifiedType.getComponentType(); } if (expected.isGenericsPlaceHolder()) { - placeholders.put(expected.getGenericsTypes()[0].getName(), new GenericsType(generifiedType)); + placeholders.put(new GenericsTypeName(expected.getGenericsTypes()[0].getName()), new GenericsType(generifiedType)); } else { GenericsType[] expectedGenericsTypes = expected.getGenericsTypes(); GenericsType[] foundGenericsTypes = generifiedType.getGenericsTypes(); @@ -5097,7 +5317,7 @@ private static ClassNode convertClosureTypeToSAMType(final Expression expression final GenericsType type = expectedGenericsTypes[i]; if (type.isPlaceholder()) { String name = type.getName(); - placeholders.put(name, foundGenericsTypes[i]); + placeholders.put(new GenericsTypeName(name), foundGenericsTypes[i]); } } } @@ -5108,8 +5328,8 @@ private static ClassNode convertClosureTypeToSAMType(final Expression expression return result; } - private ClassNode resolveGenericsWithContext(Map resolvedPlaceholders, ClassNode currentType) { - Map placeholdersFromContext = extractGenericsParameterMapOfThis(typeCheckingContext.getEnclosingMethod()); + private ClassNode resolveGenericsWithContext(Map resolvedPlaceholders, ClassNode currentType) { + Map placeholdersFromContext = extractGenericsParameterMapOfThis(typeCheckingContext.getEnclosingMethod()); return resolveClassNodeGenerics(resolvedPlaceholders, placeholdersFromContext, currentType); } @@ -5128,8 +5348,8 @@ private static ClassNode getDeclaringClass(MethodNode method, Expression argumen return declaringClass; } - private Map resolvePlaceHoldersFromDeclaration(ClassNode receiver, ClassNode declaration, MethodNode method, boolean isStaticTarget) { - Map resolvedPlaceholders; + private Map resolvePlaceHoldersFromDeclaration(ClassNode receiver, ClassNode declaration, MethodNode method, boolean isStaticTarget) { + Map resolvedPlaceholders; if (isStaticTarget && CLASS_Type.equals(receiver) && receiver.isUsingGenerics() && receiver.getGenericsTypes().length > 0 && @@ -5147,14 +5367,14 @@ private static boolean isGenericsPlaceHolderOrArrayOf(ClassNode cn) { } - private static Map extractPlaceHolders(MethodNode method, ClassNode receiver, ClassNode declaringClass) { + private static Map extractPlaceHolders(MethodNode method, ClassNode receiver, ClassNode declaringClass) { if (declaringClass.equals(OBJECT_TYPE)) { - Map resolvedPlaceholders = new HashMap(); + Map resolvedPlaceholders = new HashMap(); if (method != null) addMethodLevelDeclaredGenerics(method, resolvedPlaceholders); return resolvedPlaceholders; } - Map resolvedPlaceholders = null; + Map resolvedPlaceholders = null; if (isPrimitiveType(receiver) && !isPrimitiveType(declaringClass)) { receiver = getWrapper(receiver); } @@ -5169,7 +5389,7 @@ private static Map extractPlaceHolders(MethodNode method, while (current != null) { boolean continueLoop = true; //extract the place holders - Map currentPlaceHolders = new HashMap(); + Map currentPlaceHolders = new HashMap(); if (isGenericsPlaceHolderOrArrayOf(declaringClass) || declaringClass.equals(current)) { extractGenericsConnections(currentPlaceHolders, current, declaringClass); if (method != null) addMethodLevelDeclaredGenerics(method, currentPlaceHolders); @@ -5180,11 +5400,11 @@ private static Map extractPlaceHolders(MethodNode method, if (resolvedPlaceholders != null) { // merge maps - Set> entries = currentPlaceHolders.entrySet(); - for (Map.Entry entry : entries) { + Set> entries = currentPlaceHolders.entrySet(); + for (Map.Entry entry : entries) { GenericsType gt = entry.getValue(); if (!gt.isPlaceholder()) continue; - GenericsType referenced = resolvedPlaceholders.get(gt.getName()); + GenericsType referenced = resolvedPlaceholders.get(new GenericsTypeName(gt.getName())); if (referenced == null) continue; entry.setValue(referenced); } @@ -5216,7 +5436,7 @@ private static Map extractPlaceHolders(MethodNode method, protected boolean typeCheckMethodsWithGenericsOrFail(ClassNode receiver, ClassNode[] arguments, MethodNode candidateMethod, Expression location) { if (!typeCheckMethodsWithGenerics(receiver, arguments, candidateMethod)) { - Map classGTs = GenericsUtils.extractPlaceholders(receiver); + Map classGTs = GenericsUtils.extractPlaceholders(receiver); ClassNode[] ptypes = new ClassNode[candidateMethod.getParameters().length]; final Parameter[] parameters = candidateMethod.getParameters(); for (int i = 0; i < parameters.length; i++) { diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/trait/TraitASTTransformation.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/trait/TraitASTTransformation.java similarity index 84% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/trait/TraitASTTransformation.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/trait/TraitASTTransformation.java index 4319c7e4c4..e2b5109819 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/trait/TraitASTTransformation.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/trait/TraitASTTransformation.java @@ -68,6 +68,7 @@ import java.util.List; import java.util.Set; +import static org.apache.groovy.ast.tools.AnnotatedNodeUtils.markAsGenerated; import static org.codehaus.groovy.ast.tools.GeneralUtils.returnS; import static org.codehaus.groovy.transform.trait.SuperCallTraitTransformer.UNRESOLVED_HELPER_CLASS; @@ -184,25 +185,39 @@ private ClassNode createHelperClass(final ClassNode cNode) { // prepare fields List fields = new ArrayList(); Set fieldNames = new HashSet(); + boolean hasStatic = false; for (FieldNode field : cNode.getFields()) { if (!"metaClass".equals(field.getName()) && (!field.isSynthetic() || field.getName().indexOf('$') < 0)) { fields.add(field); fieldNames.add(field.getName()); + if (field.isStatic()) { + hasStatic = true; + } } } ClassNode fieldHelper = null; + ClassNode staticFieldHelper = null; if (!fields.isEmpty()) { fieldHelper = new InnerClassNode( cNode, Traits.fieldHelperClassName(cNode), - ACC_STATIC | ACC_PUBLIC | ACC_INTERFACE | ACC_ABSTRACT, + ACC_STATIC | ACC_PUBLIC | ACC_INTERFACE | ACC_ABSTRACT | ACC_SYNTHETIC, ClassHelper.OBJECT_TYPE ); + if (hasStatic) { + staticFieldHelper = new InnerClassNode( + cNode, + Traits.staticFieldHelperClassName(cNode), + ACC_STATIC | ACC_PUBLIC | ACC_INTERFACE | ACC_ABSTRACT | ACC_SYNTHETIC, + ClassHelper.OBJECT_TYPE + ); + } } // add methods List methods = new ArrayList(cNode.getMethods()); List nonPublicAPIMethods = new LinkedList(); + List staticInitStatements = null; for (final MethodNode methodNode : methods) { boolean declared = methodNode.getDeclaringClass() == cNode; if (declared) { @@ -211,7 +226,15 @@ private ClassNode createHelperClass(final ClassNode cNode) { methodNode.getLineNumber(), methodNode.getColumnNumber())); return null; } - helper.addMethod(processMethod(cNode, helper, methodNode, fieldHelper, fieldNames)); + if (!methodNode.isAbstract()) { + MethodNode newMethod = processMethod(cNode, helper, methodNode, fieldHelper, fieldNames); + if (methodNode.getName().equals("")) { + staticInitStatements = getStatements(newMethod.getCode()); + } else { + // add non-abstract methods; abstract methods covered from trait interface + helper.addMethod(newMethod); + } + } if (methodNode.isPrivate() || methodNode.isStatic()) { nonPublicAPIMethods.add(methodNode); } @@ -228,14 +251,31 @@ private ClassNode createHelperClass(final ClassNode cNode) { // add fields for (FieldNode field : fields) { - processField(field, initializer, staticInitializer, fieldHelper, helper, cNode, fieldNames); + processField(field, initializer, staticInitializer, fieldHelper, helper, staticFieldHelper, cNode, fieldNames); + } + + // copy statements from static and instance init blocks + if (staticInitStatements != null) { + BlockStatement toBlock = getBlockStatement(staticInitializer, staticInitializer.getCode()); + for (Statement next : staticInitStatements) { + toBlock.addStatement(next); + } + } + List initStatements = cNode.getObjectInitializerStatements(); + Statement toCode = initializer.getCode(); + BlockStatement toBlock = getBlockStatement(initializer, toCode); + for (Statement next : initStatements) { + Parameter selfParam = createSelfParameter(cNode, false); + toBlock.addStatement(processBody(new VariableExpression(selfParam), next, cNode, helper, fieldHelper, fieldNames)); } + initStatements.clear(); // clear properties to avoid generation of methods cNode.getProperties().clear(); // copy annotations copyClassAnnotations(cNode, helper); + markAsGenerated(cNode, helper); fields = new ArrayList(cNode.getFields()); // reuse the full list of fields for (FieldNode field : fields) { @@ -251,16 +291,43 @@ private ClassNode createHelperClass(final ClassNode cNode) { unit.getAST().addClass(helper); if (fieldHelper != null) { unit.getAST().addClass(fieldHelper); + if (staticFieldHelper != null) { + unit.getAST().addClass(staticFieldHelper); + } } // resolve scope (for closures) resolveScope(helper); - if (fieldHelper!=null) { + if (fieldHelper != null) { resolveScope(fieldHelper); + if (staticFieldHelper != null) { + resolveScope(staticFieldHelper); + } } return helper; } + private BlockStatement getBlockStatement(MethodNode targetMethod, Statement code) { + BlockStatement toBlock; + if (code instanceof BlockStatement) { + toBlock = (BlockStatement) code; + } else { + toBlock = new BlockStatement(); + toBlock.addStatement(code); + targetMethod.setCode(toBlock); + } + return toBlock; + } + + private List getStatements(Statement stmt) { + if (stmt instanceof BlockStatement) { + return ((BlockStatement) stmt).getStatements(); + } + List result = new ArrayList(); + result.add(stmt); + return result; + } + private static MethodNode createInitMethod(final boolean isStatic, final ClassNode cNode, final ClassNode helper) { MethodNode initializer = new MethodNode( isStatic?Traits.STATIC_INIT_METHOD:Traits.INIT_METHOD, @@ -413,7 +480,7 @@ private static boolean methodNeedsReplacement(ClassNode classNode, MethodNode m) } private void processField(final FieldNode field, final MethodNode initializer, final MethodNode staticInitializer, - final ClassNode fieldHelper, final ClassNode helper, final ClassNode trait, + final ClassNode fieldHelper, final ClassNode helper, final ClassNode staticFieldHelper, final ClassNode trait, final Set knownFields) { if (field.isProtected()) { unit.addError(new SyntaxException("Cannot have protected field in a trait (" + trait.getName() + "#" + field.getName() + ")", @@ -423,6 +490,7 @@ private void processField(final FieldNode field, final MethodNode initializer, f Expression initialExpression = field.getInitialExpression(); MethodNode selectedMethod = field.isStatic()?staticInitializer:initializer; + ClassNode target = field.isStatic() && staticFieldHelper != null ? staticFieldHelper : fieldHelper; if (initialExpression != null) { VariableExpression thisObject = new VariableExpression(selectedMethod.getParameters()[0]); ExpressionStatement initCode = new ExpressionStatement(initialExpression); @@ -438,32 +506,36 @@ private void processField(final FieldNode field, final MethodNode initializer, f returnS(initCode.getExpression()) ); helper.addMethod(fieldInitializer); - } - BlockStatement code = (BlockStatement) selectedMethod.getCode(); - MethodCallExpression mce; - if (field.isStatic()) { - mce = new MethodCallExpression( - new ClassExpression(INVOKERHELPER_CLASSNODE), - "invokeStaticMethod", - new ArgumentListExpression( - thisObject, - new ConstantExpression(Traits.helperSetterName(field)), - initCode.getExpression() - ) - ); } else { - mce = new MethodCallExpression( - new CastExpression(createReceiverType(field.isStatic(), fieldHelper), thisObject), - Traits.helperSetterName(field), - new CastExpression(field.getOriginType(),initCode.getExpression()) - ); + BlockStatement code = (BlockStatement) selectedMethod.getCode(); + MethodCallExpression mce; + if (field.isStatic()) { + if (staticFieldHelper != null) { + target = staticFieldHelper; + } + mce = new MethodCallExpression( + new ClassExpression(INVOKERHELPER_CLASSNODE), + "invokeStaticMethod", + new ArgumentListExpression( + thisObject, + new ConstantExpression(Traits.helperSetterName(field)), + initCode.getExpression() + ) + ); + } else { + mce = new MethodCallExpression( + new CastExpression(createReceiverType(field.isStatic(), fieldHelper), thisObject), + Traits.helperSetterName(field), + new CastExpression(field.getOriginType(),initCode.getExpression()) + ); + } + mce.setImplicitThis(false); + mce.setSourcePosition(initialExpression); + code.addStatement(new ExpressionStatement(mce)); } - mce.setImplicitThis(false); - mce.setSourcePosition(initialExpression); - code.addStatement(new ExpressionStatement(mce)); } // define setter/getter helper methods (setter added even for final fields for legacy compatibility) - fieldHelper.addMethod( + target.addMethod( Traits.helperSetterName(field), ACC_PUBLIC | ACC_ABSTRACT, field.getOriginType(), @@ -471,7 +543,7 @@ private void processField(final FieldNode field, final MethodNode initializer, f ClassNode.EMPTY_ARRAY, null ); - fieldHelper.addMethod( + target.addMethod( Traits.helperGetterName(field), ACC_PUBLIC | ACC_ABSTRACT, field.getOriginType(), @@ -522,7 +594,7 @@ private MethodNode processMethod(ClassNode traitClass, ClassNode traitHelperClas Parameter[] newParams = new Parameter[initialParams.length + 1]; newParams[0] = createSelfParameter(traitClass, methodNode.isStatic()); System.arraycopy(initialParams, 0, newParams, 1, initialParams.length); - final int mod = methodNode.isPrivate()?ACC_PRIVATE:ACC_PUBLIC; + final int mod = methodNode.isPrivate() ? ACC_PRIVATE : ACC_PUBLIC | (methodNode.isFinal() ? ACC_FINAL : 0); MethodNode mNode = new MethodNode( methodNode.getName(), mod | ACC_STATIC, diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/trait/TraitComposer.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/trait/TraitComposer.java similarity index 87% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/trait/TraitComposer.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/trait/TraitComposer.java index c85eec134e..1774ea6e98 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/transform/trait/TraitComposer.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/trait/TraitComposer.java @@ -19,6 +19,7 @@ package org.codehaus.groovy.transform.trait; import groovy.transform.CompileStatic; +import org.codehaus.groovy.ast.ASTNode; import org.codehaus.groovy.ast.AnnotationNode; import org.codehaus.groovy.ast.ClassHelper; import org.codehaus.groovy.ast.ClassNode; @@ -108,7 +109,7 @@ public static void doExtendTraits(final ClassNode cNode, final SourceUnit unit, List traits = findTraits(cNode); for (ClassNode trait : traits) { TraitHelpersTuple helpers = Traits.findHelpers(trait); - applyTrait(trait, cNode, helpers); + applyTrait(trait, cNode, helpers, unit); superCallTransformer.visitClass(cNode); if (unit!=null) { ASTTransformationCollectorCodeVisitor collector = new ASTTransformationCollectorCodeVisitor(unit, cu.getTransformLoader()); @@ -138,9 +139,10 @@ private static void checkTraitAllowed(final ClassNode bottomTrait, final SourceU } } - private static void applyTrait(final ClassNode trait, final ClassNode cNode, final TraitHelpersTuple helpers) { + private static void applyTrait(final ClassNode trait, final ClassNode cNode, final TraitHelpersTuple helpers, SourceUnit unit) { ClassNode helperClassNode = helpers.getHelper(); ClassNode fieldHelperClassNode = helpers.getFieldHelper(); + ClassNode staticFieldHelperClassNode = helpers.getStaticFieldHelper(); Map genericsSpec = GenericsUtils.createGenericsSpec(cNode); genericsSpec = GenericsUtils.createGenericsSpec(trait, genericsSpec); @@ -173,15 +175,9 @@ private static void applyTrait(final ClassNode trait, final ClassNode cNode, fin origParams[i-1] = parameter; argList.addExpression(new VariableExpression(params[i - 1])); } - createForwarderMethod(trait, cNode, methodNode, originalMethod, helperClassNode, methodGenericsSpec, helperMethodParams, origParams, params, argList); + createForwarderMethod(trait, cNode, methodNode, originalMethod, helperClassNode, methodGenericsSpec, helperMethodParams, origParams, params, argList, unit); } } - cNode.addObjectInitializerStatements(new ExpressionStatement( - new MethodCallExpression( - new ClassExpression(helperClassNode), - Traits.INIT_METHOD, - new ArgumentListExpression(new VariableExpression("this"))) - )); MethodCallExpression staticInitCall = new MethodCallExpression( new ClassExpression(helperClassNode), Traits.STATIC_INIT_METHOD, @@ -206,6 +202,17 @@ private static void applyTrait(final ClassNode trait, final ClassNode cNode, fin declaredMethods.add(declaredMethod); } } + + if (staticFieldHelperClassNode != null) { + for (MethodNode declaredMethod : staticFieldHelperClassNode.getAllDeclaredMethods()) { + if (declaredMethod.getName().endsWith(Traits.DIRECT_GETTER_SUFFIX)) { + declaredMethods.add(0, declaredMethod); + } else { + declaredMethods.add(declaredMethod); + } + } + } + for (MethodNode methodNode : declaredMethods) { String fieldName = methodNode.getName(); if (fieldName.endsWith(Traits.DIRECT_GETTER_SUFFIX) || fieldName.endsWith(Traits.DIRECT_SETTER_SUFFIX)) { @@ -263,12 +270,16 @@ private static void applyTrait(final ClassNode trait, final ClassNode cNode, fin // so instead set within (static) initializer if (fieldNode.isFinal()) { String baseName = fieldNode.isStatic() ? Traits.STATIC_INIT_METHOD : Traits.INIT_METHOD; - Expression mce = callX(helperClassNode, baseName + fieldNode.getName(), args(varX("this"))); - Statement stmt = stmt(assignX(varX(fieldNode.getName(), fieldNode.getType()), mce)); - if (isStatic == 0) { - cNode.addObjectInitializerStatements(stmt); - } else { - cNode.addStaticInitializerStatements(Collections.singletonList(stmt), false); + StaticMethodCallExpression mce = callX(helperClassNode, baseName + fieldNode.getName(), args(varX("this"))); + if (helperClassNode.hasPossibleStaticMethod(mce.getMethod(), mce.getArguments())) { + Statement stmt = stmt(assignX(varX(fieldNode.getName(), fieldNode.getType()), mce)); + if (isStatic == 0) { + cNode.addObjectInitializerStatements(stmt); + } else { + List staticStatements = new ArrayList(); + staticStatements.add(stmt); + cNode.addStaticInitializerStatements(staticStatements, true); + } } } } @@ -310,6 +321,12 @@ private static void applyTrait(final ClassNode trait, final ClassNode cNode, fin } } } + cNode.addObjectInitializerStatements(new ExpressionStatement( + new MethodCallExpression( + new ClassExpression(helperClassNode), + Traits.INIT_METHOD, + new ArgumentListExpression(new VariableExpression("this"))) + )); } private static void createForwarderMethod( @@ -318,11 +335,11 @@ private static void createForwarderMethod( MethodNode helperMethod, MethodNode originalMethod, ClassNode helperClassNode, - Map genericsSpec, + Map genericsSpec, Parameter[] helperMethodParams, Parameter[] traitMethodParams, Parameter[] forwarderParams, - ArgumentListExpression helperMethodArgList) { + ArgumentListExpression helperMethodArgList, SourceUnit unit) { MethodCallExpression mce = new MethodCallExpression( new ClassExpression(helperClassNode), helperMethod.getName(), @@ -385,6 +402,15 @@ private static void createForwarderMethod( forwarder.setOriginal(originalMethod); // GRECLIPSE end + MethodNode existingMethod = findExistingMethod(targetNode, forwarder); + if (existingMethod != null) { + if (!forwarder.isStatic() && existingMethod.isStatic()) { + // found an existing static method that is going to conflict with interface + unit.addError(createException(trait, targetNode, forwarder, existingMethod)); + return; + } + } + if (!shouldSkipMethod(targetNode, forwarder.getName(), forwarderParams)) { targetNode.addMethod(forwarder); } @@ -392,6 +418,35 @@ private static void createForwarderMethod( createSuperForwarder(targetNode, forwarder, genericsSpec); } + private static SyntaxException createException(ClassNode trait, ClassNode targetNode, MethodNode forwarder, MethodNode existingMethod) { + String middle; + ASTNode errorTarget; + if (existingMethod.getLineNumber() == -1) { + // came from a trait + errorTarget = targetNode; + List allAnnos = existingMethod.getAnnotations(Traits.TRAITBRIDGE_CLASSNODE); + AnnotationNode bridgeAnno = allAnnos == null ? null : allAnnos.get(0); + String fromTrait = null; + if (bridgeAnno != null) { + Expression traitClass = bridgeAnno.getMember("traitClass"); + if (traitClass instanceof ClassExpression) { + ClassExpression ce = (ClassExpression) traitClass; + fromTrait = ce.getType().getNameWithoutPackage(); + } + } + middle = "in '" + targetNode.getNameWithoutPackage(); + if (fromTrait != null) { + middle += "' from trait '" + fromTrait; + } + } else { + errorTarget = existingMethod; + middle = "declared in '" + targetNode.getNameWithoutPackage(); + } + String message = "The static '" + forwarder.getName() + "' method " + middle + + "' conflicts with the instance method having the same signature from trait '" + trait.getNameWithoutPackage() + "'"; + return new SyntaxException(message, errorTarget); + } + private static GenericsType[] removeNonPlaceHolders(GenericsType[] oldTypes) { if (oldTypes==null || oldTypes.length==0) return oldTypes; ArrayList l = new ArrayList(Arrays.asList(oldTypes)); @@ -531,8 +586,16 @@ private static ClassNode[] copyExceptions(final ClassNode[] sourceExceptions) { return exceptionNodes; } + private static MethodNode findExistingMethod(final ClassNode cNode, final MethodNode forwarder) { + return findExistingMethod(cNode, forwarder.getName(), forwarder.getParameters()); + } + + private static MethodNode findExistingMethod(final ClassNode cNode, final String name, final Parameter[] params) { + return cNode.getDeclaredMethod(name, params); + } + private static boolean shouldSkipMethod(final ClassNode cNode, final String name, final Parameter[] params) { - if (isExistingProperty(name, cNode, params) || cNode.getDeclaredMethod(name, params)!=null) { + if (isExistingProperty(name, cNode, params) || findExistingMethod(cNode, name, params) != null) { // override exists in the weaved class itself return true; } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/vmplugin/v5/Java5.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/vmplugin/v5/Java5.java similarity index 98% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/vmplugin/v5/Java5.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/vmplugin/v5/Java5.java index 4c6cf36893..834cb18c73 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/vmplugin/v5/Java5.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/vmplugin/v5/Java5.java @@ -65,6 +65,8 @@ public class Java5 implements VMPlugin { private static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; private static final Class[] PLUGIN_DGM = {PluginDefaultGroovyMethods.class}; + private static final Method[] EMPTY_METHOD_ARRAY = new Method[0]; + private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0]; public void setAdditionalClassInformation(ClassNode cn) { setGenericsTypes(cn); @@ -280,7 +282,7 @@ private void configureAnnotation(AnnotationNode node, Annotation annotation) { try { declaredMethods = type.getDeclaredMethods(); } catch (SecurityException se) { - declaredMethods = new Method[0]; + declaredMethods = EMPTY_METHOD_ARRAY; } for (Method declaredMethod : declaredMethods) { try { @@ -289,8 +291,7 @@ private void configureAnnotation(AnnotationNode node, Annotation annotation) { if (valueExpression == null) continue; node.setMember(declaredMethod.getName(), valueExpression); - } catch (IllegalAccessException e) { - } catch (InvocationTargetException e) { + } catch (IllegalAccessException | InvocationTargetException e) { } } } @@ -446,7 +447,7 @@ private Annotation[][] getConstructorParameterAnnotations(Constructor constru ); } Annotation[][] adjusted = new Annotation[parameterCount][]; - adjusted[0] = new Annotation[0]; + adjusted[0] = EMPTY_ANNOTATION_ARRAY; System.arraycopy(annotations, 0, adjusted, 1, annotations.length); return adjusted; } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/vmplugin/v8/Java8.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/vmplugin/v8/Java8.java similarity index 100% rename from base/org.codehaus.groovy26/src/org/codehaus/groovy/vmplugin/v8/Java8.java rename to base/org.codehaus.groovy30/src/org/codehaus/groovy/vmplugin/v8/Java8.java diff --git a/base/org.eclipse.jdt.groovy.core/META-INF/MANIFEST.MF b/base/org.eclipse.jdt.groovy.core/META-INF/MANIFEST.MF index bbdce8d869..5222c87c99 100644 --- a/base/org.eclipse.jdt.groovy.core/META-INF/MANIFEST.MF +++ b/base/org.eclipse.jdt.groovy.core/META-INF/MANIFEST.MF @@ -12,7 +12,7 @@ Export-Package: org.codehaus.jdt.groovy.integration.internal, org.eclipse.jdt.groovy.core.util, org.eclipse.jdt.groovy.search Import-Package: org.eclipse.jdt.launching -Require-Bundle: org.codehaus.groovy;bundle-version="[2.4.16,3)";visibility:=reexport, +Require-Bundle: org.codehaus.groovy;bundle-version="[2.4.16,4)";visibility:=reexport, org.eclipse.core.expressions;visibility:=reexport, org.eclipse.core.resources;visibility:=reexport, org.eclipse.core.runtime;visibility:=reexport, diff --git a/extras/groovy-eclipse-batch-builder/build.properties b/extras/groovy-eclipse-batch-builder/build.properties index e1f5e89391..a2fbfc018d 100644 --- a/extras/groovy-eclipse-batch-builder/build.properties +++ b/extras/groovy-eclipse-batch-builder/build.properties @@ -1,12 +1,12 @@ # version numbers version2.4=2.4.16-02 version2.5=2.5.5-01 -version2.6=2.6.0-01 +version3.0=3.0.0-01 # uncomment to do a particular build -- only one should be uncommented at a time #do-24-build=true do-25-build=true -#do-26-build=true +#do-30-build=true # location of the plugins directory for the eclipse install eclipse.install.plugins=C:/Users/Public/Eclipse-4.10/plugins diff --git a/extras/groovy-eclipse-batch-builder/build.xml b/extras/groovy-eclipse-batch-builder/build.xml index aa9384368a..e42830dda1 100644 --- a/extras/groovy-eclipse-batch-builder/build.xml +++ b/extras/groovy-eclipse-batch-builder/build.xml @@ -99,7 +99,7 @@ - + @@ -152,10 +152,10 @@ - - - - + + + + @@ -166,7 +166,7 @@ - + diff --git a/ide-test/org.codehaus.groovy.alltests/src/org/codehaus/groovy/alltests/SanityTests.groovy b/ide-test/org.codehaus.groovy.alltests/src/org/codehaus/groovy/alltests/SanityTests.groovy index fe04b419a6..3d36810931 100644 --- a/ide-test/org.codehaus.groovy.alltests/src/org/codehaus/groovy/alltests/SanityTests.groovy +++ b/ide-test/org.codehaus.groovy.alltests/src/org/codehaus/groovy/alltests/SanityTests.groovy @@ -53,7 +53,7 @@ final class SanityTests { int major = groovyVersion.major, minor = groovyVersion.minor - assert "${major}.${minor}" == '2.6' + assert "${major}.${minor}" == '3.0' } @Test diff --git a/ide-test/org.codehaus.groovy.eclipse.dsl.tests/src/org/codehaus/groovy/eclipse/dsl/tests/DSLContentAssistTests.groovy b/ide-test/org.codehaus.groovy.eclipse.dsl.tests/src/org/codehaus/groovy/eclipse/dsl/tests/DSLContentAssistTests.groovy index 1effc65004..ab3d8631de 100644 --- a/ide-test/org.codehaus.groovy.eclipse.dsl.tests/src/org/codehaus/groovy/eclipse/dsl/tests/DSLContentAssistTests.groovy +++ b/ide-test/org.codehaus.groovy.eclipse.dsl.tests/src/org/codehaus/groovy/eclipse/dsl/tests/DSLContentAssistTests.groovy @@ -797,9 +797,9 @@ final class DSLContentAssistTests extends CompletionTestSuite { ICompletionProposal[] proposals = createProposalsAtOffset(contents, getLastIndexOf(contents, '(')) proposalExists(proposals, 'meth', 2) - proposalExists(proposals, 'pogo : __', isAtLeastGroovy(26) ? 0 : 1) - proposalExists(proposals, 'name : __', isAtLeastGroovy(26) ? 1 : 0) - proposalExists(proposals, 'type : __', isAtLeastGroovy(26) ? 1 : 0) + proposalExists(proposals, 'pogo : __', 1) + proposalExists(proposals, 'name : __', 0) + proposalExists(proposals, 'type : __', 0) } @Test diff --git a/ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/GroovyEclipseTestSuite.groovy b/ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/GroovyEclipseTestSuite.groovy index 252784fb64..77c7a94078 100644 --- a/ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/GroovyEclipseTestSuite.groovy +++ b/ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/GroovyEclipseTestSuite.groovy @@ -183,7 +183,7 @@ abstract class GroovyEclipseTestSuite { protected final void addSpock() { def bundle = Platform.getBundle('org.eclipse.jdt.groovy.core.tests.builder') - URL jarUrl = FileLocator.toFileURL(bundle.getEntry('lib/spock-core-1.1-groovy-2.4.jar')) + URL jarUrl = FileLocator.toFileURL(bundle.getEntry('lib/spock-core-1.2-groovy-2.4.jar')) testProject.addExternalLibrary(new Path(jarUrl.file)) } diff --git a/ide/Feature-org.codehaus.groovy26.feature/.gitignore b/ide/Feature-org.codehaus.groovy30.feature/.gitignore similarity index 100% rename from ide/Feature-org.codehaus.groovy26.feature/.gitignore rename to ide/Feature-org.codehaus.groovy30.feature/.gitignore diff --git a/ide/Feature-org.codehaus.groovy26.feature/.project b/ide/Feature-org.codehaus.groovy30.feature/.project similarity index 86% rename from ide/Feature-org.codehaus.groovy26.feature/.project rename to ide/Feature-org.codehaus.groovy30.feature/.project index 7c554f46f7..2b195b1eab 100644 --- a/ide/Feature-org.codehaus.groovy26.feature/.project +++ b/ide/Feature-org.codehaus.groovy30.feature/.project @@ -1,6 +1,6 @@ - Feature-org.codehaus.groovy26.feature + Feature-org.codehaus.groovy30.feature diff --git a/ide/Feature-org.codehaus.groovy26.feature/build.properties b/ide/Feature-org.codehaus.groovy30.feature/build.properties similarity index 100% rename from ide/Feature-org.codehaus.groovy26.feature/build.properties rename to ide/Feature-org.codehaus.groovy30.feature/build.properties diff --git a/ide/Feature-org.codehaus.groovy26.feature/epl-v10.html b/ide/Feature-org.codehaus.groovy30.feature/epl-v10.html similarity index 100% rename from ide/Feature-org.codehaus.groovy26.feature/epl-v10.html rename to ide/Feature-org.codehaus.groovy30.feature/epl-v10.html diff --git a/ide/Feature-org.codehaus.groovy26.feature/feature.properties b/ide/Feature-org.codehaus.groovy30.feature/feature.properties similarity index 98% rename from ide/Feature-org.codehaus.groovy26.feature/feature.properties rename to ide/Feature-org.codehaus.groovy30.feature/feature.properties index 34bfd315ae..b40b1d69db 100644 --- a/ide/Feature-org.codehaus.groovy26.feature/feature.properties +++ b/ide/Feature-org.codehaus.groovy30.feature/feature.properties @@ -4,11 +4,11 @@ providerName=Pivotal Software, Inc. -featureName=Groovy Compiler 2.6 (early access) +featureName=Groovy Compiler 3.0 (early access) descriptionURL=https://github.com/groovy/groovy-eclipse/wiki -description=Provides the 2.6 version of the Groovy compiler +description=Provides the 3.0 version of the Groovy compiler # "licenseURL" property - URL of the "Feature License" # do not translate value - just change to point to a locale-specific HTML page diff --git a/ide/Feature-org.codehaus.groovy26.feature/feature.xml b/ide/Feature-org.codehaus.groovy30.feature/feature.xml similarity index 89% rename from ide/Feature-org.codehaus.groovy26.feature/feature.xml rename to ide/Feature-org.codehaus.groovy30.feature/feature.xml index c3fe5b3522..cd41c01d1a 100644 --- a/ide/Feature-org.codehaus.groovy26.feature/feature.xml +++ b/ide/Feature-org.codehaus.groovy30.feature/feature.xml @@ -1,6 +1,6 @@ - 3.3.0-SNAPSHOT org.codehaus.groovy.eclipse - org.codehaus.groovy26.feature + org.codehaus.groovy30.feature 3.3.0-SNAPSHOT eclipse-feature \ No newline at end of file diff --git a/pom.xml b/pom.xml index 7c54744f88..48813a1204 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,7 @@ base/org.codehaus.groovy24 base/org.codehaus.groovy25 - base/org.codehaus.groovy26 + base/org.codehaus.groovy30 base/org.codehaus.groovy.eclipse.compilerResolver base/org.eclipse.jdt.groovy.core @@ -79,7 +79,7 @@ ide/Feature-org.codehaus.groovy24.feature ide/Feature-org.codehaus.groovy25.feature - ide/Feature-org.codehaus.groovy26.feature + ide/Feature-org.codehaus.groovy30.feature ide/Feature-org.codehaus.groovy.compilerless.feature ide/Feature-org.codehaus.groovy.eclipse.feature ide/Feature-org.codehaus.groovy.headless.feature