From 3277fde77ca83b6eaa596b5d035e38777c88b820 Mon Sep 17 00:00:00 2001 From: Zouev Date: Mon, 18 Apr 2022 14:56:01 +0300 Subject: [PATCH] Updates --- src/main/java/lexer/Scanner.java | 154 +- src/main/java/lexer/TokenCode.java | 2 +- src/main/java/parser/JavaParser.java | 4482 ++--- src/main/java/tree/AnnoElementValue.java | 3 +- src/main/java/tree/AnnoParameterList.java | 3 +- src/main/java/tree/Annotation.java | 11 +- src/main/java/tree/Annotations.java | 8 +- src/main/java/tree/Compilation/Package.java | 3 +- .../Compilation/SimpleCompilationUnit.java | 2 + .../tree/Compilation/TopLevelComponent.java | 2 + src/main/java/tree/CompoundName.java | 23 +- src/main/java/tree/CompoundNameAnnotated.java | 41 + .../java/tree/Declaration/CatchParameter.java | 19 +- .../tree/Declaration/ClassInitializer.java | 5 +- .../tree/Declaration/ConstructorBody.java | 1 + .../Declaration/ConstructorDeclaration.java | 21 +- .../Declaration/ConstructorDeclarator.java | 4 +- .../java/tree/Declaration/Declaration.java | 7 +- src/main/java/tree/Declaration/EnumBody.java | 4 +- .../tree/Declaration/EnumDeclaration.java | 8 +- .../java/tree/Declaration/Enumerator.java | 4 +- .../ExplicitConstructorInvocation.java | 10 +- .../tree/Declaration/ImportDeclaration.java | 4 +- .../Declaration/InterfaceDeclaration.java | 8 +- .../tree/Declaration/MethodDeclaration.java | 19 +- .../tree/Declaration/MethodDeclarator.java | 4 +- .../java/tree/Declaration/MethodHeader.java | 7 +- .../Declaration/NormalClassDeclaration.java | 22 +- .../NormalInterfaceDeclaration.java | 12 +- .../Declaration/ParameterDeclaration.java | 4 + .../java/tree/Declaration/ParameterTail.java | 4 +- .../tree/Declaration/ReceiverDeclaration.java | 11 +- .../tree/Declaration/RecordComponent.java | 14 +- .../tree/Declaration/RecordDeclaration.java | 10 +- .../tree/Declaration/TypeAndDeclarators.java | 18 +- .../tree/Declaration/VariableDeclaration.java | 11 +- .../tree/Declaration/VariableDeclarator.java | 11 +- .../tree/Declaration/VariableDeclarators.java | 24 +- src/main/java/tree/Dim.java | 26 +- src/main/java/tree/DimExpr.java | 31 + src/main/java/tree/DimExprs.java | 32 + src/main/java/tree/Entity.java | 10 +- .../java/tree/Expression/ArgumentList.java | 3 +- src/main/java/tree/Expression/Binary.java | 7 +- src/main/java/tree/Expression/Cast.java | 7 +- .../java/tree/Expression/Conditional.java | 4 +- src/main/java/tree/Expression/Expression.java | 3 +- src/main/java/tree/Expression/InstanceOf.java | 11 +- src/main/java/tree/Expression/Lambda.java | 12 +- .../Expression/{ => Primary}/ArrayAccess.java | 10 +- .../Expression/Primary/ArrayCreation.java | 54 + .../tree/Expression/Primary/ClassLiteral.java | 4 +- .../Expression/{ => Primary}/FieldAccess.java | 10 +- .../Expression/Primary/InstanceCreation.java | 44 +- .../Primary/InstanceCreationQualified.java | 54 + .../Primary/InstanceCreationTmp.java | 25 + .../java/tree/Expression/Primary/Literal.java | 6 +- .../Expression/Primary/MethodInvocation.java | 10 +- .../Expression/Primary/Parenthesized.java | 5 +- .../java/tree/Expression/Primary/Primary.java | 3 +- .../java/tree/Expression/Primary/This.java | 7 +- .../java/tree/Expression/SimpleReference.java | 7 +- .../tree/Expression/SwitchExpression.java | 8 +- .../java/tree/Expression/UnaryPostfix.java | 7 +- .../java/tree/Expression/UnaryPrefix.java | 7 +- src/main/java/tree/Initializer.java | 3 +- src/main/java/tree/InitializerArray.java | 16 +- src/main/java/tree/InitializerSimple.java | 7 +- src/main/java/tree/Modifiers.java | 7 +- src/main/java/tree/ResourceSpecification.java | 3 +- src/main/java/tree/StandardModifiers.java | 8 +- src/main/java/tree/Statement/Assert.java | 9 +- src/main/java/tree/Statement/Block.java | 11 +- .../java/tree/Statement/BlockStatement.java | 13 +- src/main/java/tree/Statement/Break.java | 10 +- src/main/java/tree/Statement/CatchClause.java | 7 +- src/main/java/tree/Statement/Continue.java | 10 +- src/main/java/tree/Statement/Do.java | 11 +- src/main/java/tree/Statement/IfThenElse.java | 7 +- src/main/java/tree/Statement/Return.java | 9 +- src/main/java/tree/Statement/Statement.java | 6 +- .../tree/Statement/StatementExpression.java | 9 +- src/main/java/tree/Statement/Switch.java | 15 +- src/main/java/tree/Statement/SwitchBlock.java | 7 +- src/main/java/tree/Statement/SwitchLabel.java | 7 +- src/main/java/tree/Statement/SwitchRule.java | 7 +- .../java/tree/Statement/Synchronized.java | 11 +- src/main/java/tree/Statement/Throw.java | 9 +- src/main/java/tree/Statement/Try.java | 11 +- src/main/java/tree/Statement/While.java | 9 +- src/main/java/tree/Statement/Yield.java | 9 +- src/main/java/tree/Type/PrimitiveType.java | 14 +- src/main/java/tree/Type/Type.java | 7 +- src/main/java/tree/Type/TypeArgument.java | 7 +- src/main/java/tree/Type/TypeList.java | 6 +- src/main/java/tree/Type/TypeName.java | 24 +- src/main/java/tree/Type/TypeParameter.java | 7 +- .../java/tree/Type/TypeParameterTail.java | 8 +- src/main/java/tree/Type/UnannotatedType.java | 22 +- src/main/resources/Java_16_Grammar.y | 171 +- src/main/resources/codebase/TEST0.java | 32 + src/main/resources/codebase/TEST1.java | 33 + src/main/resources/codebase/TEST2.java | 17 + src/main/resources/codebase/View.java | 13977 ++++++++++++++++ src/test/TEST0.java | 2 + 105 files changed, 17459 insertions(+), 2506 deletions(-) create mode 100644 src/main/java/tree/CompoundNameAnnotated.java create mode 100644 src/main/java/tree/DimExpr.java create mode 100644 src/main/java/tree/DimExprs.java rename src/main/java/tree/Expression/{ => Primary}/ArrayAccess.java (75%) create mode 100644 src/main/java/tree/Expression/Primary/ArrayCreation.java rename src/main/java/tree/Expression/{ => Primary}/FieldAccess.java (80%) create mode 100644 src/main/java/tree/Expression/Primary/InstanceCreationQualified.java create mode 100644 src/main/java/tree/Expression/Primary/InstanceCreationTmp.java create mode 100644 src/main/resources/codebase/TEST0.java create mode 100644 src/main/resources/codebase/TEST1.java create mode 100644 src/main/resources/codebase/TEST2.java create mode 100644 src/main/resources/codebase/View.java diff --git a/src/main/java/lexer/Scanner.java b/src/main/java/lexer/Scanner.java index 7028c4e..a5fcf9b 100644 --- a/src/main/java/lexer/Scanner.java +++ b/src/main/java/lexer/Scanner.java @@ -59,6 +59,8 @@ public int yylex() { lastToken = get(); if (Entity.debug) { + System.out.print(lastToken.span.getBegin().getLine()); + System.out.print(" "); System.out.print(lastToken.code); if (lastToken.code == TokenCode.Identifier) { System.out.print(" " + lastToken.image); @@ -77,13 +79,18 @@ public Token getLVal() { return lastToken; } + int lineNum = 1; + int posNum = 1; + @Override public void yyerror(String msg) { - System.err.println(msg); + System.out.print(lineNum); + System.out.print(" "); + System.out.println(msg); } public Token get() { - // if ( currentToken == null ) currentToken = getToken(); + // if ( currentToken == null ) currentToken = getToken(); while (true) { currentToken = getToken(); @@ -107,30 +114,33 @@ private Token getToken() { String image; Token token; - // if ( Entity.inBlock && Entity.unAnnotatedTypeTaken ) - // { - // Entity.unAnnotatedTypeTaken = false; - // return new Token(TokenCode.Phantom,""); - // } + // if ( Entity.inBlock && Entity.unAnnotatedTypeTaken ) + // { + // Entity.unAnnotatedTypeTaken = false; + // return new Token(TokenCode.Phantom,""); + // } while (true) { ch = getChar(); if (ch == charZero) { - return new Token(TokenCode.EOS, ""); + Token end = new Token(TokenCode.EOS, ""); + end.setSpan(new Span(new Pos(lineNum,posNum),null)); + return end; } if (ch == ' ' || ch == '\t') { - // currentPos++; + // currentPos++; forgetChar(); continue; } if (ch == '\n') { - // currentLine++; - // currentPos = 0; + lineNum++; + // currentLine++; + // currentPos = 0; forgetChar(); continue; } if (ch == '\r') { - // currentPos = 0; + // currentPos = 0; forgetChar(); continue; } @@ -491,6 +501,88 @@ private Token getToken() { } break; + case '0': // integer + String literal = "" + ch; + forgetChar(); + ch = getChar(); + switch ( ch ) { + case 'x': + case 'X': + forgetChar(); + literal += ch; + while (true) { + ch = getChar(); + if (isHexadecimal(ch)) { + literal += ch; + forgetChar(); + } else if (ch == '_') { + forgetChar(); + continue; + } else + break; + } + break; + + case 'o': + case 'O': + forgetChar(); + literal += ch; + while (true) { + ch = getChar(); + if (isOctal(ch)) { + literal += ch; + forgetChar(); + } else if (ch == '_') { + forgetChar(); + continue; + } else + break; + } + break; + + case 'b': + case 'B': + forgetChar(); + literal += ch; + while (true) { + ch = getChar(); + if (isBinary(ch)) { + literal += ch; + forgetChar(); + } else if (ch == '_') { + forgetChar(); + continue; + } else + break; + } + break; + + default: + while (true) { + if (Character.isDigit(ch)) { + literal = literal.concat("" + ch); + forgetChar(); + ch = getChar(); + } else if (ch == '_') { + forgetChar(); + ch = getChar(); + continue; + } else { + // forgetChar(); + break; + } + } + break; + } + if ( Character.toUpperCase(ch) == 'L' ) + { + literal += "" + ch; + forgetChar(); + } + image = literal; + code = TokenCode.IntegerLiteral; + break; + default: if (Character.isJavaIdentifierStart(ch)) { String identifier = "" + ch; @@ -507,12 +599,14 @@ private Token getToken() { image = identifier; code = detectKeyword(identifier); } else if (Character.isDigit(ch)) { - String literal = "" + ch; + literal = "" + ch; while (true) { forgetChar(); ch = getChar(); if (Character.isDigit(ch)) { literal = literal.concat("" + ch); + } else if ( ch == '_' ) { + continue; } else { // forgetChar(); break; @@ -526,8 +620,13 @@ private Token getToken() { while (true) { if (Character.isDigit(ch)) { literal = literal.concat("" + ch); - } else { forgetChar(); + ch = getChar(); + continue; + } else if ( ch == '_' ) { + continue; + } else { + //forgetChar(); break; } } @@ -543,15 +642,35 @@ private Token getToken() { break; } token = new Token(code, image); + token.setSpan(new Span(new Pos(lineNum,posNum),null)); return token; } + private boolean isHexadecimal(char ch) + { + if ( Character.isDigit(ch) ) return true; + char chU = Character.toUpperCase(ch); + if ( chU >= 'A' && chU <= 'F' ) return true; + return false; + } + + private boolean isOctal(char ch) + { + return (ch>='0' && ch<='7'); + } + + private boolean isBinary(char ch) + { + return ch == '0' || ch == '1'; + } + private String scanShortComment() { StringBuilder comment = new StringBuilder(); while (true) { char ch = getChar(); forgetChar(); if (ch == '\n') { + lineNum++; break; } comment.append(ch); @@ -573,6 +692,9 @@ private String scanLongComment() { } else { comment.append("*").append(ch); } + } else if (ch == '\n') { + lineNum++; + comment.append(ch); } else { comment.append(ch); } @@ -591,7 +713,7 @@ private TokenCode detectKeyword(String identifier) { case "case" -> TokenCode.Case; case "char" -> TokenCode.Char; case "class" -> TokenCode.Class; - // case "const" : return TokenCode.Const; // not actually used + // case "const" -> TokenCode.Const; // not actually used case "continue" -> TokenCode.Continue; case "default" -> TokenCode.Default; case "do" -> TokenCode.Do; @@ -603,7 +725,7 @@ private TokenCode detectKeyword(String identifier) { case "finally" -> TokenCode.Finally; case "float" -> TokenCode.Float; case "for" -> TokenCode.For; - // case "goto" : return TokenCode.Goto; // not actually used + // case "goto" -> TokenCode.Goto; // not actually used case "if" -> TokenCode.If; case "implements" -> TokenCode.Implements; case "import" -> TokenCode.Import; diff --git a/src/main/java/lexer/TokenCode.java b/src/main/java/lexer/TokenCode.java index 0958632..6029e7a 100644 --- a/src/main/java/lexer/TokenCode.java +++ b/src/main/java/lexer/TokenCode.java @@ -165,7 +165,7 @@ public enum TokenCode { // to be distinguished from a yield statement. record has special meaning // in a record declaration (§8.10). - True(Lexer.FALSE), + True(Lexer.TRUE), False(Lexer.FALSE), Null(Lexer.NULL), diff --git a/src/main/java/parser/JavaParser.java b/src/main/java/parser/JavaParser.java index e7ffe46..c259c8e 100644 --- a/src/main/java/parser/JavaParser.java +++ b/src/main/java/parser/JavaParser.java @@ -274,91 +274,91 @@ public enum SymbolKind S_FieldDeclaration(171), /* FieldDeclaration */ S_VariableDeclaratorList(172), /* VariableDeclaratorList */ S_VariableDeclarator(173), /* VariableDeclarator */ - S_ArrayInitializer(174), /* ArrayInitializer */ - S_VariableInitializerListOpt(175), /* VariableInitializerListOpt */ - S_VariableInitializerList(176), /* VariableInitializerList */ - S_VariableInitializer(177), /* VariableInitializer */ - S_MethodDeclaration(178), /* MethodDeclaration */ - S_MethodHeader(179), /* MethodHeader */ - S_MethodDeclarator(180), /* MethodDeclarator */ - S_FormalParameterList(181), /* FormalParameterList */ - S_FormalParameter(182), /* FormalParameter */ - S_FormalParameterTail(183), /* FormalParameterTail */ - S_ThrowsOpt(184), /* ThrowsOpt */ - S_MethodBody(185), /* MethodBody */ - S_DimsOpt(186), /* DimsOpt */ - S_Dims(187), /* Dims */ - S_Dim(188), /* Dim */ - S_InterfaceDeclaration(189), /* InterfaceDeclaration */ - S_NormalInterfaceDeclaration(190), /* NormalInterfaceDeclaration */ - S_InterfaceExtendsOpt(191), /* InterfaceExtendsOpt */ - S_InterfaceExtends(192), /* InterfaceExtends */ - S_InterfaceBody(193), /* InterfaceBody */ - S_InterfaceMemberDeclarationSeq(194), /* InterfaceMemberDeclarationSeq */ - S_InterfaceMemberDeclaration(195), /* InterfaceMemberDeclaration */ - S_ConstantDeclaration(196), /* ConstantDeclaration */ - S_InterfaceMethodDeclaration(197), /* InterfaceMethodDeclaration */ - S_AnnotationInterfaceDeclaration(198), /* AnnotationInterfaceDeclaration */ - S_AnnotationInterfaceBody(199), /* AnnotationInterfaceBody */ - S_AnnotationInterfaceMemberDeclarationSeq(200), /* AnnotationInterfaceMemberDeclarationSeq */ - S_AnnotationInterfaceMemberDeclaration(201), /* AnnotationInterfaceMemberDeclaration */ - S_AnnotationInterfaceElementDeclaration(202), /* AnnotationInterfaceElementDeclaration */ - S_DefaultValueOpt(203), /* DefaultValueOpt */ - S_Block(204), /* Block */ - S_BlockStatementSeq(205), /* BlockStatementSeq */ - S_BlockStatement(206), /* BlockStatement */ - S_LocalVariableDeclaration(207), /* LocalVariableDeclaration */ - S_Statement(208), /* Statement */ - S_SimpleStatement(209), /* SimpleStatement */ - S_LabeledStatement(210), /* LabeledStatement */ - S_StatementExpression(211), /* StatementExpression */ - S_IfThenElseStatement(212), /* IfThenElseStatement */ - S_ElsePartOpt(213), /* ElsePartOpt */ - S_SwitchBlock(214), /* SwitchBlock */ - S_SwitchRuleSeq(215), /* SwitchRuleSeq */ - S_SwitchRule(216), /* SwitchRule */ - S_SwitchBlockStatementGroupSeq(217), /* SwitchBlockStatementGroupSeq */ - S_SwitchBlockStatementGroup(218), /* SwitchBlockStatementGroup */ - S_SwitchLabelSeq(219), /* SwitchLabelSeq */ - S_SwitchLabel(220), /* SwitchLabel */ - S_CaseExpressionList(221), /* CaseExpressionList */ - S_WhileStatement(222), /* WhileStatement */ - S_ForStatement(223), /* ForStatement */ - S_BasicForStatement(224), /* BasicForStatement */ - S_ForInitOpt(225), /* ForInitOpt */ - S_ExpressionOpt(226), /* ExpressionOpt */ - S_StatementExpressionList(227), /* StatementExpressionList */ - S_StatementExpressionListOpt(228), /* StatementExpressionListOpt */ - S_EnhancedForStatement(229), /* EnhancedForStatement */ - S_CatchesOpt(230), /* CatchesOpt */ - S_Catches(231), /* Catches */ - S_CatchClause(232), /* CatchClause */ - S_CatchFormalParameter(233), /* CatchFormalParameter */ - S_CatchType(234), /* CatchType */ - S_FinallyOpt(235), /* FinallyOpt */ - S_Finally(236), /* Finally */ - S_ResourceSpecification(237), /* ResourceSpecification */ - S_ResourceSeq(238), /* ResourceSeq */ - S_Resource(239), /* Resource */ - S_Pattern(240), /* Pattern */ - S_Primary(241), /* Primary */ - S_ClassInstanceCreationExpression(242), /* ClassInstanceCreationExpression */ - S_UnqualifiedClassInstanceCreationExpression(243), /* UnqualifiedClassInstanceCreationExpression */ - S_ClassOrInterfaceTypeToInstantiate(244), /* ClassOrInterfaceTypeToInstantiate */ - S_AnnotatedCompoundName(245), /* AnnotatedCompoundName */ - S_TypeArgumentsOpt(246), /* TypeArgumentsOpt */ - S_TypeArguments(247), /* TypeArguments */ - S_TypeArgumentList(248), /* TypeArgumentList */ - S_TypeArgument(249), /* TypeArgument */ - S_FieldAccess(250), /* FieldAccess */ - S_ArrayAccess(251), /* ArrayAccess */ - S_MethodInvocation(252), /* MethodInvocation */ - S_Arguments(253), /* Arguments */ - S_ArgumentList(254), /* ArgumentList */ - S_MethodReference(255), /* MethodReference */ - S_ArrayCreationExpression(256), /* ArrayCreationExpression */ - S_DimExprs(257), /* DimExprs */ - S_DimExpr(258), /* DimExpr */ + S_SimpleInitOpt(174), /* SimpleInitOpt */ + S_ArrayInitOpt(175), /* ArrayInitOpt */ + S_ArrayInitializer(176), /* ArrayInitializer */ + S_VariableInitializerListOpt(177), /* VariableInitializerListOpt */ + S_VariableInitializerList(178), /* VariableInitializerList */ + S_VariableInitializer(179), /* VariableInitializer */ + S_MethodDeclaration(180), /* MethodDeclaration */ + S_MethodHeader(181), /* MethodHeader */ + S_MethodDeclarator(182), /* MethodDeclarator */ + S_FormalParameterList(183), /* FormalParameterList */ + S_FormalParameter(184), /* FormalParameter */ + S_FormalParameterTail(185), /* FormalParameterTail */ + S_ThrowsOpt(186), /* ThrowsOpt */ + S_MethodBody(187), /* MethodBody */ + S_DimsOpt(188), /* DimsOpt */ + S_Dims(189), /* Dims */ + S_Dim(190), /* Dim */ + S_InterfaceDeclaration(191), /* InterfaceDeclaration */ + S_NormalInterfaceDeclaration(192), /* NormalInterfaceDeclaration */ + S_InterfaceExtendsOpt(193), /* InterfaceExtendsOpt */ + S_InterfaceExtends(194), /* InterfaceExtends */ + S_InterfaceBody(195), /* InterfaceBody */ + S_InterfaceMemberDeclarationSeq(196), /* InterfaceMemberDeclarationSeq */ + S_InterfaceMemberDeclaration(197), /* InterfaceMemberDeclaration */ + S_ConstantDeclaration(198), /* ConstantDeclaration */ + S_InterfaceMethodDeclaration(199), /* InterfaceMethodDeclaration */ + S_AnnotationInterfaceDeclaration(200), /* AnnotationInterfaceDeclaration */ + S_AnnotationInterfaceBody(201), /* AnnotationInterfaceBody */ + S_AnnotationInterfaceMemberDeclarationSeq(202), /* AnnotationInterfaceMemberDeclarationSeq */ + S_AnnotationInterfaceMemberDeclaration(203), /* AnnotationInterfaceMemberDeclaration */ + S_AnnotationInterfaceElementDeclaration(204), /* AnnotationInterfaceElementDeclaration */ + S_DefaultValueOpt(205), /* DefaultValueOpt */ + S_Block(206), /* Block */ + S_BlockStatementSeq(207), /* BlockStatementSeq */ + S_BlockStatement(208), /* BlockStatement */ + S_LocalVariableDeclaration(209), /* LocalVariableDeclaration */ + S_Statement(210), /* Statement */ + S_SimpleStatement(211), /* SimpleStatement */ + S_LabeledStatement(212), /* LabeledStatement */ + S_StatementExpression(213), /* StatementExpression */ + S_IfThenElseStatement(214), /* IfThenElseStatement */ + S_ElsePartOpt(215), /* ElsePartOpt */ + S_SwitchBlock(216), /* SwitchBlock */ + S_SwitchRuleSeq(217), /* SwitchRuleSeq */ + S_SwitchRule(218), /* SwitchRule */ + S_SwitchBlockStatementGroupSeq(219), /* SwitchBlockStatementGroupSeq */ + S_SwitchBlockStatementGroup(220), /* SwitchBlockStatementGroup */ + S_SwitchLabelSeq(221), /* SwitchLabelSeq */ + S_SwitchLabel(222), /* SwitchLabel */ + S_CaseExpressionList(223), /* CaseExpressionList */ + S_WhileStatement(224), /* WhileStatement */ + S_ForStatement(225), /* ForStatement */ + S_BasicForStatement(226), /* BasicForStatement */ + S_ForInitOpt(227), /* ForInitOpt */ + S_ExpressionOpt(228), /* ExpressionOpt */ + S_StatementExpressionList(229), /* StatementExpressionList */ + S_StatementExpressionListOpt(230), /* StatementExpressionListOpt */ + S_EnhancedForStatement(231), /* EnhancedForStatement */ + S_CatchesOpt(232), /* CatchesOpt */ + S_Catches(233), /* Catches */ + S_CatchClause(234), /* CatchClause */ + S_CatchFormalParameter(235), /* CatchFormalParameter */ + S_CatchType(236), /* CatchType */ + S_FinallyOpt(237), /* FinallyOpt */ + S_Finally(238), /* Finally */ + S_ResourceSpecification(239), /* ResourceSpecification */ + S_ResourceSeq(240), /* ResourceSeq */ + S_Resource(241), /* Resource */ + S_Pattern(242), /* Pattern */ + S_Primary(243), /* Primary */ + S_ClassInstanceCreationExpression(244), /* ClassInstanceCreationExpression */ + S_UnqualifiedClassInstanceCreationExpression(245), /* UnqualifiedClassInstanceCreationExpression */ + S_ClassOrInterfaceTypeToInstantiate(246), /* ClassOrInterfaceTypeToInstantiate */ + S_TypeArgumentsOpt(247), /* TypeArgumentsOpt */ + S_TypeArguments(248), /* TypeArguments */ + S_TypeArgumentList(249), /* TypeArgumentList */ + S_TypeArgument(250), /* TypeArgument */ + S_FieldAccess(251), /* FieldAccess */ + S_ArrayAccess(252), /* ArrayAccess */ + S_MethodInvocation(253), /* MethodInvocation */ + S_Arguments(254), /* Arguments */ + S_ArgumentList(255), /* ArgumentList */ + S_MethodReference(256), /* MethodReference */ + S_ArrayCreationExpression(257), /* ArrayCreationExpression */ + S_ArrayInitializerOpt(258), /* ArrayInitializerOpt */ S_Expression(259), /* Expression */ S_LambdaExpression(260), /* LambdaExpression */ S_LambdaParameters(261), /* LambdaParameters */ @@ -578,6 +578,8 @@ public enum SymbolKind SymbolKind.S_FieldDeclaration, SymbolKind.S_VariableDeclaratorList, SymbolKind.S_VariableDeclarator, + SymbolKind.S_SimpleInitOpt, + SymbolKind.S_ArrayInitOpt, SymbolKind.S_ArrayInitializer, SymbolKind.S_VariableInitializerListOpt, SymbolKind.S_VariableInitializerList, @@ -649,7 +651,6 @@ public enum SymbolKind SymbolKind.S_ClassInstanceCreationExpression, SymbolKind.S_UnqualifiedClassInstanceCreationExpression, SymbolKind.S_ClassOrInterfaceTypeToInstantiate, - SymbolKind.S_AnnotatedCompoundName, SymbolKind.S_TypeArgumentsOpt, SymbolKind.S_TypeArguments, SymbolKind.S_TypeArgumentList, @@ -661,8 +662,7 @@ public enum SymbolKind SymbolKind.S_ArgumentList, SymbolKind.S_MethodReference, SymbolKind.S_ArrayCreationExpression, - SymbolKind.S_DimExprs, - SymbolKind.S_DimExpr, + SymbolKind.S_ArrayInitializerOpt, SymbolKind.S_Expression, SymbolKind.S_LambdaExpression, SymbolKind.S_LambdaParameters, @@ -752,17 +752,17 @@ private static final String[] yynames_init() "EnumBodyDeclarationsOpt", "RecordDeclaration", "RecordHeader", "RecordComponentListOpt", "RecordComponent", "RecordBody", "RecordBodyDeclarationSeq", "RecordBodyDeclaration", "FieldDeclaration", - "VariableDeclaratorList", "VariableDeclarator", "ArrayInitializer", - "VariableInitializerListOpt", "VariableInitializerList", - "VariableInitializer", "MethodDeclaration", "MethodHeader", - "MethodDeclarator", "FormalParameterList", "FormalParameter", - "FormalParameterTail", "ThrowsOpt", "MethodBody", "DimsOpt", "Dims", - "Dim", "InterfaceDeclaration", "NormalInterfaceDeclaration", - "InterfaceExtendsOpt", "InterfaceExtends", "InterfaceBody", - "InterfaceMemberDeclarationSeq", "InterfaceMemberDeclaration", - "ConstantDeclaration", "InterfaceMethodDeclaration", - "AnnotationInterfaceDeclaration", "AnnotationInterfaceBody", - "AnnotationInterfaceMemberDeclarationSeq", + "VariableDeclaratorList", "VariableDeclarator", "SimpleInitOpt", + "ArrayInitOpt", "ArrayInitializer", "VariableInitializerListOpt", + "VariableInitializerList", "VariableInitializer", "MethodDeclaration", + "MethodHeader", "MethodDeclarator", "FormalParameterList", + "FormalParameter", "FormalParameterTail", "ThrowsOpt", "MethodBody", + "DimsOpt", "Dims", "Dim", "InterfaceDeclaration", + "NormalInterfaceDeclaration", "InterfaceExtendsOpt", "InterfaceExtends", + "InterfaceBody", "InterfaceMemberDeclarationSeq", + "InterfaceMemberDeclaration", "ConstantDeclaration", + "InterfaceMethodDeclaration", "AnnotationInterfaceDeclaration", + "AnnotationInterfaceBody", "AnnotationInterfaceMemberDeclarationSeq", "AnnotationInterfaceMemberDeclaration", "AnnotationInterfaceElementDeclaration", "DefaultValueOpt", "Block", "BlockStatementSeq", "BlockStatement", "LocalVariableDeclaration", @@ -778,19 +778,18 @@ private static final String[] yynames_init() "ResourceSpecification", "ResourceSeq", "Resource", "Pattern", "Primary", "ClassInstanceCreationExpression", "UnqualifiedClassInstanceCreationExpression", - "ClassOrInterfaceTypeToInstantiate", "AnnotatedCompoundName", - "TypeArgumentsOpt", "TypeArguments", "TypeArgumentList", "TypeArgument", - "FieldAccess", "ArrayAccess", "MethodInvocation", "Arguments", - "ArgumentList", "MethodReference", "ArrayCreationExpression", "DimExprs", - "DimExpr", "Expression", "LambdaExpression", "LambdaParameters", - "LambdaParameterList", "LambdaParameter", "AssignmentExpression", - "Assignment", "LeftHandSide", "AssignmentOperator", - "ConditionalExpression", "ConditionalOrTail", "ConditionalOrExpression", - "ConditionalAndExpression", "InclusiveOrExpression", - "ExclusiveOrExpression", "AndExpression", "EqualityExpression", - "RelationalExpression", "InstanceofExpression", "ShiftExpression", - "AdditiveExpression", "MultiplicativeExpression", "UnaryExpression", - "PreIncrementExpression", "PreDecrementExpression", + "ClassOrInterfaceTypeToInstantiate", "TypeArgumentsOpt", "TypeArguments", + "TypeArgumentList", "TypeArgument", "FieldAccess", "ArrayAccess", + "MethodInvocation", "Arguments", "ArgumentList", "MethodReference", + "ArrayCreationExpression", "ArrayInitializerOpt", "Expression", + "LambdaExpression", "LambdaParameters", "LambdaParameterList", + "LambdaParameter", "AssignmentExpression", "Assignment", "LeftHandSide", + "AssignmentOperator", "ConditionalExpression", "ConditionalOrTail", + "ConditionalOrExpression", "ConditionalAndExpression", + "InclusiveOrExpression", "ExclusiveOrExpression", "AndExpression", + "EqualityExpression", "RelationalExpression", "InstanceofExpression", + "ShiftExpression", "AdditiveExpression", "MultiplicativeExpression", + "UnaryExpression", "PreIncrementExpression", "PreDecrementExpression", "UnaryExpressionNotPlusMinus", "PostfixExpression", "PostIncrementExpression", "PostDecrementExpression", "SwitchExpression", "AnnotationSeqOpt", "AnnotationSeq", "Annotation", "AnnoParameterList", @@ -1253,679 +1252,679 @@ private int yyaction(int yyn, YYStack yystack, int yylen) { case 2: /* Literal: INTEGER_LITERAL */ if (yyn == 2) - /* "src/main/resources/Java_16_Grammar.y":295 */ + /* "src/main/resources/Java_16_Grammar.y":306 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 3: /* Literal: FLOATING_POINT_LITERAL */ if (yyn == 3) - /* "src/main/resources/Java_16_Grammar.y":296 */ + /* "src/main/resources/Java_16_Grammar.y":307 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 4: /* Literal: TRUE */ if (yyn == 4) - /* "src/main/resources/Java_16_Grammar.y":297 */ + /* "src/main/resources/Java_16_Grammar.y":308 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 5: /* Literal: FALSE */ if (yyn == 5) - /* "src/main/resources/Java_16_Grammar.y":298 */ + /* "src/main/resources/Java_16_Grammar.y":309 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 6: /* Literal: CHARACTER_LITERAL */ if (yyn == 6) - /* "src/main/resources/Java_16_Grammar.y":299 */ + /* "src/main/resources/Java_16_Grammar.y":310 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 7: /* Literal: STRING_LITERAL */ if (yyn == 7) - /* "src/main/resources/Java_16_Grammar.y":300 */ + /* "src/main/resources/Java_16_Grammar.y":311 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 8: /* Literal: NULL */ if (yyn == 8) - /* "src/main/resources/Java_16_Grammar.y":302 */ + /* "src/main/resources/Java_16_Grammar.y":313 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 9: /* CompoundName: IDENTIFIER */ if (yyn == 9) - /* "src/main/resources/Java_16_Grammar.y":308 */ + /* "src/main/resources/Java_16_Grammar.y":319 */ { yyval = new CompoundName(((Token)(yystack.valueAt (0))).image); }; break; case 10: /* CompoundName: CompoundName DOT IDENTIFIER */ if (yyn == 10) - /* "src/main/resources/Java_16_Grammar.y":309 */ + /* "src/main/resources/Java_16_Grammar.y":320 */ { yyval = ((CompoundName)(yystack.valueAt (2))).add(((Token)(yystack.valueAt (0))).image); }; break; case 11: /* ModifierSeqOpt: %empty */ if (yyn == 11) - /* "src/main/resources/Java_16_Grammar.y":313 */ + /* "src/main/resources/Java_16_Grammar.y":324 */ { yyval = null; }; break; case 12: /* ModifierSeqOpt: ModifierSeq */ if (yyn == 12) - /* "src/main/resources/Java_16_Grammar.y":314 */ + /* "src/main/resources/Java_16_Grammar.y":325 */ { yyval = ((Modifiers)(yystack.valueAt (0))); }; break; case 13: /* ModifierSeq: StandardModifierSeq */ if (yyn == 13) - /* "src/main/resources/Java_16_Grammar.y":318 */ + /* "src/main/resources/Java_16_Grammar.y":329 */ { yyval = new Modifiers(null,((StandardModifiers)(yystack.valueAt (0)))); }; break; case 14: /* ModifierSeq: AnnotationSeq StandardModifierSeq */ if (yyn == 14) - /* "src/main/resources/Java_16_Grammar.y":319 */ + /* "src/main/resources/Java_16_Grammar.y":330 */ { yyval = new Modifiers(((Annotations)(yystack.valueAt (1))),((StandardModifiers)(yystack.valueAt (0)))); }; break; case 15: /* StandardModifierSeq: StandardModifier */ if (yyn == 15) - /* "src/main/resources/Java_16_Grammar.y":323 */ + /* "src/main/resources/Java_16_Grammar.y":334 */ { yyval = new StandardModifiers(((Token)(yystack.valueAt (0)))); }; break; case 16: /* StandardModifierSeq: StandardModifierSeq StandardModifier */ if (yyn == 16) - /* "src/main/resources/Java_16_Grammar.y":324 */ + /* "src/main/resources/Java_16_Grammar.y":335 */ { yyval = ((StandardModifiers)(yystack.valueAt (1))).add(((Token)(yystack.valueAt (0)))); }; break; case 17: /* StandardModifier: DEFAULT */ if (yyn == 17) - /* "src/main/resources/Java_16_Grammar.y":329 */ + /* "src/main/resources/Java_16_Grammar.y":340 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 18: /* StandardModifier: FINAL */ if (yyn == 18) - /* "src/main/resources/Java_16_Grammar.y":330 */ + /* "src/main/resources/Java_16_Grammar.y":341 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 19: /* StandardModifier: PUBLIC */ if (yyn == 19) - /* "src/main/resources/Java_16_Grammar.y":331 */ + /* "src/main/resources/Java_16_Grammar.y":342 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 20: /* StandardModifier: PROTECTED */ if (yyn == 20) - /* "src/main/resources/Java_16_Grammar.y":332 */ + /* "src/main/resources/Java_16_Grammar.y":343 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 21: /* StandardModifier: PRIVATE */ if (yyn == 21) - /* "src/main/resources/Java_16_Grammar.y":333 */ + /* "src/main/resources/Java_16_Grammar.y":344 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 22: /* StandardModifier: ABSTRACT */ if (yyn == 22) - /* "src/main/resources/Java_16_Grammar.y":334 */ + /* "src/main/resources/Java_16_Grammar.y":345 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 23: /* StandardModifier: STATIC */ if (yyn == 23) - /* "src/main/resources/Java_16_Grammar.y":335 */ + /* "src/main/resources/Java_16_Grammar.y":346 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 24: /* StandardModifier: STRICTFP */ if (yyn == 24) - /* "src/main/resources/Java_16_Grammar.y":336 */ + /* "src/main/resources/Java_16_Grammar.y":347 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 25: /* StandardModifier: SYNCHRONIZED */ if (yyn == 25) - /* "src/main/resources/Java_16_Grammar.y":337 */ + /* "src/main/resources/Java_16_Grammar.y":348 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 26: /* StandardModifier: TRANSIENT */ if (yyn == 26) - /* "src/main/resources/Java_16_Grammar.y":338 */ + /* "src/main/resources/Java_16_Grammar.y":349 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 27: /* StandardModifier: VOLATILE */ if (yyn == 27) - /* "src/main/resources/Java_16_Grammar.y":339 */ + /* "src/main/resources/Java_16_Grammar.y":350 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 28: /* StandardModifier: OPEN */ if (yyn == 28) - /* "src/main/resources/Java_16_Grammar.y":340 */ + /* "src/main/resources/Java_16_Grammar.y":351 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 29: /* CompilationUnit: %empty */ if (yyn == 29) - /* "src/main/resources/Java_16_Grammar.y":346 */ + /* "src/main/resources/Java_16_Grammar.y":357 */ { yyval = null; }; break; case 30: /* CompilationUnit: Package */ if (yyn == 30) - /* "src/main/resources/Java_16_Grammar.y":347 */ + /* "src/main/resources/Java_16_Grammar.y":358 */ { yyval = ((tree.Compilation.CompilationUnit)(yystack.valueAt (0))); ast = ((tree.Compilation.CompilationUnit)(yystack.valueAt (0))); }; break; case 31: /* CompilationUnit: ImportDeclarationSeqOpt TopLevelComponentSeq */ if (yyn == 31) - /* "src/main/resources/Java_16_Grammar.y":349 */ + /* "src/main/resources/Java_16_Grammar.y":360 */ { ast = new SimpleCompilationUnit(((tree.Declaration.ImportDeclarations)(yystack.valueAt (1))),((tree.Compilation.TopLevelComponents)(yystack.valueAt (0)))); }; break; case 32: /* Package: PACKAGE CompoundName SEMICOLON ImportDeclarationSeqOpt TopLevelComponentSeqOpt */ if (yyn == 32) - /* "src/main/resources/Java_16_Grammar.y":354 */ + /* "src/main/resources/Java_16_Grammar.y":365 */ { yyval = new tree.Compilation.Package(((CompoundName)(yystack.valueAt (3))),((tree.Declaration.ImportDeclarations)(yystack.valueAt (1))),((tree.Compilation.TopLevelComponents)(yystack.valueAt (0)))); }; break; case 33: /* ImportDeclarationSeqOpt: %empty */ if (yyn == 33) - /* "src/main/resources/Java_16_Grammar.y":364 */ + /* "src/main/resources/Java_16_Grammar.y":375 */ { yyval = null; }; break; case 34: /* ImportDeclarationSeqOpt: ImportDeclarationSeq */ if (yyn == 34) - /* "src/main/resources/Java_16_Grammar.y":365 */ + /* "src/main/resources/Java_16_Grammar.y":376 */ { yyval = ((tree.Declaration.ImportDeclarations)(yystack.valueAt (0))); }; break; case 35: /* ImportDeclarationSeq: ImportDeclaration */ if (yyn == 35) - /* "src/main/resources/Java_16_Grammar.y":369 */ + /* "src/main/resources/Java_16_Grammar.y":380 */ { yyval = new ImportDeclarations(((tree.Declaration.ImportDeclaration)(yystack.valueAt (0)))); }; break; case 36: /* ImportDeclarationSeq: ImportDeclarationSeqOpt ImportDeclaration */ if (yyn == 36) - /* "src/main/resources/Java_16_Grammar.y":370 */ + /* "src/main/resources/Java_16_Grammar.y":381 */ { yyval = ((tree.Declaration.ImportDeclarations)(yystack.valueAt (1))).add(((tree.Declaration.ImportDeclaration)(yystack.valueAt (0)))); }; break; case 37: /* ImportDeclaration: IMPORT CompoundName SEMICOLON */ if (yyn == 37) - /* "src/main/resources/Java_16_Grammar.y":374 */ + /* "src/main/resources/Java_16_Grammar.y":385 */ { yyval = new ImportDeclaration(false,((CompoundName)(yystack.valueAt (1))),false); }; break; case 38: /* ImportDeclaration: IMPORT STATIC CompoundName SEMICOLON */ if (yyn == 38) - /* "src/main/resources/Java_16_Grammar.y":375 */ + /* "src/main/resources/Java_16_Grammar.y":386 */ { yyval = new ImportDeclaration(true,((CompoundName)(yystack.valueAt (1))),false); }; break; case 39: /* ImportDeclaration: IMPORT CompoundName DOT STAR SEMICOLON */ if (yyn == 39) - /* "src/main/resources/Java_16_Grammar.y":376 */ + /* "src/main/resources/Java_16_Grammar.y":387 */ { yyval = new ImportDeclaration(false,((CompoundName)(yystack.valueAt (3))),true); }; break; case 40: /* ImportDeclaration: IMPORT STATIC CompoundName DOT STAR SEMICOLON */ if (yyn == 40) - /* "src/main/resources/Java_16_Grammar.y":377 */ + /* "src/main/resources/Java_16_Grammar.y":388 */ { yyval = new ImportDeclaration(true,((CompoundName)(yystack.valueAt (3))),true); }; break; case 41: /* TopLevelComponentSeqOpt: %empty */ if (yyn == 41) - /* "src/main/resources/Java_16_Grammar.y":381 */ + /* "src/main/resources/Java_16_Grammar.y":392 */ { yyval = null; }; break; case 42: /* TopLevelComponentSeqOpt: TopLevelComponentSeq */ if (yyn == 42) - /* "src/main/resources/Java_16_Grammar.y":382 */ + /* "src/main/resources/Java_16_Grammar.y":393 */ { yyval = ((tree.Compilation.TopLevelComponents)(yystack.valueAt (0))); }; break; case 43: /* TopLevelComponentSeq: ModifierSeqOpt TopLevelComponent */ if (yyn == 43) - /* "src/main/resources/Java_16_Grammar.y":386 */ + /* "src/main/resources/Java_16_Grammar.y":397 */ { ((tree.Compilation.TopLevelComponent)(yystack.valueAt (0))).addModifiers(((Modifiers)(yystack.valueAt (1)))); yyval = new TopLevelComponents(((tree.Compilation.TopLevelComponent)(yystack.valueAt (0)))); }; break; case 44: /* TopLevelComponentSeq: TopLevelComponentSeq ModifierSeqOpt TopLevelComponent */ if (yyn == 44) - /* "src/main/resources/Java_16_Grammar.y":387 */ + /* "src/main/resources/Java_16_Grammar.y":398 */ { ((tree.Compilation.TopLevelComponent)(yystack.valueAt (0))).addModifiers(((Modifiers)(yystack.valueAt (1)))); yyval = ((tree.Compilation.TopLevelComponents)(yystack.valueAt (2))).add(((tree.Compilation.TopLevelComponent)(yystack.valueAt (0)))); }; break; case 45: /* TopLevelComponent: ClassDeclaration */ if (yyn == 45) - /* "src/main/resources/Java_16_Grammar.y":391 */ + /* "src/main/resources/Java_16_Grammar.y":402 */ { classes.put(((ClassDeclaration)(yystack.valueAt (0))).name,((ClassDeclaration)(yystack.valueAt (0)))); yyval = new TopLevelComponent(((ClassDeclaration)(yystack.valueAt (0)))); }; break; case 46: /* TopLevelComponent: InterfaceDeclaration */ if (yyn == 46) - /* "src/main/resources/Java_16_Grammar.y":392 */ + /* "src/main/resources/Java_16_Grammar.y":403 */ { classes.put(((InterfaceDeclaration)(yystack.valueAt (0))).name,((InterfaceDeclaration)(yystack.valueAt (0)))); yyval = new TopLevelComponent(((InterfaceDeclaration)(yystack.valueAt (0)))); }; break; case 47: /* Type: UnannotatedType */ if (yyn == 47) - /* "src/main/resources/Java_16_Grammar.y":439 */ + /* "src/main/resources/Java_16_Grammar.y":450 */ { yyval = ((tree.Type.UnannotatedType)(yystack.valueAt (0))); }; break; case 48: /* Type: AnnotationSeq UnannotatedType */ if (yyn == 48) - /* "src/main/resources/Java_16_Grammar.y":440 */ + /* "src/main/resources/Java_16_Grammar.y":451 */ { yyval = ((tree.Type.UnannotatedType)(yystack.valueAt (0))).addAnnotations(((Annotations)(yystack.valueAt (1)))); }; break; case 49: /* UnannotatedType: PrimitiveType */ if (yyn == 49) - /* "src/main/resources/Java_16_Grammar.y":444 */ - { yyval = new PrimitiveType(((Token)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":455 */ + { yyval = new PrimitiveType(((Token)(yystack.valueAt (0)))); }; break; case 50: /* UnannotatedType: CompoundName */ if (yyn == 50) - /* "src/main/resources/Java_16_Grammar.y":446 */ - { yyval = new TypeName(((CompoundName)(yystack.valueAt (0))),null); }; + /* "src/main/resources/Java_16_Grammar.y":457 */ + { yyval = new TypeName(((CompoundName)(yystack.valueAt (0))),null); }; break; case 51: /* UnannotatedType: CompoundName TypeArguments */ if (yyn == 51) - /* "src/main/resources/Java_16_Grammar.y":447 */ - { yyval = new TypeName(((CompoundName)(yystack.valueAt (1))),((tree.Type.TypeArguments)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":458 */ + { yyval = new TypeName(((CompoundName)(yystack.valueAt (1))),((tree.Type.TypeArguments)(yystack.valueAt (0)))); }; break; case 52: /* UnannotatedType: UnannotatedType Dim */ if (yyn == 52) - /* "src/main/resources/Java_16_Grammar.y":449 */ - { yyval = ((tree.Type.UnannotatedType)(yystack.valueAt (1))).addDimension(((Dim)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":460 */ + { yyval = ((tree.Type.UnannotatedType)(yystack.valueAt (1))).addDimension(((Dim)(yystack.valueAt (0)))); }; break; case 53: /* PrimitiveType: BYTE */ if (yyn == 53) - /* "src/main/resources/Java_16_Grammar.y":458 */ + /* "src/main/resources/Java_16_Grammar.y":469 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 54: /* PrimitiveType: SHORT */ if (yyn == 54) - /* "src/main/resources/Java_16_Grammar.y":459 */ + /* "src/main/resources/Java_16_Grammar.y":470 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 55: /* PrimitiveType: INT */ if (yyn == 55) - /* "src/main/resources/Java_16_Grammar.y":460 */ + /* "src/main/resources/Java_16_Grammar.y":471 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 56: /* PrimitiveType: LONG */ if (yyn == 56) - /* "src/main/resources/Java_16_Grammar.y":461 */ + /* "src/main/resources/Java_16_Grammar.y":472 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 57: /* PrimitiveType: CHAR */ if (yyn == 57) - /* "src/main/resources/Java_16_Grammar.y":462 */ + /* "src/main/resources/Java_16_Grammar.y":473 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 58: /* PrimitiveType: FLOAT */ if (yyn == 58) - /* "src/main/resources/Java_16_Grammar.y":464 */ + /* "src/main/resources/Java_16_Grammar.y":475 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 59: /* PrimitiveType: DOUBLE */ if (yyn == 59) - /* "src/main/resources/Java_16_Grammar.y":465 */ + /* "src/main/resources/Java_16_Grammar.y":476 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 60: /* PrimitiveType: BOOLEAN */ if (yyn == 60) - /* "src/main/resources/Java_16_Grammar.y":466 */ + /* "src/main/resources/Java_16_Grammar.y":477 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; case 61: /* ClassDeclaration: NormalClassDeclaration */ if (yyn == 61) - /* "src/main/resources/Java_16_Grammar.y":487 */ + /* "src/main/resources/Java_16_Grammar.y":498 */ { yyval = ((ClassDeclaration)(yystack.valueAt (0))); }; break; case 62: /* ClassDeclaration: EnumDeclaration */ if (yyn == 62) - /* "src/main/resources/Java_16_Grammar.y":488 */ + /* "src/main/resources/Java_16_Grammar.y":499 */ { yyval = ((tree.Declaration.Declaration)(yystack.valueAt (0))); }; break; case 63: /* ClassDeclaration: RecordDeclaration */ if (yyn == 63) - /* "src/main/resources/Java_16_Grammar.y":489 */ + /* "src/main/resources/Java_16_Grammar.y":500 */ { yyval = ((tree.Declaration.Declaration)(yystack.valueAt (0))); }; break; case 64: /* NormalClassDeclaration: ModifierSeqOpt CLASS IDENTIFIER TypeParametersOpt ClassExtendsOpt ClassImplementsOpt ClassBody */ if (yyn == 64) - /* "src/main/resources/Java_16_Grammar.y":494 */ + /* "src/main/resources/Java_16_Grammar.y":505 */ { yyval = new NormalClassDeclaration(((Token)(yystack.valueAt (4))),((TypeParameters)(yystack.valueAt (3))),((tree.Type.Type)(yystack.valueAt (2))),((tree.Type.TypeList)(yystack.valueAt (1))),((Declarations)(yystack.valueAt (0)))); }; break; case 65: /* TypeParametersOpt: %empty */ if (yyn == 65) - /* "src/main/resources/Java_16_Grammar.y":498 */ + /* "src/main/resources/Java_16_Grammar.y":509 */ { yyval = null; }; break; case 66: /* TypeParametersOpt: TypeParameters */ if (yyn == 66) - /* "src/main/resources/Java_16_Grammar.y":499 */ + /* "src/main/resources/Java_16_Grammar.y":510 */ { yyval = ((TypeParameters)(yystack.valueAt (0))); }; break; case 67: /* TypeParameters: LESS TypeParameterList GREATER */ if (yyn == 67) - /* "src/main/resources/Java_16_Grammar.y":503 */ + /* "src/main/resources/Java_16_Grammar.y":514 */ { yyval = ((TypeParameters)(yystack.valueAt (1))); }; break; case 68: /* TypeParameterList: TypeParameter */ if (yyn == 68) - /* "src/main/resources/Java_16_Grammar.y":507 */ + /* "src/main/resources/Java_16_Grammar.y":518 */ { yyval = new TypeParameters(((TypeParameter)(yystack.valueAt (0)))); }; break; case 69: /* TypeParameterList: TypeParameterList COMMA TypeParameter */ if (yyn == 69) - /* "src/main/resources/Java_16_Grammar.y":508 */ + /* "src/main/resources/Java_16_Grammar.y":519 */ { yyval = ((TypeParameters)(yystack.valueAt (2))).add(((TypeParameter)(yystack.valueAt (0)))); }; break; case 70: /* TypeParameter: AnnotationSeq TypeParameterTail */ if (yyn == 70) - /* "src/main/resources/Java_16_Grammar.y":518 */ + /* "src/main/resources/Java_16_Grammar.y":529 */ { yyval = new TypeParameter(((Annotations)(yystack.valueAt (1))),((TypeParameterTail)(yystack.valueAt (0)))); }; break; case 71: /* TypeParameter: TypeParameterTail */ if (yyn == 71) - /* "src/main/resources/Java_16_Grammar.y":519 */ + /* "src/main/resources/Java_16_Grammar.y":530 */ { yyval = new TypeParameter(null,((TypeParameterTail)(yystack.valueAt (0)))); }; break; case 72: /* TypeParameterTail: IDENTIFIER */ if (yyn == 72) - /* "src/main/resources/Java_16_Grammar.y":523 */ + /* "src/main/resources/Java_16_Grammar.y":534 */ { yyval = new TypeParameterTail(((Token)(yystack.valueAt (0))),null); }; break; case 73: /* TypeParameterTail: IDENTIFIER EXTENDS AnnotationSeqOpt IDENTIFIER */ if (yyn == 73) - /* "src/main/resources/Java_16_Grammar.y":524 */ + /* "src/main/resources/Java_16_Grammar.y":535 */ { yyval = new TypeParameterTail(((Token)(yystack.valueAt (3))),((Annotations)(yystack.valueAt (1))),((Token)(yystack.valueAt (0)))); }; break; case 74: /* TypeParameterTail: IDENTIFIER EXTENDS ClassTypeList2 */ if (yyn == 74) - /* "src/main/resources/Java_16_Grammar.y":525 */ + /* "src/main/resources/Java_16_Grammar.y":536 */ { yyval = new TypeParameterTail(((Token)(yystack.valueAt (2))),((tree.Type.TypeList)(yystack.valueAt (0)))); }; break; case 75: /* ClassExtendsOpt: %empty */ if (yyn == 75) - /* "src/main/resources/Java_16_Grammar.y":529 */ + /* "src/main/resources/Java_16_Grammar.y":540 */ { yyval = null; }; break; case 76: /* ClassExtendsOpt: EXTENDS Type */ if (yyn == 76) - /* "src/main/resources/Java_16_Grammar.y":530 */ + /* "src/main/resources/Java_16_Grammar.y":541 */ { yyval = ((tree.Type.Type)(yystack.valueAt (0))); }; break; case 77: /* ClassImplementsOpt: %empty */ if (yyn == 77) - /* "src/main/resources/Java_16_Grammar.y":534 */ + /* "src/main/resources/Java_16_Grammar.y":545 */ { yyval = null; }; break; case 78: /* ClassImplementsOpt: IMPLEMENTS ClassTypeList1 */ if (yyn == 78) - /* "src/main/resources/Java_16_Grammar.y":535 */ + /* "src/main/resources/Java_16_Grammar.y":546 */ { yyval = ((tree.Type.TypeList)(yystack.valueAt (0))); }; break; case 79: /* ClassTypeList1: Type */ if (yyn == 79) - /* "src/main/resources/Java_16_Grammar.y":539 */ + /* "src/main/resources/Java_16_Grammar.y":550 */ { yyval = new TypeList(((tree.Type.Type)(yystack.valueAt (0)))); }; break; case 80: /* ClassTypeList1: ClassTypeList1 COMMA Type */ if (yyn == 80) - /* "src/main/resources/Java_16_Grammar.y":540 */ + /* "src/main/resources/Java_16_Grammar.y":551 */ { yyval = ((tree.Type.TypeList)(yystack.valueAt (2))).add(((tree.Type.Type)(yystack.valueAt (0)))); }; break; case 81: /* ClassTypeList2: Type */ if (yyn == 81) - /* "src/main/resources/Java_16_Grammar.y":544 */ + /* "src/main/resources/Java_16_Grammar.y":555 */ { yyval = new TypeList(((tree.Type.Type)(yystack.valueAt (0)))); }; break; case 82: /* ClassTypeList2: ClassTypeList2 AMPERSAND Type */ if (yyn == 82) - /* "src/main/resources/Java_16_Grammar.y":545 */ + /* "src/main/resources/Java_16_Grammar.y":556 */ { yyval = ((tree.Type.TypeList)(yystack.valueAt (2))).add(((tree.Type.Type)(yystack.valueAt (0)))); }; break; case 83: /* ClassBodyOpt: %empty */ if (yyn == 83) - /* "src/main/resources/Java_16_Grammar.y":549 */ + /* "src/main/resources/Java_16_Grammar.y":560 */ { yyval = null; }; break; case 84: /* ClassBodyOpt: ClassBody */ if (yyn == 84) - /* "src/main/resources/Java_16_Grammar.y":550 */ + /* "src/main/resources/Java_16_Grammar.y":561 */ { yyval = ((Declarations)(yystack.valueAt (0))); }; break; case 85: /* ClassBody: LBRACE RBRACE */ if (yyn == 85) - /* "src/main/resources/Java_16_Grammar.y":554 */ + /* "src/main/resources/Java_16_Grammar.y":565 */ { yyval = null; }; break; case 86: /* ClassBody: LBRACE ClassBodyDeclarationSeq RBRACE */ if (yyn == 86) - /* "src/main/resources/Java_16_Grammar.y":555 */ + /* "src/main/resources/Java_16_Grammar.y":566 */ { yyval = ((Declarations)(yystack.valueAt (1))); }; break; case 87: /* ClassBodyDeclarationSeq: ClassBodyDeclaration */ if (yyn == 87) - /* "src/main/resources/Java_16_Grammar.y":559 */ + /* "src/main/resources/Java_16_Grammar.y":570 */ { yyval = new Declarations(((tree.Declaration.Declaration)(yystack.valueAt (0)))); }; break; case 88: /* ClassBodyDeclarationSeq: ClassBodyDeclarationSeq ClassBodyDeclaration */ if (yyn == 88) - /* "src/main/resources/Java_16_Grammar.y":560 */ + /* "src/main/resources/Java_16_Grammar.y":571 */ { yyval = ((Declarations)(yystack.valueAt (1))).add(((tree.Declaration.Declaration)(yystack.valueAt (0)))); }; break; case 89: /* ClassBodyDeclaration: ModifierSeqOpt PureBodyDeclaration */ if (yyn == 89) - /* "src/main/resources/Java_16_Grammar.y":564 */ + /* "src/main/resources/Java_16_Grammar.y":575 */ { yyval = ((tree.Declaration.Declaration)(yystack.valueAt (0))).addModifiers(((Modifiers)(yystack.valueAt (1)))); }; break; case 90: /* ClassBodyDeclaration: Block */ if (yyn == 90) - /* "src/main/resources/Java_16_Grammar.y":565 */ + /* "src/main/resources/Java_16_Grammar.y":576 */ { yyval = new ClassInitializer(((tree.Statement.Block)(yystack.valueAt (0))),false); }; break; case 91: /* ClassBodyDeclaration: STATIC Block */ if (yyn == 91) - /* "src/main/resources/Java_16_Grammar.y":566 */ + /* "src/main/resources/Java_16_Grammar.y":577 */ { yyval = new ClassInitializer(((tree.Statement.Block)(yystack.valueAt (0))),true); }; break; case 92: /* ClassBodyDeclaration: SEMICOLON */ if (yyn == 92) - /* "src/main/resources/Java_16_Grammar.y":567 */ + /* "src/main/resources/Java_16_Grammar.y":578 */ { yyval = null; }; break; case 93: /* PureBodyDeclaration: FieldDeclaration */ if (yyn == 93) - /* "src/main/resources/Java_16_Grammar.y":571 */ + /* "src/main/resources/Java_16_Grammar.y":582 */ { yyval = ((tree.Declaration.Declaration)(yystack.valueAt (0))); }; break; case 94: /* PureBodyDeclaration: MethodDeclaration */ if (yyn == 94) - /* "src/main/resources/Java_16_Grammar.y":572 */ + /* "src/main/resources/Java_16_Grammar.y":583 */ { yyval = ((tree.Declaration.Declaration)(yystack.valueAt (0))); }; break; case 95: /* PureBodyDeclaration: ClassDeclaration */ if (yyn == 95) - /* "src/main/resources/Java_16_Grammar.y":573 */ + /* "src/main/resources/Java_16_Grammar.y":584 */ { yyval = ((ClassDeclaration)(yystack.valueAt (0))); }; break; case 96: /* PureBodyDeclaration: InterfaceDeclaration */ if (yyn == 96) - /* "src/main/resources/Java_16_Grammar.y":574 */ + /* "src/main/resources/Java_16_Grammar.y":585 */ { yyval = ((InterfaceDeclaration)(yystack.valueAt (0))); }; break; case 97: /* PureBodyDeclaration: ConstructorDeclaration */ if (yyn == 97) - /* "src/main/resources/Java_16_Grammar.y":575 */ + /* "src/main/resources/Java_16_Grammar.y":586 */ { yyval = ((ConstructorDeclaration)(yystack.valueAt (0))); }; break; case 98: /* ConstructorDeclaration: ConstructorDeclarator ThrowsOpt ConstructorBody */ if (yyn == 98) - /* "src/main/resources/Java_16_Grammar.y":582 */ + /* "src/main/resources/Java_16_Grammar.y":593 */ { yyval = new ConstructorDeclaration(null,((ConstructorDeclarator)(yystack.valueAt (2))).typeParameters,((ConstructorDeclarator)(yystack.valueAt (2))).formalParameters, ((tree.Type.TypeList)(yystack.valueAt (1))),((ConstructorBody)(yystack.valueAt (0))).invocation,((ConstructorBody)(yystack.valueAt (0))).block); }; break; @@ -1933,56 +1932,56 @@ private int yyaction(int yyn, YYStack yystack, int yylen) case 99: /* ConstructorDeclarator: TypeParametersOpt IDENTIFIER LPAREN FormalParameterList RPAREN */ if (yyn == 99) - /* "src/main/resources/Java_16_Grammar.y":588 */ + /* "src/main/resources/Java_16_Grammar.y":599 */ { yyval = new ConstructorDeclarator(((TypeParameters)(yystack.valueAt (4))),((ParameterDeclarations)(yystack.valueAt (1)))); }; break; case 100: /* ConstructorBody: LBRACE RBRACE */ if (yyn == 100) - /* "src/main/resources/Java_16_Grammar.y":592 */ + /* "src/main/resources/Java_16_Grammar.y":603 */ { yyval = new ConstructorBody(null,null); }; break; case 101: /* ConstructorBody: LBRACE ExplicitConstructorInvocation RBRACE */ if (yyn == 101) - /* "src/main/resources/Java_16_Grammar.y":593 */ + /* "src/main/resources/Java_16_Grammar.y":604 */ { yyval = new ConstructorBody(((ExplicitConstructorInvocation)(yystack.valueAt (1))),null); }; break; case 102: /* ConstructorBody: LBRACE BlockStatementSeq RBRACE */ if (yyn == 102) - /* "src/main/resources/Java_16_Grammar.y":594 */ + /* "src/main/resources/Java_16_Grammar.y":605 */ { yyval = new ConstructorBody(null,new Block(null,((tree.Statement.BlockStatements)(yystack.valueAt (1))))); }; break; case 103: /* ConstructorBody: LBRACE ExplicitConstructorInvocation BlockStatementSeq RBRACE */ if (yyn == 103) - /* "src/main/resources/Java_16_Grammar.y":595 */ + /* "src/main/resources/Java_16_Grammar.y":606 */ { yyval = new ConstructorBody(((ExplicitConstructorInvocation)(yystack.valueAt (2))),new Block(null,((tree.Statement.BlockStatements)(yystack.valueAt (1))))); }; break; case 104: /* ExplicitConstructorInvocation: TypeArgumentsOpt THIS Arguments SEMICOLON */ if (yyn == 104) - /* "src/main/resources/Java_16_Grammar.y":599 */ + /* "src/main/resources/Java_16_Grammar.y":610 */ { yyval = new ExplicitConstructorInvocation(null,((tree.Type.TypeArguments)(yystack.valueAt (3))),false,((tree.Expression.ArgumentList)(yystack.valueAt (1)))); }; break; case 105: /* ExplicitConstructorInvocation: TypeArgumentsOpt SUPER Arguments SEMICOLON */ if (yyn == 105) - /* "src/main/resources/Java_16_Grammar.y":600 */ + /* "src/main/resources/Java_16_Grammar.y":611 */ { yyval = new ExplicitConstructorInvocation(null,((tree.Type.TypeArguments)(yystack.valueAt (3))),true,((tree.Expression.ArgumentList)(yystack.valueAt (1)))); }; break; case 106: /* ExplicitConstructorInvocation: CompoundName DOT TypeArgumentsOpt SUPER Arguments SEMICOLON */ if (yyn == 106) - /* "src/main/resources/Java_16_Grammar.y":601 */ + /* "src/main/resources/Java_16_Grammar.y":612 */ { Expression expr = new SimpleReference(((CompoundName)(yystack.valueAt (5)))); yyval = new ExplicitConstructorInvocation(expr,((tree.Type.TypeArguments)(yystack.valueAt (3))),true,((tree.Expression.ArgumentList)(yystack.valueAt (1)))); }; break; @@ -1990,2124 +1989,2214 @@ private int yyaction(int yyn, YYStack yystack, int yylen) case 107: /* ExplicitConstructorInvocation: Primary DOT TypeArgumentsOpt SUPER Arguments SEMICOLON */ if (yyn == 107) - /* "src/main/resources/Java_16_Grammar.y":603 */ - { yyval = new ExplicitConstructorInvocation(((tree.Expression.Expression)(yystack.valueAt (5))),((tree.Type.TypeArguments)(yystack.valueAt (3))),true,((tree.Expression.ArgumentList)(yystack.valueAt (1)))); }; + /* "src/main/resources/Java_16_Grammar.y":614 */ + { yyval = new ExplicitConstructorInvocation(((Primary)(yystack.valueAt (5))),((tree.Type.TypeArguments)(yystack.valueAt (3))),true,((tree.Expression.ArgumentList)(yystack.valueAt (1)))); }; break; case 108: /* EnumDeclaration: ENUM IDENTIFIER ClassImplementsOpt EnumBody */ if (yyn == 108) - /* "src/main/resources/Java_16_Grammar.y":609 */ + /* "src/main/resources/Java_16_Grammar.y":620 */ { yyval = new EnumDeclaration(((Token)(yystack.valueAt (2))),((tree.Type.TypeList)(yystack.valueAt (1))),((EnumBody)(yystack.valueAt (0)))); }; break; case 109: /* EnumBody: LBRACE EnumConstantListOpt EnumBodyDeclarationsOpt RBRACE */ if (yyn == 109) - /* "src/main/resources/Java_16_Grammar.y":613 */ + /* "src/main/resources/Java_16_Grammar.y":624 */ { yyval = new EnumBody(((Enumerators)(yystack.valueAt (2))),((Declarations)(yystack.valueAt (1)))); }; break; case 110: /* EnumBody: LBRACE EnumConstantListOpt COMMA EnumBodyDeclarationsOpt RBRACE */ if (yyn == 110) - /* "src/main/resources/Java_16_Grammar.y":614 */ + /* "src/main/resources/Java_16_Grammar.y":625 */ { yyval = new EnumBody(((Enumerators)(yystack.valueAt (3))),((Declarations)(yystack.valueAt (1)))); }; break; case 111: /* EnumConstantListOpt: %empty */ if (yyn == 111) - /* "src/main/resources/Java_16_Grammar.y":618 */ + /* "src/main/resources/Java_16_Grammar.y":629 */ { yyval = null; }; break; case 112: /* EnumConstantListOpt: EnumConstantList */ if (yyn == 112) - /* "src/main/resources/Java_16_Grammar.y":619 */ + /* "src/main/resources/Java_16_Grammar.y":630 */ { yyval = ((Enumerators)(yystack.valueAt (0))); }; break; case 113: /* EnumConstantList: EnumConstant */ if (yyn == 113) - /* "src/main/resources/Java_16_Grammar.y":623 */ + /* "src/main/resources/Java_16_Grammar.y":634 */ { yyval = new Enumerators(((Enumerator)(yystack.valueAt (0)))); }; break; case 114: /* EnumConstantList: EnumConstantList COMMA EnumConstant */ if (yyn == 114) - /* "src/main/resources/Java_16_Grammar.y":624 */ + /* "src/main/resources/Java_16_Grammar.y":635 */ { yyval = ((Enumerators)(yystack.valueAt (2))).add(((Enumerator)(yystack.valueAt (0)))); }; break; case 115: /* EnumConstant: AnnotationSeqOpt IDENTIFIER */ if (yyn == 115) - /* "src/main/resources/Java_16_Grammar.y":628 */ + /* "src/main/resources/Java_16_Grammar.y":639 */ { yyval = new Enumerator(((Annotations)(yystack.valueAt (1))),((Token)(yystack.valueAt (0))),null,null); }; break; case 116: /* EnumConstant: AnnotationSeqOpt IDENTIFIER Arguments */ if (yyn == 116) - /* "src/main/resources/Java_16_Grammar.y":629 */ + /* "src/main/resources/Java_16_Grammar.y":640 */ { yyval = new Enumerator(((Annotations)(yystack.valueAt (2))),((Token)(yystack.valueAt (1))),((tree.Expression.ArgumentList)(yystack.valueAt (0))),null); }; break; case 117: /* EnumConstant: AnnotationSeqOpt IDENTIFIER Arguments ClassBody */ if (yyn == 117) - /* "src/main/resources/Java_16_Grammar.y":630 */ + /* "src/main/resources/Java_16_Grammar.y":641 */ { yyval = new Enumerator(((Annotations)(yystack.valueAt (3))),((Token)(yystack.valueAt (2))),((tree.Expression.ArgumentList)(yystack.valueAt (1))),((Declarations)(yystack.valueAt (0)))); }; break; case 118: /* EnumBodyDeclarationsOpt: %empty */ if (yyn == 118) - /* "src/main/resources/Java_16_Grammar.y":634 */ + /* "src/main/resources/Java_16_Grammar.y":645 */ { yyval = null; }; break; case 119: /* EnumBodyDeclarationsOpt: SEMICOLON */ if (yyn == 119) - /* "src/main/resources/Java_16_Grammar.y":635 */ + /* "src/main/resources/Java_16_Grammar.y":646 */ { yyval = null; }; break; case 120: /* EnumBodyDeclarationsOpt: SEMICOLON ClassBodyDeclarationSeq */ if (yyn == 120) - /* "src/main/resources/Java_16_Grammar.y":636 */ + /* "src/main/resources/Java_16_Grammar.y":647 */ { yyval = ((Declarations)(yystack.valueAt (0))); }; break; case 121: /* RecordDeclaration: RECORD IDENTIFIER TypeParametersOpt RecordHeader ClassImplementsOpt RecordBody */ if (yyn == 121) - /* "src/main/resources/Java_16_Grammar.y":642 */ + /* "src/main/resources/Java_16_Grammar.y":653 */ { yyval = null; }; break; case 134: /* FieldDeclaration: UnannotatedType VariableDeclaratorList SEMICOLON */ if (yyn == 134) - /* "src/main/resources/Java_16_Grammar.y":679 */ + /* "src/main/resources/Java_16_Grammar.y":690 */ { yyval = new TypeAndDeclarators(((tree.Type.UnannotatedType)(yystack.valueAt (2))),((VariableDeclarators)(yystack.valueAt (1)))); }; break; case 135: /* VariableDeclaratorList: VariableDeclarator */ if (yyn == 135) - /* "src/main/resources/Java_16_Grammar.y":683 */ + /* "src/main/resources/Java_16_Grammar.y":694 */ { yyval = new VariableDeclarators(((VariableDeclarator)(yystack.valueAt (0)))); }; break; case 136: /* VariableDeclaratorList: VariableDeclaratorList COMMA VariableDeclarator */ if (yyn == 136) - /* "src/main/resources/Java_16_Grammar.y":684 */ + /* "src/main/resources/Java_16_Grammar.y":695 */ { yyval = ((VariableDeclarators)(yystack.valueAt (2))).add(((VariableDeclarator)(yystack.valueAt (0)))); }; break; - case 137: /* VariableDeclarator: IDENTIFIER */ + case 137: /* VariableDeclarator: IDENTIFIER SimpleInitOpt */ if (yyn == 137) - /* "src/main/resources/Java_16_Grammar.y":688 */ - { yyval = new VariableDeclarator(((Token)(yystack.valueAt (0))),null,null); }; + /* "src/main/resources/Java_16_Grammar.y":706 */ + { yyval = new VariableDeclarator(((Token)(yystack.valueAt (1))),null,((Initializer)(yystack.valueAt (0)))); }; break; - case 138: /* VariableDeclarator: IDENTIFIER EQUAL Expression */ + case 138: /* VariableDeclarator: IDENTIFIER Dims ArrayInitOpt */ if (yyn == 138) - /* "src/main/resources/Java_16_Grammar.y":689 */ - { yyval = new VariableDeclarator(((Token)(yystack.valueAt (2))),null,new InitializerSimple(((tree.Expression.Expression)(yystack.valueAt (0))))); }; + /* "src/main/resources/Java_16_Grammar.y":707 */ + { yyval = new VariableDeclarator(((Token)(yystack.valueAt (2))),((Dims)(yystack.valueAt (1))),((Initializer)(yystack.valueAt (0)))); }; break; - case 139: /* VariableDeclarator: IDENTIFIER Dims */ + case 139: /* SimpleInitOpt: %empty */ if (yyn == 139) - /* "src/main/resources/Java_16_Grammar.y":690 */ - { yyval = new VariableDeclarator(((Token)(yystack.valueAt (1))),((Dims)(yystack.valueAt (0))),null); }; + /* "src/main/resources/Java_16_Grammar.y":711 */ + { yyval = null; }; break; - case 140: /* VariableDeclarator: IDENTIFIER Dims EQUAL ArrayInitializer */ + case 140: /* SimpleInitOpt: EQUAL Expression */ if (yyn == 140) - /* "src/main/resources/Java_16_Grammar.y":691 */ - { yyval = new VariableDeclarator(((Token)(yystack.valueAt (3))),((Dims)(yystack.valueAt (2))),((InitializerArray)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":712 */ + { yyval = new InitializerSimple(((tree.Expression.Expression)(yystack.valueAt (0)))); }; break; - case 141: /* ArrayInitializer: LBRACE VariableInitializerListOpt RBRACE */ + case 141: /* SimpleInitOpt: EQUAL ArrayInitializer */ if (yyn == 141) - /* "src/main/resources/Java_16_Grammar.y":695 */ - { yyval = ((InitializerArray)(yystack.valueAt (1))); }; + /* "src/main/resources/Java_16_Grammar.y":713 */ + { yyval = ((InitializerArray)(yystack.valueAt (0))); }; break; - case 142: /* ArrayInitializer: LBRACE VariableInitializerListOpt COMMA RBRACE */ + case 142: /* ArrayInitOpt: %empty */ if (yyn == 142) - /* "src/main/resources/Java_16_Grammar.y":696 */ - { yyval = ((InitializerArray)(yystack.valueAt (2))); }; + /* "src/main/resources/Java_16_Grammar.y":717 */ + { yyval = null; }; break; - case 143: /* VariableInitializerListOpt: %empty */ + case 143: /* ArrayInitOpt: EQUAL ArrayInitializer */ if (yyn == 143) - /* "src/main/resources/Java_16_Grammar.y":700 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":718 */ + { yyval = ((InitializerArray)(yystack.valueAt (0))); }; break; - case 144: /* VariableInitializerListOpt: VariableInitializerList */ + case 144: /* ArrayInitializer: LBRACE VariableInitializerListOpt RBRACE */ if (yyn == 144) - /* "src/main/resources/Java_16_Grammar.y":701 */ - { yyval = ((InitializerArray)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":722 */ + { yyval = ((InitializerArray)(yystack.valueAt (1))); }; break; - case 145: /* VariableInitializerList: VariableInitializer */ + case 145: /* ArrayInitializer: LBRACE VariableInitializerListOpt COMMA RBRACE */ if (yyn == 145) - /* "src/main/resources/Java_16_Grammar.y":705 */ - { yyval = new InitializerArray(((InitializerSimple)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":723 */ + { yyval = ((InitializerArray)(yystack.valueAt (2))); }; break; - case 146: /* VariableInitializerList: VariableInitializerList COMMA VariableInitializer */ + case 146: /* VariableInitializerListOpt: %empty */ if (yyn == 146) - /* "src/main/resources/Java_16_Grammar.y":706 */ - { yyval = ((InitializerArray)(yystack.valueAt (2))).add(((InitializerSimple)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":727 */ + { yyval = null; }; break; - case 147: /* VariableInitializer: Expression */ + case 147: /* VariableInitializerListOpt: VariableInitializerList */ if (yyn == 147) - /* "src/main/resources/Java_16_Grammar.y":710 */ - { yyval = new InitializerSimple(((tree.Expression.Expression)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":728 */ + { yyval = ((InitializerArray)(yystack.valueAt (0))); }; break; - case 148: /* VariableInitializer: ArrayInitializer */ + case 148: /* VariableInitializerList: VariableInitializer */ if (yyn == 148) - /* "src/main/resources/Java_16_Grammar.y":711 */ - { yyval = ((InitializerArray)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":732 */ + { yyval = new InitializerArray(((InitializerSimple)(yystack.valueAt (0)))); }; break; - case 149: /* MethodDeclaration: MethodHeader MethodBody */ + case 149: /* VariableInitializerList: VariableInitializerList COMMA VariableInitializer */ if (yyn == 149) - /* "src/main/resources/Java_16_Grammar.y":717 */ - { yyval = new MethodDeclaration(((MethodHeader)(yystack.valueAt (1))),((tree.Statement.Block)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":733 */ + { yyval = ((InitializerArray)(yystack.valueAt (2))).add(((InitializerSimple)(yystack.valueAt (0)))); }; break; - case 150: /* MethodHeader: TypeParameters Type MethodDeclarator ThrowsOpt */ + case 150: /* VariableInitializer: Expression */ if (yyn == 150) - /* "src/main/resources/Java_16_Grammar.y":727 */ - { yyval = new MethodHeader(((TypeParameters)(yystack.valueAt (3))),((tree.Type.Type)(yystack.valueAt (2))),((MethodDeclarator)(yystack.valueAt (1))),((tree.Type.TypeList)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":737 */ + { yyval = new InitializerSimple(((tree.Expression.Expression)(yystack.valueAt (0)))); }; break; - case 151: /* MethodHeader: TypeParameters AnnotationSeq VOID MethodDeclarator ThrowsOpt */ + case 151: /* VariableInitializer: ArrayInitializer */ if (yyn == 151) - /* "src/main/resources/Java_16_Grammar.y":728 */ - { yyval = new MethodHeader(((TypeParameters)(yystack.valueAt (4))),null,((MethodDeclarator)(yystack.valueAt (1))),((tree.Type.TypeList)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":738 */ + { yyval = ((InitializerArray)(yystack.valueAt (0))); }; break; - case 152: /* MethodHeader: TypeParameters UnannotatedType MethodDeclarator ThrowsOpt */ + case 152: /* MethodDeclaration: MethodHeader MethodBody */ if (yyn == 152) - /* "src/main/resources/Java_16_Grammar.y":729 */ - { yyval = new MethodHeader(((TypeParameters)(yystack.valueAt (3))),((tree.Type.UnannotatedType)(yystack.valueAt (2))),((MethodDeclarator)(yystack.valueAt (1))),((tree.Type.TypeList)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":744 */ + { yyval = new MethodDeclaration(((MethodHeader)(yystack.valueAt (1))),((tree.Statement.Block)(yystack.valueAt (0)))); }; break; - case 153: /* MethodHeader: TypeParameters VOID MethodDeclarator ThrowsOpt */ + case 153: /* MethodHeader: TypeParameters Type MethodDeclarator ThrowsOpt */ if (yyn == 153) - /* "src/main/resources/Java_16_Grammar.y":730 */ - { yyval = new MethodHeader(((TypeParameters)(yystack.valueAt (3))),null,((MethodDeclarator)(yystack.valueAt (1))),((tree.Type.TypeList)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":754 */ + { yyval = new MethodHeader(((TypeParameters)(yystack.valueAt (3))),((tree.Type.Type)(yystack.valueAt (2))),((MethodDeclarator)(yystack.valueAt (1))),((tree.Type.TypeList)(yystack.valueAt (0)))); }; break; - case 154: /* MethodHeader: UnannotatedType MethodDeclarator ThrowsOpt */ + case 154: /* MethodHeader: TypeParameters AnnotationSeq VOID MethodDeclarator ThrowsOpt */ if (yyn == 154) - /* "src/main/resources/Java_16_Grammar.y":731 */ - { yyval = new MethodHeader(null,((tree.Type.UnannotatedType)(yystack.valueAt (2))),((MethodDeclarator)(yystack.valueAt (1))),((tree.Type.TypeList)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":755 */ + { yyval = new MethodHeader(((TypeParameters)(yystack.valueAt (4))),null,((MethodDeclarator)(yystack.valueAt (1))),((tree.Type.TypeList)(yystack.valueAt (0)))); }; break; - case 155: /* MethodHeader: VOID MethodDeclarator ThrowsOpt */ + case 155: /* MethodHeader: TypeParameters UnannotatedType MethodDeclarator ThrowsOpt */ if (yyn == 155) - /* "src/main/resources/Java_16_Grammar.y":732 */ - { yyval = new MethodHeader(null,null,((MethodDeclarator)(yystack.valueAt (1))),((tree.Type.TypeList)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":756 */ + { yyval = new MethodHeader(((TypeParameters)(yystack.valueAt (3))),((tree.Type.UnannotatedType)(yystack.valueAt (2))),((MethodDeclarator)(yystack.valueAt (1))),((tree.Type.TypeList)(yystack.valueAt (0)))); }; break; - case 156: /* MethodDeclarator: IDENTIFIER LPAREN RPAREN DimsOpt */ + case 156: /* MethodHeader: TypeParameters VOID MethodDeclarator ThrowsOpt */ if (yyn == 156) - /* "src/main/resources/Java_16_Grammar.y":741 */ - { yyval = new MethodDeclarator(((Token)(yystack.valueAt (3))),null,((Dims)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":757 */ + { yyval = new MethodHeader(((TypeParameters)(yystack.valueAt (3))),null,((MethodDeclarator)(yystack.valueAt (1))),((tree.Type.TypeList)(yystack.valueAt (0)))); }; break; - case 157: /* MethodDeclarator: IDENTIFIER LPAREN FormalParameterList RPAREN DimsOpt */ + case 157: /* MethodHeader: UnannotatedType MethodDeclarator ThrowsOpt */ if (yyn == 157) - /* "src/main/resources/Java_16_Grammar.y":742 */ - { yyval = new MethodDeclarator(((Token)(yystack.valueAt (4))),((ParameterDeclarations)(yystack.valueAt (2))),((Dims)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":758 */ + { yyval = new MethodHeader(null,((tree.Type.UnannotatedType)(yystack.valueAt (2))),((MethodDeclarator)(yystack.valueAt (1))),((tree.Type.TypeList)(yystack.valueAt (0)))); }; break; - case 158: /* FormalParameterList: FormalParameter */ + case 158: /* MethodHeader: VOID MethodDeclarator ThrowsOpt */ if (yyn == 158) - /* "src/main/resources/Java_16_Grammar.y":756 */ - { yyval = new ParameterDeclarations(((ParameterDeclaration)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":759 */ + { yyval = new MethodHeader(null,null,((MethodDeclarator)(yystack.valueAt (1))),((tree.Type.TypeList)(yystack.valueAt (0)))); }; break; - case 159: /* FormalParameterList: FormalParameterList COMMA FormalParameter */ + case 159: /* MethodDeclarator: IDENTIFIER LPAREN RPAREN DimsOpt */ if (yyn == 159) - /* "src/main/resources/Java_16_Grammar.y":757 */ - { yyval = ((ParameterDeclarations)(yystack.valueAt (2))).add(((ParameterDeclaration)(yystack.valueAt (0))));}; + /* "src/main/resources/Java_16_Grammar.y":768 */ + { yyval = new MethodDeclarator(((Token)(yystack.valueAt (3))),null,((Dims)(yystack.valueAt (0)))); }; break; - case 160: /* FormalParameter: ModifierSeq UnannotatedType FormalParameterTail */ + case 160: /* MethodDeclarator: IDENTIFIER LPAREN FormalParameterList RPAREN DimsOpt */ if (yyn == 160) - /* "src/main/resources/Java_16_Grammar.y":761 */ - { yyval = ParameterDeclaration.create(((Modifiers)(yystack.valueAt (2))),((tree.Type.UnannotatedType)(yystack.valueAt (1))),((ParameterTail)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":769 */ + { yyval = new MethodDeclarator(((Token)(yystack.valueAt (4))),((ParameterDeclarations)(yystack.valueAt (2))),((Dims)(yystack.valueAt (0)))); }; break; - case 161: /* FormalParameter: UnannotatedType FormalParameterTail */ + case 161: /* FormalParameterList: FormalParameter */ if (yyn == 161) - /* "src/main/resources/Java_16_Grammar.y":762 */ - { yyval = ParameterDeclaration.create(null,((tree.Type.UnannotatedType)(yystack.valueAt (1))),((ParameterTail)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":783 */ + { yyval = new ParameterDeclarations(((ParameterDeclaration)(yystack.valueAt (0)))); }; break; - case 162: /* FormalParameterTail: IDENTIFIER DimsOpt */ + case 162: /* FormalParameterList: FormalParameterList COMMA FormalParameter */ if (yyn == 162) - /* "src/main/resources/Java_16_Grammar.y":766 */ - { yyval = new ParameterTail(null,((Token)(yystack.valueAt (1))),((Dims)(yystack.valueAt (0))),false,false); }; + /* "src/main/resources/Java_16_Grammar.y":784 */ + { yyval = ((ParameterDeclarations)(yystack.valueAt (2))).add(((ParameterDeclaration)(yystack.valueAt (0))));}; break; - case 163: /* FormalParameterTail: AnnotationSeqOpt ELLIPSIS IDENTIFIER */ + case 163: /* FormalParameter: ModifierSeq UnannotatedType FormalParameterTail */ if (yyn == 163) - /* "src/main/resources/Java_16_Grammar.y":767 */ - { yyval = new ParameterTail(((Annotations)(yystack.valueAt (2))),((Token)(yystack.valueAt (0))),null,true,false); }; + /* "src/main/resources/Java_16_Grammar.y":788 */ + { yyval = ParameterDeclaration.create(((Modifiers)(yystack.valueAt (2))),((tree.Type.UnannotatedType)(yystack.valueAt (1))),((ParameterTail)(yystack.valueAt (0)))); }; break; - case 164: /* FormalParameterTail: THIS */ + case 164: /* FormalParameter: UnannotatedType FormalParameterTail */ if (yyn == 164) - /* "src/main/resources/Java_16_Grammar.y":768 */ - { yyval = new ParameterTail(null,null,null,false,true); }; + /* "src/main/resources/Java_16_Grammar.y":789 */ + { yyval = ParameterDeclaration.create(null,((tree.Type.UnannotatedType)(yystack.valueAt (1))),((ParameterTail)(yystack.valueAt (0)))); }; break; - case 165: /* FormalParameterTail: IDENTIFIER DOT THIS */ + case 165: /* FormalParameterTail: IDENTIFIER DimsOpt */ if (yyn == 165) - /* "src/main/resources/Java_16_Grammar.y":769 */ - { yyval = new ParameterTail(null,((Token)(yystack.valueAt (2))),null,false,true); }; + /* "src/main/resources/Java_16_Grammar.y":793 */ + { yyval = new ParameterTail(null,((Token)(yystack.valueAt (1))),((Dims)(yystack.valueAt (0))),false,false); }; break; - case 166: /* ThrowsOpt: %empty */ + case 166: /* FormalParameterTail: AnnotationSeqOpt ELLIPSIS IDENTIFIER */ if (yyn == 166) - /* "src/main/resources/Java_16_Grammar.y":781 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":794 */ + { yyval = new ParameterTail(((Annotations)(yystack.valueAt (2))),((Token)(yystack.valueAt (0))),null,true,false); }; break; - case 167: /* ThrowsOpt: THROWS ClassTypeList1 */ + case 167: /* FormalParameterTail: THIS */ if (yyn == 167) - /* "src/main/resources/Java_16_Grammar.y":782 */ - { yyval = ((tree.Type.TypeList)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":795 */ + { yyval = new ParameterTail(null,null,null,false,true); }; break; - case 168: /* MethodBody: Block */ + case 168: /* FormalParameterTail: IDENTIFIER DOT THIS */ if (yyn == 168) - /* "src/main/resources/Java_16_Grammar.y":786 */ - { yyval = ((tree.Statement.Block)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":796 */ + { yyval = new ParameterTail(null,((Token)(yystack.valueAt (2))),null,false,true); }; break; - case 169: /* MethodBody: SEMICOLON */ + case 169: /* ThrowsOpt: %empty */ if (yyn == 169) - /* "src/main/resources/Java_16_Grammar.y":787 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":808 */ + { yyval = null; }; break; - case 170: /* DimsOpt: %empty */ + case 170: /* ThrowsOpt: THROWS ClassTypeList1 */ if (yyn == 170) - /* "src/main/resources/Java_16_Grammar.y":793 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":809 */ + { yyval = ((tree.Type.TypeList)(yystack.valueAt (0))); }; break; - case 171: /* DimsOpt: Dims */ + case 171: /* MethodBody: Block */ if (yyn == 171) - /* "src/main/resources/Java_16_Grammar.y":794 */ - { yyval = ((Dims)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":813 */ + { yyval = ((tree.Statement.Block)(yystack.valueAt (0))); }; break; - case 172: /* Dims: Dim */ + case 172: /* MethodBody: SEMICOLON */ if (yyn == 172) - /* "src/main/resources/Java_16_Grammar.y":798 */ - { yyval = new Dims(((Dim)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":814 */ + { yyval = null; }; break; - case 173: /* Dims: Dims Dim */ + case 173: /* DimsOpt: %empty */ if (yyn == 173) - /* "src/main/resources/Java_16_Grammar.y":799 */ - { yyval = ((Dims)(yystack.valueAt (1))).add(((Dim)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":820 */ + { yyval = null; }; break; - case 174: /* Dim: AnnotationSeq LBRACKET RBRACKET */ + case 174: /* DimsOpt: Dims */ if (yyn == 174) - /* "src/main/resources/Java_16_Grammar.y":803 */ - { yyval = new Dim(((Annotations)(yystack.valueAt (2)))); }; + /* "src/main/resources/Java_16_Grammar.y":821 */ + { yyval = ((Dims)(yystack.valueAt (0))); }; break; - case 175: /* Dim: LBRACKET RBRACKET */ + case 175: /* Dims: Dim */ if (yyn == 175) - /* "src/main/resources/Java_16_Grammar.y":804 */ - { yyval = new Dim(null); }; + /* "src/main/resources/Java_16_Grammar.y":825 */ + { yyval = new Dims(((Dim)(yystack.valueAt (0)))); }; break; - case 176: /* InterfaceDeclaration: NormalInterfaceDeclaration */ + case 176: /* Dims: Dims Dim */ if (yyn == 176) - /* "src/main/resources/Java_16_Grammar.y":810 */ - { yyval = ((InterfaceDeclaration)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":826 */ + { yyval = ((Dims)(yystack.valueAt (1))).add(((Dim)(yystack.valueAt (0)))); }; break; - case 177: /* InterfaceDeclaration: AnnotationInterfaceDeclaration */ + case 177: /* Dim: LBRACKET RBRACKET */ if (yyn == 177) - /* "src/main/resources/Java_16_Grammar.y":811 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":839 */ + { yyval = new Dim(null,null); }; break; - case 178: /* NormalInterfaceDeclaration: INTERFACE IDENTIFIER TypeParametersOpt InterfaceExtendsOpt InterfaceBody */ + case 178: /* Dim: AnnotationSeq LBRACKET RBRACKET */ if (yyn == 178) - /* "src/main/resources/Java_16_Grammar.y":816 */ - { yyval = new NormalInterfaceDeclaration(((Token)(yystack.valueAt (3))),((TypeParameters)(yystack.valueAt (2))),((tree.Type.TypeList)(yystack.valueAt (1))),((Declarations)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":840 */ + { yyval = new Dim(((Annotations)(yystack.valueAt (2))),null); }; break; - case 179: /* InterfaceExtendsOpt: %empty */ + case 179: /* Dim: LBRACKET Expression RBRACKET */ if (yyn == 179) - /* "src/main/resources/Java_16_Grammar.y":820 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":841 */ + { yyval = new Dim(null,((tree.Expression.Expression)(yystack.valueAt (1)))); }; break; - case 180: /* InterfaceExtendsOpt: InterfaceExtends */ + case 180: /* Dim: AnnotationSeq LBRACKET Expression RBRACKET */ if (yyn == 180) - /* "src/main/resources/Java_16_Grammar.y":821 */ - { yyval = ((tree.Type.TypeList)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":842 */ + { yyval = new Dim(((Annotations)(yystack.valueAt (3))),((tree.Expression.Expression)(yystack.valueAt (1)))); }; break; - case 181: /* InterfaceExtends: EXTENDS Type */ + case 181: /* InterfaceDeclaration: NormalInterfaceDeclaration */ if (yyn == 181) - /* "src/main/resources/Java_16_Grammar.y":825 */ - { yyval = new TypeList(((tree.Type.Type)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":848 */ + { yyval = ((InterfaceDeclaration)(yystack.valueAt (0))); }; break; - case 182: /* InterfaceExtends: InterfaceExtends COMMA Type */ + case 182: /* InterfaceDeclaration: AnnotationInterfaceDeclaration */ if (yyn == 182) - /* "src/main/resources/Java_16_Grammar.y":826 */ - { yyval = ((tree.Type.TypeList)(yystack.valueAt (2))).add(((tree.Type.Type)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":849 */ + { yyval = null; }; break; - case 183: /* InterfaceBody: LBRACE RBRACE */ + case 183: /* NormalInterfaceDeclaration: INTERFACE IDENTIFIER TypeParametersOpt InterfaceExtendsOpt InterfaceBody */ if (yyn == 183) - /* "src/main/resources/Java_16_Grammar.y":830 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":854 */ + { yyval = new NormalInterfaceDeclaration(((Token)(yystack.valueAt (3))),((TypeParameters)(yystack.valueAt (2))),((tree.Type.TypeList)(yystack.valueAt (1))),((Declarations)(yystack.valueAt (0)))); }; break; - case 184: /* InterfaceBody: LBRACE InterfaceMemberDeclarationSeq RBRACE */ + case 184: /* InterfaceExtendsOpt: %empty */ if (yyn == 184) - /* "src/main/resources/Java_16_Grammar.y":831 */ - { yyval = ((Declarations)(yystack.valueAt (1))); }; + /* "src/main/resources/Java_16_Grammar.y":858 */ + { yyval = null; }; break; - case 185: /* InterfaceMemberDeclarationSeq: ModifierSeqOpt InterfaceMemberDeclaration */ + case 185: /* InterfaceExtendsOpt: InterfaceExtends */ if (yyn == 185) - /* "src/main/resources/Java_16_Grammar.y":835 */ - { yyval = new Declarations(((tree.Declaration.Declaration)(yystack.valueAt (0))).addModifiers(((Modifiers)(yystack.valueAt (1))))); }; + /* "src/main/resources/Java_16_Grammar.y":859 */ + { yyval = ((tree.Type.TypeList)(yystack.valueAt (0))); }; break; - case 186: /* InterfaceMemberDeclarationSeq: InterfaceMemberDeclarationSeq ModifierSeqOpt InterfaceMemberDeclaration */ + case 186: /* InterfaceExtends: EXTENDS Type */ if (yyn == 186) - /* "src/main/resources/Java_16_Grammar.y":836 */ - { yyval = ((Declarations)(yystack.valueAt (2))).add(((tree.Declaration.Declaration)(yystack.valueAt (0))).addModifiers(((Modifiers)(yystack.valueAt (1))))); }; + /* "src/main/resources/Java_16_Grammar.y":863 */ + { yyval = new TypeList(((tree.Type.Type)(yystack.valueAt (0)))); }; break; - case 187: /* InterfaceMemberDeclaration: ConstantDeclaration */ + case 187: /* InterfaceExtends: InterfaceExtends COMMA Type */ if (yyn == 187) - /* "src/main/resources/Java_16_Grammar.y":840 */ - { yyval = ((tree.Declaration.Declaration)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":864 */ + { yyval = ((tree.Type.TypeList)(yystack.valueAt (2))).add(((tree.Type.Type)(yystack.valueAt (0)))); }; break; - case 188: /* InterfaceMemberDeclaration: InterfaceMethodDeclaration */ + case 188: /* InterfaceBody: LBRACE RBRACE */ if (yyn == 188) - /* "src/main/resources/Java_16_Grammar.y":841 */ - { yyval = ((tree.Declaration.Declaration)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":868 */ + { yyval = null; }; break; - case 189: /* InterfaceMemberDeclaration: ClassDeclaration */ + case 189: /* InterfaceBody: LBRACE InterfaceMemberDeclarationSeq RBRACE */ if (yyn == 189) - /* "src/main/resources/Java_16_Grammar.y":842 */ - { yyval = ((ClassDeclaration)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":869 */ + { yyval = ((Declarations)(yystack.valueAt (1))); }; break; - case 190: /* InterfaceMemberDeclaration: InterfaceDeclaration */ + case 190: /* InterfaceMemberDeclarationSeq: ModifierSeqOpt InterfaceMemberDeclaration */ if (yyn == 190) - /* "src/main/resources/Java_16_Grammar.y":843 */ - { yyval = ((InterfaceDeclaration)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":873 */ + { yyval = new Declarations(((tree.Declaration.Declaration)(yystack.valueAt (0))).addModifiers(((Modifiers)(yystack.valueAt (1))))); }; break; - case 191: /* ConstantDeclaration: Type VariableDeclaratorList SEMICOLON */ + case 191: /* InterfaceMemberDeclarationSeq: InterfaceMemberDeclarationSeq ModifierSeqOpt InterfaceMemberDeclaration */ if (yyn == 191) - /* "src/main/resources/Java_16_Grammar.y":847 */ - { yyval = new TypeAndDeclarators(((tree.Type.Type)(yystack.valueAt (2))),((VariableDeclarators)(yystack.valueAt (1)))); }; + /* "src/main/resources/Java_16_Grammar.y":874 */ + { yyval = ((Declarations)(yystack.valueAt (2))).add(((tree.Declaration.Declaration)(yystack.valueAt (0))).addModifiers(((Modifiers)(yystack.valueAt (1))))); }; break; - case 192: /* InterfaceMethodDeclaration: MethodHeader MethodBody */ + case 192: /* InterfaceMemberDeclaration: ConstantDeclaration */ if (yyn == 192) - /* "src/main/resources/Java_16_Grammar.y":851 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":878 */ + { yyval = ((tree.Declaration.Declaration)(yystack.valueAt (0))); }; break; - case 193: /* AnnotationInterfaceDeclaration: AT INTERFACE IDENTIFIER AnnotationInterfaceBody */ + case 193: /* InterfaceMemberDeclaration: InterfaceMethodDeclaration */ if (yyn == 193) - /* "src/main/resources/Java_16_Grammar.y":855 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":879 */ + { yyval = ((tree.Declaration.Declaration)(yystack.valueAt (0))); }; break; - case 205: /* Block: LBRACE RBRACE */ - if (yyn == 205) - /* "src/main/resources/Java_16_Grammar.y":888 */ - { yyval = null; }; + case 194: /* InterfaceMemberDeclaration: ClassDeclaration */ + if (yyn == 194) + /* "src/main/resources/Java_16_Grammar.y":880 */ + { yyval = ((ClassDeclaration)(yystack.valueAt (0))); }; break; - case 206: /* Block: LBRACE BlockStatementSeq RBRACE */ - if (yyn == 206) - /* "src/main/resources/Java_16_Grammar.y":889 */ - { yyval = new Block(null,((tree.Statement.BlockStatements)(yystack.valueAt (1)))); }; + case 195: /* InterfaceMemberDeclaration: InterfaceDeclaration */ + if (yyn == 195) + /* "src/main/resources/Java_16_Grammar.y":881 */ + { yyval = ((InterfaceDeclaration)(yystack.valueAt (0))); }; break; - case 207: /* BlockStatementSeq: BlockStatement */ - if (yyn == 207) - /* "src/main/resources/Java_16_Grammar.y":893 */ - { yyval = new BlockStatements(((tree.Statement.BlockStatement)(yystack.valueAt (0)))); }; + case 196: /* ConstantDeclaration: Type VariableDeclaratorList SEMICOLON */ + if (yyn == 196) + /* "src/main/resources/Java_16_Grammar.y":885 */ + { yyval = new TypeAndDeclarators(((tree.Type.Type)(yystack.valueAt (2))),((VariableDeclarators)(yystack.valueAt (1)))); }; break; - case 208: /* BlockStatementSeq: BlockStatementSeq BlockStatement */ - if (yyn == 208) - /* "src/main/resources/Java_16_Grammar.y":894 */ - { yyval = ((tree.Statement.BlockStatements)(yystack.valueAt (1))).add(((tree.Statement.BlockStatement)(yystack.valueAt (0)))); }; + case 197: /* InterfaceMethodDeclaration: MethodHeader MethodBody */ + if (yyn == 197) + /* "src/main/resources/Java_16_Grammar.y":889 */ + { yyval = null; }; break; - case 209: /* BlockStatement: ModifierSeqOpt ClassDeclaration */ - if (yyn == 209) - /* "src/main/resources/Java_16_Grammar.y":910 */ - { yyval = new BlockStatement(((ClassDeclaration)(yystack.valueAt (0))).addModifiers(((Modifiers)(yystack.valueAt (1))))); }; + case 198: /* AnnotationInterfaceDeclaration: AT INTERFACE IDENTIFIER AnnotationInterfaceBody */ + if (yyn == 198) + /* "src/main/resources/Java_16_Grammar.y":893 */ + { yyval = null; }; break; - case 210: /* BlockStatement: ModifierSeqOpt NormalInterfaceDeclaration */ + case 210: /* Block: LBRACE RBRACE */ if (yyn == 210) - /* "src/main/resources/Java_16_Grammar.y":911 */ - { yyval = new BlockStatement(((InterfaceDeclaration)(yystack.valueAt (0))).addModifiers(((Modifiers)(yystack.valueAt (1))))); }; + /* "src/main/resources/Java_16_Grammar.y":926 */ + { yyval = null; }; break; - case 211: /* BlockStatement: ModifierSeq LocalVariableDeclaration SEMICOLON */ + case 211: /* Block: LBRACE BlockStatementSeq RBRACE */ if (yyn == 211) - /* "src/main/resources/Java_16_Grammar.y":913 */ - { yyval = new BlockStatement(((tree.Declaration.Declaration)(yystack.valueAt (1))).addModifiers(((Modifiers)(yystack.valueAt (2))))); }; + /* "src/main/resources/Java_16_Grammar.y":927 */ + { yyval = new Block(null,((tree.Statement.BlockStatements)(yystack.valueAt (1)))); }; break; - case 212: /* BlockStatement: LocalVariableDeclaration SEMICOLON */ + case 212: /* BlockStatementSeq: BlockStatement */ if (yyn == 212) - /* "src/main/resources/Java_16_Grammar.y":915 */ - { yyval = new BlockStatement(((tree.Declaration.Declaration)(yystack.valueAt (1)))); }; + /* "src/main/resources/Java_16_Grammar.y":931 */ + { yyval = new BlockStatements(((tree.Statement.BlockStatement)(yystack.valueAt (0)))); }; break; - case 213: /* BlockStatement: Statement */ + case 213: /* BlockStatementSeq: BlockStatementSeq BlockStatement */ if (yyn == 213) - /* "src/main/resources/Java_16_Grammar.y":916 */ - { yyval = new BlockStatement(((tree.Statement.Statement)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":932 */ + { yyval = ((tree.Statement.BlockStatements)(yystack.valueAt (1))).add(((tree.Statement.BlockStatement)(yystack.valueAt (0)))); }; break; - case 214: /* LocalVariableDeclaration: UnannotatedType VariableDeclaratorList */ + case 214: /* BlockStatement: ModifierSeqOpt ClassDeclaration */ if (yyn == 214) - /* "src/main/resources/Java_16_Grammar.y":920 */ - { yyval = new TypeAndDeclarators(((tree.Type.UnannotatedType)(yystack.valueAt (1))),((VariableDeclarators)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":948 */ + { yyval = new BlockStatement(((ClassDeclaration)(yystack.valueAt (0))).addModifiers(((Modifiers)(yystack.valueAt (1))))); }; break; - case 215: /* LocalVariableDeclaration: VAR VariableDeclaratorList */ + case 215: /* BlockStatement: ModifierSeqOpt NormalInterfaceDeclaration */ if (yyn == 215) - /* "src/main/resources/Java_16_Grammar.y":921 */ - { yyval = new TypeAndDeclarators(null,((VariableDeclarators)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":949 */ + { yyval = new BlockStatement(((InterfaceDeclaration)(yystack.valueAt (0))).addModifiers(((Modifiers)(yystack.valueAt (1))))); }; break; - case 216: /* Statement: SimpleStatement */ + case 216: /* BlockStatement: ModifierSeq LocalVariableDeclaration SEMICOLON */ if (yyn == 216) - /* "src/main/resources/Java_16_Grammar.y":925 */ - { yyval = ((tree.Statement.Statement)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":951 */ + { yyval = new BlockStatement(((tree.Declaration.Declaration)(yystack.valueAt (1))).addModifiers(((Modifiers)(yystack.valueAt (2))))); }; break; - case 217: /* Statement: LabeledStatement */ + case 217: /* BlockStatement: LocalVariableDeclaration SEMICOLON */ if (yyn == 217) - /* "src/main/resources/Java_16_Grammar.y":926 */ - { yyval = ((tree.Statement.Statement)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":953 */ + { yyval = new BlockStatement(((tree.Declaration.Declaration)(yystack.valueAt (1)))); }; break; - case 218: /* Statement: IfThenElseStatement */ + case 218: /* BlockStatement: Statement */ if (yyn == 218) - /* "src/main/resources/Java_16_Grammar.y":927 */ - { yyval = ((tree.Statement.Statement)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":954 */ + { yyval = new BlockStatement(((tree.Statement.Statement)(yystack.valueAt (0)))); }; break; - case 219: /* Statement: WhileStatement */ + case 219: /* LocalVariableDeclaration: UnannotatedType VariableDeclaratorList */ if (yyn == 219) - /* "src/main/resources/Java_16_Grammar.y":928 */ - { yyval = ((tree.Statement.Statement)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":958 */ + { yyval = new TypeAndDeclarators(((tree.Type.UnannotatedType)(yystack.valueAt (1))),((VariableDeclarators)(yystack.valueAt (0)))); /*$$.report(30);*/ }; break; - case 220: /* Statement: ForStatement */ + case 220: /* LocalVariableDeclaration: VAR VariableDeclaratorList */ if (yyn == 220) - /* "src/main/resources/Java_16_Grammar.y":929 */ - { yyval = ((tree.Statement.Statement)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":959 */ + { yyval = new TypeAndDeclarators(null,((VariableDeclarators)(yystack.valueAt (0)))); }; break; - case 221: /* SimpleStatement: Block */ + case 221: /* Statement: SimpleStatement */ if (yyn == 221) - /* "src/main/resources/Java_16_Grammar.y":933 */ - { yyval = ((tree.Statement.Block)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":963 */ + { yyval = ((tree.Statement.Statement)(yystack.valueAt (0))); }; break; - case 222: /* SimpleStatement: SEMICOLON */ + case 222: /* Statement: LabeledStatement */ if (yyn == 222) - /* "src/main/resources/Java_16_Grammar.y":934 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":964 */ + { yyval = ((tree.Statement.Statement)(yystack.valueAt (0))); }; break; - case 223: /* SimpleStatement: StatementExpression SEMICOLON */ + case 223: /* Statement: IfThenElseStatement */ if (yyn == 223) - /* "src/main/resources/Java_16_Grammar.y":935 */ - { yyval = ((StatementExpression)(yystack.valueAt (1))); }; + /* "src/main/resources/Java_16_Grammar.y":965 */ + { yyval = ((tree.Statement.Statement)(yystack.valueAt (0))); }; break; - case 224: /* SimpleStatement: ASSERT Expression SEMICOLON */ + case 224: /* Statement: WhileStatement */ if (yyn == 224) - /* "src/main/resources/Java_16_Grammar.y":937 */ - { yyval = new Assert(null,((tree.Expression.Expression)(yystack.valueAt (1))),null); }; + /* "src/main/resources/Java_16_Grammar.y":966 */ + { yyval = ((tree.Statement.Statement)(yystack.valueAt (0))); }; break; - case 225: /* SimpleStatement: ASSERT Expression COLON Expression SEMICOLON */ + case 225: /* Statement: ForStatement */ if (yyn == 225) - /* "src/main/resources/Java_16_Grammar.y":938 */ - { yyval = new Assert(null,((tree.Expression.Expression)(yystack.valueAt (3))),((tree.Expression.Expression)(yystack.valueAt (1)))); }; + /* "src/main/resources/Java_16_Grammar.y":967 */ + { yyval = ((tree.Statement.Statement)(yystack.valueAt (0))); }; break; - case 226: /* SimpleStatement: SWITCH LPAREN Expression RPAREN SwitchBlock */ + case 226: /* SimpleStatement: Block */ if (yyn == 226) - /* "src/main/resources/Java_16_Grammar.y":940 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":971 */ + { yyval = ((tree.Statement.Block)(yystack.valueAt (0))); }; break; - case 227: /* SimpleStatement: DO Statement WHILE LPAREN Expression RPAREN SEMICOLON */ + case 227: /* SimpleStatement: SEMICOLON */ if (yyn == 227) - /* "src/main/resources/Java_16_Grammar.y":941 */ - { yyval = new Do(null,((tree.Statement.Statement)(yystack.valueAt (5))),((tree.Expression.Expression)(yystack.valueAt (2)))); }; + /* "src/main/resources/Java_16_Grammar.y":972 */ + { yyval = null; }; break; - case 228: /* SimpleStatement: BREAK SEMICOLON */ + case 228: /* SimpleStatement: StatementExpression SEMICOLON */ if (yyn == 228) - /* "src/main/resources/Java_16_Grammar.y":943 */ - { yyval = new Break(null,null); }; + /* "src/main/resources/Java_16_Grammar.y":973 */ + { yyval = ((StatementExpression)(yystack.valueAt (1))); }; break; - case 229: /* SimpleStatement: BREAK IDENTIFIER SEMICOLON */ + case 229: /* SimpleStatement: ASSERT Expression SEMICOLON */ if (yyn == 229) - /* "src/main/resources/Java_16_Grammar.y":944 */ - { yyval = new Break(null,((Token)(yystack.valueAt (1)))); }; + /* "src/main/resources/Java_16_Grammar.y":975 */ + { yyval = new Assert(null,((tree.Expression.Expression)(yystack.valueAt (1))),null); }; break; - case 230: /* SimpleStatement: CONTINUE SEMICOLON */ + case 230: /* SimpleStatement: ASSERT Expression COLON Expression SEMICOLON */ if (yyn == 230) - /* "src/main/resources/Java_16_Grammar.y":946 */ - { yyval = new Continue(null,null); }; + /* "src/main/resources/Java_16_Grammar.y":976 */ + { yyval = new Assert(null,((tree.Expression.Expression)(yystack.valueAt (3))),((tree.Expression.Expression)(yystack.valueAt (1)))); }; break; - case 231: /* SimpleStatement: CONTINUE IDENTIFIER SEMICOLON */ + case 231: /* SimpleStatement: SWITCH LPAREN Expression RPAREN SwitchBlock */ if (yyn == 231) - /* "src/main/resources/Java_16_Grammar.y":947 */ - { yyval = new Continue(null,((Token)(yystack.valueAt (1)))); }; + /* "src/main/resources/Java_16_Grammar.y":978 */ + { yyval = null; }; break; - case 232: /* SimpleStatement: RETURN SEMICOLON */ + case 232: /* SimpleStatement: DO Statement WHILE LPAREN Expression RPAREN SEMICOLON */ if (yyn == 232) - /* "src/main/resources/Java_16_Grammar.y":949 */ - { yyval = new Return(null,null); }; + /* "src/main/resources/Java_16_Grammar.y":979 */ + { yyval = new Do(null,((tree.Statement.Statement)(yystack.valueAt (5))),((tree.Expression.Expression)(yystack.valueAt (2)))); }; break; - case 233: /* SimpleStatement: RETURN Expression SEMICOLON */ + case 233: /* SimpleStatement: BREAK SEMICOLON */ if (yyn == 233) - /* "src/main/resources/Java_16_Grammar.y":950 */ - { yyval = new Return(null,((tree.Expression.Expression)(yystack.valueAt (1)))); }; + /* "src/main/resources/Java_16_Grammar.y":981 */ + { yyval = new Break(null,null); }; break; - case 234: /* SimpleStatement: SYNCHRONIZED LPAREN Expression RPAREN Block */ + case 234: /* SimpleStatement: BREAK IDENTIFIER SEMICOLON */ if (yyn == 234) - /* "src/main/resources/Java_16_Grammar.y":952 */ - { yyval = new Synchronized(null,((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Statement.Block)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":982 */ + { yyval = new Break(null,((Token)(yystack.valueAt (1)))); }; break; - case 235: /* SimpleStatement: THROW Expression SEMICOLON */ + case 235: /* SimpleStatement: CONTINUE SEMICOLON */ if (yyn == 235) - /* "src/main/resources/Java_16_Grammar.y":954 */ - { yyval = new Throw(null,((tree.Expression.Expression)(yystack.valueAt (1)))); }; + /* "src/main/resources/Java_16_Grammar.y":984 */ + { yyval = new Continue(null,null); }; break; - case 236: /* SimpleStatement: YIELD Expression SEMICOLON */ + case 236: /* SimpleStatement: CONTINUE IDENTIFIER SEMICOLON */ if (yyn == 236) - /* "src/main/resources/Java_16_Grammar.y":955 */ - { yyval = new Yield(null,((tree.Expression.Expression)(yystack.valueAt (1)))); }; + /* "src/main/resources/Java_16_Grammar.y":985 */ + { yyval = new Continue(null,((Token)(yystack.valueAt (1)))); }; break; - case 237: /* SimpleStatement: TRY Block Catches */ + case 237: /* SimpleStatement: RETURN SEMICOLON */ if (yyn == 237) - /* "src/main/resources/Java_16_Grammar.y":958 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":987 */ + { yyval = new Return(null,null); }; break; - case 238: /* SimpleStatement: TRY Block Catches Finally */ + case 238: /* SimpleStatement: RETURN Expression SEMICOLON */ if (yyn == 238) - /* "src/main/resources/Java_16_Grammar.y":959 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":988 */ + { yyval = new Return(null,((tree.Expression.Expression)(yystack.valueAt (1)))); }; break; - case 239: /* SimpleStatement: TRY Block Finally */ + case 239: /* SimpleStatement: SYNCHRONIZED LPAREN Expression RPAREN Block */ if (yyn == 239) - /* "src/main/resources/Java_16_Grammar.y":960 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":990 */ + { yyval = new Synchronized(null,((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Statement.Block)(yystack.valueAt (0)))); }; break; - case 240: /* SimpleStatement: TRY ResourceSpecification Block CatchesOpt FinallyOpt */ + case 240: /* SimpleStatement: THROW Expression SEMICOLON */ if (yyn == 240) - /* "src/main/resources/Java_16_Grammar.y":962 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":992 */ + { yyval = new Throw(null,((tree.Expression.Expression)(yystack.valueAt (1)))); }; break; - case 241: /* SimpleStatement: error SEMICOLON */ + case 241: /* SimpleStatement: YIELD Expression SEMICOLON */ if (yyn == 241) - /* "src/main/resources/Java_16_Grammar.y":963 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":993 */ + { yyval = new Yield(null,((tree.Expression.Expression)(yystack.valueAt (1)))); }; break; - case 242: /* LabeledStatement: IDENTIFIER COLON Statement */ + case 242: /* SimpleStatement: TRY Block Catches */ if (yyn == 242) - /* "src/main/resources/Java_16_Grammar.y":967 */ - { yyval = ((tree.Statement.Statement)(yystack.valueAt (0))).addLabel(((Token)(yystack.valueAt (2)))); }; + /* "src/main/resources/Java_16_Grammar.y":996 */ + { yyval = null; }; break; - case 243: /* StatementExpression: Assignment */ + case 243: /* SimpleStatement: TRY Block Catches Finally */ if (yyn == 243) - /* "src/main/resources/Java_16_Grammar.y":971 */ - { yyval = new StatementExpression(null,((tree.Expression.Expression)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":997 */ + { yyval = null; }; break; - case 244: /* StatementExpression: PreIncrementExpression */ + case 244: /* SimpleStatement: TRY Block Finally */ if (yyn == 244) - /* "src/main/resources/Java_16_Grammar.y":972 */ - { yyval = new StatementExpression(null,((UnaryPrefix)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":998 */ + { yyval = null; }; break; - case 245: /* StatementExpression: PreDecrementExpression */ + case 245: /* SimpleStatement: TRY ResourceSpecification Block CatchesOpt FinallyOpt */ if (yyn == 245) - /* "src/main/resources/Java_16_Grammar.y":973 */ - { yyval = new StatementExpression(null,((UnaryPrefix)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1000 */ + { yyval = null; }; break; - case 246: /* StatementExpression: PostIncrementExpression */ + case 246: /* SimpleStatement: error SEMICOLON */ if (yyn == 246) - /* "src/main/resources/Java_16_Grammar.y":974 */ - { yyval = new StatementExpression(null,((UnaryPostfix)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1001 */ + { yyval = null; }; break; - case 247: /* StatementExpression: PostDecrementExpression */ + case 247: /* LabeledStatement: IDENTIFIER COLON Statement */ if (yyn == 247) - /* "src/main/resources/Java_16_Grammar.y":975 */ - { yyval = new StatementExpression(null,((UnaryPostfix)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1005 */ + { yyval = ((tree.Statement.Statement)(yystack.valueAt (0))).addLabel(((Token)(yystack.valueAt (2)))); }; break; - case 248: /* StatementExpression: MethodInvocation */ + case 248: /* StatementExpression: Assignment */ if (yyn == 248) - /* "src/main/resources/Java_16_Grammar.y":976 */ - { yyval = new StatementExpression(null,((tree.Expression.Expression)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1009 */ + { yyval = new StatementExpression(null,((tree.Expression.Expression)(yystack.valueAt (0)))); }; break; - case 249: /* StatementExpression: ClassInstanceCreationExpression */ + case 249: /* StatementExpression: PreIncrementExpression */ if (yyn == 249) - /* "src/main/resources/Java_16_Grammar.y":977 */ - { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":1010 */ + { yyval = new StatementExpression(null,((UnaryPrefix)(yystack.valueAt (0)))); }; break; - case 250: /* IfThenElseStatement: IF LPAREN Expression RPAREN Statement ElsePartOpt */ + case 250: /* StatementExpression: PreDecrementExpression */ if (yyn == 250) - /* "src/main/resources/Java_16_Grammar.y":981 */ - { yyval = new IfThenElse(null,((tree.Expression.Expression)(yystack.valueAt (3))),((tree.Statement.Statement)(yystack.valueAt (1))),((tree.Statement.Statement)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1011 */ + { yyval = new StatementExpression(null,((UnaryPrefix)(yystack.valueAt (0)))); }; break; - case 251: /* ElsePartOpt: %empty */ + case 251: /* StatementExpression: PostIncrementExpression */ if (yyn == 251) - /* "src/main/resources/Java_16_Grammar.y":985 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":1012 */ + { yyval = new StatementExpression(null,((UnaryPostfix)(yystack.valueAt (0)))); }; break; - case 252: /* ElsePartOpt: ELSE Statement */ + case 252: /* StatementExpression: PostDecrementExpression */ if (yyn == 252) - /* "src/main/resources/Java_16_Grammar.y":986 */ - { yyval = ((tree.Statement.Statement)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":1013 */ + { yyval = new StatementExpression(null,((UnaryPostfix)(yystack.valueAt (0)))); }; break; - case 253: /* SwitchBlock: LBRACE RBRACE */ + case 253: /* StatementExpression: MethodInvocation */ if (yyn == 253) - /* "src/main/resources/Java_16_Grammar.y":990 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":1014 */ + { yyval = new StatementExpression(null,((tree.Expression.Expression)(yystack.valueAt (0)))); }; break; - case 254: /* SwitchBlock: LBRACE SwitchRuleSeq RBRACE */ + case 254: /* StatementExpression: ClassInstanceCreationExpression */ if (yyn == 254) - /* "src/main/resources/Java_16_Grammar.y":991 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":1015 */ + { yyval = new StatementExpression(null,((Primary)(yystack.valueAt (0)))); }; break; - case 255: /* SwitchBlock: LBRACE SwitchBlockStatementGroupSeq RBRACE */ + case 255: /* IfThenElseStatement: IF LPAREN Expression RPAREN Statement ElsePartOpt */ if (yyn == 255) - /* "src/main/resources/Java_16_Grammar.y":992 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":1019 */ + { yyval = new IfThenElse(null,((tree.Expression.Expression)(yystack.valueAt (3))),((tree.Statement.Statement)(yystack.valueAt (1))),((tree.Statement.Statement)(yystack.valueAt (0)))); }; break; - case 256: /* SwitchRuleSeq: SwitchRule */ + case 256: /* ElsePartOpt: %empty */ if (yyn == 256) - /* "src/main/resources/Java_16_Grammar.y":999 */ - { yyval = new SwitchRules(((SwitchRule)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1023 */ + { yyval = null; }; break; - case 257: /* SwitchRuleSeq: SwitchRuleSeq SwitchRule */ + case 257: /* ElsePartOpt: ELSE Statement */ if (yyn == 257) - /* "src/main/resources/Java_16_Grammar.y":1000 */ - { yyval = ((SwitchRules)(yystack.valueAt (1))).add(((SwitchRule)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1024 */ + { yyval = ((tree.Statement.Statement)(yystack.valueAt (0))); }; break; - case 258: /* SwitchRule: SwitchLabel ARROW Expression SEMICOLON */ + case 258: /* SwitchBlock: LBRACE RBRACE */ if (yyn == 258) - /* "src/main/resources/Java_16_Grammar.y":1004 */ - { yyval = new SwitchRule(((SwitchLabel)(yystack.valueAt (3))),((tree.Expression.Expression)(yystack.valueAt (1)))); }; + /* "src/main/resources/Java_16_Grammar.y":1028 */ + { yyval = null; }; break; - case 259: /* SwitchRule: SwitchLabel ARROW Block */ + case 259: /* SwitchBlock: LBRACE SwitchRuleSeq RBRACE */ if (yyn == 259) - /* "src/main/resources/Java_16_Grammar.y":1005 */ - { yyval = new SwitchRule(((SwitchLabel)(yystack.valueAt (2))),((tree.Statement.Block)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1029 */ + { yyval = null; }; break; - case 260: /* SwitchRule: SwitchLabel ARROW THROW Expression SEMICOLON */ + case 260: /* SwitchBlock: LBRACE SwitchBlockStatementGroupSeq RBRACE */ if (yyn == 260) - /* "src/main/resources/Java_16_Grammar.y":1006 */ - { yyval = new SwitchRule(((SwitchLabel)(yystack.valueAt (4))),new Throw(null,((tree.Expression.Expression)(yystack.valueAt (1))))); }; + /* "src/main/resources/Java_16_Grammar.y":1030 */ + { yyval = null; }; break; - case 264: /* SwitchLabelSeq: SwitchLabel COLON */ + case 261: /* SwitchRuleSeq: SwitchRule */ + if (yyn == 261) + /* "src/main/resources/Java_16_Grammar.y":1037 */ + { yyval = new SwitchRules(((SwitchRule)(yystack.valueAt (0)))); }; + break; + + + case 262: /* SwitchRuleSeq: SwitchRuleSeq SwitchRule */ + if (yyn == 262) + /* "src/main/resources/Java_16_Grammar.y":1038 */ + { yyval = ((SwitchRules)(yystack.valueAt (1))).add(((SwitchRule)(yystack.valueAt (0)))); }; + break; + + + case 263: /* SwitchRule: SwitchLabel ARROW Expression SEMICOLON */ + if (yyn == 263) + /* "src/main/resources/Java_16_Grammar.y":1042 */ + { yyval = new SwitchRule(((SwitchLabel)(yystack.valueAt (3))),((tree.Expression.Expression)(yystack.valueAt (1)))); }; + break; + + + case 264: /* SwitchRule: SwitchLabel ARROW Block */ if (yyn == 264) - /* "src/main/resources/Java_16_Grammar.y":1020 */ - { yyval = new SwitchLabels(((SwitchLabel)(yystack.valueAt (1)))); }; + /* "src/main/resources/Java_16_Grammar.y":1043 */ + { yyval = new SwitchRule(((SwitchLabel)(yystack.valueAt (2))),((tree.Statement.Block)(yystack.valueAt (0)))); }; break; - case 265: /* SwitchLabelSeq: SwitchLabelSeq SwitchLabel COLON */ + case 265: /* SwitchRule: SwitchLabel ARROW THROW Expression SEMICOLON */ if (yyn == 265) - /* "src/main/resources/Java_16_Grammar.y":1021 */ + /* "src/main/resources/Java_16_Grammar.y":1044 */ + { yyval = new SwitchRule(((SwitchLabel)(yystack.valueAt (4))),new Throw(null,((tree.Expression.Expression)(yystack.valueAt (1))))); }; + break; + + + case 269: /* SwitchLabelSeq: SwitchLabel COLON */ + if (yyn == 269) + /* "src/main/resources/Java_16_Grammar.y":1058 */ + { yyval = new SwitchLabels(((SwitchLabel)(yystack.valueAt (1)))); }; + break; + + + case 270: /* SwitchLabelSeq: SwitchLabelSeq SwitchLabel COLON */ + if (yyn == 270) + /* "src/main/resources/Java_16_Grammar.y":1059 */ { yyval = ((SwitchLabels)(yystack.valueAt (2))).add(((SwitchLabel)(yystack.valueAt (1)))); }; break; - case 266: /* SwitchLabel: CASE CaseExpressionList */ - if (yyn == 266) - /* "src/main/resources/Java_16_Grammar.y":1025 */ + case 271: /* SwitchLabel: CASE CaseExpressionList */ + if (yyn == 271) + /* "src/main/resources/Java_16_Grammar.y":1063 */ { yyval = ((SwitchLabel)(yystack.valueAt (0))); }; break; - case 267: /* SwitchLabel: DEFAULT */ - if (yyn == 267) - /* "src/main/resources/Java_16_Grammar.y":1026 */ + case 272: /* SwitchLabel: DEFAULT */ + if (yyn == 272) + /* "src/main/resources/Java_16_Grammar.y":1064 */ { yyval = null; }; break; - case 268: /* CaseExpressionList: AssignmentExpression */ - if (yyn == 268) - /* "src/main/resources/Java_16_Grammar.y":1030 */ + case 273: /* CaseExpressionList: AssignmentExpression */ + if (yyn == 273) + /* "src/main/resources/Java_16_Grammar.y":1068 */ { yyval = new SwitchLabel(((tree.Expression.Expression)(yystack.valueAt (0)))); }; break; - case 269: /* CaseExpressionList: CaseExpressionList COMMA AssignmentExpression */ - if (yyn == 269) - /* "src/main/resources/Java_16_Grammar.y":1031 */ + case 274: /* CaseExpressionList: CaseExpressionList COMMA AssignmentExpression */ + if (yyn == 274) + /* "src/main/resources/Java_16_Grammar.y":1069 */ { yyval = ((SwitchLabel)(yystack.valueAt (2))).add(((tree.Expression.Expression)(yystack.valueAt (0)))); }; break; - case 270: /* WhileStatement: WHILE LPAREN Expression RPAREN Statement */ - if (yyn == 270) - /* "src/main/resources/Java_16_Grammar.y":1038 */ + case 275: /* WhileStatement: WHILE LPAREN Expression RPAREN Statement */ + if (yyn == 275) + /* "src/main/resources/Java_16_Grammar.y":1076 */ { yyval = new While(null,((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Statement.Statement)(yystack.valueAt (0)))); }; break; - case 271: /* ForStatement: BasicForStatement */ - if (yyn == 271) - /* "src/main/resources/Java_16_Grammar.y":1042 */ + case 276: /* ForStatement: BasicForStatement */ + if (yyn == 276) + /* "src/main/resources/Java_16_Grammar.y":1080 */ { yyval = ((tree.Statement.Statement)(yystack.valueAt (0))); }; break; - case 272: /* ForStatement: EnhancedForStatement */ - if (yyn == 272) - /* "src/main/resources/Java_16_Grammar.y":1043 */ + case 277: /* ForStatement: EnhancedForStatement */ + if (yyn == 277) + /* "src/main/resources/Java_16_Grammar.y":1081 */ { yyval = ((tree.Statement.Statement)(yystack.valueAt (0))); }; break; - case 273: /* BasicForStatement: FOR LPAREN ForInitOpt SEMICOLON ExpressionOpt SEMICOLON StatementExpressionListOpt RPAREN Statement */ - if (yyn == 273) - /* "src/main/resources/Java_16_Grammar.y":1048 */ + case 278: /* BasicForStatement: FOR LPAREN ForInitOpt SEMICOLON ExpressionOpt SEMICOLON StatementExpressionListOpt RPAREN Statement */ + if (yyn == 278) + /* "src/main/resources/Java_16_Grammar.y":1086 */ { yyval = null; }; break; - case 277: /* ExpressionOpt: %empty */ - if (yyn == 277) - /* "src/main/resources/Java_16_Grammar.y":1058 */ + case 282: /* ExpressionOpt: %empty */ + if (yyn == 282) + /* "src/main/resources/Java_16_Grammar.y":1096 */ { yyval = null; }; break; - case 278: /* ExpressionOpt: Expression */ - if (yyn == 278) - /* "src/main/resources/Java_16_Grammar.y":1059 */ + case 283: /* ExpressionOpt: Expression */ + if (yyn == 283) + /* "src/main/resources/Java_16_Grammar.y":1097 */ { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 279: /* StatementExpressionList: StatementExpression */ - if (yyn == 279) - /* "src/main/resources/Java_16_Grammar.y":1066 */ + case 284: /* StatementExpressionList: StatementExpression */ + if (yyn == 284) + /* "src/main/resources/Java_16_Grammar.y":1104 */ { yyval = ((StatementExpression)(yystack.valueAt (0))); }; break; - case 280: /* StatementExpressionList: StatementExpressionList COMMA StatementExpression */ - if (yyn == 280) - /* "src/main/resources/Java_16_Grammar.y":1067 */ + case 285: /* StatementExpressionList: StatementExpressionList COMMA StatementExpression */ + if (yyn == 285) + /* "src/main/resources/Java_16_Grammar.y":1105 */ { yyval = ((StatementExpressions)(yystack.valueAt (2))).add(((StatementExpression)(yystack.valueAt (0)))); }; break; - case 281: /* StatementExpressionListOpt: %empty */ - if (yyn == 281) - /* "src/main/resources/Java_16_Grammar.y":1071 */ + case 286: /* StatementExpressionListOpt: %empty */ + if (yyn == 286) + /* "src/main/resources/Java_16_Grammar.y":1109 */ { yyval = null; }; break; - case 282: /* StatementExpressionListOpt: StatementExpressionList */ - if (yyn == 282) - /* "src/main/resources/Java_16_Grammar.y":1072 */ + case 287: /* StatementExpressionListOpt: StatementExpressionList */ + if (yyn == 287) + /* "src/main/resources/Java_16_Grammar.y":1110 */ { yyval = ((StatementExpressions)(yystack.valueAt (0))); }; break; - case 283: /* EnhancedForStatement: FOR LPAREN LocalVariableDeclaration COLON Expression RPAREN Statement */ - if (yyn == 283) - /* "src/main/resources/Java_16_Grammar.y":1076 */ + case 288: /* EnhancedForStatement: FOR LPAREN LocalVariableDeclaration COLON Expression RPAREN Statement */ + if (yyn == 288) + /* "src/main/resources/Java_16_Grammar.y":1114 */ { yyval = null; }; break; - case 284: /* CatchesOpt: %empty */ - if (yyn == 284) - /* "src/main/resources/Java_16_Grammar.y":1080 */ + case 289: /* CatchesOpt: %empty */ + if (yyn == 289) + /* "src/main/resources/Java_16_Grammar.y":1118 */ { yyval = null; }; break; - case 285: /* CatchesOpt: Catches */ - if (yyn == 285) - /* "src/main/resources/Java_16_Grammar.y":1081 */ + case 290: /* CatchesOpt: Catches */ + if (yyn == 290) + /* "src/main/resources/Java_16_Grammar.y":1119 */ { yyval = ((CatchClauses)(yystack.valueAt (0))); }; break; - case 286: /* Catches: CatchClause */ - if (yyn == 286) - /* "src/main/resources/Java_16_Grammar.y":1085 */ + case 291: /* Catches: CatchClause */ + if (yyn == 291) + /* "src/main/resources/Java_16_Grammar.y":1123 */ { yyval = new CatchClauses(((CatchClause)(yystack.valueAt (0)))); }; break; - case 287: /* Catches: Catches CatchClause */ - if (yyn == 287) - /* "src/main/resources/Java_16_Grammar.y":1086 */ + case 292: /* Catches: Catches CatchClause */ + if (yyn == 292) + /* "src/main/resources/Java_16_Grammar.y":1124 */ { yyval = ((CatchClauses)(yystack.valueAt (1))).add(((CatchClause)(yystack.valueAt (0)))); }; break; - case 288: /* CatchClause: CATCH LPAREN CatchFormalParameter RPAREN Block */ - if (yyn == 288) - /* "src/main/resources/Java_16_Grammar.y":1090 */ + case 293: /* CatchClause: CATCH LPAREN CatchFormalParameter RPAREN Block */ + if (yyn == 293) + /* "src/main/resources/Java_16_Grammar.y":1128 */ { yyval = new CatchClause(((CatchParameter)(yystack.valueAt (2))),((tree.Statement.Block)(yystack.valueAt (0)))); }; break; - case 289: /* CatchFormalParameter: ModifierSeqOpt CatchType IDENTIFIER DimsOpt */ - if (yyn == 289) - /* "src/main/resources/Java_16_Grammar.y":1094 */ + case 294: /* CatchFormalParameter: ModifierSeqOpt CatchType IDENTIFIER DimsOpt */ + if (yyn == 294) + /* "src/main/resources/Java_16_Grammar.y":1132 */ { yyval = new CatchParameter(((Modifiers)(yystack.valueAt (3))),((tree.Type.TypeList)(yystack.valueAt (2))),((Token)(yystack.valueAt (1))),((Dims)(yystack.valueAt (0)))); }; break; - case 290: /* CatchType: Type */ - if (yyn == 290) - /* "src/main/resources/Java_16_Grammar.y":1098 */ + case 295: /* CatchType: Type */ + if (yyn == 295) + /* "src/main/resources/Java_16_Grammar.y":1136 */ { yyval = new TypeList(((tree.Type.Type)(yystack.valueAt (0)))); }; break; - case 291: /* CatchType: CatchType VERTICAL Type */ - if (yyn == 291) - /* "src/main/resources/Java_16_Grammar.y":1099 */ + case 296: /* CatchType: CatchType VERTICAL Type */ + if (yyn == 296) + /* "src/main/resources/Java_16_Grammar.y":1137 */ { yyval = ((tree.Type.TypeList)(yystack.valueAt (2))).add(((tree.Type.Type)(yystack.valueAt (0)))); }; break; - case 302: /* Primary: Literal */ - if (yyn == 302) - /* "src/main/resources/Java_16_Grammar.y":1136 */ + case 307: /* Primary: Literal */ + if (yyn == 307) + /* "src/main/resources/Java_16_Grammar.y":1174 */ { yyval = new Literal(((Token)(yystack.valueAt (0)))); }; break; - case 303: /* Primary: Type DimsOpt DOT CLASS */ - if (yyn == 303) - /* "src/main/resources/Java_16_Grammar.y":1137 */ + case 308: /* Primary: Type DimsOpt DOT CLASS */ + if (yyn == 308) + /* "src/main/resources/Java_16_Grammar.y":1175 */ { yyval = new ClassLiteral(((tree.Type.Type)(yystack.valueAt (3))),((Dims)(yystack.valueAt (2)))); }; break; - case 304: /* Primary: VOID DimsOpt DOT CLASS */ - if (yyn == 304) - /* "src/main/resources/Java_16_Grammar.y":1138 */ + case 309: /* Primary: VOID DimsOpt DOT CLASS */ + if (yyn == 309) + /* "src/main/resources/Java_16_Grammar.y":1176 */ { yyval = new ClassLiteral(null,((Dims)(yystack.valueAt (2)))); }; break; - case 305: /* Primary: THIS */ - if (yyn == 305) - /* "src/main/resources/Java_16_Grammar.y":1139 */ + case 310: /* Primary: THIS */ + if (yyn == 310) + /* "src/main/resources/Java_16_Grammar.y":1177 */ { yyval = new This(null); }; break; - case 306: /* Primary: Type DOT THIS */ - if (yyn == 306) - /* "src/main/resources/Java_16_Grammar.y":1140 */ + case 311: /* Primary: Type DOT THIS */ + if (yyn == 311) + /* "src/main/resources/Java_16_Grammar.y":1178 */ { yyval = new This(((tree.Type.Type)(yystack.valueAt (2)))); }; break; - case 307: /* Primary: LPAREN Expression RPAREN */ - if (yyn == 307) - /* "src/main/resources/Java_16_Grammar.y":1141 */ + case 312: /* Primary: LPAREN Expression RPAREN */ + if (yyn == 312) + /* "src/main/resources/Java_16_Grammar.y":1179 */ { yyval = new Parenthesized(((tree.Expression.Expression)(yystack.valueAt (1)))); }; break; - case 308: /* Primary: ClassInstanceCreationExpression */ - if (yyn == 308) - /* "src/main/resources/Java_16_Grammar.y":1142 */ - { yyval = null; }; + case 313: /* Primary: ClassInstanceCreationExpression */ + if (yyn == 313) + /* "src/main/resources/Java_16_Grammar.y":1180 */ + { yyval = ((Primary)(yystack.valueAt (0))); }; break; - case 309: /* Primary: FieldAccess */ - if (yyn == 309) - /* "src/main/resources/Java_16_Grammar.y":1143 */ + case 314: /* Primary: FieldAccess */ + if (yyn == 314) + /* "src/main/resources/Java_16_Grammar.y":1181 */ { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 310: /* Primary: ArrayAccess */ - if (yyn == 310) - /* "src/main/resources/Java_16_Grammar.y":1144 */ + case 315: /* Primary: ArrayAccess */ + if (yyn == 315) + /* "src/main/resources/Java_16_Grammar.y":1182 */ { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 311: /* Primary: MethodInvocation */ - if (yyn == 311) - /* "src/main/resources/Java_16_Grammar.y":1145 */ + case 316: /* Primary: MethodInvocation */ + if (yyn == 316) + /* "src/main/resources/Java_16_Grammar.y":1183 */ { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 312: /* Primary: MethodReference */ - if (yyn == 312) - /* "src/main/resources/Java_16_Grammar.y":1146 */ + case 317: /* Primary: MethodReference */ + if (yyn == 317) + /* "src/main/resources/Java_16_Grammar.y":1184 */ { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 313: /* Primary: ArrayCreationExpression */ - if (yyn == 313) - /* "src/main/resources/Java_16_Grammar.y":1147 */ + case 318: /* Primary: ArrayCreationExpression */ + if (yyn == 318) + /* "src/main/resources/Java_16_Grammar.y":1185 */ { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 314: /* ClassInstanceCreationExpression: UnqualifiedClassInstanceCreationExpression */ - if (yyn == 314) - /* "src/main/resources/Java_16_Grammar.y":1157 */ - { yyval = null; }; + case 319: /* ClassInstanceCreationExpression: UnqualifiedClassInstanceCreationExpression */ + if (yyn == 319) + /* "src/main/resources/Java_16_Grammar.y":1201 */ + { yyval = new InstanceCreationQualified((Primary)null,((InstanceCreation)(yystack.valueAt (0)))); }; break; - case 315: /* ClassInstanceCreationExpression: CompoundName DOT UnqualifiedClassInstanceCreationExpression */ - if (yyn == 315) - /* "src/main/resources/Java_16_Grammar.y":1158 */ - { yyval = null; }; + case 320: /* ClassInstanceCreationExpression: CompoundName DOT UnqualifiedClassInstanceCreationExpression */ + if (yyn == 320) + /* "src/main/resources/Java_16_Grammar.y":1202 */ + { yyval = new InstanceCreationQualified(((CompoundName)(yystack.valueAt (2))),((InstanceCreation)(yystack.valueAt (0)))); }; break; - case 316: /* ClassInstanceCreationExpression: Primary DOT UnqualifiedClassInstanceCreationExpression */ - if (yyn == 316) - /* "src/main/resources/Java_16_Grammar.y":1159 */ - { yyval = null; }; + case 321: /* ClassInstanceCreationExpression: Primary DOT UnqualifiedClassInstanceCreationExpression */ + if (yyn == 321) + /* "src/main/resources/Java_16_Grammar.y":1203 */ + { yyval = new InstanceCreationQualified(((Primary)(yystack.valueAt (2))),((InstanceCreation)(yystack.valueAt (0)))); }; break; - case 322: /* TypeArgumentsOpt: %empty */ + case 322: /* UnqualifiedClassInstanceCreationExpression: NEW TypeArgumentsOpt ClassOrInterfaceTypeToInstantiate Arguments ClassBodyOpt */ if (yyn == 322) - /* "src/main/resources/Java_16_Grammar.y":1177 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":1208 */ + { yyval = new InstanceCreation(((tree.Type.TypeArguments)(yystack.valueAt (3))),((Type)(yystack.valueAt (2))),((tree.Expression.ArgumentList)(yystack.valueAt (1))),((Declarations)(yystack.valueAt (0)))); }; break; - case 323: /* TypeArgumentsOpt: TypeArguments */ + case 323: /* ClassOrInterfaceTypeToInstantiate: Type */ if (yyn == 323) - /* "src/main/resources/Java_16_Grammar.y":1178 */ - { yyval = ((tree.Type.TypeArguments)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":1212 */ + { yyval = ((tree.Type.Type)(yystack.valueAt (0))); }; break; - case 324: /* TypeArguments: LESS TypeArgumentList GREATER */ + case 324: /* TypeArgumentsOpt: %empty */ if (yyn == 324) - /* "src/main/resources/Java_16_Grammar.y":1182 */ - { yyval = ((tree.Type.TypeArguments)(yystack.valueAt (1))); }; + /* "src/main/resources/Java_16_Grammar.y":1226 */ + { yyval = null; }; break; - case 325: /* TypeArgumentList: TypeArgument */ + case 325: /* TypeArgumentsOpt: TypeArguments */ if (yyn == 325) - /* "src/main/resources/Java_16_Grammar.y":1186 */ - { yyval = new TypeArguments(((tree.Type.TypeArgument)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1227 */ + { yyval = ((tree.Type.TypeArguments)(yystack.valueAt (0))); }; break; - case 326: /* TypeArgumentList: TypeArgumentList COMMA TypeArgument */ + case 326: /* TypeArguments: LESS GREATER */ if (yyn == 326) - /* "src/main/resources/Java_16_Grammar.y":1187 */ - { yyval = ((tree.Type.TypeArguments)(yystack.valueAt (2))).add(((tree.Type.TypeArgument)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1231 */ + { yyval = null; }; break; - case 327: /* TypeArgument: Type */ + case 327: /* TypeArguments: LESS TypeArgumentList GREATER */ if (yyn == 327) - /* "src/main/resources/Java_16_Grammar.y":1191 */ - { yyval = new TypeArgument(((tree.Type.Type)(yystack.valueAt (0))),0,null); }; + /* "src/main/resources/Java_16_Grammar.y":1232 */ + { yyval = ((tree.Type.TypeArguments)(yystack.valueAt (1))); }; break; - case 328: /* TypeArgument: QUESTION */ + case 328: /* TypeArgumentList: TypeArgument */ if (yyn == 328) - /* "src/main/resources/Java_16_Grammar.y":1192 */ - { yyval = new TypeArgument(null,1,null); }; + /* "src/main/resources/Java_16_Grammar.y":1236 */ + { yyval = new TypeArguments(((tree.Type.TypeArgument)(yystack.valueAt (0)))); }; break; - case 329: /* TypeArgument: QUESTION EXTENDS Type */ + case 329: /* TypeArgumentList: TypeArgumentList COMMA TypeArgument */ if (yyn == 329) - /* "src/main/resources/Java_16_Grammar.y":1193 */ - { yyval = new TypeArgument(((tree.Type.Type)(yystack.valueAt (0))),1,null); }; + /* "src/main/resources/Java_16_Grammar.y":1237 */ + { yyval = ((tree.Type.TypeArguments)(yystack.valueAt (2))).add(((tree.Type.TypeArgument)(yystack.valueAt (0)))); }; break; - case 330: /* TypeArgument: QUESTION SUPER Type */ + case 330: /* TypeArgument: Type */ if (yyn == 330) - /* "src/main/resources/Java_16_Grammar.y":1194 */ - { yyval = new TypeArgument(((tree.Type.Type)(yystack.valueAt (0))),2,null); }; + /* "src/main/resources/Java_16_Grammar.y":1241 */ + { yyval = new TypeArgument(((tree.Type.Type)(yystack.valueAt (0))),0,null); }; break; - case 331: /* TypeArgument: AnnotationSeq QUESTION */ + case 331: /* TypeArgument: QUESTION */ if (yyn == 331) - /* "src/main/resources/Java_16_Grammar.y":1195 */ - { yyval = new TypeArgument(null,1,((Annotations)(yystack.valueAt (1)))); }; + /* "src/main/resources/Java_16_Grammar.y":1242 */ + { yyval = new TypeArgument(null,1,null); }; break; - case 332: /* TypeArgument: AnnotationSeq QUESTION EXTENDS Type */ + case 332: /* TypeArgument: QUESTION EXTENDS Type */ if (yyn == 332) - /* "src/main/resources/Java_16_Grammar.y":1196 */ - { yyval = new TypeArgument(((tree.Type.Type)(yystack.valueAt (0))),2,((Annotations)(yystack.valueAt (3)))); }; + /* "src/main/resources/Java_16_Grammar.y":1243 */ + { yyval = new TypeArgument(((tree.Type.Type)(yystack.valueAt (0))),1,null); }; break; - case 333: /* TypeArgument: AnnotationSeq QUESTION SUPER Type */ + case 333: /* TypeArgument: QUESTION SUPER Type */ if (yyn == 333) - /* "src/main/resources/Java_16_Grammar.y":1197 */ - { yyval = new TypeArgument(((tree.Type.Type)(yystack.valueAt (0))),3,((Annotations)(yystack.valueAt (3)))); }; + /* "src/main/resources/Java_16_Grammar.y":1244 */ + { yyval = new TypeArgument(((tree.Type.Type)(yystack.valueAt (0))),2,null); }; break; - case 334: /* FieldAccess: Primary DOT IDENTIFIER */ + case 334: /* TypeArgument: AnnotationSeq QUESTION */ if (yyn == 334) - /* "src/main/resources/Java_16_Grammar.y":1207 */ - { yyval = new FieldAccess(((tree.Expression.Expression)(yystack.valueAt (2))), false,((Token)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1245 */ + { yyval = new TypeArgument(null,1,((Annotations)(yystack.valueAt (1)))); }; break; - case 335: /* FieldAccess: SUPER DOT IDENTIFIER */ + case 335: /* TypeArgument: AnnotationSeq QUESTION EXTENDS Type */ if (yyn == 335) - /* "src/main/resources/Java_16_Grammar.y":1208 */ - { yyval = new FieldAccess(null,true, ((Token)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1246 */ + { yyval = new TypeArgument(((tree.Type.Type)(yystack.valueAt (0))),2,((Annotations)(yystack.valueAt (3)))); }; break; - case 336: /* FieldAccess: CompoundName DOT SUPER DOT IDENTIFIER */ + case 336: /* TypeArgument: AnnotationSeq QUESTION SUPER Type */ if (yyn == 336) - /* "src/main/resources/Java_16_Grammar.y":1209 */ - { yyval = new FieldAccess(new SimpleReference(((CompoundName)(yystack.valueAt (4)))),true,((Token)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1247 */ + { yyval = new TypeArgument(((tree.Type.Type)(yystack.valueAt (0))),3,((Annotations)(yystack.valueAt (3)))); }; break; - case 337: /* ArrayAccess: CompoundName LBRACKET Expression RBRACKET */ + case 337: /* FieldAccess: Primary DOT IDENTIFIER */ if (yyn == 337) - /* "src/main/resources/Java_16_Grammar.y":1213 */ - { yyval = new ArrayAccess(new SimpleReference(((CompoundName)(yystack.valueAt (3)))),((tree.Expression.Expression)(yystack.valueAt (1)))); }; + /* "src/main/resources/Java_16_Grammar.y":1257 */ + { yyval = new FieldAccess(((Primary)(yystack.valueAt (2))), false,((Token)(yystack.valueAt (0)))); }; break; - case 338: /* ArrayAccess: Primary LBRACKET Expression RBRACKET */ + case 338: /* FieldAccess: SUPER DOT IDENTIFIER */ if (yyn == 338) - /* "src/main/resources/Java_16_Grammar.y":1214 */ - { yyval = new ArrayAccess(((tree.Expression.Expression)(yystack.valueAt (3))),((tree.Expression.Expression)(yystack.valueAt (1)))); }; + /* "src/main/resources/Java_16_Grammar.y":1258 */ + { yyval = new FieldAccess(null,true, ((Token)(yystack.valueAt (0)))); }; break; - case 339: /* MethodInvocation: CompoundName Arguments */ + case 339: /* FieldAccess: CompoundName DOT SUPER DOT IDENTIFIER */ if (yyn == 339) - /* "src/main/resources/Java_16_Grammar.y":1218 */ - { var ref = new SimpleReference(((CompoundName)(yystack.valueAt (1)))); - yyval = new MethodInvocation(ref,false,null,null,((tree.Expression.ArgumentList)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1259 */ + { yyval = new FieldAccess(new SimpleReference(((CompoundName)(yystack.valueAt (4)))),true,((Token)(yystack.valueAt (0)))); }; break; - case 340: /* MethodInvocation: CompoundName DOT TypeArguments IDENTIFIER Arguments */ + case 340: /* ArrayAccess: CompoundName Dim */ if (yyn == 340) - /* "src/main/resources/Java_16_Grammar.y":1220 */ - { var ref = new SimpleReference(((CompoundName)(yystack.valueAt (4)))); - yyval = new MethodInvocation(ref,false,((tree.Type.TypeArguments)(yystack.valueAt (2))),((Token)(yystack.valueAt (1))),((tree.Expression.ArgumentList)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1263 */ + { yyval = new ArrayAccess(new SimpleReference(((CompoundName)(yystack.valueAt (1)))),((Dim)(yystack.valueAt (0))).expression); }; break; - case 341: /* MethodInvocation: Primary DOT TypeArgumentsOpt IDENTIFIER Arguments */ + case 341: /* ArrayAccess: Primary Dim */ if (yyn == 341) - /* "src/main/resources/Java_16_Grammar.y":1222 */ - { yyval = new MethodInvocation(((tree.Expression.Expression)(yystack.valueAt (4))),false,((tree.Type.TypeArguments)(yystack.valueAt (2))),((Token)(yystack.valueAt (1))),((tree.Expression.ArgumentList)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1264 */ + { yyval = new ArrayAccess(((Primary)(yystack.valueAt (1))),((Dim)(yystack.valueAt (0))).expression); }; break; - case 342: /* MethodInvocation: SUPER DOT TypeArgumentsOpt IDENTIFIER Arguments */ + case 342: /* ArrayAccess: ArrayAccess Dim */ if (yyn == 342) - /* "src/main/resources/Java_16_Grammar.y":1223 */ - { yyval = new MethodInvocation(null,true,((tree.Type.TypeArguments)(yystack.valueAt (2))),((Token)(yystack.valueAt (1))),((tree.Expression.ArgumentList)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1265 */ + { yyval = null; /* $1.addDimension($2.expression);*/ }; break; - case 343: /* MethodInvocation: CompoundName DOT SUPER DOT TypeArgumentsOpt IDENTIFIER Arguments */ + case 343: /* MethodInvocation: CompoundName Arguments */ if (yyn == 343) - /* "src/main/resources/Java_16_Grammar.y":1224 */ - { var ref = new SimpleReference(((CompoundName)(yystack.valueAt (6)))); - yyval = new MethodInvocation(ref,true,((tree.Type.TypeArguments)(yystack.valueAt (2))),((Token)(yystack.valueAt (1))),((tree.Expression.ArgumentList)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1269 */ + { var ref = new SimpleReference(((CompoundName)(yystack.valueAt (1)))); + yyval = new MethodInvocation(ref,false,null,null,((tree.Expression.ArgumentList)(yystack.valueAt (0)))); }; break; - case 344: /* Arguments: LPAREN RPAREN */ + case 344: /* MethodInvocation: CompoundName DOT TypeArguments IDENTIFIER Arguments */ if (yyn == 344) - /* "src/main/resources/Java_16_Grammar.y":1229 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":1271 */ + { var ref = new SimpleReference(((CompoundName)(yystack.valueAt (4)))); + yyval = new MethodInvocation(ref,false,((tree.Type.TypeArguments)(yystack.valueAt (2))),((Token)(yystack.valueAt (1))),((tree.Expression.ArgumentList)(yystack.valueAt (0)))); }; break; - case 345: /* Arguments: LPAREN ArgumentList RPAREN */ + case 345: /* MethodInvocation: Primary DOT TypeArgumentsOpt IDENTIFIER Arguments */ if (yyn == 345) - /* "src/main/resources/Java_16_Grammar.y":1230 */ - { yyval = ((tree.Expression.ArgumentList)(yystack.valueAt (1))); }; + /* "src/main/resources/Java_16_Grammar.y":1273 */ + { yyval = new MethodInvocation(((Primary)(yystack.valueAt (4))),false,((tree.Type.TypeArguments)(yystack.valueAt (2))),((Token)(yystack.valueAt (1))),((tree.Expression.ArgumentList)(yystack.valueAt (0)))); }; break; - case 346: /* ArgumentList: Expression */ + case 346: /* MethodInvocation: SUPER DOT TypeArgumentsOpt IDENTIFIER Arguments */ if (yyn == 346) - /* "src/main/resources/Java_16_Grammar.y":1239 */ - { yyval = new ArgumentList(((tree.Expression.Expression)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1274 */ + { yyval = new MethodInvocation(null,true,((tree.Type.TypeArguments)(yystack.valueAt (2))),((Token)(yystack.valueAt (1))),((tree.Expression.ArgumentList)(yystack.valueAt (0)))); }; break; - case 347: /* ArgumentList: ArgumentList COMMA Expression */ + case 347: /* MethodInvocation: CompoundName DOT SUPER DOT TypeArgumentsOpt IDENTIFIER Arguments */ if (yyn == 347) - /* "src/main/resources/Java_16_Grammar.y":1240 */ - { yyval = ((tree.Expression.ArgumentList)(yystack.valueAt (2))).add(((tree.Expression.Expression)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1275 */ + { var ref = new SimpleReference(((CompoundName)(yystack.valueAt (6)))); + yyval = new MethodInvocation(ref,true,((tree.Type.TypeArguments)(yystack.valueAt (2))),((Token)(yystack.valueAt (1))),((tree.Expression.ArgumentList)(yystack.valueAt (0)))); }; break; - case 348: /* MethodReference: Primary DBL_COLON TypeArgumentsOpt IDENTIFIER */ + case 348: /* Arguments: LPAREN RPAREN */ if (yyn == 348) - /* "src/main/resources/Java_16_Grammar.y":1245 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":1280 */ + { yyval = null; }; break; - case 349: /* MethodReference: Type DBL_COLON TypeArgumentsOpt IDENTIFIER */ + case 349: /* Arguments: LPAREN ArgumentList RPAREN */ if (yyn == 349) - /* "src/main/resources/Java_16_Grammar.y":1246 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":1281 */ + { yyval = ((tree.Expression.ArgumentList)(yystack.valueAt (1))); }; break; - case 350: /* MethodReference: SUPER DBL_COLON TypeArgumentsOpt IDENTIFIER */ + case 350: /* ArgumentList: Expression */ if (yyn == 350) - /* "src/main/resources/Java_16_Grammar.y":1247 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":1290 */ + { yyval = new ArgumentList(((tree.Expression.Expression)(yystack.valueAt (0)))); }; break; - case 351: /* MethodReference: Type DOT SUPER DBL_COLON TypeArgumentsOpt IDENTIFIER */ + case 351: /* ArgumentList: ArgumentList COMMA Expression */ if (yyn == 351) - /* "src/main/resources/Java_16_Grammar.y":1248 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":1291 */ + { yyval = ((tree.Expression.ArgumentList)(yystack.valueAt (2))).add(((tree.Expression.Expression)(yystack.valueAt (0)))); }; break; - case 352: /* MethodReference: Type DBL_COLON TypeArgumentsOpt NEW */ + case 352: /* MethodReference: Primary DBL_COLON TypeArgumentsOpt IDENTIFIER */ if (yyn == 352) - /* "src/main/resources/Java_16_Grammar.y":1249 */ + /* "src/main/resources/Java_16_Grammar.y":1296 */ { yyval = null; }; break; - case 353: /* ArrayCreationExpression: NEW Type DimExprs DimsOpt */ + case 353: /* MethodReference: Type DBL_COLON TypeArgumentsOpt IDENTIFIER */ if (yyn == 353) - /* "src/main/resources/Java_16_Grammar.y":1253 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":1297 */ + { yyval = null; }; break; - case 354: /* ArrayCreationExpression: NEW Type Dims ArrayInitializer */ + case 354: /* MethodReference: SUPER DBL_COLON TypeArgumentsOpt IDENTIFIER */ if (yyn == 354) - /* "src/main/resources/Java_16_Grammar.y":1254 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":1298 */ + { yyval = null; }; + break; + + + case 355: /* MethodReference: Type DOT SUPER DBL_COLON TypeArgumentsOpt IDENTIFIER */ + if (yyn == 355) + /* "src/main/resources/Java_16_Grammar.y":1299 */ + { yyval = null; }; + break; + + + case 356: /* MethodReference: Type DBL_COLON TypeArgumentsOpt NEW */ + if (yyn == 356) + /* "src/main/resources/Java_16_Grammar.y":1300 */ + { yyval = null; }; + break; + + + case 357: /* ArrayCreationExpression: NEW PrimitiveType Dims ArrayInitializerOpt */ + if (yyn == 357) + /* "src/main/resources/Java_16_Grammar.y":1309 */ + { PrimitiveType pt = new PrimitiveType(((Token)(yystack.valueAt (2)))); + pt.setDimensions(((Dims)(yystack.valueAt (1)))); + yyval = new ArrayCreation(pt,((InitializerArray)(yystack.valueAt (0)))); }; + break; + + + case 358: /* ArrayCreationExpression: NEW CompoundName Dims ArrayInitializerOpt */ + if (yyn == 358) + /* "src/main/resources/Java_16_Grammar.y":1312 */ + { TypeName tn = new TypeName(((CompoundName)(yystack.valueAt (2))),null); + tn.setDimensions(((Dims)(yystack.valueAt (1)))); + yyval = new ArrayCreation(tn,((InitializerArray)(yystack.valueAt (0)))); }; break; - case 359: /* Expression: LambdaExpression */ + case 359: /* ArrayCreationExpression: NEW CompoundName TypeArguments Dims ArrayInitializerOpt */ if (yyn == 359) - /* "src/main/resources/Java_16_Grammar.y":1270 */ - { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":1315 */ + { TypeName tn = new TypeName(((CompoundName)(yystack.valueAt (3))),((tree.Type.TypeArguments)(yystack.valueAt (2)))); + tn.setDimensions(((Dims)(yystack.valueAt (1)))); + yyval = new ArrayCreation(tn,((InitializerArray)(yystack.valueAt (0)))); }; break; - case 360: /* Expression: AssignmentExpression */ + case 360: /* ArrayInitializerOpt: %empty */ if (yyn == 360) - /* "src/main/resources/Java_16_Grammar.y":1271 */ - { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":1321 */ + { yyval = null; }; break; - case 361: /* LambdaExpression: IDENTIFIER ARROW Expression */ + case 361: /* ArrayInitializerOpt: ArrayInitializer */ if (yyn == 361) - /* "src/main/resources/Java_16_Grammar.y":1276 */ - { yyval = new Lambda(new ParameterDeclarations(new ParameterDeclaration(((Token)(yystack.valueAt (2))))),((tree.Expression.Expression)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1322 */ + { yyval = ((InitializerArray)(yystack.valueAt (0))); }; break; - case 362: /* LambdaExpression: IDENTIFIER ARROW Block */ + case 362: /* Expression: LambdaExpression */ if (yyn == 362) - /* "src/main/resources/Java_16_Grammar.y":1278 */ - { yyval = new Lambda(new ParameterDeclarations(new ParameterDeclaration(((Token)(yystack.valueAt (2))))),((tree.Statement.Block)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1345 */ + { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 363: /* LambdaExpression: LambdaParameters ARROW Expression */ + case 363: /* Expression: AssignmentExpression */ if (yyn == 363) - /* "src/main/resources/Java_16_Grammar.y":1279 */ - { yyval = new Lambda(((ParameterDeclarations)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1346 */ + { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 364: /* LambdaExpression: LambdaParameters ARROW Block */ + case 364: /* LambdaExpression: IDENTIFIER ARROW Expression */ if (yyn == 364) - /* "src/main/resources/Java_16_Grammar.y":1280 */ - { yyval = new Lambda(((ParameterDeclarations)(yystack.valueAt (2))),((tree.Statement.Block)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1351 */ + { yyval = new Lambda(new ParameterDeclarations(new ParameterDeclaration(((Token)(yystack.valueAt (2))))),((tree.Expression.Expression)(yystack.valueAt (0)))); }; break; - case 365: /* LambdaParameters: LPAREN RPAREN */ + case 365: /* LambdaExpression: IDENTIFIER ARROW Block */ if (yyn == 365) - /* "src/main/resources/Java_16_Grammar.y":1289 */ - { yyval = null; }; + /* "src/main/resources/Java_16_Grammar.y":1353 */ + { yyval = new Lambda(new ParameterDeclarations(new ParameterDeclaration(((Token)(yystack.valueAt (2))))),((tree.Statement.Block)(yystack.valueAt (0)))); }; break; - case 366: /* LambdaParameters: LPAREN LambdaParameterList RPAREN */ + case 366: /* LambdaExpression: LambdaParameters ARROW Expression */ if (yyn == 366) - /* "src/main/resources/Java_16_Grammar.y":1292 */ - { yyval = ((ParameterDeclarations)(yystack.valueAt (1))); }; + /* "src/main/resources/Java_16_Grammar.y":1354 */ + { yyval = new Lambda(((ParameterDeclarations)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0)))); }; break; - case 367: /* LambdaParameterList: LambdaParameter */ + case 367: /* LambdaExpression: LambdaParameters ARROW Block */ if (yyn == 367) - /* "src/main/resources/Java_16_Grammar.y":1296 */ - { yyval = new ParameterDeclarations(((ParameterDeclaration)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1355 */ + { yyval = new Lambda(((ParameterDeclarations)(yystack.valueAt (2))),((tree.Statement.Block)(yystack.valueAt (0)))); }; break; - case 368: /* LambdaParameterList: LambdaParameterList COMMA LambdaParameter */ + case 368: /* LambdaParameters: LPAREN RPAREN */ if (yyn == 368) - /* "src/main/resources/Java_16_Grammar.y":1297 */ - { yyval = ((ParameterDeclarations)(yystack.valueAt (2))).add(((ParameterDeclaration)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1364 */ + { yyval = null; }; break; - case 369: /* LambdaParameter: ModifierSeqOpt UnannotatedType IDENTIFIER DimsOpt */ + case 369: /* LambdaParameters: LPAREN LambdaParameterList RPAREN */ if (yyn == 369) - /* "src/main/resources/Java_16_Grammar.y":1312 */ - { yyval = new ParameterDeclaration(((Modifiers)(yystack.valueAt (3))),((tree.Type.UnannotatedType)(yystack.valueAt (2))),((Token)(yystack.valueAt (1))).image,null,false,((Dims)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1367 */ + { yyval = ((ParameterDeclarations)(yystack.valueAt (1))); }; break; - case 370: /* LambdaParameter: ModifierSeqOpt VAR IDENTIFIER DimsOpt */ + case 370: /* LambdaParameterList: LambdaParameter */ if (yyn == 370) - /* "src/main/resources/Java_16_Grammar.y":1313 */ - { yyval = new ParameterDeclaration(((Modifiers)(yystack.valueAt (3))),null,((Token)(yystack.valueAt (1))).image,null,false,((Dims)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1371 */ + { yyval = new ParameterDeclarations(((ParameterDeclaration)(yystack.valueAt (0)))); }; break; - case 371: /* LambdaParameter: ModifierSeqOpt UnannotatedType AnnotationSeqOpt ELLIPSIS IDENTIFIER */ + case 371: /* LambdaParameterList: LambdaParameterList COMMA LambdaParameter */ if (yyn == 371) - /* "src/main/resources/Java_16_Grammar.y":1315 */ - { yyval = new ParameterDeclaration(((Modifiers)(yystack.valueAt (4))),((tree.Type.UnannotatedType)(yystack.valueAt (3))),((Token)(yystack.valueAt (0))).image,((Annotations)(yystack.valueAt (2))),true,null); }; + /* "src/main/resources/Java_16_Grammar.y":1372 */ + { yyval = ((ParameterDeclarations)(yystack.valueAt (2))).add(((ParameterDeclaration)(yystack.valueAt (0)))); }; break; - case 372: /* AssignmentExpression: ConditionalExpression */ + case 372: /* LambdaParameter: ModifierSeqOpt UnannotatedType IDENTIFIER DimsOpt */ if (yyn == 372) - /* "src/main/resources/Java_16_Grammar.y":1324 */ - { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":1387 */ + { yyval = new ParameterDeclaration(((Modifiers)(yystack.valueAt (3))),((tree.Type.UnannotatedType)(yystack.valueAt (2))),((Token)(yystack.valueAt (1))).image,null,false,((Dims)(yystack.valueAt (0)))); }; break; - case 373: /* AssignmentExpression: Assignment */ + case 373: /* LambdaParameter: ModifierSeqOpt VAR IDENTIFIER DimsOpt */ if (yyn == 373) - /* "src/main/resources/Java_16_Grammar.y":1325 */ - { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":1388 */ + { yyval = new ParameterDeclaration(((Modifiers)(yystack.valueAt (3))),null,((Token)(yystack.valueAt (1))).image,null,false,((Dims)(yystack.valueAt (0)))); }; break; - case 374: /* Assignment: LeftHandSide AssignmentOperator Expression */ + case 374: /* LambdaParameter: ModifierSeqOpt UnannotatedType AnnotationSeqOpt ELLIPSIS IDENTIFIER */ if (yyn == 374) - /* "src/main/resources/Java_16_Grammar.y":1329 */ - { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; + /* "src/main/resources/Java_16_Grammar.y":1390 */ + { yyval = new ParameterDeclaration(((Modifiers)(yystack.valueAt (4))),((tree.Type.UnannotatedType)(yystack.valueAt (3))),((Token)(yystack.valueAt (0))).image,((Annotations)(yystack.valueAt (2))),true,null); }; break; - case 375: /* LeftHandSide: CompoundName */ + case 375: /* AssignmentExpression: ConditionalExpression */ if (yyn == 375) - /* "src/main/resources/Java_16_Grammar.y":1333 */ - { yyval = new SimpleReference(((CompoundName)(yystack.valueAt (0)))); }; + /* "src/main/resources/Java_16_Grammar.y":1399 */ + { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 376: /* LeftHandSide: FieldAccess */ + case 376: /* AssignmentExpression: Assignment */ if (yyn == 376) - /* "src/main/resources/Java_16_Grammar.y":1334 */ - { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":1400 */ + { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 377: /* LeftHandSide: ArrayAccess */ + case 377: /* Assignment: LeftHandSide AssignmentOperator Expression */ if (yyn == 377) - /* "src/main/resources/Java_16_Grammar.y":1335 */ - { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":1404 */ + { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 378: /* AssignmentOperator: EQUAL */ + case 378: /* LeftHandSide: CompoundName */ if (yyn == 378) - /* "src/main/resources/Java_16_Grammar.y":1339 */ - { yyval = ((Token)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":1408 */ + { yyval = new SimpleReference(((CompoundName)(yystack.valueAt (0)))); }; break; - case 379: /* AssignmentOperator: STAR_EQUAL */ + case 379: /* LeftHandSide: FieldAccess */ if (yyn == 379) - /* "src/main/resources/Java_16_Grammar.y":1340 */ - { yyval = ((Token)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":1409 */ + { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 380: /* AssignmentOperator: SLASH_EQUAL */ + case 380: /* LeftHandSide: ArrayAccess */ if (yyn == 380) - /* "src/main/resources/Java_16_Grammar.y":1341 */ - { yyval = ((Token)(yystack.valueAt (0))); }; + /* "src/main/resources/Java_16_Grammar.y":1410 */ + { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 381: /* AssignmentOperator: PERCENT_EQUAL */ + case 381: /* AssignmentOperator: EQUAL */ if (yyn == 381) - /* "src/main/resources/Java_16_Grammar.y":1342 */ + /* "src/main/resources/Java_16_Grammar.y":1414 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; - case 382: /* AssignmentOperator: PLUS_EQUAL */ + case 382: /* AssignmentOperator: STAR_EQUAL */ if (yyn == 382) - /* "src/main/resources/Java_16_Grammar.y":1343 */ + /* "src/main/resources/Java_16_Grammar.y":1415 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; - case 383: /* AssignmentOperator: MINUS_EQUAL */ + case 383: /* AssignmentOperator: SLASH_EQUAL */ if (yyn == 383) - /* "src/main/resources/Java_16_Grammar.y":1344 */ + /* "src/main/resources/Java_16_Grammar.y":1416 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; - case 384: /* AssignmentOperator: LESS_LESS_EQUAL */ + case 384: /* AssignmentOperator: PERCENT_EQUAL */ if (yyn == 384) - /* "src/main/resources/Java_16_Grammar.y":1345 */ + /* "src/main/resources/Java_16_Grammar.y":1417 */ + { yyval = ((Token)(yystack.valueAt (0))); }; + break; + + + case 385: /* AssignmentOperator: PLUS_EQUAL */ + if (yyn == 385) + /* "src/main/resources/Java_16_Grammar.y":1418 */ + { yyval = ((Token)(yystack.valueAt (0))); }; + break; + + + case 386: /* AssignmentOperator: MINUS_EQUAL */ + if (yyn == 386) + /* "src/main/resources/Java_16_Grammar.y":1419 */ + { yyval = ((Token)(yystack.valueAt (0))); }; + break; + + + case 387: /* AssignmentOperator: LESS_LESS_EQUAL */ + if (yyn == 387) + /* "src/main/resources/Java_16_Grammar.y":1420 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; - case 385: /* AssignmentOperator: GR_GR_EQUAL */ - if (yyn == 385) - /* "src/main/resources/Java_16_Grammar.y":1346 */ + case 388: /* AssignmentOperator: GR_GR_EQUAL */ + if (yyn == 388) + /* "src/main/resources/Java_16_Grammar.y":1421 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; - case 386: /* AssignmentOperator: GR_GR_GR_EQUAL */ - if (yyn == 386) - /* "src/main/resources/Java_16_Grammar.y":1347 */ + case 389: /* AssignmentOperator: GR_GR_GR_EQUAL */ + if (yyn == 389) + /* "src/main/resources/Java_16_Grammar.y":1422 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; - case 387: /* AssignmentOperator: AMP_EQUAL */ - if (yyn == 387) - /* "src/main/resources/Java_16_Grammar.y":1348 */ + case 390: /* AssignmentOperator: AMP_EQUAL */ + if (yyn == 390) + /* "src/main/resources/Java_16_Grammar.y":1423 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; - case 388: /* AssignmentOperator: CARET_EQUAL */ - if (yyn == 388) - /* "src/main/resources/Java_16_Grammar.y":1349 */ + case 391: /* AssignmentOperator: CARET_EQUAL */ + if (yyn == 391) + /* "src/main/resources/Java_16_Grammar.y":1424 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; - case 389: /* AssignmentOperator: VERTICAL_EQUAL */ - if (yyn == 389) - /* "src/main/resources/Java_16_Grammar.y":1350 */ + case 392: /* AssignmentOperator: VERTICAL_EQUAL */ + if (yyn == 392) + /* "src/main/resources/Java_16_Grammar.y":1425 */ { yyval = ((Token)(yystack.valueAt (0))); }; break; - case 390: /* ConditionalExpression: ConditionalOrExpression ConditionalOrTail */ - if (yyn == 390) - /* "src/main/resources/Java_16_Grammar.y":1354 */ + case 393: /* ConditionalExpression: ConditionalOrExpression ConditionalOrTail */ + if (yyn == 393) + /* "src/main/resources/Java_16_Grammar.y":1429 */ { if ( ((tree.Expression.Binary)(yystack.valueAt (0))) == null ) yyval = ((tree.Expression.Expression)(yystack.valueAt (1))); else yyval = new Conditional(((tree.Expression.Expression)(yystack.valueAt (1))),((tree.Expression.Binary)(yystack.valueAt (0))).left,((tree.Expression.Binary)(yystack.valueAt (0))).right); }; break; - case 391: /* ConditionalOrTail: %empty */ - if (yyn == 391) - /* "src/main/resources/Java_16_Grammar.y":1359 */ + case 394: /* ConditionalOrTail: %empty */ + if (yyn == 394) + /* "src/main/resources/Java_16_Grammar.y":1434 */ { yyval = null; }; break; - case 392: /* ConditionalOrTail: QUESTION Expression COLON ConditionalExpression */ - if (yyn == 392) - /* "src/main/resources/Java_16_Grammar.y":1360 */ + case 395: /* ConditionalOrTail: QUESTION Expression COLON ConditionalExpression */ + if (yyn == 395) + /* "src/main/resources/Java_16_Grammar.y":1435 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),null); }; break; - case 393: /* ConditionalOrTail: QUESTION Expression COLON LambdaExpression */ - if (yyn == 393) - /* "src/main/resources/Java_16_Grammar.y":1361 */ + case 396: /* ConditionalOrTail: QUESTION Expression COLON LambdaExpression */ + if (yyn == 396) + /* "src/main/resources/Java_16_Grammar.y":1436 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),null); }; break; - case 394: /* ConditionalOrExpression: ConditionalAndExpression */ - if (yyn == 394) - /* "src/main/resources/Java_16_Grammar.y":1365 */ + case 397: /* ConditionalOrExpression: ConditionalAndExpression */ + if (yyn == 397) + /* "src/main/resources/Java_16_Grammar.y":1440 */ { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 395: /* ConditionalOrExpression: ConditionalOrExpression DBL_VERTICAL ConditionalAndExpression */ - if (yyn == 395) - /* "src/main/resources/Java_16_Grammar.y":1366 */ + case 398: /* ConditionalOrExpression: ConditionalOrExpression DBL_VERTICAL ConditionalAndExpression */ + if (yyn == 398) + /* "src/main/resources/Java_16_Grammar.y":1441 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 396: /* ConditionalAndExpression: InclusiveOrExpression */ - if (yyn == 396) - /* "src/main/resources/Java_16_Grammar.y":1370 */ + case 399: /* ConditionalAndExpression: InclusiveOrExpression */ + if (yyn == 399) + /* "src/main/resources/Java_16_Grammar.y":1445 */ { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 397: /* ConditionalAndExpression: ConditionalAndExpression DBL_AMPERSAND InclusiveOrExpression */ - if (yyn == 397) - /* "src/main/resources/Java_16_Grammar.y":1371 */ + case 400: /* ConditionalAndExpression: ConditionalAndExpression DBL_AMPERSAND InclusiveOrExpression */ + if (yyn == 400) + /* "src/main/resources/Java_16_Grammar.y":1446 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 398: /* InclusiveOrExpression: ExclusiveOrExpression */ - if (yyn == 398) - /* "src/main/resources/Java_16_Grammar.y":1375 */ + case 401: /* InclusiveOrExpression: ExclusiveOrExpression */ + if (yyn == 401) + /* "src/main/resources/Java_16_Grammar.y":1450 */ { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 399: /* InclusiveOrExpression: InclusiveOrExpression VERTICAL ExclusiveOrExpression */ - if (yyn == 399) - /* "src/main/resources/Java_16_Grammar.y":1376 */ + case 402: /* InclusiveOrExpression: InclusiveOrExpression VERTICAL ExclusiveOrExpression */ + if (yyn == 402) + /* "src/main/resources/Java_16_Grammar.y":1451 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 400: /* ExclusiveOrExpression: AndExpression */ - if (yyn == 400) - /* "src/main/resources/Java_16_Grammar.y":1380 */ + case 403: /* ExclusiveOrExpression: AndExpression */ + if (yyn == 403) + /* "src/main/resources/Java_16_Grammar.y":1455 */ { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 401: /* ExclusiveOrExpression: ExclusiveOrExpression CARET AndExpression */ - if (yyn == 401) - /* "src/main/resources/Java_16_Grammar.y":1381 */ + case 404: /* ExclusiveOrExpression: ExclusiveOrExpression CARET AndExpression */ + if (yyn == 404) + /* "src/main/resources/Java_16_Grammar.y":1456 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 402: /* AndExpression: EqualityExpression */ - if (yyn == 402) - /* "src/main/resources/Java_16_Grammar.y":1385 */ + case 405: /* AndExpression: EqualityExpression */ + if (yyn == 405) + /* "src/main/resources/Java_16_Grammar.y":1460 */ { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 403: /* AndExpression: AndExpression AMPERSAND EqualityExpression */ - if (yyn == 403) - /* "src/main/resources/Java_16_Grammar.y":1386 */ + case 406: /* AndExpression: AndExpression AMPERSAND EqualityExpression */ + if (yyn == 406) + /* "src/main/resources/Java_16_Grammar.y":1461 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 404: /* EqualityExpression: RelationalExpression */ - if (yyn == 404) - /* "src/main/resources/Java_16_Grammar.y":1390 */ + case 407: /* EqualityExpression: RelationalExpression */ + if (yyn == 407) + /* "src/main/resources/Java_16_Grammar.y":1465 */ { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 405: /* EqualityExpression: EqualityExpression DBL_EQUAL RelationalExpression */ - if (yyn == 405) - /* "src/main/resources/Java_16_Grammar.y":1391 */ + case 408: /* EqualityExpression: EqualityExpression DBL_EQUAL RelationalExpression */ + if (yyn == 408) + /* "src/main/resources/Java_16_Grammar.y":1466 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 406: /* EqualityExpression: EqualityExpression NON_EQUAL RelationalExpression */ - if (yyn == 406) - /* "src/main/resources/Java_16_Grammar.y":1392 */ + case 409: /* EqualityExpression: EqualityExpression NON_EQUAL RelationalExpression */ + if (yyn == 409) + /* "src/main/resources/Java_16_Grammar.y":1467 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 407: /* RelationalExpression: ShiftExpression */ - if (yyn == 407) - /* "src/main/resources/Java_16_Grammar.y":1396 */ + case 410: /* RelationalExpression: ShiftExpression */ + if (yyn == 410) + /* "src/main/resources/Java_16_Grammar.y":1471 */ { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 408: /* RelationalExpression: RelationalExpression LESS ShiftExpression */ - if (yyn == 408) - /* "src/main/resources/Java_16_Grammar.y":1397 */ + case 411: /* RelationalExpression: RelationalExpression LESS ShiftExpression */ + if (yyn == 411) + /* "src/main/resources/Java_16_Grammar.y":1472 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 409: /* RelationalExpression: RelationalExpression GREATER ShiftExpression */ - if (yyn == 409) - /* "src/main/resources/Java_16_Grammar.y":1398 */ + case 412: /* RelationalExpression: RelationalExpression GREATER ShiftExpression */ + if (yyn == 412) + /* "src/main/resources/Java_16_Grammar.y":1473 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 410: /* RelationalExpression: RelationalExpression LESS_EQUAL ShiftExpression */ - if (yyn == 410) - /* "src/main/resources/Java_16_Grammar.y":1399 */ + case 413: /* RelationalExpression: RelationalExpression LESS_EQUAL ShiftExpression */ + if (yyn == 413) + /* "src/main/resources/Java_16_Grammar.y":1474 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 411: /* RelationalExpression: RelationalExpression GREATER_EQUAL ShiftExpression */ - if (yyn == 411) - /* "src/main/resources/Java_16_Grammar.y":1400 */ + case 414: /* RelationalExpression: RelationalExpression GREATER_EQUAL ShiftExpression */ + if (yyn == 414) + /* "src/main/resources/Java_16_Grammar.y":1475 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 412: /* RelationalExpression: InstanceofExpression */ - if (yyn == 412) - /* "src/main/resources/Java_16_Grammar.y":1401 */ + case 415: /* RelationalExpression: InstanceofExpression */ + if (yyn == 415) + /* "src/main/resources/Java_16_Grammar.y":1476 */ { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 413: /* InstanceofExpression: RelationalExpression INSTANCEOF Type */ - if (yyn == 413) - /* "src/main/resources/Java_16_Grammar.y":1405 */ + case 416: /* InstanceofExpression: RelationalExpression INSTANCEOF Type */ + if (yyn == 416) + /* "src/main/resources/Java_16_Grammar.y":1480 */ { yyval = new InstanceOf(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Type.Type)(yystack.valueAt (0)))); }; break; - case 414: /* InstanceofExpression: RelationalExpression INSTANCEOF Pattern */ - if (yyn == 414) - /* "src/main/resources/Java_16_Grammar.y":1406 */ + case 417: /* InstanceofExpression: RelationalExpression INSTANCEOF Pattern */ + if (yyn == 417) + /* "src/main/resources/Java_16_Grammar.y":1481 */ { yyval = new InstanceOf(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Declaration.Declaration)(yystack.valueAt (0)))); }; break; - case 415: /* ShiftExpression: AdditiveExpression */ - if (yyn == 415) - /* "src/main/resources/Java_16_Grammar.y":1410 */ + case 418: /* ShiftExpression: AdditiveExpression */ + if (yyn == 418) + /* "src/main/resources/Java_16_Grammar.y":1485 */ { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 416: /* ShiftExpression: ShiftExpression DBL_LESS AdditiveExpression */ - if (yyn == 416) - /* "src/main/resources/Java_16_Grammar.y":1411 */ + case 419: /* ShiftExpression: ShiftExpression DBL_LESS AdditiveExpression */ + if (yyn == 419) + /* "src/main/resources/Java_16_Grammar.y":1486 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 417: /* ShiftExpression: ShiftExpression DBL_GREATER AdditiveExpression */ - if (yyn == 417) - /* "src/main/resources/Java_16_Grammar.y":1412 */ + case 420: /* ShiftExpression: ShiftExpression DBL_GREATER AdditiveExpression */ + if (yyn == 420) + /* "src/main/resources/Java_16_Grammar.y":1487 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 418: /* ShiftExpression: ShiftExpression TRIPL_GREATER AdditiveExpression */ - if (yyn == 418) - /* "src/main/resources/Java_16_Grammar.y":1413 */ + case 421: /* ShiftExpression: ShiftExpression TRIPL_GREATER AdditiveExpression */ + if (yyn == 421) + /* "src/main/resources/Java_16_Grammar.y":1488 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 419: /* AdditiveExpression: MultiplicativeExpression */ - if (yyn == 419) - /* "src/main/resources/Java_16_Grammar.y":1417 */ + case 422: /* AdditiveExpression: MultiplicativeExpression */ + if (yyn == 422) + /* "src/main/resources/Java_16_Grammar.y":1492 */ { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 420: /* AdditiveExpression: AdditiveExpression PLUS MultiplicativeExpression */ - if (yyn == 420) - /* "src/main/resources/Java_16_Grammar.y":1418 */ + case 423: /* AdditiveExpression: AdditiveExpression PLUS MultiplicativeExpression */ + if (yyn == 423) + /* "src/main/resources/Java_16_Grammar.y":1493 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 421: /* AdditiveExpression: AdditiveExpression MINUS MultiplicativeExpression */ - if (yyn == 421) - /* "src/main/resources/Java_16_Grammar.y":1419 */ + case 424: /* AdditiveExpression: AdditiveExpression MINUS MultiplicativeExpression */ + if (yyn == 424) + /* "src/main/resources/Java_16_Grammar.y":1494 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 422: /* MultiplicativeExpression: UnaryExpression */ - if (yyn == 422) - /* "src/main/resources/Java_16_Grammar.y":1423 */ + case 425: /* MultiplicativeExpression: UnaryExpression */ + if (yyn == 425) + /* "src/main/resources/Java_16_Grammar.y":1498 */ { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 423: /* MultiplicativeExpression: MultiplicativeExpression STAR UnaryExpression */ - if (yyn == 423) - /* "src/main/resources/Java_16_Grammar.y":1424 */ + case 426: /* MultiplicativeExpression: MultiplicativeExpression STAR UnaryExpression */ + if (yyn == 426) + /* "src/main/resources/Java_16_Grammar.y":1499 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 424: /* MultiplicativeExpression: MultiplicativeExpression SLASH UnaryExpression */ - if (yyn == 424) - /* "src/main/resources/Java_16_Grammar.y":1425 */ + case 427: /* MultiplicativeExpression: MultiplicativeExpression SLASH UnaryExpression */ + if (yyn == 427) + /* "src/main/resources/Java_16_Grammar.y":1500 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 425: /* MultiplicativeExpression: MultiplicativeExpression PERCENT UnaryExpression */ - if (yyn == 425) - /* "src/main/resources/Java_16_Grammar.y":1426 */ + case 428: /* MultiplicativeExpression: MultiplicativeExpression PERCENT UnaryExpression */ + if (yyn == 428) + /* "src/main/resources/Java_16_Grammar.y":1501 */ { yyval = new Binary(((tree.Expression.Expression)(yystack.valueAt (2))),((tree.Expression.Expression)(yystack.valueAt (0))),((Token)(yystack.valueAt (1)))); }; break; - case 426: /* UnaryExpression: PreIncrementExpression */ - if (yyn == 426) - /* "src/main/resources/Java_16_Grammar.y":1430 */ + case 429: /* UnaryExpression: PreIncrementExpression */ + if (yyn == 429) + /* "src/main/resources/Java_16_Grammar.y":1505 */ { yyval = ((UnaryPrefix)(yystack.valueAt (0))); }; break; - case 427: /* UnaryExpression: PreDecrementExpression */ - if (yyn == 427) - /* "src/main/resources/Java_16_Grammar.y":1431 */ + case 430: /* UnaryExpression: PreDecrementExpression */ + if (yyn == 430) + /* "src/main/resources/Java_16_Grammar.y":1506 */ { yyval = ((UnaryPrefix)(yystack.valueAt (0))); }; break; - case 428: /* UnaryExpression: PLUS UnaryExpression */ - if (yyn == 428) - /* "src/main/resources/Java_16_Grammar.y":1432 */ + case 431: /* UnaryExpression: PLUS UnaryExpression */ + if (yyn == 431) + /* "src/main/resources/Java_16_Grammar.y":1507 */ { yyval = new UnaryPrefix(((Token)(yystack.valueAt (1))),((tree.Expression.Expression)(yystack.valueAt (0)))); }; break; - case 429: /* UnaryExpression: MINUS UnaryExpression */ - if (yyn == 429) - /* "src/main/resources/Java_16_Grammar.y":1433 */ + case 432: /* UnaryExpression: MINUS UnaryExpression */ + if (yyn == 432) + /* "src/main/resources/Java_16_Grammar.y":1508 */ { yyval = new UnaryPrefix(((Token)(yystack.valueAt (1))),((tree.Expression.Expression)(yystack.valueAt (0)))); }; break; - case 430: /* UnaryExpression: UnaryExpressionNotPlusMinus */ - if (yyn == 430) - /* "src/main/resources/Java_16_Grammar.y":1434 */ + case 433: /* UnaryExpression: UnaryExpressionNotPlusMinus */ + if (yyn == 433) + /* "src/main/resources/Java_16_Grammar.y":1509 */ { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 431: /* PreIncrementExpression: DBL_PLUS UnaryExpression */ - if (yyn == 431) - /* "src/main/resources/Java_16_Grammar.y":1438 */ + case 434: /* PreIncrementExpression: DBL_PLUS UnaryExpression */ + if (yyn == 434) + /* "src/main/resources/Java_16_Grammar.y":1513 */ { yyval = new UnaryPrefix(((Token)(yystack.valueAt (1))),((tree.Expression.Expression)(yystack.valueAt (0)))); }; break; - case 432: /* PreDecrementExpression: DBL_MINUS UnaryExpression */ - if (yyn == 432) - /* "src/main/resources/Java_16_Grammar.y":1442 */ + case 435: /* PreDecrementExpression: DBL_MINUS UnaryExpression */ + if (yyn == 435) + /* "src/main/resources/Java_16_Grammar.y":1517 */ { yyval = new UnaryPrefix(((Token)(yystack.valueAt (1))),((tree.Expression.Expression)(yystack.valueAt (0)))); }; break; - case 434: /* UnaryExpressionNotPlusMinus: TILDE UnaryExpression */ - if (yyn == 434) - /* "src/main/resources/Java_16_Grammar.y":1447 */ + case 437: /* UnaryExpressionNotPlusMinus: TILDE UnaryExpression */ + if (yyn == 437) + /* "src/main/resources/Java_16_Grammar.y":1522 */ { yyval = new UnaryPrefix(((Token)(yystack.valueAt (1))),((tree.Expression.Expression)(yystack.valueAt (0)))); }; break; - case 435: /* UnaryExpressionNotPlusMinus: EXCLAMATION UnaryExpression */ - if (yyn == 435) - /* "src/main/resources/Java_16_Grammar.y":1448 */ + case 438: /* UnaryExpressionNotPlusMinus: EXCLAMATION UnaryExpression */ + if (yyn == 438) + /* "src/main/resources/Java_16_Grammar.y":1523 */ { yyval = new UnaryPrefix(((Token)(yystack.valueAt (1))),((tree.Expression.Expression)(yystack.valueAt (0)))); }; break; - case 436: /* UnaryExpressionNotPlusMinus: SwitchExpression */ - if (yyn == 436) - /* "src/main/resources/Java_16_Grammar.y":1450 */ + case 439: /* UnaryExpressionNotPlusMinus: SwitchExpression */ + if (yyn == 439) + /* "src/main/resources/Java_16_Grammar.y":1525 */ { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; break; - case 437: /* PostfixExpression: Primary */ - if (yyn == 437) - /* "src/main/resources/Java_16_Grammar.y":1454 */ - { yyval = ((tree.Expression.Expression)(yystack.valueAt (0))); }; + case 440: /* PostfixExpression: Primary */ + if (yyn == 440) + /* "src/main/resources/Java_16_Grammar.y":1529 */ + { yyval = ((Primary)(yystack.valueAt (0))); }; break; - case 438: /* PostfixExpression: CompoundName */ - if (yyn == 438) - /* "src/main/resources/Java_16_Grammar.y":1455 */ + case 441: /* PostfixExpression: CompoundName */ + if (yyn == 441) + /* "src/main/resources/Java_16_Grammar.y":1530 */ { yyval = new SimpleReference(((CompoundName)(yystack.valueAt (0)))); }; break; - case 439: /* PostfixExpression: PostIncrementExpression */ - if (yyn == 439) - /* "src/main/resources/Java_16_Grammar.y":1456 */ + case 442: /* PostfixExpression: PostIncrementExpression */ + if (yyn == 442) + /* "src/main/resources/Java_16_Grammar.y":1531 */ { yyval = ((UnaryPostfix)(yystack.valueAt (0))); }; break; - case 440: /* PostfixExpression: PostDecrementExpression */ - if (yyn == 440) - /* "src/main/resources/Java_16_Grammar.y":1457 */ + case 443: /* PostfixExpression: PostDecrementExpression */ + if (yyn == 443) + /* "src/main/resources/Java_16_Grammar.y":1532 */ { yyval = ((UnaryPostfix)(yystack.valueAt (0))); }; break; - case 441: /* PostIncrementExpression: PostfixExpression DBL_PLUS */ - if (yyn == 441) - /* "src/main/resources/Java_16_Grammar.y":1461 */ + case 444: /* PostIncrementExpression: PostfixExpression DBL_PLUS */ + if (yyn == 444) + /* "src/main/resources/Java_16_Grammar.y":1536 */ { yyval = new UnaryPostfix(((Token)(yystack.valueAt (0))),((tree.Expression.Expression)(yystack.valueAt (1)))); }; break; - case 442: /* PostDecrementExpression: PostfixExpression DBL_MINUS */ - if (yyn == 442) - /* "src/main/resources/Java_16_Grammar.y":1465 */ + case 445: /* PostDecrementExpression: PostfixExpression DBL_MINUS */ + if (yyn == 445) + /* "src/main/resources/Java_16_Grammar.y":1540 */ { yyval = new UnaryPostfix(((Token)(yystack.valueAt (0))),((tree.Expression.Expression)(yystack.valueAt (1)))); }; break; - case 443: /* SwitchExpression: SWITCH LPAREN Expression RPAREN SwitchBlock */ - if (yyn == 443) - /* "src/main/resources/Java_16_Grammar.y":1483 */ + case 446: /* SwitchExpression: SWITCH LPAREN Expression RPAREN SwitchBlock */ + if (yyn == 446) + /* "src/main/resources/Java_16_Grammar.y":1558 */ { yyval = new SwitchExpression(((tree.Expression.Expression)(yystack.valueAt (2))),((SwitchBlock)(yystack.valueAt (0)))); }; break; - case 444: /* AnnotationSeqOpt: %empty */ - if (yyn == 444) - /* "src/main/resources/Java_16_Grammar.y":1495 */ + case 447: /* AnnotationSeqOpt: %empty */ + if (yyn == 447) + /* "src/main/resources/Java_16_Grammar.y":1570 */ { yyval = null; }; break; - case 445: /* AnnotationSeqOpt: AnnotationSeq */ - if (yyn == 445) - /* "src/main/resources/Java_16_Grammar.y":1496 */ + case 448: /* AnnotationSeqOpt: AnnotationSeq */ + if (yyn == 448) + /* "src/main/resources/Java_16_Grammar.y":1571 */ { yyval = ((Annotations)(yystack.valueAt (0))); }; break; - case 446: /* AnnotationSeq: Annotation */ - if (yyn == 446) - /* "src/main/resources/Java_16_Grammar.y":1500 */ + case 449: /* AnnotationSeq: Annotation */ + if (yyn == 449) + /* "src/main/resources/Java_16_Grammar.y":1575 */ { yyval = new Annotations(((Annotation)(yystack.valueAt (0)))); }; break; - case 447: /* AnnotationSeq: AnnotationSeq Annotation */ - if (yyn == 447) - /* "src/main/resources/Java_16_Grammar.y":1501 */ + case 450: /* AnnotationSeq: AnnotationSeq Annotation */ + if (yyn == 450) + /* "src/main/resources/Java_16_Grammar.y":1576 */ { yyval = ((Annotations)(yystack.valueAt (1))).add(((Annotation)(yystack.valueAt (0)))); }; break; - case 448: /* Annotation: AT CompoundName */ - if (yyn == 448) - /* "src/main/resources/Java_16_Grammar.y":1505 */ + case 451: /* Annotation: AT CompoundName */ + if (yyn == 451) + /* "src/main/resources/Java_16_Grammar.y":1580 */ { yyval = new Annotation(((CompoundName)(yystack.valueAt (0))),(AnnoParameterList)null); }; break; - case 449: /* Annotation: AT CompoundName LPAREN RPAREN */ - if (yyn == 449) - /* "src/main/resources/Java_16_Grammar.y":1506 */ + case 452: /* Annotation: AT CompoundName LPAREN RPAREN */ + if (yyn == 452) + /* "src/main/resources/Java_16_Grammar.y":1581 */ { yyval = new Annotation(((CompoundName)(yystack.valueAt (2))),(AnnoParameterList)null); }; break; - case 450: /* Annotation: AT CompoundName LPAREN AnnoParameterList RPAREN */ - if (yyn == 450) - /* "src/main/resources/Java_16_Grammar.y":1507 */ + case 453: /* Annotation: AT CompoundName LPAREN AnnoParameterList RPAREN */ + if (yyn == 453) + /* "src/main/resources/Java_16_Grammar.y":1582 */ { yyval = new Annotation(((CompoundName)(yystack.valueAt (3))),/*$4*/ (AnnoParameterList)null); }; break; - case 451: /* Annotation: AT CompoundName LPAREN ElementValue RPAREN */ - if (yyn == 451) - /* "src/main/resources/Java_16_Grammar.y":1508 */ + case 454: /* Annotation: AT CompoundName LPAREN ElementValue RPAREN */ + if (yyn == 454) + /* "src/main/resources/Java_16_Grammar.y":1583 */ { yyval = new Annotation(((CompoundName)(yystack.valueAt (3))),(AnnoElementValue)null); }; break; - case 452: /* AnnoParameterList: IDENTIFIER EQUAL ElementValue */ - if (yyn == 452) - /* "src/main/resources/Java_16_Grammar.y":1512 */ + case 455: /* AnnoParameterList: IDENTIFIER EQUAL ElementValue */ + if (yyn == 455) + /* "src/main/resources/Java_16_Grammar.y":1587 */ { yyval = null; }; break; - case 453: /* AnnoParameterList: AnnoParameterList COMMA IDENTIFIER EQUAL ElementValue */ - if (yyn == 453) - /* "src/main/resources/Java_16_Grammar.y":1513 */ + case 456: /* AnnoParameterList: AnnoParameterList COMMA IDENTIFIER EQUAL ElementValue */ + if (yyn == 456) + /* "src/main/resources/Java_16_Grammar.y":1588 */ { yyval = null; }; break; - case 454: /* ElementValue: ConditionalExpression */ - if (yyn == 454) - /* "src/main/resources/Java_16_Grammar.y":1517 */ + case 457: /* ElementValue: ConditionalExpression */ + if (yyn == 457) + /* "src/main/resources/Java_16_Grammar.y":1592 */ { yyval = null; }; break; - case 455: /* ElementValue: LBRACE ElementValueListOpt RBRACE */ - if (yyn == 455) - /* "src/main/resources/Java_16_Grammar.y":1518 */ + case 458: /* ElementValue: LBRACE ElementValueListOpt RBRACE */ + if (yyn == 458) + /* "src/main/resources/Java_16_Grammar.y":1593 */ { yyval = null; }; break; - case 456: /* ElementValue: LBRACE COMMA RBRACE */ - if (yyn == 456) - /* "src/main/resources/Java_16_Grammar.y":1519 */ + case 459: /* ElementValue: LBRACE COMMA RBRACE */ + if (yyn == 459) + /* "src/main/resources/Java_16_Grammar.y":1594 */ { yyval = null; }; break; - case 457: /* ElementValue: Annotation */ - if (yyn == 457) - /* "src/main/resources/Java_16_Grammar.y":1520 */ + case 460: /* ElementValue: Annotation */ + if (yyn == 460) + /* "src/main/resources/Java_16_Grammar.y":1595 */ { yyval = null; }; break; -/* "src/main/java/parser/JavaParser.java":4111 */ +/* "src/main/java/parser/JavaParser.java":4200 */ default: break; } @@ -4521,8 +4610,8 @@ private static boolean yyTableValueIsError (int yyvalue) return yyvalue == yytable_ninf_; } - private static final short yypact_ninf_ = -620; - private static final short yytable_ninf_ = -458; + private static final short yypact_ninf_ = -609; + private static final short yytable_ninf_ = -461; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ @@ -4531,89 +4620,88 @@ private static final short[] yypact_init() { return new short[] { - 26, -18, 17, 142, -620, 4079, -620, -620, -620, 17, - 452, 525, -620, 17, -620, -620, -620, -620, -620, -620, - -620, -620, -620, -620, -620, -620, 777, -620, 4380, -620, - -620, 806, 4321, -620, 551, 33, -620, 132, 150, 155, - 76, 211, 217, 225, 184, -620, -620, -620, -620, -620, - -620, -620, -620, -620, 777, 4380, -620, 55, -620, 308, - -620, 483, 2790, 312, 289, 364, 364, 334, -620, 384, - -620, -620, 1266, 3450, -620, 2856, 3516, 3516, 3516, 3516, - 3516, 3516, 375, -620, -620, -620, -620, -620, -620, -620, - -620, -620, -620, -620, -620, 4364, -620, -620, 436, 427, - -620, -620, 311, -620, 387, 448, 311, -620, 492, -620, - -620, -620, -620, -620, -620, -620, -620, 135, 430, 472, - 477, 481, 197, 218, -620, 465, 542, 541, -620, -620, - -620, -620, 526, -620, -620, -620, 1833, 486, 295, 538, - 562, 1833, 569, 67, 501, -620, 585, 364, -620, 2678, - 522, 4479, 338, 891, 578, -620, 566, -620, -620, 1001, - -620, 586, -620, 485, -620, -620, -620, -620, -620, -620, - 2988, 2642, 266, 380, 576, -620, 41, 577, 3450, 590, - 599, 311, -620, 386, 3054, 3450, 12, -620, -620, 426, - 577, 600, -620, 3450, 9, 577, 3450, 3516, -620, 3516, - 3516, 3516, 3516, 3516, 3516, 3516, 3516, 3516, 3516, 1511, - 3516, 3516, 3516, 3516, 3516, 3516, 3516, 3516, -620, -620, - 311, -620, 556, -620, 1104, -620, -620, 605, 97, -620, - 545, 422, -620, -620, 67, 1833, 610, 608, 307, 289, - 546, -620, 1083, 333, -620, 4300, 3120, -620, 3120, -620, - -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, - -620, 3450, -620, -620, 2988, -620, 66, -620, 431, -620, - 4392, 3186, 409, 380, -620, 447, 619, 284, 572, 576, - -620, 582, 583, 625, -620, 563, -620, 624, -620, 424, - -620, 631, 577, 623, -620, 589, 628, -620, -9, 587, - 638, -620, -620, 592, 595, 639, 430, 472, 477, 481, - 197, 218, 218, 465, 465, 465, 465, 601, -620, 240, - -620, -620, 542, 542, 542, 541, 541, -620, -620, -620, - 626, -620, 4257, 4030, 1833, 332, 648, -620, 603, 1833, - 67, -620, -620, -620, 4051, -620, 1833, 441, -620, 1946, - 654, 1833, 289, 606, 242, -620, 4321, 1878, -620, -620, - -620, -620, -620, -620, 1833, 1833, 2642, -620, 118, 652, - 3252, -620, -620, -620, 3318, 658, 576, -620, -620, -620, - 619, -620, 659, -620, -620, -620, 3450, -620, 105, 619, - 577, -620, -620, -620, -620, 619, -620, 3450, 236, 656, - -620, 656, 2988, 601, 250, -620, -620, -620, -620, -620, - -620, 4257, -620, 657, 1382, 661, 576, 619, -620, 660, - 616, 1833, -620, -620, 4145, 4090, -620, -620, 576, 252, - 3839, -620, -620, 658, 311, 311, 642, 386, -620, 665, - -620, -620, 666, 3450, 34, 52, 2574, 676, 677, 3384, - 679, 680, 3450, 471, 683, 3450, 2729, 1715, -620, 1994, - -620, 678, -620, -620, -620, 682, -620, -620, -620, -620, - -620, 398, 464, -620, -620, -620, 526, 535, 555, -620, - -620, -620, 1833, 1833, -620, -620, 494, 685, -620, -620, - 687, 3878, -620, -620, 643, -620, 38, -620, -620, -620, - 644, -620, 646, -620, -620, -620, 3450, 282, 601, -620, - 475, 700, -620, 698, -620, 701, 4145, 3931, -620, -620, - -620, -620, 658, 1833, -620, 650, 260, -620, 2529, 57, - -620, -620, -620, -620, -620, 4145, -620, -620, 681, -620, - 4202, -620, 3970, -620, -620, -620, -620, 653, -620, 2574, - 574, -620, 702, -620, 708, 680, 594, 3578, 3450, -620, - 712, 3450, 3450, 713, 3762, 108, 701, 3450, 714, -620, - -620, 240, 716, -620, -620, -620, -620, -620, -620, -620, - 722, 3252, -620, -620, 3991, -620, -620, 3516, -620, 106, - -620, 110, -620, 2110, 241, 619, -620, -620, 724, -620, - -620, 728, -620, -620, 275, -620, 684, 2529, -620, -620, - 627, -620, -620, 57, -620, -620, -620, -620, 730, 627, - 627, 650, 650, 260, 2631, -620, -620, -620, -620, 686, - 731, -620, -620, -620, -620, -620, 3450, -620, -620, 732, - 725, -620, 727, 734, 740, -620, 743, 744, -620, 415, - -620, 324, -620, 492, 357, 746, 701, 108, -620, -620, - 694, 748, -620, -620, -620, -620, -620, 737, -620, -620, - -620, 729, -620, -620, 738, 749, 1646, 750, -620, 2922, - -620, -620, 311, 280, 543, 762, 1833, 731, -620, 3818, - -620, -620, 627, 627, 627, 650, -620, 1762, -620, 755, - 3450, 3450, 3450, 3640, 2574, 659, 701, -620, 3702, 4321, - -620, -620, -620, 689, 694, 2574, 3516, -620, 3450, -620, - 759, 703, -620, 4300, 605, -620, 311, 1946, 83, 460, - -620, -620, -620, -620, 627, -620, 434, 2226, 2342, 519, - 428, -620, 770, 774, 769, -620, -620, 711, -620, -620, - -620, -620, 1833, 781, -620, -620, -620, -620, 775, -620, - 2988, 776, 468, -620, 83, 401, -620, -620, 757, 311, - 4300, -620, 12, -620, 2458, -620, 9, 619, 619, 778, - 2574, 3640, 2574, -620, -620, 128, 701, -620, -620, -620, - -620, -620, 692, -620, 735, -620, -620, 690, 589, -620, - -5, 787, 788, -620, -620, 734, 796, -620, 1833, 311, - -620, -620, -620, 619, 619, -620, -620, 2574, -620, -620, - 790, 793, -620, -620, -620 + 31, -8, 11, 176, -609, 4469, -609, -609, -609, 11, + 485, 497, -609, 11, -609, -609, -609, -609, -609, -609, + -609, -609, -609, -609, -609, -609, 2773, -609, 1592, -609, + -609, 1516, 4480, -609, 545, 36, -609, 240, -21, 413, + 95, 248, 265, 295, 286, -609, -609, -609, -609, -609, + -609, -609, -609, -609, 2773, 1592, -609, 264, -609, 380, + -609, 963, 2834, 356, 333, 386, 386, 373, -609, 443, + -609, -609, 2642, 3494, -609, 2900, 3560, 3560, 3560, 3560, + 3560, 3560, 430, -609, -609, -609, -609, -609, -609, -609, + -609, -609, -609, -609, -609, 1173, -609, -609, 431, 459, + -609, -609, 273, -609, 454, 370, 273, -609, 390, -609, + -609, -609, 273, -609, -609, -609, -609, 287, 437, 481, + 452, 496, 469, 22, -609, 492, 537, 606, -609, -609, + -609, -609, 522, -609, -609, -609, 1123, 423, 332, 513, + 531, 1123, 535, 164, 477, -609, 526, 386, -609, 2722, + 539, 4579, 752, 596, 580, -609, 563, -609, -609, 1769, + -609, 591, -609, 75, -609, -609, -609, -609, -609, -609, + 3032, 1092, 400, 273, 1123, -609, 34, 572, 3494, 3098, + 598, 273, -609, 348, 3164, 5, -609, -609, -609, 72, + 572, 600, -609, 9, 572, -609, -609, 3494, 3560, -609, + 3560, 3560, 3560, 3560, 3560, 3560, 3560, 3560, 3560, 3560, + 1032, 3560, 3560, 3560, 3560, 3560, 3560, 3560, 3560, -609, + -609, 323, 273, -609, 544, -609, 4114, -609, -609, 592, + 177, -609, 548, 351, -609, -609, 164, 1123, 601, 620, + 321, 333, 570, -609, 486, 377, -609, 4396, 3230, -609, + 3230, -609, -609, -609, -609, -609, -609, -609, -609, -609, + -609, -609, -609, 3494, -609, -609, 3032, -609, -609, -16, + -609, 378, -609, 589, 360, 273, 360, -609, 643, -609, + 599, 605, 651, -609, 657, 604, -609, 3296, -609, 397, + -609, 572, 663, -609, 622, 662, -609, 193, 610, -609, + -609, 630, 634, 679, 437, 481, 452, 496, 469, 22, + 22, 492, 492, 492, 492, 637, -609, 49, -609, -609, + 537, 537, 537, 606, 606, -609, -609, -609, 667, -609, + 4353, 4142, 1123, 540, 687, -609, 642, 680, 1123, 164, + -609, -609, -609, 4153, -609, 1123, 473, -609, 940, 698, + 1123, 333, 649, 242, -609, 4480, 1899, -609, -609, -609, + -609, -609, -609, 1123, 1123, 1385, -609, 78, 3362, -609, + -609, 360, -609, 702, 643, -609, 703, -609, -609, -609, + 704, -609, 3494, 38, 643, 572, -609, -609, -609, 643, + -609, 3494, 161, 701, -609, 701, 3032, 637, 259, -609, + -609, -609, -609, -609, -609, 4353, -609, 700, 3883, 707, + 680, 643, -609, 697, 660, 1123, -609, -609, 4241, 4181, + -609, -609, 680, 261, 3922, -609, -609, 702, 273, 273, + 688, 348, -609, 710, -609, -609, 711, 3494, 41, 71, + 2595, 719, 721, 3428, 723, 727, 3494, 569, 735, 3494, + 4441, 1502, -609, 2015, -609, 729, -609, -609, -609, 732, + -609, -609, -609, -609, -609, 306, 482, -609, -609, -609, + 522, 532, 567, -609, -609, -609, 1123, 1123, -609, 436, + 737, -609, -609, -609, 3975, -609, -609, -609, 62, -609, + -609, -609, -609, 692, -609, 693, -609, -609, -609, 3362, + -609, 274, 637, -609, 571, 746, -609, 745, -609, 749, + 4241, 4014, -609, -609, -609, -609, 702, 1123, -609, 695, + 266, -609, 384, 335, -609, -609, -609, -609, -609, 4241, + -609, -609, 724, -609, 4298, -609, 4035, -609, -609, -609, + -609, 705, -609, 2595, 614, -609, 750, -609, 751, 727, + 641, 3622, 3494, -609, 755, 3494, 3494, 756, 3806, 7, + 749, 3494, 757, -609, -609, 49, 764, -609, -609, -609, + -609, -609, -609, -609, 770, 3362, -609, 4081, -609, 3560, + -609, 96, -609, 172, -609, 2131, 276, 643, -609, -609, + -609, 772, -609, -609, -609, 753, -609, -609, 280, -609, + 726, 384, -609, -609, 672, -609, -609, 335, -609, -609, + -609, -609, 779, 672, 672, 695, 695, 266, 921, -609, + -609, -609, -609, 728, 792, -609, -609, -609, -609, -609, + 3494, -609, -609, 781, 786, -609, 789, 794, 805, -609, + 812, 813, -609, 366, -609, 420, -609, 390, 429, 825, + 749, 7, -609, -609, 761, 826, -609, -609, -609, -609, + -609, 820, -609, -609, -609, 808, -609, -609, 821, 822, + 1667, 823, -609, 2966, -609, -609, 273, 283, 585, 833, + 1123, 792, -609, 3862, -609, -609, 672, 672, 672, 695, + -609, 1783, -609, 827, 3494, 3494, 3494, 3684, 2595, 703, + 749, -609, 3746, 4480, -609, -609, -609, 765, 761, 2595, + 3560, -609, 3494, -609, 828, 774, -609, 4396, 592, -609, + 273, 940, 28, 490, -609, -609, -609, -609, 672, -609, + 524, 2247, 2363, 471, 350, -609, 838, 843, 837, -609, + -609, 776, -609, -609, -609, -609, 1123, 847, -609, -609, + -609, -609, 841, -609, 3032, 842, 494, -609, 28, 165, + -609, -609, 835, 273, 4396, -609, 5, -609, 2479, -609, + 9, 643, 643, 844, 2595, 3684, 2595, -609, -609, 141, + 749, -609, -609, -609, -609, -609, 771, -609, 829, -609, + -609, 773, 622, -609, 3, 867, 868, -609, -609, 794, + 876, -609, 1123, 273, -609, -609, -609, 643, 643, -609, + -609, 2595, -609, -609, 870, 871, -609, -609, -609 }; } @@ -4628,86 +4716,85 @@ private static final short[] yydefact_init() 33, 0, 0, 0, 30, 11, 34, 35, 9, 0, 0, 0, 1, 0, 22, 17, 18, 28, 21, 20, 19, 23, 24, 25, 26, 27, 11, 12, 13, 15, - 36, 11, 0, 446, 0, 0, 37, 0, 33, 448, + 36, 11, 0, 449, 0, 0, 37, 0, 33, 451, 0, 0, 0, 0, 0, 43, 45, 61, 62, 63, - 46, 176, 177, 16, 11, 14, 447, 0, 38, 0, + 46, 181, 182, 16, 11, 14, 450, 0, 38, 0, 10, 11, 0, 0, 77, 65, 65, 0, 44, 0, - 39, 32, 11, 0, 449, 458, 0, 0, 0, 0, + 39, 32, 11, 0, 452, 461, 0, 0, 0, 0, 0, 0, 9, 2, 3, 6, 7, 60, 53, 57, - 59, 5, 58, 55, 56, 0, 8, 54, 0, 0, - 305, 4, 170, 302, 438, 0, 47, 49, 437, 308, - 314, 309, 310, 311, 312, 313, 454, 391, 394, 396, - 398, 400, 402, 404, 412, 407, 415, 419, 422, 426, - 427, 430, 433, 439, 440, 436, 0, 446, 0, 0, - 0, 0, 0, 0, 179, 66, 0, 65, 40, 11, - 9, 438, 309, 310, 0, 359, 0, 360, 373, 0, - 372, 0, 459, 0, 428, 429, 434, 435, 431, 432, - 0, 0, 50, 0, 444, 323, 0, 322, 0, 0, - 0, 171, 172, 0, 0, 0, 0, 51, 339, 0, - 322, 0, 52, 0, 0, 322, 0, 0, 390, 0, + 59, 5, 58, 55, 56, 324, 8, 54, 0, 0, + 310, 4, 173, 307, 441, 0, 47, 49, 440, 313, + 319, 314, 315, 316, 317, 318, 457, 394, 397, 399, + 401, 403, 405, 407, 415, 410, 418, 422, 425, 429, + 430, 433, 436, 442, 443, 439, 0, 449, 0, 0, + 0, 0, 0, 0, 184, 66, 0, 65, 40, 11, + 9, 441, 314, 315, 0, 362, 0, 363, 376, 0, + 375, 0, 462, 0, 431, 432, 437, 438, 434, 435, + 0, 0, 0, 0, 0, 325, 0, 324, 0, 0, + 0, 174, 175, 0, 0, 0, 340, 51, 343, 0, + 324, 0, 52, 0, 324, 341, 342, 0, 0, 393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 441, 442, - 48, 450, 0, 451, 11, 193, 79, 78, 111, 108, - 72, 0, 68, 71, 0, 0, 0, 180, 444, 77, - 75, 365, 0, 0, 367, 0, 0, 307, 0, 378, - 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, - 389, 0, 456, 455, 0, 452, 328, 327, 0, 325, - 0, 0, 0, 170, 355, 0, 0, 322, 0, 445, - 335, 0, 0, 0, 175, 0, 173, 0, 344, 0, - 346, 0, 322, 0, 315, 0, 0, 306, 0, 0, - 0, 334, 316, 0, 0, 0, 395, 397, 399, 401, - 403, 405, 406, 408, 409, 410, 411, 0, 413, 47, - 301, 414, 416, 417, 418, 420, 421, 423, 424, 425, - 0, 194, 11, 11, 0, 118, 112, 113, 0, 0, - 0, 67, 70, 181, 11, 178, 0, 0, 124, 0, - 0, 0, 77, 0, 444, 366, 11, 0, 362, 361, - 364, 363, 374, 460, 0, 0, 0, 324, 331, 0, - 143, 354, 353, 356, 0, 83, 444, 319, 318, 320, - 0, 350, 0, 304, 174, 345, 0, 337, 0, 0, - 322, 349, 352, 303, 338, 0, 348, 0, 137, 215, - 135, 214, 0, 0, 0, 200, 201, 199, 196, 198, - 195, 11, 80, 118, 11, 0, 444, 115, 81, 74, - 0, 0, 69, 183, 11, 11, 182, 122, 444, 444, - 11, 121, 76, 0, 170, 170, 0, 445, 368, 0, - 205, 222, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 25, 0, 0, 0, 0, 11, 12, 221, 0, - 207, 0, 213, 216, 217, 0, 218, 219, 220, 271, - 272, 308, 311, 243, 244, 245, 0, 246, 247, 329, - 330, 326, 0, 0, 357, 148, 0, 144, 145, 147, - 0, 11, 317, 84, 0, 342, 0, 443, 347, 336, - 0, 340, 0, 341, 393, 392, 0, 139, 0, 453, - 0, 0, 197, 0, 92, 23, 11, 11, 87, 90, - 109, 114, 116, 0, 73, 0, 0, 189, 0, 0, - 190, 185, 187, 188, 184, 11, 125, 126, 0, 128, - 11, 132, 11, 130, 64, 370, 369, 0, 241, 0, - 0, 228, 0, 230, 0, 0, 0, 274, 0, 232, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 209, - 210, 0, 0, 206, 208, 212, 223, 332, 333, 141, - 0, 0, 358, 85, 11, 321, 253, 0, 267, 0, - 256, 0, 261, 0, 0, 0, 351, 138, 0, 136, - 191, 0, 110, 91, 0, 95, 0, 0, 89, 97, - 166, 93, 94, 0, 96, 88, 117, 82, 0, 166, - 166, 0, 0, 0, 0, 169, 192, 168, 186, 0, - 9, 129, 131, 371, 242, 224, 0, 229, 231, 0, - 276, 279, 0, 275, 0, 233, 0, 0, 235, 50, - 299, 0, 297, 0, 309, 0, 0, 237, 286, 239, - 284, 0, 236, 211, 142, 146, 86, 266, 268, 254, - 257, 0, 255, 262, 0, 17, 0, 0, 264, 0, - 343, 140, 170, 137, 0, 0, 0, 0, 149, 0, - 155, 154, 166, 166, 166, 0, 127, 0, 133, 0, - 0, 0, 277, 0, 0, 0, 0, 295, 0, 11, - 294, 287, 238, 292, 285, 0, 0, 265, 0, 259, - 0, 203, 134, 0, 167, 98, 170, 0, 444, 0, - 158, 153, 150, 152, 166, 100, 375, 0, 0, 437, - 0, 225, 0, 0, 0, 278, 280, 251, 226, 234, - 296, 298, 0, 0, 240, 293, 270, 269, 0, 258, - 0, 0, 0, 156, 444, 170, 164, 161, 0, 170, - 0, 151, 0, 101, 0, 102, 322, 0, 0, 0, - 0, 281, 0, 250, 290, 0, 0, 260, 204, 202, - 99, 160, 0, 162, 0, 157, 159, 0, 323, 103, - 0, 0, 0, 227, 283, 282, 0, 252, 0, 170, - 288, 165, 163, 0, 0, 105, 104, 0, 291, 289, - 0, 0, 273, 106, 107 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, + 445, 50, 48, 453, 0, 454, 11, 198, 79, 78, + 111, 108, 72, 0, 68, 71, 0, 0, 0, 185, + 447, 77, 75, 368, 0, 0, 370, 0, 0, 312, + 0, 381, 382, 383, 384, 385, 386, 387, 388, 389, + 390, 391, 392, 0, 459, 458, 0, 455, 326, 331, + 330, 0, 328, 0, 360, 0, 360, 323, 0, 338, + 0, 0, 0, 177, 0, 0, 176, 0, 348, 0, + 350, 324, 0, 320, 0, 0, 311, 0, 0, 337, + 321, 0, 0, 0, 398, 400, 402, 404, 406, 408, + 409, 411, 412, 413, 414, 0, 416, 47, 306, 417, + 419, 420, 421, 423, 424, 426, 427, 428, 0, 199, + 11, 11, 0, 118, 112, 113, 0, 448, 0, 0, + 67, 70, 186, 11, 183, 0, 0, 124, 0, 0, + 0, 77, 0, 447, 369, 11, 0, 365, 364, 367, + 366, 377, 463, 0, 0, 0, 327, 334, 146, 361, + 358, 360, 357, 83, 0, 354, 0, 179, 309, 178, + 0, 349, 0, 0, 0, 324, 353, 356, 308, 0, + 352, 0, 139, 220, 135, 219, 0, 0, 0, 205, + 206, 204, 201, 203, 200, 11, 80, 118, 11, 0, + 447, 115, 81, 74, 0, 0, 69, 188, 11, 11, + 187, 122, 447, 447, 11, 121, 76, 0, 173, 173, + 0, 448, 371, 0, 210, 227, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, + 11, 12, 226, 0, 212, 0, 218, 221, 222, 0, + 223, 224, 225, 276, 277, 313, 316, 248, 249, 250, + 0, 251, 252, 332, 333, 329, 0, 0, 151, 0, + 147, 148, 150, 359, 11, 322, 84, 346, 0, 446, + 180, 351, 339, 0, 344, 0, 345, 396, 395, 0, + 137, 142, 0, 456, 0, 0, 202, 0, 92, 23, + 11, 11, 87, 90, 109, 114, 116, 0, 73, 0, + 0, 194, 0, 0, 195, 190, 192, 193, 189, 11, + 125, 126, 0, 128, 11, 132, 11, 130, 64, 373, + 372, 0, 246, 0, 0, 233, 0, 235, 0, 0, + 0, 279, 0, 237, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 214, 215, 0, 0, 211, 213, 217, + 228, 335, 336, 144, 0, 0, 85, 11, 258, 0, + 272, 0, 261, 0, 266, 0, 0, 0, 355, 141, + 140, 0, 138, 136, 196, 0, 110, 91, 0, 95, + 0, 0, 89, 97, 169, 93, 94, 0, 96, 88, + 117, 82, 0, 169, 169, 0, 0, 0, 0, 172, + 197, 171, 191, 0, 9, 129, 131, 374, 247, 229, + 0, 234, 236, 0, 281, 284, 0, 280, 0, 238, + 0, 0, 240, 50, 304, 0, 302, 0, 314, 0, + 0, 242, 291, 244, 289, 0, 241, 216, 145, 149, + 86, 271, 273, 259, 262, 0, 260, 267, 0, 17, + 0, 0, 269, 0, 347, 143, 173, 139, 0, 0, + 0, 0, 152, 0, 158, 157, 169, 169, 169, 0, + 127, 0, 133, 0, 0, 0, 282, 0, 0, 0, + 0, 300, 0, 11, 299, 292, 243, 297, 290, 0, + 0, 270, 0, 264, 0, 208, 134, 0, 170, 98, + 173, 0, 447, 0, 161, 156, 153, 155, 169, 100, + 378, 0, 0, 440, 0, 230, 0, 0, 0, 283, + 285, 256, 231, 239, 301, 303, 0, 0, 245, 298, + 275, 274, 0, 263, 0, 0, 0, 159, 447, 173, + 167, 164, 0, 173, 0, 154, 0, 101, 0, 102, + 324, 0, 0, 0, 0, 286, 0, 255, 295, 0, + 0, 265, 209, 207, 99, 163, 0, 165, 0, 160, + 162, 0, 325, 103, 0, 0, 0, 232, 288, 287, + 0, 257, 0, 173, 293, 168, 166, 0, 0, 105, + 104, 0, 296, 294, 0, 0, 278, 106, 107 }; } @@ -4717,24 +4804,24 @@ private static final short[] yypgoto_init() { return new short[] { - -620, -620, -1, 82, -353, -13, 129, -620, -620, 771, - -620, 31, -620, 747, 756, -12, 812, -620, -239, -620, - -8, -384, -620, 473, 581, -620, -218, 125, -620, -620, - -392, 327, -417, -620, -620, -620, 143, -620, -620, -620, - -620, -620, 406, 416, -620, -620, -620, 403, -620, -620, - 290, -620, -312, 325, -266, -620, -620, 253, -620, -474, - -477, 112, 68, 72, -515, 226, -78, -163, -83, -261, - 385, -620, -620, -620, -620, 309, -399, -620, -620, -620, - -620, 432, -620, -620, 239, -564, -450, -195, -431, -620, - -620, -539, -620, -620, 137, -620, 256, -620, 255, -620, - -364, -620, -620, -620, -620, -620, -620, 74, -620, -620, - -620, 188, -619, -620, -620, -620, -592, -620, -620, 141, - -620, -542, 79, -183, -620, -620, -160, -102, -620, 496, - 862, 901, 540, -269, -620, -620, -620, -620, 591, 579, - 461, -620, -620, 509, -563, 634, -620, -620, -42, -620, - -620, 670, 669, 675, 688, 697, 399, -620, 343, 358, - 394, -25, 726, 742, -620, 850, 854, 904, -620, -115, - 286, 11, -620, -43, -620 + -609, -609, -1, 233, -338, -13, 137, -609, -609, 845, + -609, 67, -609, 830, 832, 568, 564, 795, -259, -609, + -17, -258, -609, 549, 653, -609, -207, 207, -609, -609, + -387, 408, -413, -609, -609, -609, 212, -609, -609, -609, + -609, -609, 487, 488, -609, -609, -609, 474, -609, -609, + 363, -609, -309, 399, -609, -609, -347, -609, -609, 327, + -609, -225, -468, 187, 143, 147, -577, 301, -101, -163, + 815, -260, 460, -609, -609, -609, -609, 382, -392, -609, + -609, -609, -609, 504, -609, -609, -185, -560, -450, -190, + -402, -609, -609, -534, -609, -609, 217, -609, 336, -609, + 342, -609, -115, -609, -609, -609, -609, -609, -609, 151, + -609, -609, -609, 275, -608, -609, -609, -609, -606, -609, + -609, 228, -609, -535, -4, -180, -609, -161, -82, -609, + 573, 656, 744, 475, -144, -609, -609, -609, -246, 793, + 543, -609, -609, 582, -572, 668, -609, -609, -48, -609, + -609, 742, 741, 734, 768, 740, 438, -609, 316, 458, + 435, 40, 736, 804, -609, 824, 853, 934, -609, -196, + 82, 123, -609, -73, -609 }; } @@ -4746,21 +4833,21 @@ private static final short[] yydefgoto_init() { -1, 103, 151, 44, 27, 28, 29, 3, 4, 5, 6, 7, 71, 31, 45, 105, 106, 107, 46, 47, - 606, 145, 231, 232, 233, 352, 142, 227, 419, 492, - 493, 517, 518, 608, 609, 610, 698, 737, 48, 229, - 335, 336, 337, 415, 49, 239, 347, 348, 431, 542, - 543, 611, 401, 400, 485, 486, 487, 488, 612, 529, - 620, 729, 730, 767, 687, 626, 180, 181, 182, 50, - 51, 236, 237, 345, 425, 531, 407, 533, 52, 225, - 333, 408, 409, 761, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 783, 497, 589, 590, 591, 592, 593, - 594, 667, 467, 468, 469, 642, 744, 643, 806, 470, - 713, 657, 658, 753, 785, 754, 659, 566, 651, 652, - 321, 108, 109, 110, 276, 277, 174, 175, 268, 269, - 152, 153, 113, 188, 289, 114, 115, 273, 274, 154, - 155, 156, 243, 244, 157, 158, 159, 261, 160, 198, + 600, 145, 233, 234, 235, 351, 142, 229, 413, 485, + 486, 511, 512, 602, 603, 604, 692, 731, 48, 231, + 333, 334, 335, 409, 49, 241, 346, 347, 425, 536, + 537, 605, 395, 394, 500, 592, 369, 479, 480, 481, + 606, 523, 614, 723, 724, 761, 681, 620, 180, 181, + 182, 50, 51, 238, 239, 344, 419, 525, 401, 527, + 52, 227, 331, 402, 403, 755, 452, 453, 454, 455, + 456, 457, 458, 459, 460, 777, 489, 581, 582, 583, + 584, 585, 586, 661, 461, 462, 463, 636, 738, 637, + 800, 464, 707, 651, 652, 747, 779, 748, 653, 560, + 645, 646, 319, 108, 109, 110, 278, 174, 175, 271, + 272, 152, 153, 113, 188, 289, 114, 115, 370, 154, + 155, 156, 245, 246, 157, 158, 159, 263, 160, 199, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 338, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 336, 136, 33, 138, 139, 163 }; } @@ -4773,311 +4860,322 @@ private static final short[] yytable_init() { return new short[] { - 10, 11, 187, 294, 457, 399, 371, 375, 34, 574, - 272, 302, 39, 541, 320, 556, 281, 282, 641, 55, - 116, 350, 653, 192, 668, 532, -29, 191, 171, 676, - 298, 171, 162, 116, 303, 304, 30, 8, 711, 39, - 528, 544, 613, 56, 586, 551, 391, 59, 619, 187, - 395, 164, 165, 166, 167, 168, 169, 144, 146, 278, - 171, 104, 357, 553, 301, 712, 613, 60, 625, 69, - 187, 406, 8, 137, 104, 104, 104, 104, 104, 104, - 104, 392, 9, 173, 295, 13, 137, 26, 60, 552, - 179, 510, 30, 405, 172, 711, 280, 814, 286, 292, - 615, 13, 292, 587, 690, 691, 457, 554, 588, 1, - 60, 495, 669, 54, 293, 13, 672, 378, 634, 2, - 501, 755, 230, 349, 171, 541, 503, 265, 116, 226, - 616, 8, 607, 738, 433, 172, 532, 192, 765, 240, - 172, 364, 12, 26, 692, 693, 694, 56, 522, 808, - 406, 528, -444, 757, 54, 739, 607, 53, 62, 267, - 499, 196, 63, 530, 746, 37, 653, 615, 365, 104, - 172, 587, 405, 774, 655, 587, 588, 731, 732, 733, - 588, 137, 197, 809, 53, 527, 656, 60, 766, 286, - 327, 328, 329, 482, 56, 372, 104, 318, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 172, 104, - 104, 104, 104, 104, 104, 104, 104, 569, 734, 771, - 483, 363, 116, 343, 420, 671, 574, 674, 500, 677, - 502, 242, 55, 1, 172, 507, 192, 205, 206, 436, - 457, 172, 641, 179, 172, 56, 203, 179, 204, 179, - 207, 208, 67, 678, 13, 614, 56, 179, 13, 179, - 13, 494, 572, 104, 506, 679, 64, 179, 13, 172, - 13, 192, 65, 747, 530, 137, 37, 605, 13, 614, - 66, 56, 179, 689, 756, 171, 56, 179, 574, 179, - 56, 32, 684, 13, 376, 398, 527, 435, 13, 221, - 13, 605, 209, 171, 222, 511, 332, 537, 506, 377, - 598, -123, 32, 349, 538, 618, -123, 32, 179, 70, - 403, 192, 412, 457, 574, 13, 680, 418, 707, 13, - 683, 172, 681, 172, 426, 708, 727, 355, 172, 432, - 32, 413, 356, 414, 457, 172, 192, 32, 172, 804, - 172, 807, 479, 480, 267, 505, 545, 546, 32, 509, - 116, -300, 640, 172, 172, 172, -376, 140, -300, 650, - 727, 141, -376, -376, -376, -376, -376, -376, -376, -376, - -376, -376, -376, 143, 457, 457, 822, 271, 183, 147, - 184, 183, 183, 287, 185, 148, 104, 186, 13, 403, - -50, 104, -249, 170, 13, -50, 171, -249, 179, -249, - 172, 792, 403, 137, 370, 411, 179, 727, 184, 13, - 172, 457, 185, 172, 286, 186, 424, 13, 385, 234, - 178, 340, 56, 386, 171, 245, 471, 184, 242, 456, - 366, 185, 341, 192, 772, 427, 176, -50, 56, 177, - 428, 367, -50, 171, 374, 179, 172, 270, 189, 275, - 279, 190, 35, 36, 769, 13, 13, 183, -248, 770, - 577, 578, 790, -248, 564, -248, 357, 770, 199, -438, - -438, 172, 172, -41, 508, 358, 600, 360, 192, -50, - -457, 263, -457, 200, 264, -457, 516, -457, 202, 193, - 579, 13, 194, 580, 201, 195, 183, 535, 801, 802, - 32, 617, 540, 650, 279, 172, 622, 210, 211, 212, - 507, 192, 172, 403, 279, 471, 193, 172, 296, 776, - 777, 297, 195, 778, 172, 37, 38, 740, 471, 172, - 192, 456, 223, 14, 820, 821, 246, 187, 313, 314, - 315, 316, 508, 15, 722, 215, 216, 217, 183, 275, - 16, 57, 58, 649, 213, 214, 1, 224, 322, 323, - 324, 218, 219, 516, 228, 17, 235, 18, 19, 20, - -439, -439, 247, 21, 22, 635, 636, 23, 238, 294, - 248, 24, 262, 302, 13, 622, 171, 25, 284, 516, - -440, -440, 311, 312, 721, 183, 172, 325, 326, 285, - 299, 330, 797, 768, 334, 344, 800, 346, 245, 32, - 339, 351, 184, 172, 540, 421, 234, 379, 471, 382, - 32, 383, 384, 388, 187, 56, 471, 380, 381, 387, - 437, 390, 32, 245, 389, 192, 394, 395, 763, 768, - 396, 397, 270, 519, 402, 393, 398, 416, 417, 430, - 484, 434, 279, 491, 496, 508, 516, 520, 414, 519, - 798, 524, 471, 547, 226, 456, 548, 523, 549, 557, - 558, 192, 561, 562, 183, 172, 567, 793, 172, 575, - 183, 795, 565, 576, 581, 582, 736, 245, 585, 595, - 32, 596, 279, 601, 602, 618, 357, 649, 633, 639, - 245, 32, 629, 637, 279, 437, 32, 788, 116, 638, - 183, 183, 172, 645, 648, 662, 172, 663, 664, 370, - 519, 819, 682, 689, 686, 700, 697, 701, 702, 685, - 784, 696, 32, 703, 704, 245, 716, 705, 706, 709, - 678, 172, 715, 679, 603, 471, 519, 283, 456, 104, - 655, -267, 717, 290, 291, 723, 741, 656, 627, 172, - 759, 137, 300, 760, 779, 305, 471, 32, 780, 456, - 781, 519, 471, 471, 782, 786, 787, 789, 794, 803, - 812, 752, 813, 183, 471, 40, 818, 811, 815, 816, - 817, 823, 32, 32, 824, 660, -31, 172, 72, 61, - 68, 724, 183, 422, 624, 342, 471, 471, 584, 456, - 456, 245, 521, 519, 13, 359, 32, 361, 32, 513, - 725, 536, 632, 599, 665, 762, 791, 14, 796, 688, - 362, 570, 748, 512, 628, 670, 673, 15, 714, 751, - 369, 41, 627, 471, 16, 805, 456, 183, 504, 471, - 471, 471, 481, 42, 373, 438, 14, 306, 307, 17, - 32, 18, 19, 20, 43, 308, 15, 21, 22, 245, - 0, 23, 0, 16, 0, 24, 0, 0, 0, 309, - 183, 25, 0, 624, 0, 710, 471, 472, 17, 310, - 18, 19, 20, 0, 0, 0, 21, 22, 0, 183, - 23, 0, 0, 0, 24, 0, 0, 0, 719, -377, - 25, 0, 0, 0, 111, -377, -377, -377, -377, -377, - -377, -377, -377, -377, -377, -377, 0, 111, 111, 111, - 111, 111, 111, 111, 0, 749, 0, 0, 220, 489, - 0, 0, 0, 490, 0, 0, 0, 0, 0, 0, - 0, 0, 245, 112, 0, 498, 0, 0, 183, 183, - 0, 0, 0, 0, 0, 32, 112, 112, 112, 112, - 112, 112, 112, 245, 0, 0, 472, 0, 0, 0, - 0, 473, 0, 0, 0, 32, 0, 0, 0, 472, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, - 0, 0, 183, 0, 437, 0, 0, 0, 0, 0, - 0, 319, 550, 245, 245, 810, 0, 0, 560, 249, - 0, 563, 111, 0, 568, 250, 251, 252, 253, 254, - 255, 256, 257, 258, 259, 260, 0, 0, 0, 0, - 437, 183, 0, 0, 354, 183, 32, 220, 0, 111, - 245, 111, 111, 111, 111, 111, 111, 111, 111, 111, - 111, 112, 111, 111, 111, 111, 111, 111, 111, 111, - 473, 0, 220, 474, 0, 597, 0, 0, 0, 472, - 0, 0, 0, 473, 0, 183, 0, 472, 112, 475, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 331, 112, 112, 112, 112, 112, 112, 112, 112, 0, - 0, 0, 13, 0, 0, 0, 111, 0, 0, 0, - 0, 0, 0, 472, 0, 0, 0, 644, 8, 0, - 646, 647, 0, 0, 404, 87, 661, 88, 0, 0, - 89, 0, 0, 0, 0, 90, 0, 0, 0, 0, - 489, 429, 92, 0, 14, 112, 0, 0, 93, 319, - 94, 0, 474, 0, 15, 0, 0, 0, 0, 0, - 0, 16, 97, 473, 0, 474, 0, 0, 475, 0, - 0, 473, 0, 0, 0, 353, 17, 0, 18, 19, - 20, 475, 0, 0, 21, 22, 0, 476, 23, 0, - 0, 477, 24, 0, 0, 699, 472, 0, 25, 0, - 0, 0, 0, 404, 0, 0, 0, 473, 0, 0, - 0, 0, 0, 220, 0, 0, 526, 472, 0, 0, - 0, 0, 0, 472, 472, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 472, 0, 0, 720, 111, - 0, 478, 0, 0, 111, 0, -42, 0, 0, 571, - 0, 319, 0, 0, 0, 474, 0, 472, 472, 742, - 743, 745, 0, 474, 13, 0, 0, 0, 0, 0, - 0, 475, 0, 0, 0, 0, 476, 758, 112, 475, - 477, 0, 0, 112, 0, 0, 0, 0, 0, 476, - 473, 0, 0, 477, 472, 0, 0, 0, 0, 474, - 472, 472, 472, 0, 0, 0, 14, 0, 604, 0, - 0, 473, 0, 0, 0, 475, 15, 473, 473, 0, - 623, 0, 0, 16, 0, 0, 0, 526, 0, 473, - 478, 0, 604, 0, 0, 0, 0, 472, 17, 0, - 18, 19, 20, 478, 0, 0, 21, 22, 0, 319, - 23, 473, 473, 0, 24, 0, 319, 0, 0, 0, - 25, 0, 0, 0, 0, 0, 0, 357, -119, 0, - 0, 0, 0, 514, 0, 0, 0, 0, 0, 476, - 13, 0, 474, 477, 0, 319, 0, 476, 473, 0, - 0, 477, 0, 0, 473, 473, 473, 0, 475, 623, - 0, 0, 0, 474, 0, 0, 654, 0, 0, 474, - 474, 0, 0, 0, 0, 0, 220, 0, 0, 475, - 0, 474, 14, 476, 0, 475, 475, 477, 0, 0, - 0, 473, 15, 478, 0, 0, 0, 475, 0, 16, - 0, 478, 0, 474, 474, 112, 0, 0, 0, 0, - 0, 0, 0, 0, 17, 0, 18, 19, 20, 475, - 475, 0, 515, 22, 0, 0, 23, 0, 319, 0, - 24, 0, 0, 0, 0, 0, 25, 478, 0, 0, - 474, 728, 0, 0, 0, 0, 474, 474, 474, 319, - 0, 0, 0, 0, 0, 0, 475, 0, 0, 0, - 319, 0, 475, 475, 475, 0, 476, 0, 0, 13, - 477, 0, 0, 0, 0, 728, 0, 0, 0, 764, - 0, 0, 0, 474, 0, 0, 0, 476, 0, 319, - 319, 477, 0, 476, 476, 0, 0, 477, 477, 475, - 0, 0, 0, 0, 0, 476, 8, 0, 0, 477, - 654, 0, 0, 87, 0, 88, 0, 0, 89, 0, - 478, 0, 728, 90, 0, 0, 319, 476, 476, 0, - 92, 477, 477, 0, 0, 0, 93, 0, 94, 0, - 0, 478, 0, 0, 0, 0, 0, 478, 478, 112, - 97, 0, 0, 0, 0, 0, 0, 0, 0, 478, - 0, 0, 111, 317, 476, 0, 0, 0, 477, 0, - 476, 476, 476, 0, 477, 477, 477, 0, 0, 0, - 0, 478, 478, 0, 0, 0, 0, 439, 0, 73, - 0, 357, -263, 0, 0, 0, 0, 441, 0, 0, - 0, 112, 0, 0, 13, 0, 0, 476, 0, 0, - 0, 477, 0, 0, 0, 0, 0, 0, 478, 0, - 0, 0, 0, 0, 478, 478, 478, 0, 0, 0, - 0, 80, 81, 0, 0, 0, 0, 0, 0, 0, - 0, 442, 83, 84, 85, 86, 14, 443, 87, 444, - 88, -263, 0, 89, -11, 445, 15, 446, 90, 0, - -11, 478, 91, 16, 0, 92, 447, 448, 0, 0, - 0, 93, -11, 94, 0, 0, 95, 96, 17, 0, - 18, 19, 20, -11, 449, 97, 21, 22, 98, 450, - 451, 100, 452, 0, 24, 0, 101, 453, 317, 102, - 25, 454, 455, 439, 0, 73, 0, 357, 735, 0, - 8, 0, 0, 441, 0, 0, 0, 87, 0, 88, - 13, 171, 89, 0, 0, 0, 0, 90, 0, 0, - 0, 0, 0, 0, 92, 0, 0, 0, 0, 0, - 93, 0, 94, 0, 0, 0, 0, 80, 81, 0, - 0, 0, 0, 0, 97, 0, 0, 442, 83, 84, - 85, 86, 14, 443, 87, 444, 88, 317, 0, 89, - -11, 445, 15, 446, 90, 0, -11, 0, 91, 16, - 0, 92, 447, 448, 0, 0, 0, 93, -11, 94, - 0, 13, 95, 96, 17, 0, 18, 19, 20, -11, - 449, 97, 21, 22, 98, 450, 451, 100, 452, 0, - 24, 0, 101, 453, 317, 102, 25, 454, 455, 439, - 0, 73, 0, 357, 440, 0, 0, 0, 8, 441, - 0, 0, 0, 0, 0, 87, 13, 88, 0, 0, - 89, 0, 0, 0, 0, 90, 0, 0, 0, 0, - 0, 0, 92, 0, 0, 0, 0, 0, 93, 0, - 94, 0, 0, 80, 81, 0, 0, 0, 0, 0, - 0, 0, 97, 442, 83, 84, 85, 86, 14, 443, - 87, 444, 88, 0, 0, 89, -11, 445, 15, 446, - 90, 0, -11, 0, 91, 16, 0, 92, 447, 448, - 0, 0, 0, 93, -11, 94, 0, 0, 95, 96, - 17, 0, 18, 19, 20, -11, 449, 97, 21, 22, - 98, 450, 451, 100, 452, 0, 24, 0, 101, 453, - 317, 102, 25, 454, 455, 439, 0, 73, 0, 357, - 573, 8, 0, 0, 0, 441, 0, 0, 87, 0, - 88, 0, 13, 89, 0, 0, 0, 0, 90, 0, - 0, 0, 0, 0, 0, 92, 0, 0, 0, 0, - 0, 93, 0, 94, 0, 0, 0, 0, 0, 80, - 81, 0, 0, 0, 0, 97, 0, 0, 0, 442, - 83, 84, 85, 86, 14, 443, 87, 444, 88, 0, - 0, 89, -11, 445, 15, 446, 90, 0, -11, 0, - 91, 16, 0, 92, 447, 448, 0, 0, 0, 93, - -11, 94, 0, 0, 95, 96, 17, 0, 18, 19, - 20, -11, 449, 97, 21, 22, 98, 450, 451, 100, - 452, 0, 24, 0, 101, 453, 317, 102, 25, 454, - 455, 439, 0, 73, 0, 357, 0, 0, 0, 0, - 0, 441, 0, 0, 0, 0, 0, 0, 13, 0, + 10, 11, 162, 568, 191, 293, 393, 662, 34, 274, + 276, 535, 39, 300, 116, 280, 281, 635, 451, 55, + 318, 478, 187, 647, 171, 670, 526, 116, 171, 297, + 372, -29, 301, 302, 349, 179, 684, 685, 550, 39, + 538, 206, 207, 705, 348, 706, 13, 8, 144, 146, + 59, 613, 545, 171, 208, 209, 179, 171, 389, 363, + 60, 104, 1, 357, 299, 359, 8, 13, 578, 187, + 400, 399, 30, 649, 104, 104, 104, 104, 104, 104, + 104, 265, 547, 759, 266, 650, 364, 32, 504, 279, + 275, 60, 9, 492, 172, 291, 546, 267, 609, 291, + 705, 749, 663, 294, 392, 808, 210, 292, 32, 725, + 726, 727, 371, 32, 1, 451, 164, 165, 166, 167, + 168, 169, 116, 535, 2, 483, 548, 579, 30, 610, + 242, 732, 580, 760, 373, 221, 32, 526, 751, 187, + 221, 628, 414, 32, 427, 400, 399, 686, 687, 688, + 8, 765, 589, 476, 32, 56, 733, 430, 524, 521, + 522, 579, 802, 740, 609, 53, 580, 647, 179, 104, + 221, 768, 179, 221, 295, 786, 12, 296, 666, 13, + 477, 63, 13, 13, 183, 137, 183, 183, 183, 499, + 183, 563, 53, 362, 183, 13, 803, 104, 137, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 221, + 104, 104, 104, 104, 104, 104, 104, 104, 116, 232, + 568, 728, 493, 513, 495, 236, 348, 532, 478, 501, + 487, 247, -447, 183, 55, 183, 221, 579, 26, 513, + 494, 635, 580, 221, 675, 496, 221, 451, 386, 179, + 608, 599, 601, 273, 183, 183, 325, 326, 327, 56, + 13, 566, 559, 183, 54, 104, 179, 516, 179, 524, + 521, 522, 221, 179, 608, 599, 601, 13, 69, 13, + 179, 179, 568, 387, 13, 607, 683, 179, 672, 678, + 179, 13, 13, 137, 26, 60, 741, 429, 13, 513, + 673, 13, 591, 64, 183, 54, 56, 750, 32, 607, + -254, 499, 337, 197, 505, -254, 531, -254, 568, 60, + 65, 612, 337, 503, 597, -123, 513, 539, 540, 221, + -123, 221, 451, 37, 198, 677, 223, 221, 621, 13, + 356, 224, 171, 498, 221, 721, 619, 221, 116, 221, + 66, 513, 465, 451, 67, 287, 183, 183, 183, 56, + 339, 634, 221, 221, 221, 368, 13, 179, 644, 184, + 56, 340, 798, 179, 801, 654, 185, 179, 13, 721, + 189, 354, 244, 190, 13, 171, 355, 365, 13, 137, + 104, 70, 513, 451, 451, 104, 56, 179, 366, 183, + 193, 381, 13, 194, 221, 143, 382, 179, 13, 816, + 37, 140, 247, 32, 221, 141, 62, 221, 13, 171, + 415, 236, 621, 37, 701, 32, 721, -460, 147, -460, + 451, 702, -460, -305, -460, 431, 465, 32, 247, 8, + -305, 176, 573, 674, 177, 574, 87, 273, 88, 465, + 221, 89, 771, 183, 148, 772, 90, 184, 170, 330, + 56, 179, 178, 92, 185, 704, 665, -50, 668, 93, + 671, 94, 13, 171, 183, 221, 221, 421, 179, 202, + 183, 770, 422, 97, 194, 200, -253, 247, 713, 13, + 32, -253, 337, -253, 763, 35, 36, 615, 784, 764, + 247, 32, 201, 764, 337, 431, 32, 37, 38, 221, + 183, 183, 644, 203, 501, 743, 221, 225, 204, 137, + 205, 221, 311, 312, 313, 314, 762, 184, 221, 240, + 734, 179, 32, 221, 766, 247, 226, -50, 56, 465, + 230, 8, 13, 171, 211, 212, 213, 465, 87, 407, + 88, 408, 237, 89, 56, 57, 58, 643, 90, 214, + 215, 187, 762, 248, 405, 92, 32, 219, 220, -441, + -441, 93, 558, 94, 356, 715, 418, -442, -442, -50, + 502, 465, 594, 183, 249, 97, 293, 250, 244, 450, + 300, 171, 32, 32, 502, 804, 716, 264, 352, 328, + 221, 332, 183, 179, 618, 791, 343, 13, 285, 794, + 298, 247, -443, -443, 13, 367, 32, 221, 32, 757, + 216, 217, 218, 338, -380, 629, 630, 795, 796, 345, + -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, + -380, 510, 309, 310, 8, 350, 184, 183, 187, 323, + 324, 87, 529, 88, 374, 376, 89, 534, 787, 32, + 375, 90, 789, 814, 815, 377, 465, 247, 92, 320, + 321, 322, 378, 383, 93, 385, 94, 384, 388, 221, + 183, 782, 221, 618, 792, 389, 450, 465, 97, 390, + 730, 391, 392, 465, 465, 396, 410, 411, 13, 183, + 222, 643, 813, 424, 428, 465, 116, 484, 488, 228, + 502, 408, 490, 514, 517, 518, 221, 510, 111, 541, + 221, 542, 551, 543, 552, 183, 555, 465, 465, 183, + 556, 111, 111, 111, 111, 111, 111, 111, 561, 270, + 569, 56, 277, 570, 510, 221, 575, 587, 588, 595, + 612, 596, 247, 104, 356, 623, 633, 676, 183, 183, + 627, 631, 632, 221, 465, 32, 639, 642, 656, 534, + 465, 465, 465, 247, 317, 657, 658, 368, 316, 680, + -379, 679, 683, 690, 694, 32, -379, -379, -379, -379, + -379, -379, -379, -379, -379, -379, -379, 691, 695, 32, + 696, 221, 183, 697, 431, 342, 112, 465, 353, 698, + 510, 222, 183, 247, 247, 183, 699, 700, 450, 112, + 112, 112, 112, 112, 112, 112, 111, 649, 703, 710, + 709, 466, 673, 672, -272, 711, 717, 222, 735, 753, + 431, 183, 773, 650, 754, 183, 32, 774, 775, 776, + 247, 780, 781, 783, 111, 797, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 788, 111, 111, 111, + 111, 111, 111, 111, 111, 807, 805, 137, 809, 810, + 811, 817, 818, 61, 806, 183, 68, 718, 416, 341, + 173, 72, 577, 719, 398, 507, 530, 515, 397, 626, + 406, 593, 659, 450, 756, 785, 412, 790, 682, 506, + 564, 622, 423, 420, 112, 466, 742, 664, 426, 186, + 317, 192, 111, 195, 450, 667, 799, 196, 466, 708, + 745, 473, 474, 270, 497, 306, 746, 432, 475, 13, + 304, 305, 112, 308, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 0, 112, 112, 112, 112, 112, + 112, 112, 112, -41, 450, 450, 186, 0, 196, 398, + 307, 282, 284, 397, 0, 0, 8, 290, 0, 222, + 0, 13, 520, 87, 0, 88, 397, 0, 89, 0, + 303, 0, 0, 90, 0, 8, 286, 0, 0, 0, + 92, 450, 87, 0, 88, 0, 93, 89, 94, 0, + 112, 0, 90, 0, 0, 565, 0, 317, 466, 92, + 97, 0, 0, 14, 467, 93, 466, 94, 0, 0, + 0, 0, 0, 15, 689, 0, 0, 192, 0, 97, + 16, 358, 0, 360, 571, 572, 1, 111, 0, 0, + 13, 0, 111, 0, 0, 17, 361, 18, 19, 20, + 466, 0, 0, 21, 22, 0, 0, 23, 0, 0, + 0, 24, 0, 0, 598, 0, 0, 25, 0, 0, + 380, 0, 0, 0, 0, 611, 617, 8, 0, 286, + 616, 286, 468, 520, 87, 0, 88, 397, 598, 89, + 0, 0, 0, 0, 90, 0, 0, 0, 467, 0, + 13, 92, 268, 0, 0, 317, 0, 93, 269, 94, + 0, 467, 317, 0, 0, 0, 0, 0, 0, 0, + 0, 97, 192, 0, 0, 112, 0, 0, 0, 0, + 112, 13, 0, 0, 315, 466, 0, 8, 0, 317, + 0, 0, 0, 0, 87, 0, 88, 0, 0, 89, + 469, 482, 0, 0, 90, 617, 466, 0, 192, 616, + 0, 92, 466, 466, 0, 491, 468, 93, 8, 94, + 470, 0, 222, 0, 466, 87, 286, 88, 0, 468, + 89, 97, 171, 0, 0, 90, 0, 0, 0, 0, + 0, 0, 92, 0, 0, 0, 466, 466, 93, 471, + 94, 467, 0, 192, 648, 0, 0, 0, 0, 467, + 0, 0, 97, 0, 0, 0, 0, 0, 8, 0, + 544, 0, 0, 0, 317, 87, 554, 88, 192, 557, + 89, 0, 562, 466, 469, 90, 0, 722, 228, 466, + 466, 466, 92, 467, 0, 317, 0, 469, 93, 0, + 94, 0, 0, 0, 470, 0, 317, 0, 0, 0, + 0, 0, 97, 0, 0, 0, 0, 470, 0, 468, + 0, 722, 0, 0, 0, 758, 466, 468, 0, 0, + 472, 0, 590, 471, 0, 317, 317, 0, 0, 0, + 0, 0, 112, 0, 0, 0, 471, 0, 0, 0, + 0, 0, 0, 0, 778, 0, 286, 0, 0, 0, + 0, 468, 0, 0, 0, 0, 0, 0, 722, 0, + 0, 0, 317, 0, 0, 192, 0, 0, 467, 0, + 0, 0, 0, 0, 0, 638, 0, 469, 640, 641, + 0, 0, 0, 0, 655, 469, 0, 0, 648, 467, + 0, 0, 0, 0, 0, 467, 467, 470, 482, 0, + 812, 0, 0, 0, 472, 470, 0, 467, 0, 0, + 192, 0, 0, 0, 0, 0, 0, 472, 0, 469, + 0, 0, 0, 0, 0, 0, 471, 0, 0, 467, + 467, 0, 0, 13, 471, 0, 468, 0, 0, 470, + 111, 269, 0, 192, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 693, 0, 0, 0, 468, 0, 0, + 0, 0, 192, 468, 468, 0, 467, 0, 471, 0, + 8, 0, 467, 467, 467, 468, 112, 87, 0, 88, + 0, 0, 89, 0, 0, 0, 0, 90, 186, 0, + 0, 0, 195, 0, 92, 0, 714, 468, 468, 0, + 93, 0, 94, 0, 469, 0, 0, 472, 0, 467, + 0, 0, 0, 0, 97, 472, 0, 736, 737, 739, + 0, 0, 0, 0, 470, 469, 0, 0, 112, 0, + 0, 469, 469, 0, 468, 752, 0, 0, 0, 0, + 468, 468, 468, 469, 0, 470, -31, 0, 0, 472, + 0, 470, 470, 471, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 470, 13, 469, 469, 192, 0, 0, + 0, 0, 0, 0, 471, 186, 0, 468, 195, 0, + 471, 471, 0, 0, 0, 470, 470, 8, 0, 0, + 0, 0, 471, 0, 87, 0, 88, 0, 0, 89, + 0, 0, 469, 192, 90, 0, 14, 0, 469, 469, + 469, 92, 0, 0, 471, 471, 15, 93, 0, 94, + 0, 0, 470, 16, 0, 0, 0, 0, 470, 470, + 470, 97, 0, 0, 472, 0, 0, 0, 17, 0, + 18, 19, 20, 0, 315, 469, 21, 22, 0, 0, + 23, 471, 0, 0, 24, 472, 0, 471, 471, 471, + 25, 472, 472, 0, 0, 470, 0, 0, 0, 0, + 0, 0, 0, 472, 0, 0, 0, 0, 0, 0, + 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 471, 472, 472, 0, 433, 16, + 73, 0, 356, -268, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 17, 13, 18, 19, 20, 0, + 0, 0, 21, 22, 0, 0, 23, 0, 0, 0, + 24, 0, 472, 0, 0, 0, 25, 0, 472, 472, + 472, 0, 80, 81, 0, 0, 0, 0, 0, 0, + 0, 0, 436, 83, 84, 85, 86, 14, 437, 87, + 438, 88, -268, 0, 89, -11, 439, 15, 440, 90, + 0, -11, 0, 91, 16, 472, 92, 441, 442, 0, + 0, 0, 93, -11, 94, 0, 0, 95, 96, 17, + 0, 18, 19, 20, -11, 443, 97, 21, 22, 98, + 444, 445, 100, 446, 0, 24, 0, 101, 447, 315, + 102, 25, 448, 449, 433, 0, 73, 0, 356, 729, + 0, 0, 0, 0, 435, 0, 0, 251, 0, 0, + 0, 13, 171, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 80, 81, + 0, 0, 0, 0, 0, 0, 0, 0, 436, 83, + 84, 85, 86, 14, 437, 87, 438, 88, 0, 0, + 89, -11, 439, 15, 440, 90, 0, -11, 0, 91, + 16, 0, 92, 441, 442, 0, 0, 0, 93, -11, + 94, 0, 0, 95, 96, 17, 0, 18, 19, 20, + -11, 443, 97, 21, 22, 98, 444, 445, 100, 446, + 0, 24, 0, 101, 447, 315, 102, 25, 448, 449, + 433, 0, 73, 0, 356, 434, 0, 0, 0, 0, + 435, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 80, 81, 0, 0, 0, - 0, 0, 0, 0, 0, 442, 83, 84, 85, 86, - 14, 443, 87, 444, 88, 587, 0, 89, -11, 445, - 675, 446, 90, 0, -11, 0, 91, 16, 0, 92, - 447, 448, 0, 0, 0, 93, -11, 94, 0, 0, - 95, 96, 17, 0, 18, 19, 20, -11, 449, 97, - 21, 22, 98, 450, 451, 100, 452, 0, 24, 0, - 101, 453, 317, 102, 25, 454, 455, 439, 0, 73, - 0, 357, 773, 0, 0, 0, 0, 441, 0, 0, - 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 80, 81, 0, 0, 0, 0, + 0, 0, 0, 0, 436, 83, 84, 85, 86, 14, + 437, 87, 438, 88, 0, 0, 89, -11, 439, 15, + 440, 90, 0, -11, 0, 91, 16, 0, 92, 441, + 442, 0, 0, 0, 93, -11, 94, 0, 0, 95, + 96, 17, 0, 18, 19, 20, -11, 443, 97, 21, + 22, 98, 444, 445, 100, 446, 0, 24, 0, 101, + 447, 315, 102, 25, 448, 449, 433, 0, 73, 0, + 356, 567, 0, 0, 0, 0, 435, 0, 0, 0, + 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 80, 81, 0, 0, 0, 0, 0, 0, 0, - 0, 442, 83, 84, 85, 86, 14, 443, 87, 444, - 88, 0, 0, 89, -11, 445, 15, 446, 90, 0, - -11, 0, 91, 16, 0, 92, 447, 448, 0, 0, - 0, 93, -11, 94, 0, 0, 95, 96, 17, 0, - 18, 19, 20, -11, 449, 97, 21, 22, 98, 450, - 451, 100, 452, 0, 24, 0, 101, 453, 317, 102, - 25, 454, 455, 439, 0, 73, 0, 357, 775, 0, - 0, 0, 0, 441, 0, 0, 0, 0, 0, 0, - 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 80, 81, 0, 0, 0, 0, 0, 0, 0, 0, + 436, 83, 84, 85, 86, 14, 437, 87, 438, 88, + 0, 0, 89, -11, 439, 15, 440, 90, 0, -11, + 0, 91, 16, 0, 92, 441, 442, 0, 0, 0, + 93, -11, 94, 0, 0, 95, 96, 17, 0, 18, + 19, 20, -11, 443, 97, 21, 22, 98, 444, 445, + 100, 446, 0, 24, 0, 101, 447, 315, 102, 25, + 448, 449, 433, 0, 73, 0, 356, 0, 0, 0, + 0, 0, 435, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 80, 81, 0, - 0, 0, 0, 0, 0, 0, 0, 442, 83, 84, - 85, 86, 14, 443, 87, 444, 88, 0, 0, 89, - -11, 445, 15, 446, 90, 0, -11, 0, 91, 16, - 0, 92, 447, 448, 0, 0, 0, 93, -11, 94, - 0, 0, 95, 96, 17, 0, 18, 19, 20, -11, - 449, 97, 21, 22, 98, 450, 451, 100, 452, 0, - 24, 0, 101, 453, 317, 102, 25, 454, 455, 439, - 0, 73, 0, 357, 799, 0, 0, 0, 0, 441, - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 80, 81, 0, 0, + 0, 0, 0, 0, 0, 0, 436, 83, 84, 85, + 86, 14, 437, 87, 438, 88, 579, 0, 89, -11, + 439, 669, 440, 90, 0, -11, 0, 91, 16, 0, + 92, 441, 442, 0, 0, 0, 93, -11, 94, 0, + 0, 95, 96, 17, 0, 18, 19, 20, -11, 443, + 97, 21, 22, 98, 444, 445, 100, 446, 0, 24, + 0, 101, 447, 315, 102, 25, 448, 449, 433, 0, + 73, 0, 356, 767, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 80, 81, 0, 0, 0, 0, 0, 0, + 0, 0, 436, 83, 84, 85, 86, 14, 437, 87, + 438, 88, 0, 0, 89, -11, 439, 15, 440, 90, + 0, -11, 0, 91, 16, 0, 92, 441, 442, 0, + 0, 0, 93, -11, 94, 0, 0, 95, 96, 17, + 0, 18, 19, 20, -11, 443, 97, 21, 22, 98, + 444, 445, 100, 446, 0, 24, 0, 101, 447, 315, + 102, 25, 448, 449, 433, 0, 73, 0, 356, 769, + 0, 0, 0, 0, 435, 0, 0, 0, 0, 0, + 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 80, 81, + 0, 0, 0, 0, 0, 0, 0, 0, 436, 83, + 84, 85, 86, 14, 437, 87, 438, 88, 0, 0, + 89, -11, 439, 15, 440, 90, 0, -11, 0, 91, + 16, 0, 92, 441, 442, 0, 0, 0, 93, -11, + 94, 0, 0, 95, 96, 17, 0, 18, 19, 20, + -11, 443, 97, 21, 22, 98, 444, 445, 100, 446, + 0, 24, 0, 101, 447, 315, 102, 25, 448, 449, + 433, 0, 73, 0, 356, 793, 0, 0, 0, 0, + 435, 0, 0, 0, 0, 0, 0, 13, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 80, 81, 0, 0, 0, 0, + 0, 0, 0, 0, 436, 83, 84, 85, 86, 14, + 437, 87, 438, 88, 0, 0, 89, -11, 439, 15, + 440, 90, 0, -11, 0, 91, 16, 0, 92, 441, + 442, 0, 0, 0, 93, -11, 94, 0, 0, 95, + 96, 17, 0, 18, 19, 20, -11, 443, 97, 21, + 22, 98, 444, 445, 100, 446, 0, 24, 0, 101, + 447, 315, 102, 25, 448, 449, 433, 0, 73, 0, + 356, 0, 0, 0, 0, 0, 435, 0, 0, 0, + 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 80, 81, 0, 0, 0, 0, 0, - 0, 0, 0, 442, 83, 84, 85, 86, 14, 443, - 87, 444, 88, 0, 0, 89, -11, 445, 15, 446, - 90, 0, -11, 0, 91, 16, 0, 92, 447, 448, - 0, 0, 0, 93, -11, 94, 0, 13, 95, 96, - 17, 0, 18, 19, 20, -11, 449, 97, 21, 22, - 98, 450, 451, 100, 452, 0, 24, 0, 101, 453, - 317, 102, 25, 454, 455, 439, 0, 73, 0, 357, - 0, 0, 0, 0, 8, 441, 0, 0, 0, 0, - 0, 87, 13, 88, 0, 0, 89, 0, 0, 0, - 0, 90, 0, 0, 0, 0, 0, 0, 92, 0, - 0, 0, 0, 0, 93, 0, 94, 0, 0, 80, - 81, 0, 0, 0, 0, 0, 0, 0, 97, 442, - 83, 84, 85, 86, 0, 443, 87, 444, 88, 0, - 0, 89, 621, 445, 0, 446, 90, 0, 0, 13, - 91, 0, 0, 92, 447, 448, 0, 0, 0, 93, - 13, 94, 0, 0, 95, 96, 0, 0, 266, 0, - 0, 0, 449, 97, 0, 0, 98, 450, 555, 100, - 452, 149, 241, 0, 101, 453, 8, 102, 0, 454, - 455, 0, 0, 87, 0, 88, 13, 8, 89, 0, - 76, 77, 0, 90, 87, 0, 88, 78, 79, 89, - 92, 0, 0, 0, 90, 0, 93, 0, 94, 0, - 0, 92, 0, 80, 81, 0, 0, 93, 0, 94, - 97, 0, 0, 150, 83, 84, 85, 86, 14, 0, - 87, 97, 88, 0, 695, 89, 0, 13, 15, 0, - 90, 0, 0, 0, 91, 16, 0, 92, 0, 0, - 0, 0, 0, 93, 0, 94, 0, 0, 95, 96, - 17, 0, 18, 19, 20, 0, 0, 97, 21, 22, - 98, 99, 23, 100, 0, 0, 24, 0, 101, 14, - 0, 102, 25, 73, 74, 75, 0, 0, 0, 15, - 0, 0, 0, 41, 0, 0, 16, 0, 13, 0, - 0, 0, 76, 77, 0, 42, 0, 0, 0, 78, - 79, 17, 0, 18, 19, 20, 43, 0, 0, 21, - 22, 0, 0, 23, 0, 80, 81, 24, 0, 0, - 0, 0, 0, 25, 0, 82, 83, 84, 85, 86, - 0, 0, 87, 0, 88, 0, 0, 89, 0, 73, - 0, 75, 90, 0, 0, 161, 91, 0, 0, 92, + 80, 81, -42, 0, 0, 0, 0, 0, 0, 0, + 436, 83, 84, 85, 86, 0, 437, 87, 438, 88, + 13, 0, 89, 0, 439, 0, 440, 90, 0, 0, + 0, 91, 0, 0, 92, 441, 442, 0, 0, 0, + 93, 0, 94, 0, 0, 95, 96, 0, 0, 0, + 0, 0, 0, 443, 97, 0, 0, 98, 444, 549, + 100, 446, 14, 0, 0, 101, 447, 0, 102, 0, + 448, 449, 15, 0, 0, 0, 0, 0, 0, 16, + 0, 0, 0, 0, 0, 149, 243, 0, 0, 0, + 0, 0, 0, 0, 17, 0, 18, 19, 20, 0, + 13, 0, 21, 22, 76, 77, 23, 0, 0, 0, + 24, 78, 79, 0, 0, 0, 25, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 80, 81, 0, + 0, 0, 0, 0, 0, 0, 0, 150, 83, 84, + 85, 86, 14, 0, 87, 0, 88, 0, 0, 89, + 0, 40, 15, 0, 90, 0, 0, 0, 91, 16, + 0, 92, 0, 0, 0, 0, 0, 93, 0, 94, + 0, 0, 95, 96, 17, 0, 18, 19, 20, 0, + 0, 97, 21, 22, 98, 99, 23, 100, 0, 0, + 24, 0, 101, 14, 0, 102, 25, 73, 74, 75, + 0, 0, 0, 15, 0, 0, 0, 41, 0, 0, + 16, 0, 13, 0, 0, 0, 76, 77, 0, 42, + 0, 0, 0, 78, 79, 17, 0, 18, 19, 20, + 43, 0, 0, 21, 22, 0, 0, 23, 0, 80, + 81, 24, 0, 0, 0, 0, 0, 25, 0, 82, + 83, 84, 85, 86, 0, 0, 87, 0, 88, 0, + 0, 89, 0, 73, 0, 75, 90, 0, 0, 161, + 91, 0, 0, 92, 0, 0, 0, 0, 13, 93, + 0, 94, 76, 77, 95, 96, 0, 0, 0, 78, + 79, 0, 0, 97, 0, 0, 98, 99, 0, 100, + 0, 0, 0, 0, 101, 80, 81, 102, 0, 0, + 0, 0, 0, 0, 0, 8, 83, 84, 85, 86, + 0, 0, 87, 0, 88, 0, 0, 89, 0, 149, + 0, 356, 90, 0, 0, 0, 91, 0, 0, 92, 0, 0, 0, 0, 13, 93, 0, 94, 76, 77, 95, 96, 0, 0, 0, 78, 79, 0, 0, 97, 0, 0, 98, 99, 0, 100, 0, 0, 0, 0, 101, 80, 81, 102, 0, 0, 0, 0, 0, 0, - 0, 8, 83, 84, 85, 86, 0, 0, 87, 0, - 88, 0, 0, 89, 0, 149, 0, 357, 90, 0, + 0, 150, 83, 84, 85, 86, 0, 0, 87, 0, + 88, 0, 0, 89, 0, 73, 0, 75, 90, 0, 0, 0, 91, 0, 0, 92, 0, 0, 0, 0, 13, 93, 0, 94, 76, 77, 95, 96, 0, 0, 0, 78, 79, 0, 0, 97, 0, 0, 98, 99, - 0, 100, 0, 0, 0, 0, 101, 80, 81, 102, - 0, 0, 0, 0, 0, 0, 0, 150, 83, 84, + 0, 100, 712, 0, 0, 0, 101, 80, 81, 102, + 0, 0, 0, 0, 0, 0, 0, 8, 83, 84, 85, 86, 0, 0, 87, 0, 88, 0, 0, 89, - 0, 73, 0, 75, 90, 0, 0, 0, 91, 0, + 0, 149, 0, 0, 90, 0, 283, 0, 91, 0, 0, 92, 0, 0, 0, 0, 13, 93, 0, 94, 76, 77, 95, 96, 0, 0, 0, 78, 79, 0, - 0, 97, 0, 0, 98, 99, 0, 100, 718, 0, + 0, 97, 0, 0, 98, 99, 0, 100, 0, 0, 0, 0, 101, 80, 81, 102, 0, 0, 0, 0, - 0, 0, 0, 8, 83, 84, 85, 86, 0, 0, + 0, 0, 0, 150, 83, 84, 85, 86, 0, 0, 87, 0, 88, 0, 0, 89, 0, 149, 288, 0, 90, 0, 0, 0, 91, 0, 0, 92, 0, 0, 0, 0, 13, 93, 0, 94, 76, 77, 95, 96, @@ -5085,147 +5183,146 @@ private static final short[] yytable_init() 98, 99, 0, 100, 0, 0, 0, 0, 101, 80, 81, 102, 0, 0, 0, 0, 0, 0, 0, 150, 83, 84, 85, 86, 0, 0, 87, 0, 88, 0, - 0, 89, 0, 149, 0, 357, 90, 0, 0, 0, + 0, 89, 0, 149, 0, 356, 90, 0, 0, 0, 91, 0, 0, 92, 0, 0, 0, 0, 13, 93, 0, 94, 76, 77, 95, 96, 0, 0, 0, 78, 79, 0, 0, 97, 0, 0, 98, 99, 0, 100, 0, 0, 0, 0, 101, 80, 81, 102, 0, 0, 0, 0, 0, 0, 0, 150, 83, 84, 85, 86, 0, 0, 87, 0, 88, 0, 0, 89, 0, 149, - 0, 0, 90, 0, 284, 0, 91, 0, 0, 92, + 0, 0, 90, 0, 379, 0, 91, 0, 0, 92, 0, 0, 0, 0, 13, 93, 0, 94, 76, 77, 95, 96, 0, 0, 0, 78, 79, 0, 0, 97, 0, 0, 98, 99, 0, 100, 0, 0, 0, 0, 101, 80, 81, 102, 0, 0, 0, 0, 0, 0, 0, 150, 83, 84, 85, 86, 0, 0, 87, 0, - 88, 0, 0, 89, 0, 149, 0, 370, 90, 0, + 88, 0, 0, 89, 0, 149, 0, 368, 90, 0, 0, 0, 91, 0, 0, 92, 0, 0, 0, 0, 13, 93, 0, 94, 76, 77, 95, 96, 0, 0, 0, 78, 79, 0, 0, 97, 0, 0, 98, 99, 0, 100, 0, 0, 0, 0, 101, 80, 81, 102, 0, 0, 0, 0, 0, 0, 0, 150, 83, 84, 85, 86, 0, 0, 87, 0, 88, 0, 0, 89, - 0, 149, 0, 0, 90, 0, 384, 0, 91, 0, + 0, 149, 0, 0, 90, 0, 0, 0, 91, 553, 0, 92, 0, 0, 0, 0, 13, 93, 0, 94, 76, 77, 95, 96, 0, 0, 0, 78, 79, 0, 0, 97, 0, 0, 98, 99, 0, 100, 0, 0, 0, 0, 101, 80, 81, 102, 0, 0, 0, 0, 0, 0, 0, 150, 83, 84, 85, 86, 0, 0, 87, 0, 88, 0, 0, 89, 0, 149, 0, 0, - 90, 0, 0, 0, 91, 559, 0, 92, 0, 0, + 90, 0, 0, 0, 91, 0, 0, 92, 0, 0, 0, 0, 13, 93, 0, 94, 76, 77, 95, 96, 0, 0, 0, 78, 79, 0, 0, 97, 0, 0, 98, 99, 0, 100, 0, 0, 0, 0, 101, 80, 81, 102, 0, 0, 0, 0, 0, 0, 0, 150, 83, 84, 85, 86, 0, 0, 87, 0, 88, 0, - 0, 89, 0, 149, 0, 0, 90, 0, 0, 0, + 0, 89, 0, 73, 0, 0, 90, 0, 0, 0, 91, 0, 0, 92, 0, 0, 0, 0, 13, 93, 0, 94, 76, 77, 95, 96, 0, 0, 0, 78, 79, 0, 0, 97, 0, 0, 98, 99, 0, 100, 0, 0, 0, 0, 101, 80, 81, 102, 0, 0, - 0, 0, 0, 0, 0, 150, 83, 84, 85, 86, - 0, 0, 87, 0, 88, 0, 0, 89, 0, 73, - 0, 0, 90, 0, 0, 0, 91, 0, 0, 92, - 0, 0, 0, 0, 13, 93, 0, 94, 76, 77, - 95, 96, 0, 0, 0, 78, 79, 0, 0, 97, - 0, 0, 98, 99, 0, 100, 0, 0, 0, 0, - 101, 80, 81, 102, 0, 0, 0, 0, 0, 0, - 0, 8, 83, 84, 85, 86, 0, 0, 87, 0, - 88, 73, 0, 89, 0, 0, 0, 0, 90, 0, - 0, 0, 91, 0, 0, 92, 13, 0, 0, 0, - 0, 93, 0, 94, 0, 0, 95, 96, 0, 0, - 0, 0, 0, 0, 0, 97, 0, 0, 98, 99, - 0, 100, 0, 80, 81, 0, 101, 0, 0, 102, - 0, 0, 0, 8, 83, 84, 85, 86, 0, 0, - 87, 0, 88, 73, 0, 89, 0, 0, 0, 0, - 90, 0, 0, 0, 91, 0, 0, 92, 13, 0, - 0, 0, 0, 93, 0, 94, 0, 0, 95, 96, - 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, - 98, 0, 0, 100, 0, 80, 81, 0, 101, 0, - 317, 102, 0, 0, 0, 8, 83, 84, 85, 86, - 0, 0, 87, 0, 88, 73, 750, 89, 0, 0, + 0, 0, 0, 0, 0, 8, 83, 84, 85, 86, + 0, 0, 87, 0, 88, 73, 0, 89, 0, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 92, 13, 0, 0, 0, 0, 93, 0, 94, 0, 0, 95, 96, 0, 0, 0, 0, 0, 0, 0, 97, - 0, 0, 98, 0, 0, 100, 0, 0, 0, 0, + 0, 0, 98, 99, 0, 100, 0, 80, 81, 0, 101, 0, 0, 102, 0, 0, 0, 8, 83, 84, - 85, 86, 0, 0, 87, 73, 88, 0, 0, 89, + 85, 86, 0, 0, 87, 0, 88, 73, 0, 89, 0, 0, 0, 0, 90, 0, 0, 0, 91, 0, - 13, 92, 0, 0, 0, 0, 0, 93, 0, 94, + 0, 92, 13, 0, 0, 0, 0, 93, 0, 94, 0, 0, 95, 96, 0, 0, 0, 0, 0, 0, - 0, 97, 0, 0, 98, 0, 0, 100, 0, 0, - 0, 0, 101, 0, 317, 102, 0, 8, 83, 84, - 85, 86, 726, 0, 87, 0, 88, 0, 0, 89, - 0, 0, 0, 0, 90, 0, 13, 0, 91, 0, - 0, 92, 0, 0, 357, 539, 0, 93, 0, 94, - 514, 0, 95, 96, 0, 0, 0, 13, 0, 0, - 0, 97, 0, 0, 98, 0, 0, 100, 0, 0, - 0, 0, 101, 8, 317, 102, 0, 0, 14, 0, - 87, 0, 88, 357, 583, 89, 0, 0, 15, 514, - 90, 0, 0, 0, 0, 16, 13, 92, 0, 14, - 0, 0, 0, 93, 0, 94, 0, 0, 0, 15, - 17, 0, 18, 19, 20, 0, 16, 97, 21, 22, - 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, - 0, 17, 25, 18, 19, 20, 357, -120, 14, 515, - 22, 0, 514, 23, 0, 0, 0, 24, 15, 13, - 0, 0, 0, 25, 0, 16, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 17, 0, 18, 19, 20, 357, 631, 0, 515, 22, - 0, 514, 23, 0, 0, 0, 24, 0, 13, 0, - 0, 14, 25, 0, 0, 0, 357, 666, 0, 0, - 0, 15, 514, 0, 0, 0, 0, 0, 16, 13, + 0, 97, 0, 0, 98, 0, 0, 100, 0, 80, + 81, 0, 101, 0, 315, 102, 0, 0, 0, 8, + 83, 84, 85, 86, 0, 0, 87, 0, 88, 73, + 744, 89, 0, 0, 0, 0, 90, 0, 0, 0, + 91, 0, 0, 92, 13, 0, 0, 0, 0, 93, + 0, 94, 0, 0, 95, 96, 0, 0, 0, 0, + 0, 0, 0, 97, 0, 0, 98, 0, 0, 100, + 0, 0, 0, 0, 101, 0, 0, 102, 0, 0, + 0, 8, 83, 84, 85, 86, 0, 0, 87, 73, + 88, 0, 0, 89, 0, 0, 0, 0, 90, 0, + 0, 0, 91, 0, 13, 92, 0, 0, 0, 0, + 0, 93, 0, 94, 0, 0, 95, 96, 0, 0, + 0, 0, 0, 0, 0, 97, 0, 0, 98, 0, + 0, 100, 0, 0, 0, 0, 101, 0, 315, 102, + 0, 8, 83, 84, 85, 86, 720, 0, 87, 0, + 88, 0, 0, 89, 0, 0, 0, 0, 90, 0, + 13, 0, 91, 0, 0, 92, 0, 0, 356, -119, + 0, 93, 0, 94, 508, 0, 95, 96, 0, 0, + 0, 13, 0, 0, 0, 97, 0, 0, 98, 0, + 0, 100, 0, 0, 0, 0, 101, 8, 315, 102, + 0, 0, 14, 0, 87, 0, 88, 356, 533, 89, + 0, 0, 15, 508, 90, 0, 0, 0, 0, 16, + 13, 92, 0, 14, 0, 0, 0, 93, 0, 94, + 0, 0, 0, 15, 17, 0, 18, 19, 20, 0, + 16, 97, 21, 22, 0, 0, 23, 0, 0, 0, + 24, 0, 0, 0, 0, 17, 25, 18, 19, 20, + 356, 576, 14, 509, 22, 0, 508, 23, 0, 0, + 0, 24, 15, 13, 0, 0, 0, 25, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 17, 0, 18, 19, 20, 356, + -120, 0, 509, 22, 0, 508, 23, 0, 0, 0, + 24, 0, 13, 0, 0, 14, 25, 0, 0, 0, + 356, 625, 0, 0, 0, 15, 508, 0, 0, 0, + 0, 0, 16, 13, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 17, 0, 18, + 19, 20, 0, 0, 14, 509, 22, 0, 0, 23, + 0, 0, 0, 24, 15, 0, 356, 660, 0, 25, + 0, 16, 508, 0, 0, 14, 0, 0, 0, 13, + 0, 0, 0, 0, 0, 15, 17, 0, 18, 19, + 20, 0, 16, 0, 509, 22, 0, 0, 23, 0, + 329, 0, 24, 0, 0, 0, 0, 17, 25, 18, + 19, 20, 13, 0, 0, 509, 22, 0, 0, 23, + 0, 14, 0, 24, 0, 0, 0, 0, 404, 25, + 0, 15, 0, 0, 0, 0, 0, 0, 16, 417, + 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 13, 0, 17, 14, 18, 19, 20, 0, 0, + 0, 509, 22, 0, 15, 23, 0, 528, 0, 24, + 0, 16, 0, 0, 0, 25, 0, 0, 0, 13, + 0, 0, 14, 0, 0, 0, 17, 0, 18, 19, + 20, 0, 15, 14, 21, 22, 0, 0, 23, 16, + 0, 0, 24, 15, 0, 0, 0, 0, 25, 0, + 16, 0, 0, 0, 17, 0, 18, 19, 20, 0, + 0, 14, 21, 22, 0, 17, 23, 18, 19, 20, + 24, 15, 0, 21, 22, 0, 25, 23, 16, 40, + 143, 24, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 17, 0, 18, 19, 20, 0, 0, - 14, 515, 22, 0, 0, 23, 410, 0, 0, 24, - 15, 0, 0, 0, 0, 25, 0, 16, 13, 0, - 0, 14, 0, 0, 0, 0, 0, 423, 0, 0, - 0, 15, 17, 0, 18, 19, 20, 0, 16, 13, - 515, 22, 0, 0, 23, 0, 0, 0, 24, 0, - 0, 0, 0, 17, 25, 18, 19, 20, 0, 0, - 14, 515, 22, 0, 0, 23, 534, 13, 0, 24, - 15, 0, 0, 0, 0, 25, 0, 16, 13, 0, - 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 15, 17, 0, 18, 19, 20, 0, 16, 0, - 21, 22, 0, 0, 23, 0, 0, 0, 24, 14, - 0, 0, 0, 17, 25, 18, 19, 20, 0, 15, + 0, 21, 22, 0, 0, 23, 0, 0, 0, 24, + 0, 0, 0, 0, 0, 25, 8, 0, 0, 0, + 0, 14, 0, 87, 0, 88, 0, 0, 89, 0, + 0, 15, 0, 90, 0, 41, 40, 143, 16, 0, + 92, 0, 0, 0, 0, 0, 93, 42, 94, 0, + 0, 0, 0, 17, 0, 18, 19, 20, 43, 0, + 97, 21, 22, 0, 0, 23, 0, 0, 0, 24, + 0, 0, 0, 624, 519, 25, 0, 0, 14, 0, + 87, 0, 88, 0, 0, 89, 0, 0, 15, 0, + 90, 40, 41, 0, 0, 16, 0, 92, 0, 0, + 0, 0, 0, 93, 42, 94, 0, 0, 0, 0, + 17, 0, 18, 19, 20, 43, 0, 97, 21, 22, + 0, 0, 23, 0, 0, 0, 24, 0, 8, 0, + 0, 519, 25, 14, 13, 87, 0, 88, 0, 0, + 89, 0, 0, 15, 0, 90, 0, 41, 0, 0, + 16, 0, 92, 0, 0, 0, 0, 0, 93, 42, + 94, 0, 0, 0, 0, 17, 0, 18, 19, 20, + 43, 8, 97, 21, 22, 0, 14, 23, 87, 13, + 88, 24, 0, 89, 0, 0, 15, 25, 90, 0, + 0, 0, 0, 16, 0, 92, 0, 0, 0, 0, + 0, 93, 0, 94, 0, 0, 0, 13, 17, 0, + 18, 19, 20, 0, 0, 97, 21, 22, 13, 0, + 23, 14, 0, 0, 24, 0, 0, 0, 0, 0, + 25, 15, 0, 0, 0, 41, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 0, 42, 0, 14, + 0, 0, 0, 17, 0, 18, 19, 20, 43, 15, 14, 21, 22, 0, 0, 23, 16, 0, 0, 24, - 15, 0, 1, 40, 143, 25, 0, 16, 0, 0, + 15, 0, 1, 0, 0, 25, 0, 16, 0, 0, 0, 17, 0, 18, 19, 20, 0, 0, 0, 21, 22, 0, 17, 23, 18, 19, 20, 24, 0, 0, - 21, 22, 0, 25, 23, 0, 0, 0, 24, 0, - 8, 0, 0, 0, 25, 14, 0, 87, 0, 88, - 0, 0, 89, 0, 0, 15, 0, 90, 0, 41, - 40, 143, 16, 0, 92, 0, 0, 0, 0, 0, - 93, 42, 94, 0, 0, 0, 0, 17, 0, 18, - 19, 20, 43, 0, 97, 21, 22, 0, 0, 23, - 0, 0, 0, 24, 0, 0, 0, 630, 525, 25, - 0, 0, 14, 0, 87, 0, 88, 0, 0, 89, - 0, 0, 15, 0, 90, 40, 41, 0, 0, 16, - 0, 92, 0, 0, 0, 0, 0, 93, 42, 94, - 0, 0, 0, 0, 17, 0, 18, 19, 20, 43, - 0, 97, 21, 22, 0, 0, 23, 0, 0, 0, - 24, 0, 8, 0, 0, 525, 25, 14, 13, 87, - 0, 88, 0, 0, 89, 0, 0, 15, 0, 90, - 0, 41, 0, 0, 16, 0, 92, 0, 0, 13, - 0, 0, 93, 42, 94, 0, 0, 0, 0, 17, - 0, 18, 19, 20, 43, 8, 97, 21, 22, 0, - 14, 23, 87, 0, 88, 24, 0, 89, 0, 0, - 15, 25, 90, 0, 0, 0, 0, 16, 0, 92, - 0, 14, 13, 171, 0, 93, 0, 94, 0, 0, - 0, 15, 17, 0, 18, 19, 20, 0, 16, 97, - 21, 22, 0, 0, 23, 0, 0, 0, 24, 0, - 13, 0, 0, 17, 25, 18, 19, 20, 368, 8, - 0, 21, 22, 0, 0, 23, 87, 0, 88, 24, - 0, 89, 0, 0, 0, 25, 90, 0, 0, 0, - 14, 0, 0, 92, 0, 0, 0, 8, 0, 93, - 15, 94, 0, 0, 87, 0, 88, 16, 0, 89, - 0, 0, 0, 97, 90, 0, 0, 0, 0, 0, - 0, 92, 17, 0, 18, 19, 20, 93, 0, 94, - 21, 22, 184, 0, 23, 0, 185, 0, 24, 186, - 0, 97, -50, 0, 25, 0, 0, -50, 171, 0, - 0, 0, 0, 0, 0, 0, 0, -375, 0, 0, - 0, 0, 0, -375, -375, -375, -375, -375, -375, -375, - -375, -375, -375, -375, 0, 0, 0, 0, 0, 0, + 21, 22, 184, 25, 23, 0, 179, 0, 24, 185, + 0, 0, -50, 0, 25, 0, 0, 13, 171, 0, + 0, 0, 0, 0, 0, 0, 0, -378, 0, 0, + 0, 0, 0, -378, -378, -378, -378, -378, -378, -378, + -378, -378, -378, -378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -50 }; } @@ -5235,293 +5332,304 @@ private static final short[] yycheck_init() { return new short[] { - 1, 2, 104, 186, 357, 317, 272, 276, 9, 459, - 173, 194, 13, 430, 209, 446, 176, 177, 557, 32, - 62, 239, 564, 106, 587, 424, 0, 105, 19, 593, - 190, 19, 75, 75, 194, 195, 5, 55, 657, 40, - 424, 433, 516, 32, 6, 11, 55, 14, 525, 151, - 55, 76, 77, 78, 79, 80, 81, 65, 66, 174, - 19, 62, 5, 11, 55, 657, 540, 55, 11, 14, - 172, 332, 55, 62, 75, 76, 77, 78, 79, 80, - 81, 90, 100, 95, 186, 18, 75, 5, 55, 55, - 7, 403, 61, 332, 95, 714, 55, 102, 181, 90, - 517, 18, 90, 65, 619, 620, 459, 55, 70, 83, - 55, 380, 6, 31, 102, 18, 6, 277, 549, 93, - 389, 713, 55, 238, 19, 542, 395, 170, 170, 141, - 522, 55, 516, 697, 352, 136, 535, 220, 55, 147, - 141, 75, 0, 61, 621, 622, 623, 136, 417, 21, - 411, 535, 55, 716, 72, 697, 540, 28, 3, 171, - 55, 26, 86, 424, 703, 10, 708, 584, 102, 170, - 171, 65, 411, 737, 66, 65, 70, 692, 693, 694, - 70, 170, 47, 55, 55, 424, 78, 55, 105, 272, - 215, 216, 217, 75, 183, 273, 197, 209, 199, 200, + 1, 2, 75, 453, 105, 185, 315, 579, 9, 172, + 173, 424, 13, 193, 62, 176, 177, 551, 356, 32, + 210, 368, 104, 558, 19, 585, 418, 75, 19, 190, + 276, 0, 193, 194, 241, 7, 613, 614, 440, 40, + 427, 19, 20, 651, 240, 651, 18, 55, 65, 66, + 14, 519, 11, 19, 32, 33, 7, 19, 55, 75, + 55, 62, 83, 248, 55, 250, 55, 18, 6, 151, + 330, 330, 5, 66, 75, 76, 77, 78, 79, 80, + 81, 6, 11, 55, 9, 78, 102, 5, 397, 55, + 172, 55, 100, 55, 95, 90, 55, 170, 511, 90, + 708, 707, 6, 185, 55, 102, 84, 102, 26, 686, + 687, 688, 275, 31, 83, 453, 76, 77, 78, 79, + 80, 81, 170, 536, 93, 371, 55, 65, 61, 516, + 147, 691, 70, 105, 278, 136, 54, 529, 710, 221, + 141, 543, 338, 61, 351, 405, 405, 615, 616, 617, + 55, 728, 499, 75, 72, 32, 691, 353, 418, 418, + 418, 65, 21, 697, 577, 28, 70, 702, 7, 170, + 171, 731, 7, 174, 102, 10, 0, 105, 6, 18, + 102, 86, 18, 18, 102, 62, 104, 105, 106, 28, + 108, 450, 55, 266, 112, 18, 55, 198, 75, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, 456, 695, 734, - 102, 264, 264, 235, 339, 589, 676, 591, 388, 593, - 390, 149, 245, 83, 235, 398, 319, 19, 20, 354, - 593, 242, 781, 7, 245, 234, 49, 7, 51, 7, - 32, 33, 68, 12, 18, 516, 245, 7, 18, 7, - 18, 376, 457, 264, 28, 24, 55, 7, 18, 270, - 18, 354, 55, 704, 535, 264, 10, 516, 18, 540, - 55, 270, 7, 3, 715, 19, 275, 7, 738, 7, - 279, 5, 604, 18, 10, 55, 535, 55, 18, 4, - 18, 540, 84, 19, 9, 55, 224, 55, 28, 25, - 28, 4, 26, 428, 429, 55, 9, 31, 7, 11, - 332, 404, 334, 676, 774, 18, 595, 339, 4, 18, - 55, 332, 598, 334, 346, 11, 689, 4, 339, 351, - 54, 9, 9, 11, 697, 346, 429, 61, 349, 780, - 351, 782, 364, 365, 366, 397, 434, 435, 72, 402, - 402, 4, 557, 364, 365, 366, 28, 55, 11, 564, - 723, 82, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 19, 737, 738, 817, 7, 102, 55, - 3, 105, 106, 7, 7, 11, 397, 10, 18, 411, - 13, 402, 4, 28, 18, 18, 19, 9, 7, 11, - 411, 10, 424, 402, 5, 333, 7, 770, 3, 18, - 421, 774, 7, 424, 507, 10, 344, 18, 4, 143, - 3, 9, 421, 9, 19, 149, 357, 3, 356, 357, - 9, 7, 20, 526, 10, 4, 10, 13, 437, 13, - 9, 20, 18, 19, 7, 7, 457, 171, 10, 173, - 174, 13, 10, 11, 4, 18, 18, 181, 4, 9, - 482, 483, 4, 9, 3, 11, 5, 9, 48, 45, - 46, 482, 483, 0, 9, 246, 11, 248, 571, 55, - 4, 6, 6, 21, 9, 9, 414, 11, 17, 7, - 6, 18, 10, 9, 27, 13, 220, 425, 777, 778, - 224, 523, 430, 708, 228, 516, 528, 52, 53, 54, - 683, 604, 523, 535, 238, 446, 7, 528, 102, 10, - 102, 105, 13, 105, 535, 10, 11, 697, 459, 540, - 623, 459, 4, 60, 813, 814, 24, 649, 205, 206, - 207, 208, 9, 70, 11, 14, 15, 16, 272, 273, - 77, 10, 11, 564, 22, 23, 83, 5, 210, 211, - 212, 45, 46, 491, 5, 92, 75, 94, 95, 96, - 45, 46, 4, 100, 101, 11, 12, 104, 3, 772, - 24, 108, 6, 776, 18, 607, 19, 114, 8, 517, - 45, 46, 203, 204, 682, 319, 607, 213, 214, 10, - 10, 55, 772, 728, 9, 5, 776, 9, 332, 333, - 75, 75, 3, 624, 542, 339, 340, 55, 549, 4, - 344, 68, 8, 10, 736, 624, 557, 55, 55, 8, - 354, 13, 356, 357, 55, 728, 8, 55, 726, 764, - 55, 12, 366, 414, 28, 68, 55, 9, 55, 5, - 8, 55, 376, 5, 5, 9, 584, 6, 11, 430, - 772, 55, 593, 31, 686, 593, 11, 17, 12, 3, - 3, 764, 3, 3, 398, 686, 3, 765, 689, 11, - 404, 769, 453, 11, 9, 8, 697, 411, 55, 55, - 414, 55, 416, 3, 6, 55, 5, 708, 55, 115, - 424, 425, 31, 11, 428, 429, 430, 760, 760, 11, - 434, 435, 723, 11, 11, 11, 727, 11, 6, 5, - 491, 809, 4, 3, 107, 3, 5, 12, 11, 55, - 752, 55, 456, 9, 4, 459, 9, 4, 4, 3, - 12, 752, 4, 24, 515, 676, 517, 178, 676, 760, - 66, 12, 12, 184, 185, 3, 11, 78, 529, 770, - 11, 760, 193, 70, 4, 196, 697, 491, 4, 697, - 11, 542, 703, 704, 73, 4, 11, 11, 31, 11, - 55, 709, 102, 507, 715, 18, 808, 105, 11, 11, - 4, 11, 516, 517, 11, 566, 0, 808, 61, 38, - 54, 686, 526, 340, 528, 234, 737, 738, 491, 737, - 738, 535, 416, 584, 18, 246, 540, 248, 542, 413, - 687, 428, 542, 508, 581, 723, 764, 60, 770, 613, - 261, 456, 705, 411, 535, 589, 591, 70, 660, 708, - 271, 74, 613, 774, 77, 781, 774, 571, 397, 780, - 781, 782, 366, 86, 273, 356, 60, 197, 199, 92, - 584, 94, 95, 96, 97, 200, 70, 100, 101, 593, - -1, 104, -1, 77, -1, 108, -1, -1, -1, 201, - 604, 114, -1, 607, -1, 656, 817, 357, 92, 202, - 94, 95, 96, -1, -1, -1, 100, 101, -1, 623, - 104, -1, -1, -1, 108, -1, -1, -1, 679, 28, - 114, -1, -1, -1, 62, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, -1, 75, 76, 77, - 78, 79, 80, 81, -1, 706, -1, -1, 136, 370, - -1, -1, -1, 374, -1, -1, -1, -1, -1, -1, - -1, -1, 676, 62, -1, 386, -1, -1, 682, 683, - -1, -1, -1, -1, -1, 689, 75, 76, 77, 78, - 79, 80, 81, 697, -1, -1, 446, -1, -1, -1, - -1, 357, -1, -1, -1, 709, -1, -1, -1, 459, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 723, - -1, -1, 726, -1, 728, -1, -1, -1, -1, -1, - -1, 209, 443, 737, 738, 786, -1, -1, 449, 28, - -1, 452, 170, -1, 455, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, -1, -1, -1, -1, - 764, 765, -1, -1, 242, 769, 770, 245, -1, 197, - 774, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 170, 210, 211, 212, 213, 214, 215, 216, 217, - 446, -1, 270, 357, -1, 506, -1, -1, -1, 549, - -1, -1, -1, 459, -1, 809, -1, 557, 197, 357, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 6, 210, 211, 212, 213, 214, 215, 216, 217, -1, - -1, -1, 18, -1, -1, -1, 264, -1, -1, -1, - -1, -1, -1, 593, -1, -1, -1, 558, 55, -1, - 561, 562, -1, -1, 332, 62, 567, 64, -1, -1, - 67, -1, -1, -1, -1, 72, -1, -1, -1, -1, - 581, 349, 79, -1, 60, 264, -1, -1, 85, 357, - 87, -1, 446, -1, 70, -1, -1, -1, -1, -1, - -1, 77, 99, 549, -1, 459, -1, -1, 446, -1, - -1, 557, -1, -1, -1, 112, 92, -1, 94, 95, - 96, 459, -1, -1, 100, 101, -1, 357, 104, -1, - -1, 357, 108, -1, -1, 636, 676, -1, 114, -1, - -1, -1, -1, 411, -1, -1, -1, 593, -1, -1, - -1, -1, -1, 421, -1, -1, 424, 697, -1, -1, - -1, -1, -1, 703, 704, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 715, -1, -1, 679, 397, - -1, 357, -1, -1, 402, -1, 0, -1, -1, 457, - -1, 459, -1, -1, -1, 549, -1, 737, 738, 700, - 701, 702, -1, 557, 18, -1, -1, -1, -1, -1, - -1, 549, -1, -1, -1, -1, 446, 718, 397, 557, - 446, -1, -1, 402, -1, -1, -1, -1, -1, 459, - 676, -1, -1, 459, 774, -1, -1, -1, -1, 593, - 780, 781, 782, -1, -1, -1, 60, -1, 516, -1, - -1, 697, -1, -1, -1, 593, 70, 703, 704, -1, - 528, -1, -1, 77, -1, -1, -1, 535, -1, 715, - 446, -1, 540, -1, -1, -1, -1, 817, 92, -1, - 94, 95, 96, 459, -1, -1, 100, 101, -1, 557, - 104, 737, 738, -1, 108, -1, 564, -1, -1, -1, - 114, -1, -1, -1, -1, -1, -1, 5, 6, -1, - -1, -1, -1, 11, -1, -1, -1, -1, -1, 549, - 18, -1, 676, 549, -1, 593, -1, 557, 774, -1, - -1, 557, -1, -1, 780, 781, 782, -1, 676, 607, - -1, -1, -1, 697, -1, -1, 564, -1, -1, 703, - 704, -1, -1, -1, -1, -1, 624, -1, -1, 697, - -1, 715, 60, 593, -1, 703, 704, 593, -1, -1, - -1, 817, 70, 549, -1, -1, -1, 715, -1, 77, - -1, 557, -1, 737, 738, 564, -1, -1, -1, -1, - -1, -1, -1, -1, 92, -1, 94, 95, 96, 737, - 738, -1, 100, 101, -1, -1, 104, -1, 676, -1, - 108, -1, -1, -1, -1, -1, 114, 593, -1, -1, - 774, 689, -1, -1, -1, -1, 780, 781, 782, 697, - -1, -1, -1, -1, -1, -1, 774, -1, -1, -1, - 708, -1, 780, 781, 782, -1, 676, -1, -1, 18, - 676, -1, -1, -1, -1, 723, -1, -1, -1, 727, - -1, -1, -1, 817, -1, -1, -1, 697, -1, 737, - 738, 697, -1, 703, 704, -1, -1, 703, 704, 817, - -1, -1, -1, -1, -1, 715, 55, -1, -1, 715, - 708, -1, -1, 62, -1, 64, -1, -1, 67, -1, - 676, -1, 770, 72, -1, -1, 774, 737, 738, -1, - 79, 737, 738, -1, -1, -1, 85, -1, 87, -1, - -1, 697, -1, -1, -1, -1, -1, 703, 704, 708, - 99, -1, -1, -1, -1, -1, -1, -1, -1, 715, - -1, -1, 760, 112, 774, -1, -1, -1, 774, -1, - 780, 781, 782, -1, 780, 781, 782, -1, -1, -1, - -1, 737, 738, -1, -1, -1, -1, 1, -1, 3, - -1, 5, 6, -1, -1, -1, -1, 11, -1, -1, - -1, 760, -1, -1, 18, -1, -1, 817, -1, -1, - -1, 817, -1, -1, -1, -1, -1, -1, 774, -1, - -1, -1, -1, -1, 780, 781, 782, -1, -1, -1, - -1, 45, 46, -1, -1, -1, -1, -1, -1, -1, - -1, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, -1, 67, 68, 69, 70, 71, 72, -1, - 74, 817, 76, 77, -1, 79, 80, 81, -1, -1, - -1, 85, 86, 87, -1, -1, 90, 91, 92, -1, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, -1, 108, -1, 110, 111, 112, 113, - 114, 115, 116, 1, -1, 3, -1, 5, 6, -1, - 55, -1, -1, 11, -1, -1, -1, 62, -1, 64, - 18, 19, 67, -1, -1, -1, -1, 72, -1, -1, - -1, -1, -1, -1, 79, -1, -1, -1, -1, -1, - 85, -1, 87, -1, -1, -1, -1, 45, 46, -1, - -1, -1, -1, -1, 99, -1, -1, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 112, -1, 67, - 68, 69, 70, 71, 72, -1, 74, -1, 76, 77, - -1, 79, 80, 81, -1, -1, -1, 85, 86, 87, - -1, 18, 90, 91, 92, -1, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, -1, - 108, -1, 110, 111, 112, 113, 114, 115, 116, 1, - -1, 3, -1, 5, 6, -1, -1, -1, 55, 11, - -1, -1, -1, -1, -1, 62, 18, 64, -1, -1, - 67, -1, -1, -1, -1, 72, -1, -1, -1, -1, - -1, -1, 79, -1, -1, -1, -1, -1, 85, -1, - 87, -1, -1, 45, 46, -1, -1, -1, -1, -1, - -1, -1, 99, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, -1, -1, 67, 68, 69, 70, 71, - 72, -1, 74, -1, 76, 77, -1, 79, 80, 81, - -1, -1, -1, 85, 86, 87, -1, -1, 90, 91, - 92, -1, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, -1, 108, -1, 110, 111, - 112, 113, 114, 115, 116, 1, -1, 3, -1, 5, - 6, 55, -1, -1, -1, 11, -1, -1, 62, -1, - 64, -1, 18, 67, -1, -1, -1, -1, 72, -1, - -1, -1, -1, -1, -1, 79, -1, -1, -1, -1, - -1, 85, -1, 87, -1, -1, -1, -1, -1, 45, - 46, -1, -1, -1, -1, 99, -1, -1, -1, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, -1, - -1, 67, 68, 69, 70, 71, 72, -1, 74, -1, - 76, 77, -1, 79, 80, 81, -1, -1, -1, 85, - 86, 87, -1, -1, 90, 91, 92, -1, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, -1, 108, -1, 110, 111, 112, 113, 114, 115, - 116, 1, -1, 3, -1, 5, -1, -1, -1, -1, - -1, 11, -1, -1, -1, -1, -1, -1, 18, -1, + 211, 212, 213, 214, 215, 216, 217, 218, 266, 55, + 670, 689, 383, 408, 385, 143, 422, 423, 575, 392, + 374, 149, 55, 151, 247, 153, 237, 65, 5, 424, + 384, 775, 70, 244, 591, 389, 247, 585, 55, 7, + 510, 510, 510, 171, 172, 173, 216, 217, 218, 136, + 18, 451, 447, 181, 31, 266, 7, 411, 7, 529, + 529, 529, 273, 7, 534, 534, 534, 18, 14, 18, + 7, 7, 732, 90, 18, 510, 3, 7, 12, 598, + 7, 18, 18, 170, 61, 55, 698, 55, 18, 484, + 24, 18, 28, 55, 222, 72, 183, 709, 226, 534, + 4, 28, 230, 26, 55, 9, 55, 11, 768, 55, + 55, 55, 240, 396, 509, 4, 511, 428, 429, 330, + 9, 332, 670, 10, 47, 55, 4, 338, 523, 18, + 5, 9, 19, 391, 345, 683, 11, 348, 396, 350, + 55, 536, 356, 691, 68, 7, 274, 275, 276, 236, + 9, 551, 363, 364, 365, 5, 18, 7, 558, 3, + 247, 20, 774, 7, 776, 560, 10, 7, 18, 717, + 10, 4, 149, 13, 18, 19, 9, 9, 18, 266, + 391, 11, 577, 731, 732, 396, 273, 7, 20, 317, + 10, 4, 18, 13, 405, 19, 9, 7, 18, 811, + 10, 55, 330, 331, 415, 82, 3, 418, 18, 19, + 338, 339, 607, 10, 4, 343, 764, 4, 55, 6, + 768, 11, 9, 4, 11, 353, 440, 355, 356, 55, + 11, 10, 6, 587, 13, 9, 62, 365, 64, 453, + 451, 67, 102, 371, 11, 105, 72, 3, 28, 226, + 337, 7, 3, 79, 10, 650, 581, 13, 583, 85, + 585, 87, 18, 19, 392, 476, 477, 4, 7, 27, + 398, 10, 9, 99, 13, 48, 4, 405, 673, 18, + 408, 9, 410, 11, 4, 10, 11, 113, 4, 9, + 418, 419, 21, 9, 422, 423, 424, 10, 11, 510, + 428, 429, 702, 17, 677, 700, 517, 4, 49, 396, + 51, 522, 206, 207, 208, 209, 722, 3, 529, 3, + 691, 7, 450, 534, 10, 453, 5, 13, 415, 543, + 5, 55, 18, 19, 52, 53, 54, 551, 62, 9, + 64, 11, 75, 67, 431, 10, 11, 558, 72, 22, + 23, 643, 758, 24, 331, 79, 484, 45, 46, 45, + 46, 85, 3, 87, 5, 676, 343, 45, 46, 55, + 9, 585, 11, 501, 4, 99, 766, 24, 355, 356, + 770, 19, 510, 511, 9, 780, 11, 6, 112, 55, + 601, 9, 520, 7, 522, 766, 5, 18, 10, 770, + 10, 529, 45, 46, 18, 26, 534, 618, 536, 720, + 14, 15, 16, 75, 28, 11, 12, 771, 772, 9, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 408, 204, 205, 55, 75, 3, 565, 730, 214, + 215, 62, 419, 64, 55, 4, 67, 424, 759, 577, + 55, 72, 763, 807, 808, 8, 670, 585, 79, 211, + 212, 213, 68, 10, 85, 13, 87, 55, 68, 680, + 598, 754, 683, 601, 766, 55, 453, 691, 99, 55, + 691, 12, 55, 697, 698, 28, 9, 55, 18, 617, + 136, 702, 803, 5, 55, 709, 754, 5, 5, 141, + 9, 11, 8, 6, 17, 55, 717, 484, 62, 31, + 721, 11, 3, 12, 3, 643, 3, 731, 732, 647, + 3, 75, 76, 77, 78, 79, 80, 81, 3, 171, + 11, 618, 174, 11, 511, 746, 9, 55, 55, 3, + 55, 6, 670, 754, 5, 31, 115, 4, 676, 677, + 55, 11, 11, 764, 768, 683, 11, 11, 11, 536, + 774, 775, 776, 691, 210, 11, 6, 5, 210, 107, + 28, 55, 3, 55, 3, 703, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 5, 12, 717, + 11, 802, 720, 9, 722, 237, 62, 811, 244, 4, + 577, 247, 730, 731, 732, 733, 4, 4, 585, 75, + 76, 77, 78, 79, 80, 81, 170, 66, 3, 9, + 4, 356, 24, 12, 12, 12, 3, 273, 11, 11, + 758, 759, 4, 78, 70, 763, 764, 4, 11, 73, + 768, 4, 11, 11, 198, 11, 200, 201, 202, 203, + 204, 205, 206, 207, 208, 209, 31, 211, 212, 213, + 214, 215, 216, 217, 218, 102, 105, 754, 11, 11, + 4, 11, 11, 38, 55, 803, 54, 680, 339, 236, + 95, 61, 484, 681, 330, 407, 422, 410, 330, 536, + 332, 502, 575, 670, 717, 758, 338, 764, 607, 405, + 450, 529, 348, 345, 170, 440, 699, 581, 350, 104, + 356, 106, 266, 108, 691, 583, 775, 112, 453, 654, + 702, 363, 364, 365, 391, 201, 703, 355, 365, 18, + 198, 200, 198, 203, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, -1, 211, 212, 213, 214, 215, + 216, 217, 218, 0, 731, 732, 151, -1, 153, 405, + 202, 178, 179, 405, -1, -1, 55, 184, -1, 415, + -1, 18, 418, 62, -1, 64, 418, -1, 67, -1, + 197, -1, -1, 72, -1, 55, 181, -1, -1, -1, + 79, 768, 62, -1, 64, -1, 85, 67, 87, -1, + 266, -1, 72, -1, -1, 451, -1, 453, 543, 79, + 99, -1, -1, 60, 356, 85, 551, 87, -1, -1, + -1, -1, -1, 70, 113, -1, -1, 222, -1, 99, + 77, 248, -1, 250, 476, 477, 83, 391, -1, -1, + 18, -1, 396, -1, -1, 92, 263, 94, 95, 96, + 585, -1, -1, 100, 101, -1, -1, 104, -1, -1, + -1, 108, -1, -1, 510, -1, -1, 114, -1, -1, + 287, -1, -1, -1, -1, 517, 522, 55, -1, 274, + 522, 276, 356, 529, 62, -1, 64, 529, 534, 67, + -1, -1, -1, -1, 72, -1, -1, -1, 440, -1, + 18, 79, 20, -1, -1, 551, -1, 85, 26, 87, + -1, 453, 558, -1, -1, -1, -1, -1, -1, -1, + -1, 99, 317, -1, -1, 391, -1, -1, -1, -1, + 396, 18, -1, -1, 112, 670, -1, 55, -1, 585, + -1, -1, -1, -1, 62, -1, 64, -1, -1, 67, + 356, 368, -1, -1, 72, 601, 691, -1, 353, 601, + -1, 79, 697, 698, -1, 382, 440, 85, 55, 87, + 356, -1, 618, -1, 709, 62, 371, 64, -1, 453, + 67, 99, 19, -1, -1, 72, -1, -1, -1, -1, + -1, -1, 79, -1, -1, -1, 731, 732, 85, 356, + 87, 543, -1, 398, 558, -1, -1, -1, -1, 551, + -1, -1, 99, -1, -1, -1, -1, -1, 55, -1, + 437, -1, -1, -1, 670, 62, 443, 64, 423, 446, + 67, -1, 449, 768, 440, 72, -1, 683, 680, 774, + 775, 776, 79, 585, -1, 691, -1, 453, 85, -1, + 87, -1, -1, -1, 440, -1, 702, -1, -1, -1, + -1, -1, 99, -1, -1, -1, -1, 453, -1, 543, + -1, 717, -1, -1, -1, 721, 811, 551, -1, -1, + 356, -1, 499, 440, -1, 731, 732, -1, -1, -1, + -1, -1, 558, -1, -1, -1, 453, -1, -1, -1, + -1, -1, -1, -1, 746, -1, 501, -1, -1, -1, + -1, 585, -1, -1, -1, -1, -1, -1, 764, -1, + -1, -1, 768, -1, -1, 520, -1, -1, 670, -1, + -1, -1, -1, -1, -1, 552, -1, 543, 555, 556, + -1, -1, -1, -1, 561, 551, -1, -1, 702, 691, + -1, -1, -1, -1, -1, 697, 698, 543, 575, -1, + 802, -1, -1, -1, 440, 551, -1, 709, -1, -1, + 565, -1, -1, -1, -1, -1, -1, 453, -1, 585, + -1, -1, -1, -1, -1, -1, 543, -1, -1, 731, + 732, -1, -1, 18, 551, -1, 670, -1, -1, 585, + 754, 26, -1, 598, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 630, -1, -1, -1, 691, -1, -1, + -1, -1, 617, 697, 698, -1, 768, -1, 585, -1, + 55, -1, 774, 775, 776, 709, 702, 62, -1, 64, + -1, -1, 67, -1, -1, -1, -1, 72, 643, -1, + -1, -1, 647, -1, 79, -1, 673, 731, 732, -1, + 85, -1, 87, -1, 670, -1, -1, 543, -1, 811, + -1, -1, -1, -1, 99, 551, -1, 694, 695, 696, + -1, -1, -1, -1, 670, 691, -1, -1, 754, -1, + -1, 697, 698, -1, 768, 712, -1, -1, -1, -1, + 774, 775, 776, 709, -1, 691, 0, -1, -1, 585, + -1, 697, 698, 670, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 709, 18, 731, 732, 722, -1, -1, + -1, -1, -1, -1, 691, 730, -1, 811, 733, -1, + 697, 698, -1, -1, -1, 731, 732, 55, -1, -1, + -1, -1, 709, -1, 62, -1, 64, -1, -1, 67, + -1, -1, 768, 758, 72, -1, 60, -1, 774, 775, + 776, 79, -1, -1, 731, 732, 70, 85, -1, 87, + -1, -1, 768, 77, -1, -1, -1, -1, 774, 775, + 776, 99, -1, -1, 670, -1, -1, -1, 92, -1, + 94, 95, 96, -1, 112, 811, 100, 101, -1, -1, + 104, 768, -1, -1, 108, 691, -1, 774, 775, 776, + 114, 697, 698, -1, -1, 811, -1, -1, -1, -1, + -1, -1, -1, 709, -1, -1, -1, -1, -1, -1, + -1, -1, 60, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 70, -1, 811, 731, 732, -1, 1, 77, + 3, -1, 5, 6, -1, -1, -1, -1, 11, -1, + -1, -1, -1, -1, 92, 18, 94, 95, 96, -1, + -1, -1, 100, 101, -1, -1, 104, -1, -1, -1, + 108, -1, 768, -1, -1, -1, 114, -1, 774, 775, + 776, -1, 45, 46, -1, -1, -1, -1, -1, -1, + -1, -1, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, -1, 67, 68, 69, 70, 71, 72, + -1, 74, -1, 76, 77, 811, 79, 80, 81, -1, + -1, -1, 85, 86, 87, -1, -1, 90, 91, 92, + -1, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, -1, 108, -1, 110, 111, 112, + 113, 114, 115, 116, 1, -1, 3, -1, 5, 6, + -1, -1, -1, -1, 11, -1, -1, 28, -1, -1, + -1, 18, 19, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 45, 46, + -1, -1, -1, -1, -1, -1, -1, -1, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, -1, -1, + 67, 68, 69, 70, 71, 72, -1, 74, -1, 76, + 77, -1, 79, 80, 81, -1, -1, -1, 85, 86, + 87, -1, -1, 90, 91, 92, -1, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + -1, 108, -1, 110, 111, 112, 113, 114, 115, 116, + 1, -1, 3, -1, 5, 6, -1, -1, -1, -1, + 11, -1, -1, -1, -1, -1, -1, 18, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 45, 46, -1, -1, -1, - -1, -1, -1, -1, -1, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, -1, 67, 68, 69, - 70, 71, 72, -1, 74, -1, 76, 77, -1, 79, - 80, 81, -1, -1, -1, 85, 86, 87, -1, -1, - 90, 91, 92, -1, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, -1, 108, -1, - 110, 111, 112, 113, 114, 115, 116, 1, -1, 3, - -1, 5, 6, -1, -1, -1, -1, 11, -1, -1, - -1, -1, -1, -1, 18, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 45, 46, -1, -1, -1, -1, + -1, -1, -1, -1, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, -1, -1, 67, 68, 69, 70, + 71, 72, -1, 74, -1, 76, 77, -1, 79, 80, + 81, -1, -1, -1, 85, 86, 87, -1, -1, 90, + 91, 92, -1, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, -1, 108, -1, 110, + 111, 112, 113, 114, 115, 116, 1, -1, 3, -1, + 5, 6, -1, -1, -1, -1, 11, -1, -1, -1, + -1, -1, -1, 18, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 45, 46, -1, -1, -1, -1, -1, -1, -1, - -1, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, -1, -1, 67, 68, 69, 70, 71, 72, -1, - 74, -1, 76, 77, -1, 79, 80, 81, -1, -1, - -1, 85, 86, 87, -1, -1, 90, 91, 92, -1, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, -1, 108, -1, 110, 111, 112, 113, - 114, 115, 116, 1, -1, 3, -1, 5, 6, -1, - -1, -1, -1, 11, -1, -1, -1, -1, -1, -1, - 18, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 45, 46, -1, -1, -1, -1, -1, -1, -1, -1, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + -1, -1, 67, 68, 69, 70, 71, 72, -1, 74, + -1, 76, 77, -1, 79, 80, 81, -1, -1, -1, + 85, 86, 87, -1, -1, 90, 91, 92, -1, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, -1, 108, -1, 110, 111, 112, 113, 114, + 115, 116, 1, -1, 3, -1, 5, -1, -1, -1, + -1, -1, 11, -1, -1, -1, -1, -1, -1, 18, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 45, 46, -1, - -1, -1, -1, -1, -1, -1, -1, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, -1, -1, 67, - 68, 69, 70, 71, 72, -1, 74, -1, 76, 77, - -1, 79, 80, 81, -1, -1, -1, 85, 86, 87, - -1, -1, 90, 91, 92, -1, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, -1, - 108, -1, 110, 111, 112, 113, 114, 115, 116, 1, - -1, 3, -1, 5, 6, -1, -1, -1, -1, 11, - -1, -1, -1, -1, -1, -1, 18, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 45, 46, -1, -1, + -1, -1, -1, -1, -1, -1, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, -1, 67, 68, + 69, 70, 71, 72, -1, 74, -1, 76, 77, -1, + 79, 80, 81, -1, -1, -1, 85, 86, 87, -1, + -1, 90, 91, 92, -1, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, -1, 108, + -1, 110, 111, 112, 113, 114, 115, 116, 1, -1, + 3, -1, 5, 6, -1, -1, -1, -1, 11, -1, + -1, -1, -1, -1, -1, 18, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 45, 46, -1, -1, -1, -1, -1, - -1, -1, -1, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, -1, -1, 67, 68, 69, 70, 71, - 72, -1, 74, -1, 76, 77, -1, 79, 80, 81, - -1, -1, -1, 85, 86, 87, -1, 18, 90, 91, - 92, -1, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, -1, 108, -1, 110, 111, - 112, 113, 114, 115, 116, 1, -1, 3, -1, 5, - -1, -1, -1, -1, 55, 11, -1, -1, -1, -1, - -1, 62, 18, 64, -1, -1, 67, -1, -1, -1, - -1, 72, -1, -1, -1, -1, -1, -1, 79, -1, - -1, -1, -1, -1, 85, -1, 87, -1, -1, 45, - 46, -1, -1, -1, -1, -1, -1, -1, 99, 55, - 56, 57, 58, 59, -1, 61, 62, 63, 64, -1, - -1, 67, 113, 69, -1, 71, 72, -1, -1, 18, - 76, -1, -1, 79, 80, 81, -1, -1, -1, 85, - 18, 87, -1, -1, 90, 91, -1, -1, 26, -1, - -1, -1, 98, 99, -1, -1, 102, 103, 104, 105, - 106, 3, 4, -1, 110, 111, 55, 113, -1, 115, - 116, -1, -1, 62, -1, 64, 18, 55, 67, -1, - 22, 23, -1, 72, 62, -1, 64, 29, 30, 67, - 79, -1, -1, -1, 72, -1, 85, -1, 87, -1, - -1, 79, -1, 45, 46, -1, -1, 85, -1, 87, - 99, -1, -1, 55, 56, 57, 58, 59, 60, -1, - 62, 99, 64, -1, 113, 67, -1, 18, 70, -1, - 72, -1, -1, -1, 76, 77, -1, 79, -1, -1, - -1, -1, -1, 85, -1, 87, -1, -1, 90, 91, - 92, -1, 94, 95, 96, -1, -1, 99, 100, 101, - 102, 103, 104, 105, -1, -1, 108, -1, 110, 60, - -1, 113, 114, 3, 4, 5, -1, -1, -1, 70, - -1, -1, -1, 74, -1, -1, 77, -1, 18, -1, - -1, -1, 22, 23, -1, 86, -1, -1, -1, 29, - 30, 92, -1, 94, 95, 96, 97, -1, -1, 100, - 101, -1, -1, 104, -1, 45, 46, 108, -1, -1, - -1, -1, -1, 114, -1, 55, 56, 57, 58, 59, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 45, 46, -1, -1, -1, -1, -1, -1, + -1, -1, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, -1, -1, 67, 68, 69, 70, 71, 72, + -1, 74, -1, 76, 77, -1, 79, 80, 81, -1, + -1, -1, 85, 86, 87, -1, -1, 90, 91, 92, + -1, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, -1, 108, -1, 110, 111, 112, + 113, 114, 115, 116, 1, -1, 3, -1, 5, 6, + -1, -1, -1, -1, 11, -1, -1, -1, -1, -1, + -1, 18, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 45, 46, + -1, -1, -1, -1, -1, -1, -1, -1, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, -1, -1, + 67, 68, 69, 70, 71, 72, -1, 74, -1, 76, + 77, -1, 79, 80, 81, -1, -1, -1, 85, 86, + 87, -1, -1, 90, 91, 92, -1, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + -1, 108, -1, 110, 111, 112, 113, 114, 115, 116, + 1, -1, 3, -1, 5, 6, -1, -1, -1, -1, + 11, -1, -1, -1, -1, -1, -1, 18, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 45, 46, -1, -1, -1, -1, + -1, -1, -1, -1, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, -1, -1, 67, 68, 69, 70, + 71, 72, -1, 74, -1, 76, 77, -1, 79, 80, + 81, -1, -1, -1, 85, 86, 87, -1, -1, 90, + 91, 92, -1, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, -1, 108, -1, 110, + 111, 112, 113, 114, 115, 116, 1, -1, 3, -1, + 5, -1, -1, -1, -1, -1, 11, -1, -1, -1, + -1, -1, -1, 18, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 45, 46, 0, -1, -1, -1, -1, -1, -1, -1, + 55, 56, 57, 58, 59, -1, 61, 62, 63, 64, + 18, -1, 67, -1, 69, -1, 71, 72, -1, -1, + -1, 76, -1, -1, 79, 80, 81, -1, -1, -1, + 85, -1, 87, -1, -1, 90, 91, -1, -1, -1, + -1, -1, -1, 98, 99, -1, -1, 102, 103, 104, + 105, 106, 60, -1, -1, 110, 111, -1, 113, -1, + 115, 116, 70, -1, -1, -1, -1, -1, -1, 77, + -1, -1, -1, -1, -1, 3, 4, -1, -1, -1, + -1, -1, -1, -1, 92, -1, 94, 95, 96, -1, + 18, -1, 100, 101, 22, 23, 104, -1, -1, -1, + 108, 29, 30, -1, -1, -1, 114, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 45, 46, -1, + -1, -1, -1, -1, -1, -1, -1, 55, 56, 57, + 58, 59, 60, -1, 62, -1, 64, -1, -1, 67, + -1, 18, 70, -1, 72, -1, -1, -1, 76, 77, + -1, 79, -1, -1, -1, -1, -1, 85, -1, 87, + -1, -1, 90, 91, 92, -1, 94, 95, 96, -1, + -1, 99, 100, 101, 102, 103, 104, 105, -1, -1, + 108, -1, 110, 60, -1, 113, 114, 3, 4, 5, + -1, -1, -1, 70, -1, -1, -1, 74, -1, -1, + 77, -1, 18, -1, -1, -1, 22, 23, -1, 86, + -1, -1, -1, 29, 30, 92, -1, 94, 95, 96, + 97, -1, -1, 100, 101, -1, -1, 104, -1, 45, + 46, 108, -1, -1, -1, -1, -1, 114, -1, 55, + 56, 57, 58, 59, -1, -1, 62, -1, 64, -1, + -1, 67, -1, 3, -1, 5, 72, -1, -1, 9, + 76, -1, -1, 79, -1, -1, -1, -1, 18, 85, + -1, 87, 22, 23, 90, 91, -1, -1, -1, 29, + 30, -1, -1, 99, -1, -1, 102, 103, -1, 105, + -1, -1, -1, -1, 110, 45, 46, 113, -1, -1, + -1, -1, -1, -1, -1, 55, 56, 57, 58, 59, -1, -1, 62, -1, 64, -1, -1, 67, -1, 3, - -1, 5, 72, -1, -1, 9, 76, -1, -1, 79, + -1, 5, 72, -1, -1, -1, 76, -1, -1, 79, -1, -1, -1, -1, 18, 85, -1, 87, 22, 23, 90, 91, -1, -1, -1, 29, 30, -1, -1, 99, -1, -1, 102, 103, -1, 105, -1, -1, -1, -1, @@ -5531,13 +5639,13 @@ private static final short[] yycheck_init() -1, -1, 76, -1, -1, 79, -1, -1, -1, -1, 18, 85, -1, 87, 22, 23, 90, 91, -1, -1, -1, 29, 30, -1, -1, 99, -1, -1, 102, 103, - -1, 105, -1, -1, -1, -1, 110, 45, 46, 113, + -1, 105, 106, -1, -1, -1, 110, 45, 46, 113, -1, -1, -1, -1, -1, -1, -1, 55, 56, 57, 58, 59, -1, -1, 62, -1, 64, -1, -1, 67, - -1, 3, -1, 5, 72, -1, -1, -1, 76, -1, + -1, 3, -1, -1, 72, -1, 8, -1, 76, -1, -1, 79, -1, -1, -1, -1, 18, 85, -1, 87, 22, 23, 90, 91, -1, -1, -1, 29, 30, -1, - -1, 99, -1, -1, 102, 103, -1, 105, 106, -1, + -1, 99, -1, -1, 102, 103, -1, 105, -1, -1, -1, -1, 110, 45, 46, 113, -1, -1, -1, -1, -1, -1, -1, 55, 56, 57, 58, 59, -1, -1, 62, -1, 64, -1, -1, 67, -1, 3, 4, -1, @@ -5567,14 +5675,14 @@ private static final short[] yycheck_init() -1, 105, -1, -1, -1, -1, 110, 45, 46, 113, -1, -1, -1, -1, -1, -1, -1, 55, 56, 57, 58, 59, -1, -1, 62, -1, 64, -1, -1, 67, - -1, 3, -1, -1, 72, -1, 8, -1, 76, -1, + -1, 3, -1, -1, 72, -1, -1, -1, 76, 11, -1, 79, -1, -1, -1, -1, 18, 85, -1, 87, 22, 23, 90, 91, -1, -1, -1, 29, 30, -1, -1, 99, -1, -1, 102, 103, -1, 105, -1, -1, -1, -1, 110, 45, 46, 113, -1, -1, -1, -1, -1, -1, -1, 55, 56, 57, 58, 59, -1, -1, 62, -1, 64, -1, -1, 67, -1, 3, -1, -1, - 72, -1, -1, -1, 76, 11, -1, 79, -1, -1, + 72, -1, -1, -1, 76, -1, -1, 79, -1, -1, -1, -1, 18, 85, -1, 87, 22, 23, 90, 91, -1, -1, -1, 29, 30, -1, -1, 99, -1, -1, 102, 103, -1, 105, -1, -1, -1, -1, 110, 45, @@ -5586,105 +5694,104 @@ private static final short[] yycheck_init() 30, -1, -1, 99, -1, -1, 102, 103, -1, 105, -1, -1, -1, -1, 110, 45, 46, 113, -1, -1, -1, -1, -1, -1, -1, 55, 56, 57, 58, 59, - -1, -1, 62, -1, 64, -1, -1, 67, -1, 3, - -1, -1, 72, -1, -1, -1, 76, -1, -1, 79, - -1, -1, -1, -1, 18, 85, -1, 87, 22, 23, - 90, 91, -1, -1, -1, 29, 30, -1, -1, 99, - -1, -1, 102, 103, -1, 105, -1, -1, -1, -1, - 110, 45, 46, 113, -1, -1, -1, -1, -1, -1, - -1, 55, 56, 57, 58, 59, -1, -1, 62, -1, - 64, 3, -1, 67, -1, -1, -1, -1, 72, -1, - -1, -1, 76, -1, -1, 79, 18, -1, -1, -1, - -1, 85, -1, 87, -1, -1, 90, 91, -1, -1, - -1, -1, -1, -1, -1, 99, -1, -1, 102, 103, - -1, 105, -1, 45, 46, -1, 110, -1, -1, 113, - -1, -1, -1, 55, 56, 57, 58, 59, -1, -1, - 62, -1, 64, 3, -1, 67, -1, -1, -1, -1, - 72, -1, -1, -1, 76, -1, -1, 79, 18, -1, - -1, -1, -1, 85, -1, 87, -1, -1, 90, 91, - -1, -1, -1, -1, -1, -1, -1, 99, -1, -1, - 102, -1, -1, 105, -1, 45, 46, -1, 110, -1, - 112, 113, -1, -1, -1, 55, 56, 57, 58, 59, - -1, -1, 62, -1, 64, 3, 4, 67, -1, -1, + -1, -1, 62, -1, 64, 3, -1, 67, -1, -1, -1, -1, 72, -1, -1, -1, 76, -1, -1, 79, 18, -1, -1, -1, -1, 85, -1, 87, -1, -1, 90, 91, -1, -1, -1, -1, -1, -1, -1, 99, - -1, -1, 102, -1, -1, 105, -1, -1, -1, -1, + -1, -1, 102, 103, -1, 105, -1, 45, 46, -1, 110, -1, -1, 113, -1, -1, -1, 55, 56, 57, - 58, 59, -1, -1, 62, 3, 64, -1, -1, 67, + 58, 59, -1, -1, 62, -1, 64, 3, -1, 67, -1, -1, -1, -1, 72, -1, -1, -1, 76, -1, - 18, 79, -1, -1, -1, -1, -1, 85, -1, 87, + -1, 79, 18, -1, -1, -1, -1, 85, -1, 87, -1, -1, 90, 91, -1, -1, -1, -1, -1, -1, - -1, 99, -1, -1, 102, -1, -1, 105, -1, -1, - -1, -1, 110, -1, 112, 113, -1, 55, 56, 57, - 58, 59, 4, -1, 62, -1, 64, -1, -1, 67, - -1, -1, -1, -1, 72, -1, 18, -1, 76, -1, - -1, 79, -1, -1, 5, 6, -1, 85, -1, 87, - 11, -1, 90, 91, -1, -1, -1, 18, -1, -1, - -1, 99, -1, -1, 102, -1, -1, 105, -1, -1, - -1, -1, 110, 55, 112, 113, -1, -1, 60, -1, - 62, -1, 64, 5, 6, 67, -1, -1, 70, 11, - 72, -1, -1, -1, -1, 77, 18, 79, -1, 60, - -1, -1, -1, 85, -1, 87, -1, -1, -1, 70, - 92, -1, 94, 95, 96, -1, 77, 99, 100, 101, - -1, -1, 104, -1, -1, -1, 108, -1, -1, -1, - -1, 92, 114, 94, 95, 96, 5, 6, 60, 100, - 101, -1, 11, 104, -1, -1, -1, 108, 70, 18, - -1, -1, -1, 114, -1, 77, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 92, -1, 94, 95, 96, 5, 6, -1, 100, 101, - -1, 11, 104, -1, -1, -1, 108, -1, 18, -1, - -1, 60, 114, -1, -1, -1, 5, 6, -1, -1, - -1, 70, 11, -1, -1, -1, -1, -1, 77, 18, + -1, 99, -1, -1, 102, -1, -1, 105, -1, 45, + 46, -1, 110, -1, 112, 113, -1, -1, -1, 55, + 56, 57, 58, 59, -1, -1, 62, -1, 64, 3, + 4, 67, -1, -1, -1, -1, 72, -1, -1, -1, + 76, -1, -1, 79, 18, -1, -1, -1, -1, 85, + -1, 87, -1, -1, 90, 91, -1, -1, -1, -1, + -1, -1, -1, 99, -1, -1, 102, -1, -1, 105, + -1, -1, -1, -1, 110, -1, -1, 113, -1, -1, + -1, 55, 56, 57, 58, 59, -1, -1, 62, 3, + 64, -1, -1, 67, -1, -1, -1, -1, 72, -1, + -1, -1, 76, -1, 18, 79, -1, -1, -1, -1, + -1, 85, -1, 87, -1, -1, 90, 91, -1, -1, + -1, -1, -1, -1, -1, 99, -1, -1, 102, -1, + -1, 105, -1, -1, -1, -1, 110, -1, 112, 113, + -1, 55, 56, 57, 58, 59, 4, -1, 62, -1, + 64, -1, -1, 67, -1, -1, -1, -1, 72, -1, + 18, -1, 76, -1, -1, 79, -1, -1, 5, 6, + -1, 85, -1, 87, 11, -1, 90, 91, -1, -1, + -1, 18, -1, -1, -1, 99, -1, -1, 102, -1, + -1, 105, -1, -1, -1, -1, 110, 55, 112, 113, + -1, -1, 60, -1, 62, -1, 64, 5, 6, 67, + -1, -1, 70, 11, 72, -1, -1, -1, -1, 77, + 18, 79, -1, 60, -1, -1, -1, 85, -1, 87, + -1, -1, -1, 70, 92, -1, 94, 95, 96, -1, + 77, 99, 100, 101, -1, -1, 104, -1, -1, -1, + 108, -1, -1, -1, -1, 92, 114, 94, 95, 96, + 5, 6, 60, 100, 101, -1, 11, 104, -1, -1, + -1, 108, 70, 18, -1, -1, -1, 114, -1, 77, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 92, -1, 94, 95, 96, 5, + 6, -1, 100, 101, -1, 11, 104, -1, -1, -1, + 108, -1, 18, -1, -1, 60, 114, -1, -1, -1, + 5, 6, -1, -1, -1, 70, 11, -1, -1, -1, + -1, -1, 77, 18, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 92, -1, 94, + 95, 96, -1, -1, 60, 100, 101, -1, -1, 104, + -1, -1, -1, 108, 70, -1, 5, 6, -1, 114, + -1, 77, 11, -1, -1, 60, -1, -1, -1, 18, + -1, -1, -1, -1, -1, 70, 92, -1, 94, 95, + 96, -1, 77, -1, 100, 101, -1, -1, 104, -1, + 6, -1, 108, -1, -1, -1, -1, 92, 114, 94, + 95, 96, 18, -1, -1, 100, 101, -1, -1, 104, + -1, 60, -1, 108, -1, -1, -1, -1, 6, 114, + -1, 70, -1, -1, -1, -1, -1, -1, 77, 6, + 18, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 18, -1, 92, 60, 94, 95, 96, -1, -1, + -1, 100, 101, -1, 70, 104, -1, 6, -1, 108, + -1, 77, -1, -1, -1, 114, -1, -1, -1, 18, + -1, -1, 60, -1, -1, -1, 92, -1, 94, 95, + 96, -1, 70, 60, 100, 101, -1, -1, 104, 77, + -1, -1, 108, 70, -1, -1, -1, -1, 114, -1, + 77, -1, -1, -1, 92, -1, 94, 95, 96, -1, + -1, 60, 100, 101, -1, 92, 104, 94, 95, 96, + 108, 70, -1, 100, 101, -1, 114, 104, 77, 18, + 19, 108, -1, -1, -1, -1, -1, 114, -1, -1, -1, -1, -1, 92, -1, 94, 95, 96, -1, -1, - 60, 100, 101, -1, -1, 104, 6, -1, -1, 108, - 70, -1, -1, -1, -1, 114, -1, 77, 18, -1, - -1, 60, -1, -1, -1, -1, -1, 6, -1, -1, - -1, 70, 92, -1, 94, 95, 96, -1, 77, 18, - 100, 101, -1, -1, 104, -1, -1, -1, 108, -1, - -1, -1, -1, 92, 114, 94, 95, 96, -1, -1, - 60, 100, 101, -1, -1, 104, 6, 18, -1, 108, - 70, -1, -1, -1, -1, 114, -1, 77, 18, -1, - -1, 60, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 70, 92, -1, 94, 95, 96, -1, 77, -1, - 100, 101, -1, -1, 104, -1, -1, -1, 108, 60, - -1, -1, -1, 92, 114, 94, 95, 96, -1, 70, + -1, 100, 101, -1, -1, 104, -1, -1, -1, 108, + -1, -1, -1, -1, -1, 114, 55, -1, -1, -1, + -1, 60, -1, 62, -1, 64, -1, -1, 67, -1, + -1, 70, -1, 72, -1, 74, 18, 19, 77, -1, + 79, -1, -1, -1, -1, -1, 85, 86, 87, -1, + -1, -1, -1, 92, -1, 94, 95, 96, 97, -1, + 99, 100, 101, -1, -1, 104, -1, -1, -1, 108, + -1, -1, -1, 55, 113, 114, -1, -1, 60, -1, + 62, -1, 64, -1, -1, 67, -1, -1, 70, -1, + 72, 18, 74, -1, -1, 77, -1, 79, -1, -1, + -1, -1, -1, 85, 86, 87, -1, -1, -1, -1, + 92, -1, 94, 95, 96, 97, -1, 99, 100, 101, + -1, -1, 104, -1, -1, -1, 108, -1, 55, -1, + -1, 113, 114, 60, 18, 62, -1, 64, -1, -1, + 67, -1, -1, 70, -1, 72, -1, 74, -1, -1, + 77, -1, 79, -1, -1, -1, -1, -1, 85, 86, + 87, -1, -1, -1, -1, 92, -1, 94, 95, 96, + 97, 55, 99, 100, 101, -1, 60, 104, 62, 18, + 64, 108, -1, 67, -1, -1, 70, 114, 72, -1, + -1, -1, -1, 77, -1, 79, -1, -1, -1, -1, + -1, 85, -1, 87, -1, -1, -1, 18, 92, -1, + 94, 95, 96, -1, -1, 99, 100, 101, 18, -1, + 104, 60, -1, -1, 108, -1, -1, -1, -1, -1, + 114, 70, -1, -1, -1, 74, -1, -1, 77, -1, + -1, -1, -1, -1, -1, -1, -1, 86, -1, 60, + -1, -1, -1, 92, -1, 94, 95, 96, 97, 70, 60, 100, 101, -1, -1, 104, 77, -1, -1, 108, - 70, -1, 83, 18, 19, 114, -1, 77, -1, -1, + 70, -1, 83, -1, -1, 114, -1, 77, -1, -1, -1, 92, -1, 94, 95, 96, -1, -1, -1, 100, 101, -1, 92, 104, 94, 95, 96, 108, -1, -1, - 100, 101, -1, 114, 104, -1, -1, -1, 108, -1, - 55, -1, -1, -1, 114, 60, -1, 62, -1, 64, - -1, -1, 67, -1, -1, 70, -1, 72, -1, 74, - 18, 19, 77, -1, 79, -1, -1, -1, -1, -1, - 85, 86, 87, -1, -1, -1, -1, 92, -1, 94, - 95, 96, 97, -1, 99, 100, 101, -1, -1, 104, - -1, -1, -1, 108, -1, -1, -1, 55, 113, 114, - -1, -1, 60, -1, 62, -1, 64, -1, -1, 67, - -1, -1, 70, -1, 72, 18, 74, -1, -1, 77, - -1, 79, -1, -1, -1, -1, -1, 85, 86, 87, - -1, -1, -1, -1, 92, -1, 94, 95, 96, 97, - -1, 99, 100, 101, -1, -1, 104, -1, -1, -1, - 108, -1, 55, -1, -1, 113, 114, 60, 18, 62, - -1, 64, -1, -1, 67, -1, -1, 70, -1, 72, - -1, 74, -1, -1, 77, -1, 79, -1, -1, 18, - -1, -1, 85, 86, 87, -1, -1, -1, -1, 92, - -1, 94, 95, 96, 97, 55, 99, 100, 101, -1, - 60, 104, 62, -1, 64, 108, -1, 67, -1, -1, - 70, 114, 72, -1, -1, -1, -1, 77, -1, 79, - -1, 60, 18, 19, -1, 85, -1, 87, -1, -1, - -1, 70, 92, -1, 94, 95, 96, -1, 77, 99, - 100, 101, -1, -1, 104, -1, -1, -1, 108, -1, - 18, -1, -1, 92, 114, 94, 95, 96, 26, 55, - -1, 100, 101, -1, -1, 104, 62, -1, 64, 108, - -1, 67, -1, -1, -1, 114, 72, -1, -1, -1, - 60, -1, -1, 79, -1, -1, -1, 55, -1, 85, - 70, 87, -1, -1, 62, -1, 64, 77, -1, 67, - -1, -1, -1, 99, 72, -1, -1, -1, -1, -1, - -1, 79, 92, -1, 94, 95, 96, 85, -1, 87, - 100, 101, 3, -1, 104, -1, 7, -1, 108, 10, - -1, 99, 13, -1, 114, -1, -1, 18, 19, -1, + 100, 101, 3, 114, 104, -1, 7, -1, 108, 10, + -1, -1, 13, -1, 114, -1, -1, 18, 19, -1, -1, -1, -1, -1, -1, -1, -1, 28, -1, -1, -1, -1, -1, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, -1, -1, -1, -1, -1, @@ -5704,84 +5811,83 @@ private static final short[] yystos_init() 96, 100, 101, 104, 108, 114, 123, 124, 125, 126, 131, 133, 290, 291, 122, 10, 11, 10, 11, 122, 18, 74, 86, 97, 123, 134, 138, 139, 158, 164, - 189, 190, 198, 126, 123, 125, 291, 10, 11, 14, + 191, 192, 200, 126, 123, 125, 291, 10, 11, 14, 55, 129, 3, 86, 55, 55, 55, 68, 134, 14, 11, 132, 133, 3, 4, 5, 22, 23, 29, 30, 45, 46, 55, 56, 57, 58, 59, 62, 64, 67, 72, 76, 79, 85, 87, 90, 91, 99, 102, 103, - 105, 110, 113, 121, 122, 135, 136, 137, 241, 242, - 243, 250, 251, 252, 255, 256, 268, 270, 271, 272, + 105, 110, 113, 121, 122, 135, 136, 137, 243, 244, + 245, 251, 252, 253, 256, 257, 268, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 290, 291, 292, 293, 55, 82, 146, 19, 140, 141, 140, 55, 11, 3, - 55, 122, 250, 251, 259, 260, 261, 264, 265, 266, + 55, 122, 251, 252, 259, 260, 261, 264, 265, 266, 268, 9, 293, 294, 281, 281, 281, 281, 281, 281, - 28, 19, 122, 135, 246, 247, 10, 13, 3, 7, - 186, 187, 188, 290, 3, 7, 10, 247, 253, 10, - 13, 186, 188, 7, 10, 13, 26, 47, 269, 48, - 21, 27, 17, 49, 51, 19, 20, 32, 33, 84, - 52, 53, 54, 22, 23, 14, 15, 16, 45, 46, - 136, 4, 9, 4, 5, 199, 135, 147, 5, 159, - 55, 142, 143, 144, 290, 75, 191, 192, 3, 165, - 140, 4, 123, 262, 263, 290, 24, 4, 24, 28, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 267, 6, 6, 9, 293, 26, 135, 248, 249, - 290, 7, 187, 257, 258, 290, 244, 245, 289, 290, - 55, 246, 246, 259, 8, 10, 188, 7, 4, 254, - 259, 259, 90, 102, 243, 247, 102, 105, 246, 10, - 259, 55, 243, 246, 246, 259, 271, 272, 273, 274, - 275, 276, 276, 278, 278, 278, 278, 112, 135, 136, - 207, 240, 279, 279, 279, 280, 280, 281, 281, 281, - 55, 6, 123, 200, 9, 160, 161, 162, 289, 75, - 9, 20, 144, 135, 5, 193, 9, 166, 167, 289, - 146, 75, 145, 112, 136, 4, 9, 5, 204, 259, - 204, 259, 259, 293, 75, 102, 9, 20, 26, 259, - 5, 174, 186, 258, 7, 253, 10, 25, 246, 55, - 55, 55, 4, 68, 8, 4, 9, 8, 10, 55, - 13, 55, 90, 68, 8, 55, 55, 12, 55, 172, - 173, 172, 28, 135, 136, 138, 189, 196, 201, 202, - 6, 123, 135, 9, 11, 163, 9, 55, 135, 148, - 289, 290, 143, 6, 123, 194, 135, 4, 9, 136, - 5, 168, 135, 146, 55, 55, 289, 290, 263, 1, - 6, 11, 55, 61, 63, 69, 71, 80, 81, 98, - 103, 104, 106, 111, 115, 116, 123, 124, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 222, 223, 224, - 229, 242, 252, 265, 282, 283, 285, 286, 287, 135, - 135, 249, 75, 102, 8, 174, 175, 176, 177, 259, - 259, 5, 149, 150, 289, 253, 5, 214, 259, 55, - 246, 253, 246, 253, 260, 268, 28, 187, 9, 293, - 172, 55, 201, 163, 11, 100, 123, 151, 152, 204, - 6, 162, 253, 17, 55, 113, 136, 138, 141, 179, - 189, 195, 196, 197, 6, 123, 167, 55, 289, 6, - 123, 152, 169, 170, 150, 186, 186, 31, 11, 12, - 259, 11, 55, 11, 55, 104, 208, 3, 3, 11, - 259, 3, 3, 259, 3, 204, 237, 3, 259, 138, - 190, 136, 207, 6, 206, 11, 11, 135, 135, 6, - 9, 9, 8, 6, 151, 55, 6, 65, 70, 215, - 216, 217, 218, 219, 220, 55, 55, 259, 28, 173, - 11, 3, 6, 204, 136, 138, 140, 141, 153, 154, - 155, 171, 178, 179, 189, 152, 150, 135, 55, 180, - 180, 113, 135, 136, 290, 11, 185, 204, 195, 31, - 55, 6, 170, 55, 208, 11, 12, 11, 11, 115, - 207, 211, 225, 227, 259, 11, 259, 259, 11, 122, - 207, 238, 239, 241, 250, 66, 78, 231, 232, 236, - 204, 259, 11, 11, 6, 177, 6, 221, 264, 6, - 216, 220, 6, 218, 220, 70, 205, 220, 12, 24, - 253, 174, 4, 55, 172, 55, 107, 184, 185, 3, - 184, 184, 180, 180, 180, 113, 55, 5, 156, 259, - 3, 12, 11, 9, 4, 4, 4, 4, 11, 3, - 204, 232, 236, 230, 231, 4, 9, 12, 106, 204, - 259, 186, 11, 3, 147, 156, 4, 124, 136, 181, - 182, 184, 184, 184, 180, 6, 122, 157, 205, 241, - 246, 11, 259, 259, 226, 259, 211, 208, 214, 204, - 4, 239, 123, 233, 235, 236, 208, 264, 259, 11, - 70, 203, 181, 186, 136, 55, 105, 183, 289, 4, - 9, 184, 10, 6, 205, 6, 10, 102, 105, 4, - 4, 11, 73, 213, 135, 234, 4, 11, 293, 11, - 4, 183, 10, 186, 31, 186, 182, 246, 247, 6, - 246, 253, 253, 11, 208, 227, 228, 208, 21, 55, - 204, 105, 55, 102, 102, 11, 11, 4, 135, 186, - 253, 253, 208, 11, 11 + 28, 19, 122, 137, 247, 248, 10, 13, 3, 7, + 188, 189, 190, 290, 3, 10, 190, 248, 254, 10, + 13, 188, 190, 10, 13, 190, 190, 26, 47, 269, + 48, 21, 27, 17, 49, 51, 19, 20, 32, 33, + 84, 52, 53, 54, 22, 23, 14, 15, 16, 45, + 46, 122, 136, 4, 9, 4, 5, 201, 135, 147, + 5, 159, 55, 142, 143, 144, 290, 75, 193, 194, + 3, 165, 140, 4, 123, 262, 263, 290, 24, 4, + 24, 28, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 267, 6, 6, 9, 293, 20, 26, + 135, 249, 250, 290, 189, 248, 189, 135, 246, 55, + 247, 247, 259, 8, 259, 10, 190, 7, 4, 255, + 259, 90, 102, 245, 248, 102, 105, 247, 10, 55, + 245, 247, 247, 259, 271, 272, 273, 274, 275, 276, + 276, 278, 278, 278, 278, 112, 135, 136, 209, 242, + 279, 279, 279, 280, 280, 281, 281, 281, 55, 6, + 123, 202, 9, 160, 161, 162, 289, 290, 75, 9, + 20, 144, 135, 5, 195, 9, 166, 167, 289, 146, + 75, 145, 112, 136, 4, 9, 5, 206, 259, 206, + 259, 259, 293, 75, 102, 9, 20, 26, 5, 176, + 258, 189, 258, 254, 55, 55, 4, 8, 68, 8, + 259, 4, 9, 10, 55, 13, 55, 90, 68, 55, + 55, 12, 55, 172, 173, 172, 28, 135, 136, 138, + 191, 198, 203, 204, 6, 123, 135, 9, 11, 163, + 9, 55, 135, 148, 289, 290, 143, 6, 123, 196, + 135, 4, 9, 136, 5, 168, 135, 146, 55, 55, + 289, 290, 263, 1, 6, 11, 55, 61, 63, 69, + 71, 80, 81, 98, 103, 104, 106, 111, 115, 116, + 123, 124, 206, 207, 208, 209, 210, 211, 212, 213, + 214, 224, 225, 226, 231, 244, 253, 265, 282, 283, + 285, 286, 287, 135, 135, 250, 75, 102, 176, 177, + 178, 179, 259, 258, 5, 149, 150, 254, 5, 216, + 8, 259, 55, 247, 254, 247, 254, 260, 268, 28, + 174, 189, 9, 293, 172, 55, 203, 163, 11, 100, + 123, 151, 152, 206, 6, 162, 254, 17, 55, 113, + 136, 138, 141, 181, 191, 197, 198, 199, 6, 123, + 167, 55, 289, 6, 123, 152, 169, 170, 150, 188, + 188, 31, 11, 12, 259, 11, 55, 11, 55, 104, + 210, 3, 3, 11, 259, 3, 3, 259, 3, 206, + 239, 3, 259, 138, 192, 136, 209, 6, 208, 11, + 11, 135, 135, 6, 9, 9, 6, 151, 6, 65, + 70, 217, 218, 219, 220, 221, 222, 55, 55, 176, + 259, 28, 175, 173, 11, 3, 6, 206, 136, 138, + 140, 141, 153, 154, 155, 171, 180, 181, 191, 152, + 150, 135, 55, 182, 182, 113, 135, 136, 290, 11, + 187, 206, 197, 31, 55, 6, 170, 55, 210, 11, + 12, 11, 11, 115, 209, 213, 227, 229, 259, 11, + 259, 259, 11, 122, 209, 240, 241, 243, 251, 66, + 78, 233, 234, 238, 206, 259, 11, 11, 6, 179, + 6, 223, 264, 6, 218, 222, 6, 220, 222, 70, + 207, 222, 12, 24, 254, 176, 4, 55, 172, 55, + 107, 186, 187, 3, 186, 186, 182, 182, 182, 113, + 55, 5, 156, 259, 3, 12, 11, 9, 4, 4, + 4, 4, 11, 3, 206, 234, 238, 232, 233, 4, + 9, 12, 106, 206, 259, 188, 11, 3, 147, 156, + 4, 124, 136, 183, 184, 186, 186, 186, 182, 6, + 122, 157, 207, 243, 247, 11, 259, 259, 228, 259, + 213, 210, 216, 206, 4, 241, 123, 235, 237, 238, + 210, 264, 259, 11, 70, 205, 183, 188, 136, 55, + 105, 185, 289, 4, 9, 186, 10, 6, 207, 6, + 10, 102, 105, 4, 4, 11, 73, 215, 135, 236, + 4, 11, 293, 11, 4, 185, 10, 188, 31, 188, + 184, 247, 248, 6, 247, 254, 254, 11, 210, 229, + 230, 210, 21, 55, 206, 105, 55, 102, 102, 11, + 11, 4, 135, 188, 254, 254, 210, 11, 11 }; } @@ -5804,40 +5910,40 @@ private static final short[] yyr1_init() 156, 156, 156, 156, 157, 157, 157, 157, 158, 159, 159, 160, 160, 161, 161, 162, 162, 162, 163, 163, 163, 164, 165, 166, 166, 166, 167, 167, 168, 168, - 169, 169, 170, 170, 171, 172, 172, 173, 173, 173, - 173, 174, 174, 175, 175, 176, 176, 177, 177, 178, - 179, 179, 179, 179, 179, 179, 180, 180, 181, 181, - 182, 182, 183, 183, 183, 183, 184, 184, 185, 185, - 186, 186, 187, 187, 188, 188, 189, 189, 190, 191, - 191, 192, 192, 193, 193, 194, 194, 195, 195, 195, - 195, 196, 197, 198, 199, 199, 200, 200, 201, 201, - 201, 201, 202, 203, 203, 204, 204, 205, 205, 206, - 206, 206, 206, 206, 207, 207, 208, 208, 208, 208, - 208, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 210, 211, 211, 211, 211, 211, 211, 211, - 212, 213, 213, 214, 214, 214, 215, 215, 216, 216, - 216, 217, 217, 218, 219, 219, 220, 220, 221, 221, - 222, 223, 223, 224, 225, 225, 225, 226, 226, 227, - 227, 228, 228, 229, 230, 230, 231, 231, 232, 233, - 234, 234, 235, 235, 236, 237, 237, 238, 238, 239, - 239, 240, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 242, 242, 242, 243, 244, 244, - 245, 245, 246, 246, 247, 248, 248, 249, 249, 249, - 249, 249, 249, 249, 250, 250, 250, 251, 251, 252, - 252, 252, 252, 252, 253, 253, 254, 254, 255, 255, - 255, 255, 255, 256, 256, 257, 257, 258, 258, 259, - 259, 260, 260, 260, 260, 261, 261, 262, 262, 263, - 263, 263, 264, 264, 265, 266, 266, 266, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 268, 269, 269, 269, 270, 270, 271, 271, 272, 272, - 273, 273, 274, 274, 275, 275, 275, 276, 276, 276, - 276, 276, 276, 277, 277, 278, 278, 278, 278, 279, - 279, 279, 280, 280, 280, 280, 281, 281, 281, 281, - 281, 282, 283, 284, 284, 284, 284, 285, 285, 285, - 285, 286, 287, 288, 289, 289, 290, 290, 291, 291, - 291, 291, 292, 292, 293, 293, 293, 293, 294, 294, - 294 + 169, 169, 170, 170, 171, 172, 172, 173, 173, 174, + 174, 174, 175, 175, 176, 176, 177, 177, 178, 178, + 179, 179, 180, 181, 181, 181, 181, 181, 181, 182, + 182, 183, 183, 184, 184, 185, 185, 185, 185, 186, + 186, 187, 187, 188, 188, 189, 189, 190, 190, 190, + 190, 191, 191, 192, 193, 193, 194, 194, 195, 195, + 196, 196, 197, 197, 197, 197, 198, 199, 200, 201, + 201, 202, 202, 203, 203, 203, 203, 204, 205, 205, + 206, 206, 207, 207, 208, 208, 208, 208, 208, 209, + 209, 210, 210, 210, 210, 210, 211, 211, 211, 211, + 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, + 211, 211, 211, 211, 211, 211, 211, 212, 213, 213, + 213, 213, 213, 213, 213, 214, 215, 215, 216, 216, + 216, 217, 217, 218, 218, 218, 219, 219, 220, 221, + 221, 222, 222, 223, 223, 224, 225, 225, 226, 227, + 227, 227, 228, 228, 229, 229, 230, 230, 231, 232, + 232, 233, 233, 234, 235, 236, 236, 237, 237, 238, + 239, 239, 240, 240, 241, 241, 242, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 244, + 244, 244, 245, 246, 247, 247, 248, 248, 249, 249, + 250, 250, 250, 250, 250, 250, 250, 251, 251, 251, + 252, 252, 252, 253, 253, 253, 253, 253, 254, 254, + 255, 255, 256, 256, 256, 256, 256, 257, 257, 257, + 258, 258, 259, 259, 260, 260, 260, 260, 261, 261, + 262, 262, 263, 263, 263, 264, 264, 265, 266, 266, + 266, 267, 267, 267, 267, 267, 267, 267, 267, 267, + 267, 267, 267, 268, 269, 269, 269, 270, 270, 271, + 271, 272, 272, 273, 273, 274, 274, 275, 275, 275, + 276, 276, 276, 276, 276, 276, 277, 277, 278, 278, + 278, 278, 279, 279, 279, 280, 280, 280, 280, 281, + 281, 281, 281, 281, 282, 283, 284, 284, 284, 284, + 285, 285, 285, 285, 286, 287, 288, 289, 289, 290, + 290, 291, 291, 291, 291, 292, 292, 293, 293, 293, + 293, 294, 294, 294 }; } @@ -5860,40 +5966,40 @@ private static final byte[] yyr2_init() 2, 3, 3, 4, 4, 4, 6, 6, 4, 4, 5, 0, 1, 1, 3, 2, 3, 4, 0, 1, 2, 6, 3, 0, 1, 3, 3, 5, 2, 3, - 1, 2, 1, 3, 3, 1, 3, 1, 3, 2, - 4, 3, 4, 0, 1, 1, 3, 1, 1, 2, - 4, 5, 4, 4, 3, 3, 4, 5, 1, 3, - 3, 2, 2, 3, 1, 3, 0, 2, 1, 1, - 0, 1, 1, 2, 3, 2, 1, 1, 5, 0, - 1, 2, 3, 2, 3, 2, 3, 1, 1, 1, - 1, 3, 2, 4, 2, 3, 2, 3, 1, 1, - 1, 1, 7, 0, 2, 2, 3, 1, 2, 2, - 2, 3, 2, 1, 2, 2, 1, 1, 1, 1, - 1, 1, 1, 2, 3, 5, 5, 7, 2, 3, - 2, 3, 2, 3, 5, 3, 3, 3, 4, 3, - 5, 2, 3, 1, 1, 1, 1, 1, 1, 1, - 6, 0, 2, 2, 3, 3, 1, 2, 4, 3, - 5, 1, 2, 2, 2, 3, 2, 1, 1, 3, - 5, 1, 1, 9, 0, 1, 1, 0, 1, 1, - 3, 0, 1, 7, 0, 1, 1, 2, 5, 4, - 1, 3, 0, 1, 2, 3, 4, 1, 3, 1, - 1, 1, 1, 4, 4, 1, 3, 3, 1, 1, - 1, 1, 1, 1, 1, 3, 3, 5, 2, 2, - 2, 4, 0, 1, 3, 1, 3, 1, 1, 3, - 3, 2, 4, 4, 3, 3, 5, 4, 4, 2, - 5, 5, 5, 7, 2, 3, 1, 3, 4, 4, - 4, 6, 4, 4, 4, 1, 2, 3, 4, 1, - 1, 3, 3, 3, 3, 2, 3, 1, 3, 4, - 4, 5, 1, 1, 3, 1, 1, 1, 1, 1, + 1, 2, 1, 3, 3, 1, 3, 2, 3, 0, + 2, 2, 0, 2, 3, 4, 0, 1, 1, 3, + 1, 1, 2, 4, 5, 4, 4, 3, 3, 4, + 5, 1, 3, 3, 2, 2, 3, 1, 3, 0, + 2, 1, 1, 0, 1, 1, 2, 2, 3, 3, + 4, 1, 1, 5, 0, 1, 2, 3, 2, 3, + 2, 3, 1, 1, 1, 1, 3, 2, 4, 2, + 3, 2, 3, 1, 1, 1, 1, 7, 0, 2, + 2, 3, 1, 2, 2, 2, 3, 2, 1, 2, + 2, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 5, 5, 7, 2, 3, 2, 3, 2, 3, 5, + 3, 3, 3, 4, 3, 5, 2, 3, 1, 1, + 1, 1, 1, 1, 1, 6, 0, 2, 2, 3, + 3, 1, 2, 4, 3, 5, 1, 2, 2, 2, + 3, 2, 1, 1, 3, 5, 1, 1, 9, 0, + 1, 1, 0, 1, 1, 3, 0, 1, 7, 0, + 1, 1, 2, 5, 4, 1, 3, 0, 1, 2, + 3, 4, 1, 3, 1, 1, 1, 1, 4, 4, + 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, + 3, 3, 5, 1, 0, 1, 2, 3, 1, 3, + 1, 1, 3, 3, 2, 4, 4, 3, 3, 5, + 2, 2, 2, 2, 5, 5, 5, 7, 2, 3, + 1, 3, 4, 4, 4, 6, 4, 4, 4, 5, + 0, 1, 1, 1, 3, 3, 3, 3, 2, 3, + 1, 3, 4, 4, 5, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 0, 4, 4, 1, 3, 1, 3, 1, 3, - 1, 3, 1, 3, 1, 3, 3, 1, 3, 3, + 1, 1, 1, 2, 0, 4, 4, 1, 3, 1, + 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, + 1, 3, 3, 3, 3, 1, 3, 3, 1, 3, 3, 3, 1, 3, 3, 1, 3, 3, 3, 1, - 3, 3, 1, 3, 3, 3, 1, 1, 2, 2, - 1, 2, 2, 1, 2, 2, 1, 1, 1, 1, - 1, 2, 2, 5, 0, 1, 1, 2, 2, 4, - 5, 5, 3, 5, 1, 3, 3, 1, 0, 1, - 3 + 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, + 1, 1, 1, 1, 2, 2, 5, 0, 1, 1, + 2, 2, 4, 5, 5, 3, 5, 1, 3, 3, + 1, 0, 1, 3 }; } @@ -5960,7 +6066,7 @@ private static final byte[] yytranslate_table_init() } - private static final int YYLAST_ = 4534; + private static final int YYLAST_ = 4634; private static final int YYEMPTY_ = -2; private static final int YYFINAL_ = 12; private static final int YYNTOKENS_ = 120; @@ -5971,9 +6077,9 @@ private static final byte[] yytranslate_table_init() public CompilationUnit ast; public HashMap classes = new HashMap(); -/* "src/main/java/parser/JavaParser.java":5975 */ +/* "src/main/java/parser/JavaParser.java":6081 */ } -/* "src/main/resources/Java_16_Grammar.y":1529 */ +/* "src/main/resources/Java_16_Grammar.y":1604 */ diff --git a/src/main/java/tree/AnnoElementValue.java b/src/main/java/tree/AnnoElementValue.java index b5706b7..077a164 100644 --- a/src/main/java/tree/AnnoElementValue.java +++ b/src/main/java/tree/AnnoElementValue.java @@ -1,4 +1,5 @@ package tree; -public class AnnoElementValue extends Entity { +public class AnnoElementValue extends Entity +{ } diff --git a/src/main/java/tree/AnnoParameterList.java b/src/main/java/tree/AnnoParameterList.java index 9fdedbf..04e727e 100644 --- a/src/main/java/tree/AnnoParameterList.java +++ b/src/main/java/tree/AnnoParameterList.java @@ -17,5 +17,6 @@ // | ElementValue // | ElementValueListOpt COMMA ElementValue // ; -public class AnnoParameterList extends Entity { +public class AnnoParameterList extends Entity +{ } diff --git a/src/main/java/tree/Annotation.java b/src/main/java/tree/Annotation.java index f2dce8d..a9957cc 100644 --- a/src/main/java/tree/Annotation.java +++ b/src/main/java/tree/Annotation.java @@ -6,13 +6,15 @@ // | AT CompoundName LPAREN AnnoParameterList RPAREN // | AT CompoundName LPAREN ElementValue RPAREN // ; -public class Annotation extends Entity { +public class Annotation extends Entity +{ // Structure public CompoundName compoundName; public AnnoParameterList annoParameterList; // Creation - public Annotation(CompoundName cn, AnnoParameterList apl) { + public Annotation(CompoundName cn, AnnoParameterList apl) + { this.compoundName = cn; this.annoParameterList = apl; @@ -22,9 +24,11 @@ public Annotation(CompoundName cn, AnnoParameterList apl) { if (this.annoParameterList != null) { this.annoParameterList.parent = this; } + Entity.reportParsing("ANNOTATION"); } - public Annotation(CompoundName cn, AnnoElementValue aev) { + public Annotation(CompoundName cn, AnnoElementValue aev) + { this.compoundName = cn; this.annoParameterList = new AnnoParameterList(); // this.annoParameterList.add @@ -32,6 +36,7 @@ public Annotation(CompoundName cn, AnnoElementValue aev) { if (this.compoundName != null) { this.compoundName.parent = this; } + Entity.reportParsing("ANNOTATION"); } // Reporting diff --git a/src/main/java/tree/Annotations.java b/src/main/java/tree/Annotations.java index bb53b45..6eee66c 100644 --- a/src/main/java/tree/Annotations.java +++ b/src/main/java/tree/Annotations.java @@ -10,16 +10,12 @@ public class Annotations extends Entity { public Annotations(Annotation ann) { this.annotations = new ArrayList(); this.annotations.add(ann); - if (ann != null) { - ann.parent = this; - } + if (ann != null) ann.parent = this; } public Annotations add(Annotation ann) { this.annotations.add(ann); - if (ann != null) { - ann.parent = this; - } + if (ann != null) ann.parent = this; return this; } diff --git a/src/main/java/tree/Compilation/Package.java b/src/main/java/tree/Compilation/Package.java index 8be9846..5b6414a 100644 --- a/src/main/java/tree/Compilation/Package.java +++ b/src/main/java/tree/Compilation/Package.java @@ -28,6 +28,7 @@ public Package(CompoundName cn, ImportDeclarations ims, TopLevelComponents cs) { if (this.components != null) { this.components.parent = this; } + Entity.reportParsing("PACKAGE"); } // Reporting @@ -37,7 +38,7 @@ public void report(int sh) { compoundName.report(0); System.out.println(); - imports.report(sh); + if ( imports != null ) imports.report(sh); components.report(sh); } diff --git a/src/main/java/tree/Compilation/SimpleCompilationUnit.java b/src/main/java/tree/Compilation/SimpleCompilationUnit.java index 48328d1..1f11ec0 100644 --- a/src/main/java/tree/Compilation/SimpleCompilationUnit.java +++ b/src/main/java/tree/Compilation/SimpleCompilationUnit.java @@ -1,6 +1,7 @@ package tree.Compilation; import tree.Declaration.ImportDeclarations; +import tree.Entity; // CompilationUnit // : %empty @@ -24,6 +25,7 @@ public SimpleCompilationUnit(ImportDeclarations ids, TopLevelComponents tlcs) { if (this.components != null) { this.components.parent = this; } + Entity.reportParsing("SIMPLE COMPILATION UNIT"); } // Reporting diff --git a/src/main/java/tree/Compilation/TopLevelComponent.java b/src/main/java/tree/Compilation/TopLevelComponent.java index 59c3ada..61245e5 100644 --- a/src/main/java/tree/Compilation/TopLevelComponent.java +++ b/src/main/java/tree/Compilation/TopLevelComponent.java @@ -23,6 +23,7 @@ public TopLevelComponent(ClassDeclaration cd) { if (this.classDecl != null) { this.classDecl.parent = this; } + Entity.reportParsing("TOP_LEVEL COMPONENT"); } public TopLevelComponent(InterfaceDeclaration id) { @@ -31,6 +32,7 @@ public TopLevelComponent(InterfaceDeclaration id) { if (this.interfaceDecl != null) { this.interfaceDecl.parent = this; } + Entity.reportParsing("TOP_LEVEL COMPONENT"); } public void addModifiers(Modifiers mods) { diff --git a/src/main/java/tree/CompoundName.java b/src/main/java/tree/CompoundName.java index 555195d..7e73aa2 100644 --- a/src/main/java/tree/CompoundName.java +++ b/src/main/java/tree/CompoundName.java @@ -9,18 +9,33 @@ // : IDENTIFIER { $$ = new CompoundName($1.image); } // | CompoundName DOT IDENTIFIER { $$ = $1.add($3.image); } // ; -public class CompoundName extends Entity { +public class CompoundName extends Entity +{ // Structure public ArrayList names; // Creation - public CompoundName(String first) { + public CompoundName(String first) + { names = new ArrayList<>(); names.add(first); + + String cn = ""; + for (int i = 0; i < names.size(); i++) { + cn += names.get(i); + if (i < names.size() - 1) { + cn += "."; + } + } + cn = "COMPOUND NAME " + cn; + Entity.reportParsing(cn); } - public CompoundName(List name) { + public CompoundName(List name) + { names = new ArrayList<>(name); + + Entity.reportParsing("COMPOUND NAME"); } // Adding @@ -39,7 +54,7 @@ public String concatenatedEO() { // Reporting public void report(int sh) { - // Entity.doShift(sh); + // Entity.doShift(sh); for (int i = 0; i < names.size(); i++) { System.out.print(names.get(i)); if (i < names.size() - 1) { diff --git a/src/main/java/tree/CompoundNameAnnotated.java b/src/main/java/tree/CompoundNameAnnotated.java new file mode 100644 index 0000000..f0c3b6b --- /dev/null +++ b/src/main/java/tree/CompoundNameAnnotated.java @@ -0,0 +1,41 @@ +package tree; + +import java.util.ArrayList; + +public class CompoundNameAnnotated extends CompoundName +{ + // Structure + public ArrayList annotations; + + // Creation + public CompoundNameAnnotated(Annotations anns, String name) + { + super(name); + annotations = new ArrayList<>(); + annotations.add(anns); + + Entity.reportParsing("COMPOUND NAME ANNOTATED"); + } + + // Adding + public CompoundNameAnnotated add(Annotations anns, String next) + { + names.add(next); + annotations.add(anns); + return this; + } + + // Reporting + public void report(int sh) { + this.title("ANNOTATED COMPOUND NAME",sh); + int currSh = sh+Entity.shift; + for (int i = 0; i < names.size(); i++) { + Entity.doShift(currSh); + System.out.println(names.get(i)); + if ( annotations.get(i) != null ) + annotations.get(i).report(currSh); + currSh += Entity.shift; + } + } + +} diff --git a/src/main/java/tree/Declaration/CatchParameter.java b/src/main/java/tree/Declaration/CatchParameter.java index 7b63f4d..6ec2d0c 100644 --- a/src/main/java/tree/Declaration/CatchParameter.java +++ b/src/main/java/tree/Declaration/CatchParameter.java @@ -2,6 +2,7 @@ import lexer.Token; import tree.Dims; +import tree.Entity; import tree.Modifiers; import tree.Type.TypeList; @@ -13,17 +14,18 @@ // : Type // | CatchType VERTICAL Type // ; -public class CatchParameter extends ParameterDeclaration { +public class CatchParameter extends ParameterDeclaration +{ // Structure // From the base class: - // public Modifiers modifiers; - // public Type type; -- not used here - // public String name; - // public Annotations ellAnnotations; -- not used here - // public boolean signEllipsis; -- not used here - // public Dims dims; - // Own attributes: + // public Modifiers modifiers; + // public Type type; -- not used here + // public String name; + // public Annotations ellAnnotations; -- not used here + // public boolean signEllipsis; -- not used here + // public Dims dims; + // Own attributes: public TypeList catchTypes; // Creation @@ -34,6 +36,7 @@ public CatchParameter(Modifiers mods, TypeList types, Token id, Dims dims) { if (this.catchTypes != null) { this.catchTypes.parent = this; } + Entity.reportParsing("CATCH PARAMETER"); } // Reporting diff --git a/src/main/java/tree/Declaration/ClassInitializer.java b/src/main/java/tree/Declaration/ClassInitializer.java index 35a0232..042b641 100644 --- a/src/main/java/tree/Declaration/ClassInitializer.java +++ b/src/main/java/tree/Declaration/ClassInitializer.java @@ -1,5 +1,6 @@ package tree.Declaration; +import tree.Entity; import tree.Statement.Block; // ClassBodyDeclaration @@ -8,7 +9,8 @@ // | STATIC Block // StaticInitializer // | ... // ; -public class ClassInitializer extends Declaration { +public class ClassInitializer extends Declaration +{ // Structure public Block block; public boolean signStatic; @@ -22,6 +24,7 @@ public ClassInitializer(Block b, boolean ss) { if (this.block != null) { this.block.parent = this; } + Entity.reportParsing("CLASS INITIALIZER"); } // Reporting diff --git a/src/main/java/tree/Declaration/ConstructorBody.java b/src/main/java/tree/Declaration/ConstructorBody.java index e436ddc..d6cb5c9 100644 --- a/src/main/java/tree/Declaration/ConstructorBody.java +++ b/src/main/java/tree/Declaration/ConstructorBody.java @@ -25,6 +25,7 @@ public ConstructorBody(ExplicitConstructorInvocation inv, Block block) { if (this.block != null) { this.block.parent = this; } + Entity.reportParsing("CONSTRUCTOR BODY"); } // Reporting diff --git a/src/main/java/tree/Declaration/ConstructorDeclaration.java b/src/main/java/tree/Declaration/ConstructorDeclaration.java index e027d3d..84cb23c 100644 --- a/src/main/java/tree/Declaration/ConstructorDeclaration.java +++ b/src/main/java/tree/Declaration/ConstructorDeclaration.java @@ -1,5 +1,6 @@ package tree.Declaration; +import tree.Entity; import tree.Modifiers; import tree.Statement.Block; import tree.Type.TypeList; @@ -19,16 +20,17 @@ // | LBRACE BlockStatementSeq RBRACE // | LBRACE ExplicitConstructorInvocation BlockStatementSeq RBRACE // ; -public class ConstructorDeclaration extends MethodDeclaration { +public class ConstructorDeclaration extends MethodDeclaration +{ // Structure: all from the base class - // public Modifiers modifiers; - // public TypeParameters typeParameters; - // public Type type; // always null - // public String name; // always null - // public ReceiverDeclaration receiver; - // public ParameterDeclarations parameters; - // public Dims dims; // always null - // public TypeList exceptions; + // public Modifiers modifiers; + // public TypeParameters typeParameters; + // public Type type; // always null + // public String name; // always null + // public ReceiverDeclaration receiver; + // public ParameterDeclarations parameters; + // public Dims dims; // always null + // public TypeList exceptions; public ExplicitConstructorInvocation invocation; // public Block methodBody; @@ -45,6 +47,7 @@ public ConstructorDeclaration(Modifiers mods, if (this.invocation != null) { this.invocation.parent = this; } + Entity.reportParsing("CONSTRUCTOR DECLARATION"); } // Reporting diff --git a/src/main/java/tree/Declaration/ConstructorDeclarator.java b/src/main/java/tree/Declaration/ConstructorDeclarator.java index be7870f..943e2dc 100644 --- a/src/main/java/tree/Declaration/ConstructorDeclarator.java +++ b/src/main/java/tree/Declaration/ConstructorDeclarator.java @@ -8,7 +8,8 @@ // ConstructorDeclarator // : TypeParametersOpt IDENTIFIER LPAREN FormalParameterList/*FormalParameters*/ RPAREN // ; -public class ConstructorDeclarator extends Entity { +public class ConstructorDeclarator extends Entity +{ // Structure public TypeParameters typeParameters; public ParameterDeclarations formalParameters; @@ -24,6 +25,7 @@ public ConstructorDeclarator(TypeParameters tpars, ParameterDeclarations pars) { if (this.formalParameters != null) { this.formalParameters.parent = this; } + Entity.reportParsing("CONSTRUCTOR DECLARATOR"); } // Reporting diff --git a/src/main/java/tree/Declaration/Declaration.java b/src/main/java/tree/Declaration/Declaration.java index 58aee7e..e593bf5 100644 --- a/src/main/java/tree/Declaration/Declaration.java +++ b/src/main/java/tree/Declaration/Declaration.java @@ -35,7 +35,8 @@ // : UnannotatedType VariableDeclaratorList // | VAR VariableDeclaratorList // ; -public class Declaration extends Entity { +public class Declaration extends Entity +{ // Structure: properties common to (almost) all // kinds of declarations. public Modifiers modifiers; @@ -43,7 +44,8 @@ public class Declaration extends Entity { public Type type; // Creation - public Declaration(Modifiers mods, String n, Type t) { + public Declaration(Modifiers mods, String n, Type t) + { this.modifiers = mods; this.name = n; this.type = t; @@ -54,6 +56,7 @@ public Declaration(Modifiers mods, String n, Type t) { if (this.type != null) { this.type.parent = this; } + Entity.reportParsing("DECLARATION"); } public Declaration addModifiers(Modifiers mods) { diff --git a/src/main/java/tree/Declaration/EnumBody.java b/src/main/java/tree/Declaration/EnumBody.java index a68cbf0..97a2c10 100644 --- a/src/main/java/tree/Declaration/EnumBody.java +++ b/src/main/java/tree/Declaration/EnumBody.java @@ -8,7 +8,8 @@ // : LBRACE EnumConstantListOpt EnumBodyDeclarationsOpt RBRACE // | LBRACE EnumConstantListOpt COMMA EnumBodyDeclarationsOpt RBRACE // ; -public class EnumBody extends Entity { +public class EnumBody extends Entity +{ // Structure public Enumerators enumerators; public Declarations declarations; @@ -24,6 +25,7 @@ public EnumBody(Enumerators ens, Declarations decls) { if (this.declarations != null) { this.declarations.parent = this; } + Entity.reportParsing("ENUM BODY"); } // Reporting diff --git a/src/main/java/tree/Declaration/EnumDeclaration.java b/src/main/java/tree/Declaration/EnumDeclaration.java index 8b98286..bdd4e82 100644 --- a/src/main/java/tree/Declaration/EnumDeclaration.java +++ b/src/main/java/tree/Declaration/EnumDeclaration.java @@ -29,10 +29,11 @@ // | SEMICOLON // | SEMICOLON ClassBodyDeclarationSeq // ; -public class EnumDeclaration extends ClassDeclaration { +public class EnumDeclaration extends ClassDeclaration +{ // Structure - // public Modifiers modifiers; -- in the base class - // public String name; -- in the base class + // public Modifiers modifiers; -- in the base class + // public String name; -- in the base class public TypeList implemented; public Enumerators enumerators; public Declarations body; @@ -53,6 +54,7 @@ public EnumDeclaration(Token n, TypeList impls, EnumBody body) { if (this.body != null) { this.body.parent = this; } + Entity.reportParsing("ENUM DECLARATION"); } // Reporting diff --git a/src/main/java/tree/Declaration/Enumerator.java b/src/main/java/tree/Declaration/Enumerator.java index 92a51f3..6146b5a 100644 --- a/src/main/java/tree/Declaration/Enumerator.java +++ b/src/main/java/tree/Declaration/Enumerator.java @@ -9,7 +9,8 @@ // : AnnotationSeqOpt IDENTIFIER Arguments // | AnnotationSeqOpt IDENTIFIER Arguments ClassBody // ; -public class Enumerator extends Entity { +public class Enumerator extends Entity +{ // Structure public Annotations annotations; public String name; @@ -32,6 +33,7 @@ public Enumerator(Annotations anns, Token name, ArgumentList args, Declarations if (this.enumBody != null) { this.enumBody.parent = this; } + Entity.reportParsing("ENUMERATOR"); } // Reporting diff --git a/src/main/java/tree/Declaration/ExplicitConstructorInvocation.java b/src/main/java/tree/Declaration/ExplicitConstructorInvocation.java index a0d641c..df63842 100644 --- a/src/main/java/tree/Declaration/ExplicitConstructorInvocation.java +++ b/src/main/java/tree/Declaration/ExplicitConstructorInvocation.java @@ -13,7 +13,8 @@ // | CompoundName DOT TypeArgumentsOpt SUPER Arguments SEMICOLON // | Primary DOT TypeArgumentsOpt SUPER Arguments SEMICOLON // ; -public class ExplicitConstructorInvocation extends Entity { +public class ExplicitConstructorInvocation extends Entity +{ // Structure public Expression expression; public TypeArguments typeArguments; @@ -21,10 +22,8 @@ public class ExplicitConstructorInvocation extends Entity { public ArgumentList arguments; // Creation - public ExplicitConstructorInvocation( - Expression expr, - TypeArguments targs, - boolean ts, ArgumentList args) { + public ExplicitConstructorInvocation(Expression expr,TypeArguments targs, boolean ts, ArgumentList args) + { this.expression = expr; this.typeArguments = targs; this.thisORsuper = ts; @@ -39,6 +38,7 @@ public ExplicitConstructorInvocation( if (this.arguments != null) { this.arguments.parent = this; } + Entity.reportParsing("EXPLICIT CONSTRUCTOR INVOCATION"); } // Reporting diff --git a/src/main/java/tree/Declaration/ImportDeclaration.java b/src/main/java/tree/Declaration/ImportDeclaration.java index 60bee78..405210a 100644 --- a/src/main/java/tree/Declaration/ImportDeclaration.java +++ b/src/main/java/tree/Declaration/ImportDeclaration.java @@ -12,7 +12,8 @@ // : // empty // | STATIC // ; -public class ImportDeclaration extends Entity { +public class ImportDeclaration extends Entity +{ // Structure public boolean signStatic; public CompoundName compoundName; @@ -27,6 +28,7 @@ public ImportDeclaration(boolean stat, CompoundName cn, boolean star) { if (this.compoundName != null) { this.compoundName.parent = this; } + Entity.reportParsing("IMPORT DECLARATION"); } // Reporting diff --git a/src/main/java/tree/Declaration/InterfaceDeclaration.java b/src/main/java/tree/Declaration/InterfaceDeclaration.java index 5a02596..9d37bfb 100644 --- a/src/main/java/tree/Declaration/InterfaceDeclaration.java +++ b/src/main/java/tree/Declaration/InterfaceDeclaration.java @@ -1,13 +1,17 @@ package tree.Declaration; +import tree.Entity; import tree.Modifiers; -public class InterfaceDeclaration extends Declaration { +public class InterfaceDeclaration extends Declaration +{ // No structure // Creation - public InterfaceDeclaration(Modifiers m, String n) { + public InterfaceDeclaration(Modifiers m, String n) + { super(m, n, null); + Entity.reportParsing("INTERFACE DECLARATION"); } diff --git a/src/main/java/tree/Declaration/MethodDeclaration.java b/src/main/java/tree/Declaration/MethodDeclaration.java index 1d83703..429b19a 100644 --- a/src/main/java/tree/Declaration/MethodDeclaration.java +++ b/src/main/java/tree/Declaration/MethodDeclaration.java @@ -30,20 +30,22 @@ // : // empty // | THROWS ClassTypeList1 // ; -public class MethodDeclaration extends Declaration { +public class MethodDeclaration extends Declaration +{ // Structure - // public Modifiers modifiers; + // public Modifiers modifiers; public TypeParameters typeParameters; - // public Type type; - // public String name; - // public ReceiverDeclaration receiver; -- this is a special kind of ParameterDeclaration + // public Type type; + // public String name; + // public ReceiverDeclaration receiver; -- this is a special kind of ParameterDeclaration public ParameterDeclarations parameters; public Dims dims; public TypeList exceptions; public Block methodBody; // Creation - public MethodDeclaration(MethodHeader header, Block body) { + public MethodDeclaration(MethodHeader header, Block body) + { super(null, header.declarator.name, header.type); this.typeParameters = header.typeParameters; this.parameters = header.declarator.parameters; @@ -66,6 +68,7 @@ public MethodDeclaration(MethodHeader header, Block body) { if (this.methodBody != null) { this.methodBody.parent = this; } + Entity.reportParsing("METHOD DECLARATION"); } public MethodDeclaration(Modifiers mods, @@ -75,7 +78,8 @@ public MethodDeclaration(Modifiers mods, ParameterDeclarations pars, Dims dims, TypeList excs, - Block body) { + Block body) + { super(mods, n, t); this.typeParameters = typePars; this.parameters = pars; @@ -98,6 +102,7 @@ public MethodDeclaration(Modifiers mods, if (this.methodBody != null) { this.methodBody.parent = this; } + Entity.reportParsing("METHOD DECLARATION"); } // Reporting diff --git a/src/main/java/tree/Declaration/MethodDeclarator.java b/src/main/java/tree/Declaration/MethodDeclarator.java index c474051..9d35d6a 100644 --- a/src/main/java/tree/Declaration/MethodDeclarator.java +++ b/src/main/java/tree/Declaration/MethodDeclarator.java @@ -10,7 +10,8 @@ // : IDENTIFIER LPAREN RPAREN DimsOpt // | IDENTIFIER LPAREN FormalParameterList /*FormalParameters*/ RPAREN DimsOpt // ; -public class MethodDeclarator extends Entity { +public class MethodDeclarator extends Entity +{ // Structure public String name; public ParameterDeclarations parameters; @@ -28,6 +29,7 @@ public MethodDeclarator(Token token, ParameterDeclarations pars, Dims dims) { if (this.dims != null) { this.dims.parent = this; } + Entity.reportParsing("METHOD DECLARATOR"); } // Reporting diff --git a/src/main/java/tree/Declaration/MethodHeader.java b/src/main/java/tree/Declaration/MethodHeader.java index b9fc6a0..f237c5c 100644 --- a/src/main/java/tree/Declaration/MethodHeader.java +++ b/src/main/java/tree/Declaration/MethodHeader.java @@ -15,7 +15,8 @@ // | UnannotatedType MethodDeclarator ThrowsOpt // | VOID MethodDeclarator ThrowsOpt // ; -public class MethodHeader extends Entity { +public class MethodHeader extends Entity +{ // Structure public TypeParameters typeParameters; public Type type; // together with annotations? @@ -26,7 +27,8 @@ public MethodHeader( TypeParameters tpars, Type type, MethodDeclarator methodDecl, - TypeList thr) { + TypeList thr) + { this.typeParameters = tpars; this.type = type; this.declarator = methodDecl; @@ -44,6 +46,7 @@ public MethodHeader( if (this.throwsClause != null) { this.throwsClause.parent = this; } + Entity.reportParsing("METHOD HEADER"); } // Reporting diff --git a/src/main/java/tree/Declaration/NormalClassDeclaration.java b/src/main/java/tree/Declaration/NormalClassDeclaration.java index e1c7da7..70eecd8 100644 --- a/src/main/java/tree/Declaration/NormalClassDeclaration.java +++ b/src/main/java/tree/Declaration/NormalClassDeclaration.java @@ -40,7 +40,8 @@ // | STATIC Block // StaticInitializer // | SEMICOLON // ; -public class NormalClassDeclaration extends ClassDeclaration { +public class NormalClassDeclaration extends ClassDeclaration +{ // Structure public TypeParameters typeParameters; public Type extendedType; @@ -52,7 +53,8 @@ public NormalClassDeclaration(Token n, TypeParameters typePars, Type extType, TypeList ints, - Declarations body) { + Declarations body) + { super(null, n.image); this.typeParameters = typePars; this.extendedType = extType; @@ -71,9 +73,11 @@ public NormalClassDeclaration(Token n, if (this.body != null) { this.body.parent = this; } + Entity.reportParsing("NORMAL CLASS DECLARATION"); } - public List getStaticVariables() { + public List getStaticVariables() + { return body.declarations.stream() .filter(dec -> dec instanceof VariableDeclaration) .filter(dec -> dec.modifiers.modifiers.modifiers.contains(TokenCode.Static)) @@ -81,7 +85,8 @@ public List getStaticVariables() { .collect(Collectors.toList()); } - public List getNonStaticVariables() { + public List getNonStaticVariables() + { return body.declarations.stream() .filter(dec -> dec instanceof VariableDeclaration) .filter(dec -> !dec.modifiers.modifiers.modifiers.contains(TokenCode.Static)) @@ -89,7 +94,8 @@ public List getNonStaticVariables() { .collect(Collectors.toList()); } - public List getStaticMethods() { + public List getStaticMethods() + { return body.declarations.stream() .filter(dec -> dec instanceof MethodDeclaration) .filter(dec -> dec.modifiers.modifiers.modifiers.contains(TokenCode.Static)) @@ -97,7 +103,8 @@ public List getStaticMethods() { .collect(Collectors.toList()); } - public List getNonStaticMethods() { + public List getNonStaticMethods() + { return body.declarations.stream() .filter(dec -> dec instanceof MethodDeclaration) .filter(dec -> !dec.modifiers.modifiers.modifiers.contains(TokenCode.Static)) @@ -106,7 +113,8 @@ public List getNonStaticMethods() { } // Reporting - public void report(int sh) { + public void report(int sh) + { this.title("CLASS DECLARATION " + this.name, sh); if (this.typeParameters != null) { this.typeParameters.report(sh + shift); diff --git a/src/main/java/tree/Declaration/NormalInterfaceDeclaration.java b/src/main/java/tree/Declaration/NormalInterfaceDeclaration.java index fe0ec73..946b068 100644 --- a/src/main/java/tree/Declaration/NormalInterfaceDeclaration.java +++ b/src/main/java/tree/Declaration/NormalInterfaceDeclaration.java @@ -8,9 +8,10 @@ // NormalInterfaceDeclaration // : INTERFACE IDENTIFIER TypeParametersOpt InterfaceExtendsOpt InterfaceBody // ; -public class NormalInterfaceDeclaration extends InterfaceDeclaration { +public class NormalInterfaceDeclaration extends InterfaceDeclaration +{ // Structure - // public String identifier; + // public String identifier; public TypeParameters typeParameters; public TypeList extendingInterfaces; public Declarations interfaceBody; @@ -20,7 +21,8 @@ public NormalInterfaceDeclaration( Token id, TypeParameters typePars, TypeList extTypes, - Declarations body) { + Declarations body) + { super(null, id.image); this.typeParameters = typePars; this.extendingInterfaces = extTypes; @@ -35,10 +37,12 @@ public NormalInterfaceDeclaration( if (this.interfaceBody != null) { this.interfaceBody.parent = this; } + Entity.reportParsing("NORMAL INTERFACE DECLARATION"); } // Reporting - public void report(int sh) { + public void report(int sh) + { doShift(sh); System.out.println("INTERFACE " + super.name); if (typeParameters != null) { diff --git a/src/main/java/tree/Declaration/ParameterDeclaration.java b/src/main/java/tree/Declaration/ParameterDeclaration.java index f702208..03aad34 100644 --- a/src/main/java/tree/Declaration/ParameterDeclaration.java +++ b/src/main/java/tree/Declaration/ParameterDeclaration.java @@ -45,12 +45,16 @@ public ParameterDeclaration(Modifiers mods, if ( this.ellAnnotations != null ) this.ellAnnotations.parent = this; if ( this.dims != null ) this.dims.parent = this; + + Entity.reportParsing("PARAMETER DECLARATION"); } + public ParameterDeclaration(Token token) { // For the single lambda parameter this(null,null,token.image,null,false,null); } + public static ParameterDeclaration create(Modifiers mods,Type type,ParameterTail tail) { if ( tail.thisSign ) // this is the receiver declaration diff --git a/src/main/java/tree/Declaration/ParameterTail.java b/src/main/java/tree/Declaration/ParameterTail.java index b19590d..7efe5f0 100644 --- a/src/main/java/tree/Declaration/ParameterTail.java +++ b/src/main/java/tree/Declaration/ParameterTail.java @@ -13,7 +13,8 @@ // | THIS // receiver // | IDENTIFIER DOT THIS // receiver // ; -public class ParameterTail extends Entity { +public class ParameterTail extends Entity +{ // Structure public Annotations annotations; public String identifier; @@ -35,6 +36,7 @@ public ParameterTail(Annotations anns, Token id, Dims dims, boolean ellSign, boo if (this.dims != null) { this.dims.parent = this; } + Entity.reportParsing("PARAMETER TAIL"); } // Reporting diff --git a/src/main/java/tree/Declaration/ReceiverDeclaration.java b/src/main/java/tree/Declaration/ReceiverDeclaration.java index 2de4213..605cd61 100644 --- a/src/main/java/tree/Declaration/ReceiverDeclaration.java +++ b/src/main/java/tree/Declaration/ReceiverDeclaration.java @@ -18,20 +18,23 @@ // | THIS <<<======== // | IDENTIFIER DOT THIS <<<======== // ; -public class ReceiverDeclaration extends ParameterDeclaration { +public class ReceiverDeclaration extends ParameterDeclaration +{ // Structure public Annotations annotations; - // public Type type; - // public String name; + // public Type type; + // public String name; // Creation - public ReceiverDeclaration(Annotations anns, Type t, String n) { + public ReceiverDeclaration(Annotations anns, Type t, String n) + { super(null, t, n, null, false, null); this.annotations = anns; if (this.annotations != null) { this.annotations.parent = this; } + Entity.reportParsing("RECEIVER DECLARATION"); } // Reporting diff --git a/src/main/java/tree/Declaration/RecordComponent.java b/src/main/java/tree/Declaration/RecordComponent.java index f6b25a2..0172af7 100644 --- a/src/main/java/tree/Declaration/RecordComponent.java +++ b/src/main/java/tree/Declaration/RecordComponent.java @@ -1,6 +1,7 @@ package tree.Declaration; import tree.Annotations; +import tree.Entity; import tree.Modifiers; import tree.Type.Type; @@ -14,11 +15,12 @@ // : AnnotationSeqOpt UnannotatedType IDENTIFIER // | AnnotationSeqOpt UnannotatedType AnnotationSeqOpt ELLIPSIS IDENTIFIER // VariableArityRecordComponent // ; -public class RecordComponent extends Declaration { +public class RecordComponent extends Declaration +{ // Structure - // public Modifiers modifiers; - // public String name; - // public Type type; + // public Modifiers modifiers; + // public String name; + // public Type type; public Annotations ellAnnotations; public boolean signEllipsis; @@ -27,7 +29,8 @@ public RecordComponent(Modifiers mods, String n, Type t, Annotations ellAnns, - boolean ell) { + boolean ell) + { super(mods, n, t); this.ellAnnotations = ellAnns; this.signEllipsis = ell; @@ -35,6 +38,7 @@ public RecordComponent(Modifiers mods, if (this.ellAnnotations != null) { this.ellAnnotations.parent = this; } + Entity.reportParsing("RECORD COMPONENT"); } // Reporting diff --git a/src/main/java/tree/Declaration/RecordDeclaration.java b/src/main/java/tree/Declaration/RecordDeclaration.java index 4195f34..141adc4 100644 --- a/src/main/java/tree/Declaration/RecordDeclaration.java +++ b/src/main/java/tree/Declaration/RecordDeclaration.java @@ -1,5 +1,6 @@ package tree.Declaration; +import tree.Entity; import tree.Modifiers; import tree.Type.TypeParameters; @@ -36,19 +37,21 @@ // : ClassBodyDeclaration // | ModifierSeqOpt IDENTIFIER ConstructorBody // CompactConstructorDeclaration // ; -public class RecordDeclaration extends ClassDeclaration { +public class RecordDeclaration extends ClassDeclaration +{ // Structure public TypeParameters typeParameters; public RecordComponents recordComponents; public Declarations body; - // public CompactConstructor !!!!!!!!!!!!!!!!!!!!!!!! + // public CompactConstructor !!!!!!!!!!!!!!!!!!!!!!!! // Creation public RecordDeclaration(String n, Modifiers mods, TypeParameters typePars, RecordComponents recordComps, - Declarations body) { + Declarations body) + { super(mods, n); this.modifiers = mods; this.typeParameters = typePars; @@ -67,6 +70,7 @@ public RecordDeclaration(String n, if (this.body != null) { this.body.parent = this; } + Entity.reportParsing("RECORD DECLARATION"); } // Reporting diff --git a/src/main/java/tree/Declaration/TypeAndDeclarators.java b/src/main/java/tree/Declaration/TypeAndDeclarators.java index 3a9a5b7..f284442 100644 --- a/src/main/java/tree/Declaration/TypeAndDeclarators.java +++ b/src/main/java/tree/Declaration/TypeAndDeclarators.java @@ -7,22 +7,24 @@ public class TypeAndDeclarators extends Declaration { // Structure - // public Type type; -- in the base class + // public Type type; -- in the base class public VariableDeclarators declarators; // Creation public TypeAndDeclarators(Type t, VariableDeclarators vds) { super(null, null, t); this.declarators = vds; - if (vds != null) { - vds.parent = this; - } - if (debug) { - System.out.println("Type with declarator(s) taken"); - } + if (vds != null) vds.parent = this; +// if (debug) { +// System.out.println("Type with declarator(s) taken"); +// } + Entity.reportParsing("TYPE & DECLARATOR(S)"); } // Reporting - public void report(int sh) { + public void report(int sh) + { + if ( type != null ) type.report(sh); + declarators.report(sh); } } diff --git a/src/main/java/tree/Declaration/VariableDeclaration.java b/src/main/java/tree/Declaration/VariableDeclaration.java index 77ff1e9..b575685 100644 --- a/src/main/java/tree/Declaration/VariableDeclaration.java +++ b/src/main/java/tree/Declaration/VariableDeclaration.java @@ -30,10 +30,11 @@ // | IDENTIFIER Dims // | IDENTIFIER Dims EQUAL ArrayInitializer // ; -public class VariableDeclaration extends Declaration { +public class VariableDeclaration extends Declaration +{ // Structure - // public Modifiers modifiers; -- from the base class - // public String name; -- from the base class + // public Modifiers modifiers; -- from the base class + // public String name; -- from the base class public Dims dims; // Either a single expression, or a list of initializers @@ -44,7 +45,8 @@ public VariableDeclaration(String n, Modifiers mods, Type t, Dims dims, - Initializer init) { + Initializer init) + { super(mods, n, t); this.dims = dims; this.initializer = init; @@ -55,6 +57,7 @@ public VariableDeclaration(String n, if (this.initializer != null) { this.initializer.parent = this; } + Entity.reportParsing("VARIABLE DECLARATION"); } // Reporting diff --git a/src/main/java/tree/Declaration/VariableDeclarator.java b/src/main/java/tree/Declaration/VariableDeclarator.java index 63afa2c..9016010 100644 --- a/src/main/java/tree/Declaration/VariableDeclarator.java +++ b/src/main/java/tree/Declaration/VariableDeclarator.java @@ -13,14 +13,16 @@ // | IDENTIFIER Dims // | IDENTIFIER Dims EQUAL ArrayInitializer // ; -public class VariableDeclarator extends Entity { +public class VariableDeclarator extends Entity +{ // Structure public String name; public Dims dims; public Initializer initializer; // Creation - public VariableDeclarator(Token id, Dims dims, Initializer init) { + public VariableDeclarator(Token id, Dims dims, Initializer init) + { this.name = id.image; this.dims = dims; this.initializer = init; @@ -31,10 +33,7 @@ public VariableDeclarator(Token id, Dims dims, Initializer init) { if (this.initializer != null) { this.initializer.parent = this; } - - if (debug) { - System.out.println("Variable declarator with " + id.image + " accepted"); - } + Entity.reportParsing("VARIABLE DECLARATOR with " + id.image ); } // Reporting diff --git a/src/main/java/tree/Declaration/VariableDeclarators.java b/src/main/java/tree/Declaration/VariableDeclarators.java index 24415b6..1d63924 100644 --- a/src/main/java/tree/Declaration/VariableDeclarators.java +++ b/src/main/java/tree/Declaration/VariableDeclarators.java @@ -5,31 +5,31 @@ // Intermediate class; won't appear in the AST // -public class VariableDeclarators extends Entity { +public class VariableDeclarators extends Entity +{ // Structure public ArrayList declarators; // Creation - public VariableDeclarators(VariableDeclarator decl) { + public VariableDeclarators(VariableDeclarator decl) + { this.declarators = new ArrayList<>(); this.declarators.add(decl); - if (decl != null) { - decl.parent = this; - } + if (decl != null) decl.parent = this; } - public VariableDeclarators add(VariableDeclarator decl) { + public VariableDeclarators add(VariableDeclarator decl) + { this.declarators.add(decl); - if (decl != null) { - decl.parent = this; - } + if (decl != null) decl.parent = this; return this; } // Reporting - public void report(int sh) { - // Empty + public void report(int sh) + { + for (VariableDeclarator decl: declarators ) + decl.report(sh); } - } diff --git a/src/main/java/tree/Dim.java b/src/main/java/tree/Dim.java index f6505c2..6d39429 100644 --- a/src/main/java/tree/Dim.java +++ b/src/main/java/tree/Dim.java @@ -1,25 +1,35 @@ package tree; +import tree.Expression.Expression; + // Dim // : AnnotationSeq LBRACKET RBRACKET // | LBRACKET RBRACKET // ; -public class Dim extends Entity { +public class Dim extends Entity +{ // Structure public Annotations annotations; + public Expression expression; // Creation - public Dim(Annotations anns) { + public Dim(Annotations anns, Expression expr) + { this.annotations = anns; - if (this.annotations != null) { - this.annotations.parent = this; - } + if (this.annotations != null) this.annotations.parent = this; + this.expression = expr; + if ( this.expression != null ) this.expression.parent = this; + + String rep = "DIMENSION"; + if ( this.expression != null ) rep += " WITH EXPR"; + Entity.reportParsing(rep); } // Reporting public void report(int sh) { - annotations.report(sh); - System.out.print("[]"); + if ( annotations != null ) annotations.report(sh); + System.out.print("["); + if ( expression != null ) expression.report(sh); + System.out.print("]"); } - } diff --git a/src/main/java/tree/DimExpr.java b/src/main/java/tree/DimExpr.java new file mode 100644 index 0000000..ab8227a --- /dev/null +++ b/src/main/java/tree/DimExpr.java @@ -0,0 +1,31 @@ +package tree; + +import tree.Expression.Expression; + +public class DimExpr extends Entity +{ + // Structure + public Annotations annotations; + public Expression expression; + + // Creation + public DimExpr(Annotations anns, Expression expr) + { + this.annotations = anns; + if (this.annotations != null) this.annotations.parent = this; + this.expression = expr; + if ( this.expression != null ) this.expression.parent = this; + + String rep = "DIMENSION"; + if ( this.expression != null ) rep += " WITH EXPR"; + Entity.reportParsing(rep); + } + + // Reporting + public void report(int sh) { + if ( annotations != null ) annotations.report(sh); + System.out.print("["); + if ( expression != null ) expression.report(sh); + System.out.print("]"); + } +} diff --git a/src/main/java/tree/DimExprs.java b/src/main/java/tree/DimExprs.java new file mode 100644 index 0000000..3e1ccb0 --- /dev/null +++ b/src/main/java/tree/DimExprs.java @@ -0,0 +1,32 @@ +package tree; + +import java.util.ArrayList; + +public class DimExprs extends Entity +{ + // Structure + public ArrayList dimensions; + + // Creation + public DimExprs(DimExpr de) + { + this.dimensions = new ArrayList<>(); + this.dimensions.add(de); + if ( de != null ) de.parent = this; + } + public DimExprs add(DimExpr de) + { + this.dimensions.add(de); + if ( de != null ) de.parent = this; + return this; + } + + // Reporting + + public void report(int sh) + { + for (DimExpr de : dimensions) { + de.report(sh); + } + } +} diff --git a/src/main/java/tree/Entity.java b/src/main/java/tree/Entity.java index 5778fd9..b76e1be 100644 --- a/src/main/java/tree/Entity.java +++ b/src/main/java/tree/Entity.java @@ -6,7 +6,8 @@ // The root class of the whole hierarchy of classes // representing various Java constructs. -public class Entity { +public class Entity +{ public static final int shift = 4; public static boolean debug = false; public static boolean syntaxOnly = false; @@ -63,4 +64,11 @@ public void report(int sh) { } + public static void reportParsing(String title) + { + if ( !debug ) return; + for ( int i=1; i<=20; i++ ) System.out.print(" "); + System.out.println(title); + } + } diff --git a/src/main/java/tree/Expression/ArgumentList.java b/src/main/java/tree/Expression/ArgumentList.java index 8c2cf44..94983c1 100644 --- a/src/main/java/tree/Expression/ArgumentList.java +++ b/src/main/java/tree/Expression/ArgumentList.java @@ -12,7 +12,8 @@ // : Expression // | ArgumentList COMMA Expression // ; -public class ArgumentList extends Entity { +public class ArgumentList extends Entity +{ // Structure public ArrayList arguments; diff --git a/src/main/java/tree/Expression/Binary.java b/src/main/java/tree/Expression/Binary.java index c8af09c..6dbe7cf 100644 --- a/src/main/java/tree/Expression/Binary.java +++ b/src/main/java/tree/Expression/Binary.java @@ -4,14 +4,16 @@ import lexer.TokenCode; import tree.Entity; -public class Binary extends Expression { +public class Binary extends Expression +{ // Structure public Expression left; public Expression right; public TokenCode operator; // Creation - public Binary(Expression l, Expression r, Token token) { + public Binary(Expression l, Expression r, Token token) + { super(); this.left = l; this.right = r; @@ -23,6 +25,7 @@ public Binary(Expression l, Expression r, Token token) { if (this.right != null) { this.right.parent = this; } + Entity.reportParsing("BINARY " + operator.toString()); } // Reporting diff --git a/src/main/java/tree/Expression/Cast.java b/src/main/java/tree/Expression/Cast.java index a6ef6b5..86c4716 100644 --- a/src/main/java/tree/Expression/Cast.java +++ b/src/main/java/tree/Expression/Cast.java @@ -7,13 +7,15 @@ // : TargetType UnaryExpression // | TargetType LambdaExpression // ; -public class Cast extends Expression { +public class Cast extends Expression +{ // Structure public TypeList types; public Expression expression; // Creation - public Cast(TypeList types, Expression expr) { + public Cast(TypeList types, Expression expr) + { this.types = types; this.expression = expr; @@ -23,6 +25,7 @@ public Cast(TypeList types, Expression expr) { if (this.expression != null) { this.expression.parent = this; } + Entity.reportParsing("CAST"); } // Reporting diff --git a/src/main/java/tree/Expression/Conditional.java b/src/main/java/tree/Expression/Conditional.java index 69994fd..156bc36 100644 --- a/src/main/java/tree/Expression/Conditional.java +++ b/src/main/java/tree/Expression/Conditional.java @@ -11,7 +11,8 @@ // | QUESTION Expression COLON ConditionalExpression // | QUESTION Expression COLON LambdaExpression // ; -public class Conditional extends Expression { +public class Conditional extends Expression +{ // Structure public Expression condition; public Expression thenPart; @@ -32,6 +33,7 @@ public Conditional(Expression c, Expression t, Expression e) { if (this.elsePart != null) { this.elsePart.parent = this; } + Entity.reportParsing("CONDITIONAL"); } // Reporting diff --git a/src/main/java/tree/Expression/Expression.java b/src/main/java/tree/Expression/Expression.java index fae33bd..27905c8 100644 --- a/src/main/java/tree/Expression/Expression.java +++ b/src/main/java/tree/Expression/Expression.java @@ -2,5 +2,6 @@ import tree.Entity; -public class Expression extends Entity { +public class Expression extends Entity +{ } diff --git a/src/main/java/tree/Expression/InstanceOf.java b/src/main/java/tree/Expression/InstanceOf.java index 7eec0ab..2abba5d 100644 --- a/src/main/java/tree/Expression/InstanceOf.java +++ b/src/main/java/tree/Expression/InstanceOf.java @@ -8,7 +8,8 @@ // : RelationalExpression INSTANCEOF Type // | RelationalExpression INSTANCEOF Pattern // ; -public class InstanceOf extends Expression { +public class InstanceOf extends Expression +{ // Structure public Expression expression; // Either type OR declaration @@ -16,7 +17,8 @@ public class InstanceOf extends Expression { public Declaration declaration; // Creation - public InstanceOf(Expression expr, Type type) { + public InstanceOf(Expression expr, Type type) + { this.expression = expr; this.type = type; this.declaration = null; @@ -27,9 +29,11 @@ public InstanceOf(Expression expr, Type type) { if (this.type != null) { this.type.parent = this; } + Entity.reportParsing("INSTANCEOF"); } - public InstanceOf(Expression expr, Declaration decl) { + public InstanceOf(Expression expr, Declaration decl) + { this.expression = expr; this.type = null; this.declaration = decl; @@ -40,6 +44,7 @@ public InstanceOf(Expression expr, Declaration decl) { if (this.declaration != null) { this.declaration.parent = this; } + Entity.reportParsing("INSTANCEOF"); } // Reporting diff --git a/src/main/java/tree/Expression/Lambda.java b/src/main/java/tree/Expression/Lambda.java index 2acde10..42f40fd 100644 --- a/src/main/java/tree/Expression/Lambda.java +++ b/src/main/java/tree/Expression/Lambda.java @@ -1,6 +1,7 @@ package tree.Expression; import tree.Declaration.ParameterDeclarations; +import tree.Entity; import tree.Statement.Block; // LambdaExpression @@ -31,7 +32,8 @@ // | ModifierSeqOpt VAR IDENTIFIER DimsOpt // | ModifierSeqOpt UnannotatedType AnnotationSeqOpt ELLIPSIS IDENTIFIER // VariableArityParameter // ; -public class Lambda extends Expression { +public class Lambda extends Expression +{ // Structure public ParameterDeclarations parameters; // One of these two! @@ -39,7 +41,8 @@ public class Lambda extends Expression { public Block block; // Creation - public Lambda(ParameterDeclarations pars, Expression expr) { + public Lambda(ParameterDeclarations pars, Expression expr) + { this.parameters = pars; this.expression = expr; this.block = null; @@ -50,9 +53,11 @@ public Lambda(ParameterDeclarations pars, Expression expr) { if (this.expression != null) { this.expression.parent = this; } + Entity.reportParsing("LAMBDA"); } - public Lambda(ParameterDeclarations pars, Block block) { + public Lambda(ParameterDeclarations pars, Block block) + { this.parameters = pars; this.block = block; @@ -62,6 +67,7 @@ public Lambda(ParameterDeclarations pars, Block block) { if (this.block != null) { this.block.parent = this; } + Entity.reportParsing("LAMBDA"); } // Reporting diff --git a/src/main/java/tree/Expression/ArrayAccess.java b/src/main/java/tree/Expression/Primary/ArrayAccess.java similarity index 75% rename from src/main/java/tree/Expression/ArrayAccess.java rename to src/main/java/tree/Expression/Primary/ArrayAccess.java index 831005e..1aa842b 100644 --- a/src/main/java/tree/Expression/ArrayAccess.java +++ b/src/main/java/tree/Expression/Primary/ArrayAccess.java @@ -1,18 +1,21 @@ -package tree.Expression; +package tree.Expression.Primary; import tree.Entity; +import tree.Expression.Expression; // ArrayAccess // : CompoundName LBRACKET Expression RBRACKET // | Primary LBRACKET Expression RBRACKET // ; -public class ArrayAccess extends Expression { +public class ArrayAccess extends Primary +{ // Structure public Expression expression; public Expression size; // Creation - public ArrayAccess(Expression expr, Expression size) { + public ArrayAccess(Expression expr, Expression size) + { this.expression = expr; this.size = size; @@ -22,6 +25,7 @@ public ArrayAccess(Expression expr, Expression size) { if (this.size != null) { this.size.parent = this; } + Entity.reportParsing("ARRAY ACCESS"); } // Reporting diff --git a/src/main/java/tree/Expression/Primary/ArrayCreation.java b/src/main/java/tree/Expression/Primary/ArrayCreation.java new file mode 100644 index 0000000..fa3e559 --- /dev/null +++ b/src/main/java/tree/Expression/Primary/ArrayCreation.java @@ -0,0 +1,54 @@ +package tree.Expression.Primary; + +import tree.DimExprs; +import tree.Dims; +import tree.Entity; +import tree.InitializerArray; +import tree.Type.Type; + +// ArrayCreationExpression +// : NEW Type DimExprs DimsOpt { $$ = null; } // not implemented yet +// | NEW Type Dims ArrayInitializer { $$ = null; } // not implemented yet +// ; +// +// DimExprs +// : DimExpr +// | DimExprs DimExpr +// ; +// +// DimExpr +// : LBRACKET Expression RBRACKET +// | AnnotationSeq LBRACKET Expression RBRACKET +// ; +public class ArrayCreation extends Primary +{ + // Structure + Type type; +// DimExprs dimExprs; +// Dims dims; + InitializerArray initializer; + + // Creation + public ArrayCreation(Type t, InitializerArray init) + { + this.type = t; +// this.dimExprs = de; +// this.dims = ds; + this.initializer = init; + + if ( this.type != null ) this.type.parent = this; +// if ( this.dimExprs != null ) this.dimExprs.parent = this; +// if ( this.dims != null ) this.dims.parent = this; + if ( this.initializer != null ) this.initializer.parent = this; + + Entity.reportParsing("ARRAY CREATION"); + } + + public void report(int sh) + { + title("ARRAY CREATION",sh); + if ( type != null) type.report(sh+Entity.shift); + if ( initializer != null ) initializer.report(sh+Entity.shift); + } + +} diff --git a/src/main/java/tree/Expression/Primary/ClassLiteral.java b/src/main/java/tree/Expression/Primary/ClassLiteral.java index b7ed099..b64a684 100644 --- a/src/main/java/tree/Expression/Primary/ClassLiteral.java +++ b/src/main/java/tree/Expression/Primary/ClassLiteral.java @@ -9,7 +9,8 @@ // | Type DimsOpt DOT CLASS // ClassLiteral // | VOID DimsOpt DOT CLASS // ClassLiteral // | ... -public class ClassLiteral extends Literal { +public class ClassLiteral extends Literal +{ // Structure public Type type; // VOID, if type==null public Dims dims; @@ -26,6 +27,7 @@ public ClassLiteral(Type t, Dims d) { if (this.dims != null) { this.dims.parent = this; } + Entity.reportParsing("CLASS LITERAL"); } // Reporting diff --git a/src/main/java/tree/Expression/FieldAccess.java b/src/main/java/tree/Expression/Primary/FieldAccess.java similarity index 80% rename from src/main/java/tree/Expression/FieldAccess.java rename to src/main/java/tree/Expression/Primary/FieldAccess.java index 53b5b45..65d765f 100644 --- a/src/main/java/tree/Expression/FieldAccess.java +++ b/src/main/java/tree/Expression/Primary/FieldAccess.java @@ -1,21 +1,24 @@ -package tree.Expression; +package tree.Expression.Primary; import lexer.Token; import tree.Entity; +import tree.Expression.Expression; // FieldAccess // : Primary DOT IDENTIFIER // | SUPER DOT IDENTIFIER // | CompoundName DOT SUPER DOT IDENTIFIER // ; -public class FieldAccess extends Expression { +public class FieldAccess extends Primary +{ // Structure public Expression expression; // Primary or SimpleReference public boolean superSign; public String identifier; // Creation - public FieldAccess(Expression expr, boolean ss, Token id) { + public FieldAccess(Expression expr, boolean ss, Token id) + { this.expression = expr; this.superSign = ss; this.identifier = id.image; @@ -23,6 +26,7 @@ public FieldAccess(Expression expr, boolean ss, Token id) { if (this.expression != null) { this.expression.parent = this; } + Entity.reportParsing("FIELD ACCESS"); } // Reporting diff --git a/src/main/java/tree/Expression/Primary/InstanceCreation.java b/src/main/java/tree/Expression/Primary/InstanceCreation.java index cf96384..a218c3a 100644 --- a/src/main/java/tree/Expression/Primary/InstanceCreation.java +++ b/src/main/java/tree/Expression/Primary/InstanceCreation.java @@ -1,5 +1,14 @@ package tree.Expression.Primary; +import tree.CompoundNameAnnotated; +import tree.Declaration.Declarations; +import tree.Entity; +import tree.Expression.ArgumentList; +import tree.Type.*; +import tree.Type.TypeArguments; + +import java.util.ArrayList; + // Primary // : ... // | ClassInstanceCreationExpression @@ -24,5 +33,38 @@ // : AnnotationSeqOpt /*AnnotationOpt*/ IDENTIFIER // | AnnotatedCompoundName DOT AnnotationSeqOpt /*AnnotationOpt*/ IDENTIFIER // ; -public class InstanceCreation extends Primary { +public class InstanceCreation extends Primary +{ + // Structure + public TypeArguments targs; +// public CompoundNameAnnotated compound; +// public TypeArguments targs2; + public Type ctorType; + public ArgumentList args; + public Declarations classBody; + + // Creation + public InstanceCreation(TypeArguments targs1, Type ctorT /*InstanceCreationTmp tmp*/, ArgumentList args, Declarations body) + { + this.targs = targs1; +// this.compound = tmp.compound; +// this.targs2 = tmp.targs; + this.ctorType = ctorT; + this.args = args; + this.classBody = body; + + Entity.reportParsing("INSTANCE CREATION"); + } + + // Reporting + public void report(int sh) + { + if ( targs != null ) targs.report(sh); +// if ( compound != null ) compound.report(sh); +// if ( targs2 != null ) targs2.report(sh); + if ( ctorType != null ) ctorType.report(sh); + if ( args != null ) args.report(sh); + if ( classBody != null ) classBody.report(sh); + } + } diff --git a/src/main/java/tree/Expression/Primary/InstanceCreationQualified.java b/src/main/java/tree/Expression/Primary/InstanceCreationQualified.java new file mode 100644 index 0000000..106c46f --- /dev/null +++ b/src/main/java/tree/Expression/Primary/InstanceCreationQualified.java @@ -0,0 +1,54 @@ +package tree.Expression.Primary; + +import tree.CompoundName; +import tree.Entity; + +// Primary +// : ... +// | ClassInstanceCreationExpression +// | ... +// +// ClassInstanceCreationExpression +// : UnqualifiedClassInstanceCreationExpression +// | CompoundName DOT UnqualifiedClassInstanceCreationExpression +// | Primary DOT UnqualifiedClassInstanceCreationExpression +// ; +public class InstanceCreationQualified extends Primary +{ + // Structure + public CompoundName cmp; + public Primary primary; + + public InstanceCreation creation; + + // Creation + public InstanceCreationQualified(CompoundName cmp, InstanceCreation creation) + { + this.cmp = cmp; + this.primary = null; + this.creation = creation; + + Entity.reportParsing("INSTANCE CREATION QUALIFIED"); + } + + public InstanceCreationQualified(Primary primary, InstanceCreation creation) + { + this.cmp = null; + this.primary = primary; + this.creation = creation; + + Entity.reportParsing("INSTANCE CREATION QUALIFIED"); + } + + // Reporting + public void report(int sh) + { + this.title("NEW: Instance Creation",sh); + if ( cmp != null ) + cmp.report(sh+Entity.shift); + else if ( primary != null ) + primary.report(sh+Entity.shift); + + creation.report(sh+Entity.shift); + } +} diff --git a/src/main/java/tree/Expression/Primary/InstanceCreationTmp.java b/src/main/java/tree/Expression/Primary/InstanceCreationTmp.java new file mode 100644 index 0000000..4076204 --- /dev/null +++ b/src/main/java/tree/Expression/Primary/InstanceCreationTmp.java @@ -0,0 +1,25 @@ +package tree.Expression.Primary; + +// Temporary class - won't appear in the tree + +import tree.*; +import tree.CompoundNameAnnotated; +import tree.Type.TypeArguments; + +// ClassOrInterfaceTypeToInstantiate +// : AnnotatedCompoundName TypeArgumentsOpt +// | AnnotatedCompoundName DIAMOND +// ; +public class InstanceCreationTmp extends Entity +{ + public CompoundNameAnnotated compound; + public TypeArguments targs; + + public InstanceCreationTmp(CompoundNameAnnotated cmp, TypeArguments targs) + { + this.compound = cmp; + this.targs = targs; + + Entity.reportParsing("INSTANCE CREATION TMP"); + } +} diff --git a/src/main/java/tree/Expression/Primary/Literal.java b/src/main/java/tree/Expression/Primary/Literal.java index 48a1553..eec48d0 100644 --- a/src/main/java/tree/Expression/Primary/Literal.java +++ b/src/main/java/tree/Expression/Primary/Literal.java @@ -2,6 +2,7 @@ import lexer.Token; import lexer.TokenCode; +import tree.Entity; // Primary // : Literal @@ -19,7 +20,8 @@ //// | TextBlock // ??? // | NULL // NullLiteral // ; -public class Literal extends Primary { +public class Literal extends Primary +{ // Structure public TokenCode code; public Object value; @@ -28,6 +30,8 @@ public class Literal extends Primary { public Literal(Token token) { this.code = token.code; this.value = token.image; //.value; + + Entity.reportParsing("LITERAL"); } // Reporting diff --git a/src/main/java/tree/Expression/Primary/MethodInvocation.java b/src/main/java/tree/Expression/Primary/MethodInvocation.java index 904e20f..c132a95 100644 --- a/src/main/java/tree/Expression/Primary/MethodInvocation.java +++ b/src/main/java/tree/Expression/Primary/MethodInvocation.java @@ -15,7 +15,8 @@ // | SUPER DOT TypeArgumentsOpt IDENTIFIER Arguments // | CompoundName DOT SUPER DOT TypeArgumentsOpt IDENTIFIER Arguments // ; -public class MethodInvocation extends Primary { +public class MethodInvocation extends Primary +{ // Structure public Expression qualifier; // SimpleReference or Primary public boolean superSign; @@ -30,7 +31,8 @@ public class MethodInvocation extends Primary { // ================================== // Creation - public MethodInvocation(Expression q, boolean ss, TypeArguments targs, Token name, ArgumentList args) { + public MethodInvocation(Expression q, boolean ss, TypeArguments targs, Token name, ArgumentList args) + { this.qualifier = q; this.superSign = ss; this.typeArguments = targs; @@ -48,10 +50,12 @@ public MethodInvocation(Expression q, boolean ss, TypeArguments targs, Token nam if (this.arguments != null) { this.arguments.parent = this; } + Entity.reportParsing("METHOD INVOCATION"); } // Reporting - public void report(int sh) { + public void report(int sh) + { String t = "METHOD INVOCATION: "; if (superSign) { t += "SUPER "; diff --git a/src/main/java/tree/Expression/Primary/Parenthesized.java b/src/main/java/tree/Expression/Primary/Parenthesized.java index c2ba516..d40cdb7 100644 --- a/src/main/java/tree/Expression/Primary/Parenthesized.java +++ b/src/main/java/tree/Expression/Primary/Parenthesized.java @@ -1,12 +1,14 @@ package tree.Expression.Primary; +import tree.Entity; import tree.Expression.Expression; // Primary // : ... // | LPAREN Expression RPAREN // | ... -public class Parenthesized extends Primary { +public class Parenthesized extends Primary +{ // Structure public Expression expression; @@ -16,6 +18,7 @@ public Parenthesized(Expression expr) { if (this.expression != null) { this.expression.parent = this; } + Entity.reportParsing("PARENTHESIZED"); } // Reporting diff --git a/src/main/java/tree/Expression/Primary/Primary.java b/src/main/java/tree/Expression/Primary/Primary.java index 10f68aa..4eff60c 100644 --- a/src/main/java/tree/Expression/Primary/Primary.java +++ b/src/main/java/tree/Expression/Primary/Primary.java @@ -16,5 +16,6 @@ // | MethodReference // | ArrayCreationExpression // ; -public class Primary extends Expression { +public class Primary extends Expression +{ } diff --git a/src/main/java/tree/Expression/Primary/This.java b/src/main/java/tree/Expression/Primary/This.java index c54c85d..9347ad7 100644 --- a/src/main/java/tree/Expression/Primary/This.java +++ b/src/main/java/tree/Expression/Primary/This.java @@ -8,16 +8,19 @@ // | THIS // | Type DOT THIS // | ... -public class This extends Primary { +public class This extends Primary +{ // Empty structure public Type type; // if non-null then "qualified this" // Creation - public This(Type t) { + public This(Type t) + { this.type = t; if (this.type != null) { this.type.parent = this; } + Entity.reportParsing("THIS"); } // Reporting diff --git a/src/main/java/tree/Expression/SimpleReference.java b/src/main/java/tree/Expression/SimpleReference.java index 6e836d5..5d258f2 100644 --- a/src/main/java/tree/Expression/SimpleReference.java +++ b/src/main/java/tree/Expression/SimpleReference.java @@ -3,16 +3,19 @@ import tree.CompoundName; import tree.Entity; -public class SimpleReference extends Expression { +public class SimpleReference extends Expression +{ // Structure public CompoundName compoundName; // Creation - public SimpleReference(CompoundName cn) { + public SimpleReference(CompoundName cn) + { this.compoundName = cn; if (cn != null) { cn.parent = this; } + Entity.reportParsing("SIMPLE REFERENCE"); } // Reporting diff --git a/src/main/java/tree/Expression/SwitchExpression.java b/src/main/java/tree/Expression/SwitchExpression.java index 583baa3..e94a689 100644 --- a/src/main/java/tree/Expression/SwitchExpression.java +++ b/src/main/java/tree/Expression/SwitchExpression.java @@ -1,17 +1,20 @@ package tree.Expression; +import tree.Entity; import tree.Statement.SwitchBlock; // SwitchExpression // : SWITCH LPAREN Expression RPAREN SwitchBlock // ; -public class SwitchExpression extends Expression { +public class SwitchExpression extends Expression +{ // Structure public Expression expression; public SwitchBlock switchBlock; // Creation - public SwitchExpression(Expression expr, SwitchBlock block) { + public SwitchExpression(Expression expr, SwitchBlock block) + { this.expression = expr; this.switchBlock = block; @@ -21,6 +24,7 @@ public SwitchExpression(Expression expr, SwitchBlock block) { if (this.switchBlock != null) { this.switchBlock.parent = this; } + Entity.reportParsing("SWITCH EXPRESSION"); } // Reporting diff --git a/src/main/java/tree/Expression/UnaryPostfix.java b/src/main/java/tree/Expression/UnaryPostfix.java index 4e0f3ba..219070a 100644 --- a/src/main/java/tree/Expression/UnaryPostfix.java +++ b/src/main/java/tree/Expression/UnaryPostfix.java @@ -4,19 +4,22 @@ import lexer.TokenCode; import tree.Entity; -public class UnaryPostfix extends Expression { +public class UnaryPostfix extends Expression +{ // Structure public TokenCode operator; public Expression operand; // Creation - public UnaryPostfix(Token token, Expression op) { + public UnaryPostfix(Token token, Expression op) + { this.operator = token.code; this.operand = op; if (this.operand != null) { this.operand.parent = this; } + Entity.reportParsing("UNARY POSTFIX " + operator.toString()); } // Reporting diff --git a/src/main/java/tree/Expression/UnaryPrefix.java b/src/main/java/tree/Expression/UnaryPrefix.java index 6582f6e..1300719 100644 --- a/src/main/java/tree/Expression/UnaryPrefix.java +++ b/src/main/java/tree/Expression/UnaryPrefix.java @@ -4,19 +4,22 @@ import lexer.TokenCode; import tree.Entity; -public class UnaryPrefix extends Expression { +public class UnaryPrefix extends Expression +{ // Structure public TokenCode operator; public Expression operand; // Creation - public UnaryPrefix(Token token, Expression op) { + public UnaryPrefix(Token token, Expression op) + { this.operator = token.code; this.operand = op; if (this.operand != null) { this.operand.parent = this; } + Entity.reportParsing("UNARY PREFIX " + operator.toString()); } // Reporting diff --git a/src/main/java/tree/Initializer.java b/src/main/java/tree/Initializer.java index c5f6334..b5427ee 100644 --- a/src/main/java/tree/Initializer.java +++ b/src/main/java/tree/Initializer.java @@ -19,7 +19,8 @@ // : Expression // | ArrayInitializer // ; -public class Initializer extends Entity { +public class Initializer extends Entity +{ // NO structure // NO creation diff --git a/src/main/java/tree/InitializerArray.java b/src/main/java/tree/InitializerArray.java index ca5dce9..91fe7d7 100644 --- a/src/main/java/tree/InitializerArray.java +++ b/src/main/java/tree/InitializerArray.java @@ -2,17 +2,20 @@ import java.util.ArrayList; -public class InitializerArray extends Initializer { +public class InitializerArray extends Initializer +{ // Structure public ArrayList initializers; // Creation - public InitializerArray(Initializer init) { + public InitializerArray(Initializer init) + { this.initializers = new ArrayList<>(); this.initializers.add(init); if (init != null) { init.parent = this; } + Entity.reportParsing("INITIALIZER ARRAY"); } public InitializerArray add(Initializer init) { @@ -24,8 +27,13 @@ public InitializerArray add(Initializer init) { } // Reporting - public void report(int sh) { - + public void report(int sh) + { + title("ARRAY INITIALIZER",sh); + for ( Initializer init: initializers ) + { + init.report(sh+Entity.shift); + } } } diff --git a/src/main/java/tree/InitializerSimple.java b/src/main/java/tree/InitializerSimple.java index 892bef2..de14390 100644 --- a/src/main/java/tree/InitializerSimple.java +++ b/src/main/java/tree/InitializerSimple.java @@ -2,16 +2,19 @@ import tree.Expression.Expression; -public class InitializerSimple extends Initializer { +public class InitializerSimple extends Initializer +{ // Structure public Expression expression; // Creation - public InitializerSimple(Expression expr) { + public InitializerSimple(Expression expr) + { this.expression = expr; if (expr != null) { expr.parent = this; } + Entity.reportParsing("INITIALIZER SIMPLE"); } // Reporting diff --git a/src/main/java/tree/Modifiers.java b/src/main/java/tree/Modifiers.java index ba39409..48be879 100644 --- a/src/main/java/tree/Modifiers.java +++ b/src/main/java/tree/Modifiers.java @@ -4,13 +4,15 @@ // : StandardModifierSeq // | AnnotationSeq StandardModifierSeq // ; -public class Modifiers extends Entity { +public class Modifiers extends Entity +{ // Structure public Annotations annotations; public StandardModifiers modifiers; // Creation - public Modifiers(Annotations anns, StandardModifiers mods) { + public Modifiers(Annotations anns, StandardModifiers mods) + { this.annotations = anns; this.modifiers = mods; @@ -20,6 +22,7 @@ public Modifiers(Annotations anns, StandardModifiers mods) { if (this.modifiers != null) { this.modifiers.parent = this; } + Entity.reportParsing("MODIFIERS"); } // Reporting diff --git a/src/main/java/tree/ResourceSpecification.java b/src/main/java/tree/ResourceSpecification.java index d05fd74..2539ab2 100644 --- a/src/main/java/tree/ResourceSpecification.java +++ b/src/main/java/tree/ResourceSpecification.java @@ -14,5 +14,6 @@ // : LocalVariableDeclaration // | FieldAccess // VariableAccess? - doesn't exist in the grammar? // ; -public class ResourceSpecification extends Entity { +public class ResourceSpecification extends Entity +{ } diff --git a/src/main/java/tree/StandardModifiers.java b/src/main/java/tree/StandardModifiers.java index fb98820..d4a795a 100644 --- a/src/main/java/tree/StandardModifiers.java +++ b/src/main/java/tree/StandardModifiers.java @@ -24,14 +24,18 @@ // | VOLATILE // | OPEN // for modules only // ; -public class StandardModifiers extends Entity { +public class StandardModifiers extends Entity +{ // Structure public ArrayList modifiers; // Creation - public StandardModifiers(Token token) { + public StandardModifiers(Token token) + { this.modifiers = new ArrayList<>(); this.modifiers.add(token.code); + + Entity.reportParsing("STANDARD MODIFIERS"); } public StandardModifiers add(Token token) { diff --git a/src/main/java/tree/Statement/Assert.java b/src/main/java/tree/Statement/Assert.java index 47a1f92..5d5e4fa 100644 --- a/src/main/java/tree/Statement/Assert.java +++ b/src/main/java/tree/Statement/Assert.java @@ -10,14 +10,16 @@ // | ASSERT Expression COLON Expression SEMICOLON // AssertStatement // | ... // ; -public class Assert extends Statement { +public class Assert extends Statement +{ // Structure - // public ArrayList labels; + // public ArrayList labels; public Expression expression; public Expression expression2; // Creation - public Assert(ArrayList ls, Expression expr, Expression expr2) { + public Assert(ArrayList ls, Expression expr, Expression expr2) + { super(ls); this.expression = expr; this.expression2 = expr2; @@ -28,6 +30,7 @@ public Assert(ArrayList ls, Expression expr, Expression expr2) { if (this.expression2 != null) { this.expression2.parent = this; } + Entity.reportParsing("ASSERT"); } // Reporting diff --git a/src/main/java/tree/Statement/Block.java b/src/main/java/tree/Statement/Block.java index 8945285..d1bdc02 100644 --- a/src/main/java/tree/Statement/Block.java +++ b/src/main/java/tree/Statement/Block.java @@ -1,5 +1,7 @@ package tree.Statement; +import tree.Entity; + import java.util.ArrayList; // Block @@ -16,19 +18,22 @@ // : ModifierSeqOpt BlockDeclaration // | Statement // ; -public class Block extends Statement { +public class Block extends Statement +{ // Structure - // public ArrayList labels; -- from the base class + // public ArrayList labels; -- from the base class public BlockStatements block; // Creation - public Block(ArrayList ls, BlockStatements block) { + public Block(ArrayList ls, BlockStatements block) + { super(ls); this.block = block; if (this.block != null) { this.block.parent = this; } + Entity.reportParsing("BLOCK"); } // Reporting diff --git a/src/main/java/tree/Statement/BlockStatement.java b/src/main/java/tree/Statement/BlockStatement.java index 78e1407..02355fe 100644 --- a/src/main/java/tree/Statement/BlockStatement.java +++ b/src/main/java/tree/Statement/BlockStatement.java @@ -1,20 +1,23 @@ package tree.Statement; import tree.Declaration.Declaration; +import tree.Entity; import tree.Expression.Expression; // BlockStatement // : ModifierSeqOpt BlockDeclaration // | Statement // ; -public class BlockStatement extends Statement { +public class BlockStatement extends Statement +{ // Structure: either a declaration OR a statement OR an expression public Declaration declaration; public Statement statement; public Expression expression; // Creation - public BlockStatement(Declaration d) { + public BlockStatement(Declaration d) + { super(null); this.declaration = d; this.statement = null; @@ -23,6 +26,7 @@ public BlockStatement(Declaration d) { if (this.declaration != null) { this.declaration.parent = this; } + Entity.reportParsing("BLOCK STATEMENT"); } public BlockStatement(Statement stmt) { @@ -34,9 +38,11 @@ public BlockStatement(Statement stmt) { if (this.statement != null) { this.statement.parent = this; } + Entity.reportParsing("BLOCK STATEMENT"); } - public BlockStatement(Expression expr) { + public BlockStatement(Expression expr) + { super(null); this.declaration = null; this.statement = null; @@ -45,6 +51,7 @@ public BlockStatement(Expression expr) { if (this.expression != null) { this.expression.parent = this; } + Entity.reportParsing("BLOCK STATEMENT"); } // Reporting diff --git a/src/main/java/tree/Statement/Break.java b/src/main/java/tree/Statement/Break.java index e6d9d4e..2853150 100644 --- a/src/main/java/tree/Statement/Break.java +++ b/src/main/java/tree/Statement/Break.java @@ -10,15 +10,19 @@ // | BREAK IDENTIFIER SEMICOLON // BreakStatement // | ... // ; -public class Break extends Statement { +public class Break extends Statement +{ // Structure - // public ArrayList labels; + // public ArrayList labels; public String label; // Creation - public Break(ArrayList ls, Token label) { + public Break(ArrayList ls, Token label) + { super(ls); this.label = label.image; + + Entity.reportParsing("BREAK"); } // Reporting diff --git a/src/main/java/tree/Statement/CatchClause.java b/src/main/java/tree/Statement/CatchClause.java index f665706..187da25 100644 --- a/src/main/java/tree/Statement/CatchClause.java +++ b/src/main/java/tree/Statement/CatchClause.java @@ -6,13 +6,15 @@ // CatchClause // : CATCH LPAREN CatchFormalParameter RPAREN Block // ; -public class CatchClause extends Entity { +public class CatchClause extends Entity +{ // Structure public CatchParameter catchParameter; public Block block; // Creation - public CatchClause(CatchParameter catchPar, Block b) { + public CatchClause(CatchParameter catchPar, Block b) + { this.catchParameter = catchPar; this.block = b; @@ -22,6 +24,7 @@ public CatchClause(CatchParameter catchPar, Block b) { if (this.block != null) { this.block.parent = this; } + Entity.reportParsing("CATCH CLAUSE"); } // Reporting diff --git a/src/main/java/tree/Statement/Continue.java b/src/main/java/tree/Statement/Continue.java index 1c02c31..0f452e8 100644 --- a/src/main/java/tree/Statement/Continue.java +++ b/src/main/java/tree/Statement/Continue.java @@ -10,15 +10,19 @@ // | CONTINUE IDENTIFIER SEMICOLON // ContinueStatement // | ... // ; -public class Continue extends Statement { +public class Continue extends Statement +{ // Structure - // public ArrayList labels; + // public ArrayList labels; public String label; // Creation - public Continue(ArrayList ls, Token label) { + public Continue(ArrayList ls, Token label) + { super(ls); this.label = label.image; + + Entity.reportParsing("CONTINUE"); } // Reporting diff --git a/src/main/java/tree/Statement/Do.java b/src/main/java/tree/Statement/Do.java index 8c54350..675cb69 100644 --- a/src/main/java/tree/Statement/Do.java +++ b/src/main/java/tree/Statement/Do.java @@ -1,6 +1,8 @@ package tree.Statement; import java.util.ArrayList; + +import tree.Entity; import tree.Expression.Expression; // SimpleStatement @@ -8,14 +10,16 @@ // | DO Statement WHILE LPAREN Expression RPAREN SEMICOLON // DoStatement // | ... // ; -public class Do extends Statement { +public class Do extends Statement +{ // Structure - // public ArrayList labels; + // public ArrayList labels; public Statement statement; public Expression condition; // Creation - public Do(ArrayList ls, Statement stmt, Expression cond) { + public Do(ArrayList ls, Statement stmt, Expression cond) + { super(ls); this.statement = stmt; this.condition = cond; @@ -26,6 +30,7 @@ public Do(ArrayList ls, Statement stmt, Expression cond) { if (this.condition != null) { this.condition.parent = this; } + Entity.reportParsing("DO"); } // Reporting diff --git a/src/main/java/tree/Statement/IfThenElse.java b/src/main/java/tree/Statement/IfThenElse.java index 2e5854f..c137d12 100644 --- a/src/main/java/tree/Statement/IfThenElse.java +++ b/src/main/java/tree/Statement/IfThenElse.java @@ -18,7 +18,8 @@ // : // empty // | ELSE Statement // ; -public class IfThenElse extends Statement { +public class IfThenElse extends Statement +{ // Structure // public ArrayList labels; public Expression condition; @@ -26,7 +27,8 @@ public class IfThenElse extends Statement { public Statement elsePart; // Creation - public IfThenElse(ArrayList ls, Expression c, Statement t, Statement e) { + public IfThenElse(ArrayList ls, Expression c, Statement t, Statement e) + { super(ls); this.condition = c; this.thenPart = t; @@ -41,6 +43,7 @@ public IfThenElse(ArrayList ls, Expression c, Statement t, Statement e) if (this.elsePart != null) { this.elsePart.parent = this; } + Entity.reportParsing("IF-THEN-ELSE"); } // Reporting diff --git a/src/main/java/tree/Statement/Return.java b/src/main/java/tree/Statement/Return.java index 52ce052..235b6bc 100644 --- a/src/main/java/tree/Statement/Return.java +++ b/src/main/java/tree/Statement/Return.java @@ -10,19 +10,22 @@ // | RETURN Expression SEMICOLON // ReturnStatement // | ... // ; -public class Return extends Statement { +public class Return extends Statement +{ // Structure - // public ArrayList labels; + // public ArrayList labels; public Expression expression; // Creation - public Return(ArrayList ls, Expression expr) { + public Return(ArrayList ls, Expression expr) + { super(ls); this.expression = expr; if (this.expression != null) { this.expression.parent = this; } + Entity.reportParsing("RETURN"); } // Reporting diff --git a/src/main/java/tree/Statement/Statement.java b/src/main/java/tree/Statement/Statement.java index bdbdc16..2ca6169 100644 --- a/src/main/java/tree/Statement/Statement.java +++ b/src/main/java/tree/Statement/Statement.java @@ -53,7 +53,8 @@ // | MethodInvocation // | ClassInstanceCreationExpression // ; -public class Statement extends Entity { +public class Statement extends Entity +{ // Structure public ArrayList labels; @@ -62,7 +63,8 @@ public Statement(ArrayList ls) { this.labels = ls; } - public Statement addLabel(Token label) { + public Statement addLabel(Token label) + { if (labels == null) { labels = new ArrayList<>(); } diff --git a/src/main/java/tree/Statement/StatementExpression.java b/src/main/java/tree/Statement/StatementExpression.java index 1da1f4b..7395fa9 100644 --- a/src/main/java/tree/Statement/StatementExpression.java +++ b/src/main/java/tree/Statement/StatementExpression.java @@ -1,6 +1,8 @@ package tree.Statement; import java.util.ArrayList; + +import tree.Entity; import tree.Expression.Expression; // StatementExpression @@ -12,18 +14,21 @@ // | MethodInvocation // | ClassInstanceCreationExpression // ; -public class StatementExpression extends Statement { +public class StatementExpression extends Statement +{ // Structure public Expression expression; // Creation - public StatementExpression(ArrayList ls, Expression expr) { + public StatementExpression(ArrayList ls, Expression expr) + { super(ls); this.expression = expr; if (this.expression != null) { this.expression.parent = this; } + Entity.reportParsing("STATEMENT EXPRESSION"); } // Reporting diff --git a/src/main/java/tree/Statement/Switch.java b/src/main/java/tree/Statement/Switch.java index 6d933c5..7849b3e 100644 --- a/src/main/java/tree/Statement/Switch.java +++ b/src/main/java/tree/Statement/Switch.java @@ -1,6 +1,8 @@ package tree.Statement; import java.util.ArrayList; + +import tree.Entity; import tree.Expression.Expression; // SimpleStatement @@ -51,9 +53,10 @@ // : AssignmentExpression // | CaseExpressionList COMMA AssignmentExpression // ; -public class Switch extends Statement { +public class Switch extends Statement +{ // Structure - // public ArrayList labels; + // public ArrayList labels; public Expression expression; // Either "rules" OR "blocks" @@ -61,7 +64,8 @@ public class Switch extends Statement { public SwitchBlocks blocks; // Creation - public Switch(ArrayList ls, Expression expr, SwitchRules rs) { + public Switch(ArrayList ls, Expression expr, SwitchRules rs) + { super(ls); this.expression = expr; this.rules = rs; @@ -73,9 +77,11 @@ public Switch(ArrayList ls, Expression expr, SwitchRules rs) { if (this.rules != null) { this.rules.parent = this; } + Entity.reportParsing("SWITCH"); } - public Switch(ArrayList ls, Expression expr, SwitchBlocks bs, int useless) { + public Switch(ArrayList ls, Expression expr, SwitchBlocks bs, int useless) + { super(ls); this.expression = expr; this.blocks = bs; @@ -86,6 +92,7 @@ public Switch(ArrayList ls, Expression expr, SwitchBlocks bs, int useles if (this.blocks != null) { this.blocks.parent = this; } + Entity.reportParsing("SWITCH"); } // Reporting diff --git a/src/main/java/tree/Statement/SwitchBlock.java b/src/main/java/tree/Statement/SwitchBlock.java index 24f1fdb..6420cf6 100644 --- a/src/main/java/tree/Statement/SwitchBlock.java +++ b/src/main/java/tree/Statement/SwitchBlock.java @@ -3,19 +3,22 @@ import java.util.ArrayList; import tree.Entity; -public class SwitchBlock extends Entity { +public class SwitchBlock extends Entity +{ // Structure public ArrayList labels; public Block block; // Creation - public SwitchBlock(ArrayList ls, Block block) { + public SwitchBlock(ArrayList ls, Block block) + { this.labels = ls; this.block = block; if (this.block != null) { this.block.parent = this; } + Entity.reportParsing("SWITCH BLOCK"); } // Reporting diff --git a/src/main/java/tree/Statement/SwitchLabel.java b/src/main/java/tree/Statement/SwitchLabel.java index fb50907..4a7d658 100644 --- a/src/main/java/tree/Statement/SwitchLabel.java +++ b/src/main/java/tree/Statement/SwitchLabel.java @@ -4,17 +4,20 @@ import tree.Entity; import tree.Expression.Expression; -public class SwitchLabel extends Entity { +public class SwitchLabel extends Entity +{ // Structure public ArrayList cases; // Creation - public SwitchLabel(Expression cs) { + public SwitchLabel(Expression cs) + { this.cases = new ArrayList<>(); this.cases.add(cs); if (cs != null) { cs.parent = this; } + Entity.reportParsing("SWITCH LABEL"); } public SwitchLabel add(Expression cs) { diff --git a/src/main/java/tree/Statement/SwitchRule.java b/src/main/java/tree/Statement/SwitchRule.java index 8ed985b..71af63b 100644 --- a/src/main/java/tree/Statement/SwitchRule.java +++ b/src/main/java/tree/Statement/SwitchRule.java @@ -28,7 +28,8 @@ // : AssignmentExpression // | CaseExpressionList COMMA AssignmentExpression // ; -public class SwitchRule extends Entity { +public class SwitchRule extends Entity +{ // ONE of the following values: public Expression expression; public Block block; @@ -37,7 +38,8 @@ public class SwitchRule extends Entity { SwitchLabel label; // Creation: three cases - public SwitchRule(SwitchLabel l, Expression expr) { + public SwitchRule(SwitchLabel l, Expression expr) + { this.label = l; this.expression = expr; this.block = null; @@ -49,6 +51,7 @@ public SwitchRule(SwitchLabel l, Expression expr) { if (this.expression != null) { this.expression.parent = this; } + Entity.reportParsing("SWITCH RULE"); } public SwitchRule(SwitchLabel l, Block block) { diff --git a/src/main/java/tree/Statement/Synchronized.java b/src/main/java/tree/Statement/Synchronized.java index da48cbd..a33877e 100644 --- a/src/main/java/tree/Statement/Synchronized.java +++ b/src/main/java/tree/Statement/Synchronized.java @@ -1,6 +1,8 @@ package tree.Statement; import java.util.ArrayList; + +import tree.Entity; import tree.Expression.Expression; // SimpleStatement @@ -8,14 +10,16 @@ // | SYNCHRONIZED LPAREN Expression RPAREN Block // SynchronizedStatement // | ... // ; -public class Synchronized extends Statement { +public class Synchronized extends Statement +{ // Structure - // public ArrayList labels; + // public ArrayList labels; public Expression expression; public Block block; // Creation - public Synchronized(ArrayList ls, Expression expr, Block block) { + public Synchronized(ArrayList ls, Expression expr, Block block) + { super(ls); this.expression = expr; this.block = block; @@ -26,6 +30,7 @@ public Synchronized(ArrayList ls, Expression expr, Block block) { if (this.block != null) { this.block.parent = this; } + Entity.reportParsing("SYNCHRONIZED"); } // Reporting diff --git a/src/main/java/tree/Statement/Throw.java b/src/main/java/tree/Statement/Throw.java index e38490d..2429dbd 100644 --- a/src/main/java/tree/Statement/Throw.java +++ b/src/main/java/tree/Statement/Throw.java @@ -9,18 +9,21 @@ // | THROW Expression SEMICOLON // ThrowStatement // | ... // ; -public class Throw extends Statement { +public class Throw extends Statement +{ // Structure - // public ArrayList labels; + // public ArrayList labels; public Expression expression; // Creation - public Throw(ArrayList ls, Expression expr) { + public Throw(ArrayList ls, Expression expr) + { super(ls); this.expression = expr; if (this.expression != null) { this.expression.parent = this; } + Entity.reportParsing("THROW"); } // Reporting diff --git a/src/main/java/tree/Statement/Try.java b/src/main/java/tree/Statement/Try.java index 8a1c4b6..845370e 100644 --- a/src/main/java/tree/Statement/Try.java +++ b/src/main/java/tree/Statement/Try.java @@ -1,6 +1,8 @@ package tree.Statement; import java.util.ArrayList; + +import tree.Entity; import tree.ResourceSpecification; // SimpleStatement @@ -14,9 +16,10 @@ // Finally // : FINALLY Block // ; -public class Try extends Statement { +public class Try extends Statement +{ // Structure - // public ArrayList labels; + // public ArrayList labels; public ResourceSpecification resSpec; public Block block; public CatchClauses catches; @@ -27,7 +30,8 @@ public Try(ArrayList ls, ResourceSpecification res, Block b, CatchClauses cs, - Block finb) { + Block finb) + { super(ls); this.resSpec = res; this.block = b; @@ -46,6 +50,7 @@ public Try(ArrayList ls, if (this.finallyBlock != null) { this.finallyBlock.parent = this; } + Entity.reportParsing("TRY"); } // Reporting diff --git a/src/main/java/tree/Statement/While.java b/src/main/java/tree/Statement/While.java index 3ee1eb8..1b96e70 100644 --- a/src/main/java/tree/Statement/While.java +++ b/src/main/java/tree/Statement/While.java @@ -7,14 +7,16 @@ // WhileStatement // : WHILE LPAREN Expression RPAREN Statement // ; -public class While extends Statement { +public class While extends Statement +{ // Structure - // public ArrayList labels; + // public ArrayList labels; public Expression condition; public Statement statement; // Creation - public While(ArrayList ls, Expression c, Statement s) { + public While(ArrayList ls, Expression c, Statement s) + { super(ls); this.condition = c; this.statement = s; @@ -25,6 +27,7 @@ public While(ArrayList ls, Expression c, Statement s) { if (this.statement != null) { this.statement.parent = this; } + Entity.reportParsing("WHILE"); } // Reporting diff --git a/src/main/java/tree/Statement/Yield.java b/src/main/java/tree/Statement/Yield.java index ca2aeb1..5e29597 100644 --- a/src/main/java/tree/Statement/Yield.java +++ b/src/main/java/tree/Statement/Yield.java @@ -9,18 +9,21 @@ // | YIELD Expression SEMICOLON // YieldStatement // | ... // ; -public class Yield extends Statement { +public class Yield extends Statement +{ // Structure - // public ArrayList labels; + // public ArrayList labels; public Expression expression; // Creation - public Yield(ArrayList ls, Expression expr) { + public Yield(ArrayList ls, Expression expr) + { super(ls); this.expression = expr; if (this.expression != null) { this.expression.parent = this; } + Entity.reportParsing("YIELD"); } // Reporting diff --git a/src/main/java/tree/Type/PrimitiveType.java b/src/main/java/tree/Type/PrimitiveType.java index c77e8da..63b2cf7 100644 --- a/src/main/java/tree/Type/PrimitiveType.java +++ b/src/main/java/tree/Type/PrimitiveType.java @@ -3,6 +3,7 @@ import lexer.Token; import lexer.TokenCode; import tree.Entity; +import tree.*; // PrimitiveType // // NumericType -- IntegralType @@ -16,7 +17,8 @@ // | DOUBLE // | BOOLEAN // ; -public class PrimitiveType extends UnannotatedType { +public class PrimitiveType extends UnannotatedType +{ // Structure public TokenCode typeCode; @@ -24,11 +26,15 @@ public class PrimitiveType extends UnannotatedType { public PrimitiveType(Token token) { super(null); this.typeCode = token.code; + // super.dimensions = dims; // Entity.unAnnotatedTypeTaken = true; - if (debug) { - System.out.println("Primitive type accepted"); - } + // if (debug) { + // System.out.println("Primitive type accepted"); + // } + String rep = "PRIMITIVE TYPE " + typeCode.toString(); +// if ( dims != null ) rep += "WITH " + super.dimensions.dimensions.size() + " DIMS"; + Entity.reportParsing(rep); } // Reporting diff --git a/src/main/java/tree/Type/Type.java b/src/main/java/tree/Type/Type.java index 8e49ccb..a140fe6 100644 --- a/src/main/java/tree/Type/Type.java +++ b/src/main/java/tree/Type/Type.java @@ -9,16 +9,19 @@ // : UnannotatedType // | AnnotationSeq UnannotatedType // ; -public class Type extends Entity { +public class Type extends Entity +{ // Structure public Annotations annotations; // Creation - public Type(Annotations annSeq) { + public Type(Annotations annSeq) + { this.annotations = annSeq; if (this.annotations != null) { this.annotations.parent = this; } + Entity.reportParsing("TYPE"); } public Type addAnnotations(Annotations anns) { diff --git a/src/main/java/tree/Type/TypeArgument.java b/src/main/java/tree/Type/TypeArgument.java index 094521b..5b0e7cd 100644 --- a/src/main/java/tree/Type/TypeArgument.java +++ b/src/main/java/tree/Type/TypeArgument.java @@ -12,7 +12,8 @@ // | AnnotationSeq QUESTION EXTENDS Type { $$ = new TypeArgument($4,2,$1); } // | AnnotationSeq QUESTION SUPER Type { $$ = new TypeArgument($4,3,$1); } // ; -public class TypeArgument extends Entity { +public class TypeArgument extends Entity +{ // Structure public Type type; public boolean signExtends; @@ -20,7 +21,8 @@ public class TypeArgument extends Entity { public Annotations annotations; // Creation - public TypeArgument(Type t, int sign, Annotations anns) { + public TypeArgument(Type t, int sign, Annotations anns) + { this.type = t; signExtends = false; signSuper = false; @@ -38,6 +40,7 @@ public TypeArgument(Type t, int sign, Annotations anns) { if (this.annotations != null) { this.annotations.parent = this; } + Entity.reportParsing("TYPE ARGUMENT"); } // Reporting diff --git a/src/main/java/tree/Type/TypeList.java b/src/main/java/tree/Type/TypeList.java index d3f9443..5f9fd26 100644 --- a/src/main/java/tree/Type/TypeList.java +++ b/src/main/java/tree/Type/TypeList.java @@ -12,12 +12,14 @@ // : Type // | ClassTypeList2 AMPERSAND Type // ; -public class TypeList extends Entity { +public class TypeList extends Entity +{ // Structure public ArrayList types; // Creation - public TypeList(Type t) { + public TypeList(Type t) + { this.types = new ArrayList<>(); this.types.add(t); if (t != null) { diff --git a/src/main/java/tree/Type/TypeName.java b/src/main/java/tree/Type/TypeName.java index 888bbf9..02746a7 100644 --- a/src/main/java/tree/Type/TypeName.java +++ b/src/main/java/tree/Type/TypeName.java @@ -2,6 +2,7 @@ import tree.CompoundName; import tree.Entity; +import tree.*; // UnannotatedType // : ... @@ -12,16 +13,19 @@ // TypeArguments // : LESS TypeArgumentList GREATER // ; -public class TypeName extends UnannotatedType { +public class TypeName extends UnannotatedType +{ // Structure public CompoundName compoundName; public TypeArguments typeArguments; // Creation - public TypeName(CompoundName cn, TypeArguments targs) { + public TypeName(CompoundName cn, TypeArguments targs) + { super(null); this.compoundName = cn; this.typeArguments = targs; + // super.dimensions = dims; if (this.compoundName != null) { this.compoundName.parent = this; @@ -30,16 +34,20 @@ public TypeName(CompoundName cn, TypeArguments targs) { this.typeArguments.parent = this; } - // Entity.unAnnotatedTypeTaken = true; - if (debug) { - System.out.println("Type name accepted"); - } + // Entity.unAnnotatedTypeTaken = true; +// if (debug) { +// System.out.println("Type name accepted"); +// } + String rep = "TYPE NAME"; + if ( super.dimensions != null && super.dimensions.dimensions.size() != 0 ) + rep += " WITH "+ super.dimensions.dimensions.size() + " DIMS"; + Entity.reportParsing(rep); } // Reporting public void report(int sh) { - doShift(sh); - System.out.print("TYPE "); + title("TYPE ",sh); + Entity.doShift(sh); compoundName.report(0); System.out.println(); if (super.annotations != null) { diff --git a/src/main/java/tree/Type/TypeParameter.java b/src/main/java/tree/Type/TypeParameter.java index 2336ce1..91d1014 100644 --- a/src/main/java/tree/Type/TypeParameter.java +++ b/src/main/java/tree/Type/TypeParameter.java @@ -13,7 +13,8 @@ // | IDENTIFIER EXTENDS AnnotationSeqOpt IDENTIFIER // | IDENTIFIER EXTENDS ClassTypeList2 // ; -public class TypeParameter extends Entity { +public class TypeParameter extends Entity +{ // Structure public Annotations annotations; public String name; @@ -23,7 +24,8 @@ public class TypeParameter extends Entity { public TypeList extendingTypes; // Creation - public TypeParameter(Annotations anns, TypeParameterTail tail) { + public TypeParameter(Annotations anns, TypeParameterTail tail) + { this.annotations = anns; this.name = tail.identifier; this.extAnnotations = tail.extAnnotations; @@ -39,6 +41,7 @@ public TypeParameter(Annotations anns, TypeParameterTail tail) { if (this.extendingTypes != null) { this.extendingTypes.parent = this; } + Entity.reportParsing("TYPE PARAMETER"); } // Reporting diff --git a/src/main/java/tree/Type/TypeParameterTail.java b/src/main/java/tree/Type/TypeParameterTail.java index f27ad72..9d92291 100644 --- a/src/main/java/tree/Type/TypeParameterTail.java +++ b/src/main/java/tree/Type/TypeParameterTail.java @@ -9,7 +9,8 @@ // | IDENTIFIER EXTENDS AnnotationSeqOpt IDENTIFIER // | IDENTIFIER EXTENDS ClassTypeList2 // ; -public class TypeParameterTail extends Entity { +public class TypeParameterTail extends Entity +{ // Structure public String identifier; @@ -19,7 +20,8 @@ public class TypeParameterTail extends Entity { public TypeList types; // Creation - public TypeParameterTail(Token id, Annotations extAnns, Token ext) { + public TypeParameterTail(Token id, Annotations extAnns, Token ext) + { this.identifier = id.image; this.extAnnotations = extAnns; this.extending = ext.image; @@ -28,6 +30,7 @@ public TypeParameterTail(Token id, Annotations extAnns, Token ext) { if (this.extAnnotations != null) { this.extAnnotations.parent = this; } + Entity.reportParsing("TYPE PARAMETER TAIL"); } public TypeParameterTail(Token id, TypeList types) { @@ -37,6 +40,7 @@ public TypeParameterTail(Token id, TypeList types) { if (this.types != null) { this.types.parent = this; } + Entity.reportParsing("TYPE PARAMETER TAIL"); } // Reporting diff --git a/src/main/java/tree/Type/UnannotatedType.java b/src/main/java/tree/Type/UnannotatedType.java index e6a215a..8642981 100644 --- a/src/main/java/tree/Type/UnannotatedType.java +++ b/src/main/java/tree/Type/UnannotatedType.java @@ -3,6 +3,7 @@ import tree.Annotations; import tree.Dim; import tree.Dims; +import tree.Entity; // UnannotatedType // : PrimitiveType @@ -10,27 +11,38 @@ // | CompoundName TypeArguments // | UnannotatedType Dim // ArrayType // ; -public class UnannotatedType extends Type { +public class UnannotatedType extends Type +{ // Structure public Dims dimensions; // Creation - public UnannotatedType(Annotations anns) { + public UnannotatedType(Annotations anns) + { super(anns); dimensions = new Dims(); - // Empty + + Entity.reportParsing("UNANNOTATED TYPE"); } - public UnannotatedType addDimension(Dim dim) { + public UnannotatedType addDimension(Dim dim) + { this.dimensions.add(dim); if (dim != null) { dim.parent = this; } + Entity.reportParsing("TYPE WITH DIMENSION"); return this; } + public void setDimensions ( Dims dims ) + { + this.dimensions = dims; + } + // Reporting - public void report(int sh) { + public void report(int sh) + { // empty } diff --git a/src/main/resources/Java_16_Grammar.y b/src/main/resources/Java_16_Grammar.y index 468691b..4d8b8b8 100644 --- a/src/main/resources/Java_16_Grammar.y +++ b/src/main/resources/Java_16_Grammar.y @@ -182,7 +182,9 @@ // Nonterminal types // ================= -%nterm CompoundName +%nterm CompoundName //CompoundNameAnnotated +%nterm AnnotatedCompoundName + %nterm Annotation %nterm AnnotationSeq AnnotationSeqOpt %nterm AnnoParameterList @@ -202,6 +204,8 @@ %nterm Dims DimsOpt %nterm Dim +//%nterm DimExpr +//%nterm DimExprs %nterm TypeArgument %nterm TypeArguments TypeArgumentList TypeArgumentsOpt @@ -236,16 +240,22 @@ %nterm ElementValue +%nterm Primary %nterm Expression ExpressionOpt Assignment AssignmentExpression ConditionalExpression - SwitchExpression PostfixExpression Primary UnaryExpression UnaryExpressionNotPlusMinus + SwitchExpression PostfixExpression UnaryExpression UnaryExpressionNotPlusMinus InstanceofExpression CastExpression LambdaExpression LeftHandSide FieldAccess ArrayAccess MethodInvocation MethodReference - ArrayCreationExpression ClassInstanceCreationExpression + ArrayCreationExpression /*%nterm ConditionalOrTail*/ ConditionalOrExpression ConditionalAndExpression InclusiveOrExpression ExclusiveOrExpression AndExpression EqualityExpression RelationalExpression ShiftExpression AdditiveExpression MultiplicativeExpression +%nterm UnqualifiedClassInstanceCreationExpression +%nterm ClassInstanceCreationExpression +//%nterm ClassOrInterfaceTypeToInstantiate +%nterm ClassOrInterfaceTypeToInstantiate + %nterm ConditionalOrTail %nterm StatementExpression @@ -278,7 +288,8 @@ %nterm VariableDeclarator %nterm VariableDeclaratorList -%nterm ArrayInitializer VariableInitializerListOpt VariableInitializerList +%nterm SimpleInitOpt ArrayInitOpt +%nterm ArrayInitializer ArrayInitializerOpt VariableInitializerListOpt VariableInitializerList %nterm VariableInitializer %nterm SwitchBlock @@ -441,12 +452,12 @@ Type ; UnannotatedType - : PrimitiveType { $$ = new PrimitiveType($1); } - // ReferenceType - | CompoundName { $$ = new TypeName($1,null); } - | CompoundName TypeArguments { $$ = new TypeName($1,$2); } - // ArrayType - | UnannotatedType Dim { $$ = $1.addDimension($2); } + : PrimitiveType { $$ = new PrimitiveType($1); } + // ReferenceType + | CompoundName { $$ = new TypeName($1,null); } + | CompoundName TypeArguments { $$ = new TypeName($1,$2); } +// // ArrayType + | UnannotatedType Dim { $$ = $1.addDimension($2); } ; //PrimitiveType @@ -684,11 +695,27 @@ VariableDeclaratorList | VariableDeclaratorList COMMA VariableDeclarator { $$ = $1.add($3); } ; +//VariableDeclarator +// : IDENTIFIER { $$ = new VariableDeclarator($1,null,null); } +// | IDENTIFIER EQUAL Expression { $$ = new VariableDeclarator($1,null,new InitializerSimple($3)); } +// | IDENTIFIER Dims { $$ = new VariableDeclarator($1,$2,null); } +// | IDENTIFIER Dims EQUAL ArrayInitializer { $$ = new VariableDeclarator($1,$2,$4); } +// ; + VariableDeclarator - : IDENTIFIER { $$ = new VariableDeclarator($1,null,null); } - | IDENTIFIER EQUAL Expression { $$ = new VariableDeclarator($1,null,new InitializerSimple($3)); } - | IDENTIFIER Dims { $$ = new VariableDeclarator($1,$2,null); } - | IDENTIFIER Dims EQUAL ArrayInitializer { $$ = new VariableDeclarator($1,$2,$4); } + : IDENTIFIER SimpleInitOpt { $$ = new VariableDeclarator($1,null,$2); } + | IDENTIFIER Dims ArrayInitOpt { $$ = new VariableDeclarator($1,$2,$3); } + ; + +SimpleInitOpt + : %empty { $$ = null; } + | EQUAL Expression { $$ = new InitializerSimple($2); } + | EQUAL ArrayInitializer { $$ = $2; } + ; + +ArrayInitOpt + : %empty { $$ = null; } + | EQUAL ArrayInitializer { $$ = $2; } ; ArrayInitializer @@ -799,9 +826,20 @@ Dims | Dims Dim { $$ = $1.add($2); } ; +// We have joined together two productions: Dim & DimExpr. +// For parsing semantically correct programs this change won't affect, +// as well as for type calculation algorithms. + +//Dim +// : AnnotationSeq LBRACKET RBRACKET { $$ = new Dim($1); } +// | LBRACKET RBRACKET { $$ = new Dim(null); } +// ; + Dim - : AnnotationSeq LBRACKET RBRACKET { $$ = new Dim($1); } - | LBRACKET RBRACKET { $$ = new Dim(null); } + : LBRACKET RBRACKET { $$ = new Dim(null,null); } + | AnnotationSeq LBRACKET RBRACKET { $$ = new Dim($1,null); } + | LBRACKET Expression RBRACKET { $$ = new Dim(null,$2); } + | AnnotationSeq LBRACKET Expression RBRACKET { $$ = new Dim($1,$3); } ; //// InterfaceDeclaration //////////////////////// @@ -917,7 +955,7 @@ BlockStatement ; LocalVariableDeclaration - : UnannotatedType VariableDeclaratorList { $$ = new TypeAndDeclarators($1,$2); } + : UnannotatedType VariableDeclaratorList { $$ = new TypeAndDeclarators($1,$2); /*$$.report(30);*/ } | VAR VariableDeclaratorList { $$ = new TypeAndDeclarators(null,$2); } ; @@ -968,13 +1006,13 @@ LabeledStatement ; StatementExpression - : Assignment { $$ = new StatementExpression(null,$1); } - | PreIncrementExpression { $$ = new StatementExpression(null,$1); } - | PreDecrementExpression { $$ = new StatementExpression(null,$1); } - | PostIncrementExpression { $$ = new StatementExpression(null,$1); } - | PostDecrementExpression { $$ = new StatementExpression(null,$1); } - | MethodInvocation { $$ = new StatementExpression(null,$1); } - | ClassInstanceCreationExpression { $$ = $1; } + : Assignment { $$ = new StatementExpression(null,$1); } + | PreIncrementExpression { $$ = new StatementExpression(null,$1); } + | PreDecrementExpression { $$ = new StatementExpression(null,$1); } + | PostIncrementExpression { $$ = new StatementExpression(null,$1); } + | PostDecrementExpression { $$ = new StatementExpression(null,$1); } + | MethodInvocation { $$ = new StatementExpression(null,$1); } + | ClassInstanceCreationExpression { $$ = new StatementExpression(null,$1); } ; IfThenElseStatement @@ -1139,7 +1177,7 @@ Primary | THIS { $$ = new This(null); } | Type DOT THIS { $$ = new This($1); } | LPAREN Expression RPAREN { $$ = new Parenthesized($2); } - | ClassInstanceCreationExpression { $$ = null; } // not implemented yet + | ClassInstanceCreationExpression { $$ = $1; } | FieldAccess { $$ = $1; } | ArrayAccess { $$ = $1; } | MethodInvocation { $$ = $1; } @@ -1147,31 +1185,42 @@ Primary | ArrayCreationExpression { $$ = $1; } // not implemented yet ; +//ArrayAccess +// : CompoundName Dim { $$ = new ArrayAccess(new SimpleReference($1),$2.expression); } +// | Primary Dim { $$ = new ArrayAccess($1,$2.expression); } +// ; + //ClassLiteral: // TypeName { [ ] } . class // NumericType { [ ] } . class // boolean { [ ] } . class // void . class + ClassInstanceCreationExpression - : UnqualifiedClassInstanceCreationExpression { $$ = null; } // not implemented yet - | CompoundName DOT UnqualifiedClassInstanceCreationExpression { $$ = null; } // not implemented yet - | Primary DOT UnqualifiedClassInstanceCreationExpression { $$ = null; } // not implemented yet + : UnqualifiedClassInstanceCreationExpression { $$ = new InstanceCreationQualified((Primary)null,$1); } + | CompoundName DOT UnqualifiedClassInstanceCreationExpression { $$ = new InstanceCreationQualified($1,$3); } + | Primary DOT UnqualifiedClassInstanceCreationExpression { $$ = new InstanceCreationQualified($1,$3); } ; UnqualifiedClassInstanceCreationExpression : NEW TypeArgumentsOpt ClassOrInterfaceTypeToInstantiate Arguments ClassBodyOpt + { $$ = new InstanceCreation($2,$3,$4,$5); } ; ClassOrInterfaceTypeToInstantiate - : AnnotatedCompoundName TypeArgumentsOpt - | AnnotatedCompoundName DIAMOND + : Type { $$ = $1; } ; -AnnotatedCompoundName - : AnnotationSeqOpt /*AnnotationOpt*/ IDENTIFIER - | AnnotatedCompoundName DOT AnnotationSeqOpt /*AnnotationOpt*/ IDENTIFIER - ; +// ClassOrInterfaceTypeToInstantiate +// : AnnotatedCompoundName TypeArgumentsOpt { $$ = new InstanceCreationTmp($1,$2); } +// | AnnotatedCompoundName DIAMOND { $$ = new InstanceCreationTmp($1,null); } +// ; +// +//AnnotatedCompoundName +// : AnnotationSeqOpt /*AnnotationOpt*/ IDENTIFIER { $$ = new CompoundNameAnnotated($1,$2.image); } +// | AnnotatedCompoundName DOT AnnotationSeqOpt /*AnnotationOpt*/ IDENTIFIER { $$ = $1.add($3,$4.image); } +// ; TypeArgumentsOpt : %empty { $$ = null; } @@ -1179,7 +1228,8 @@ TypeArgumentsOpt ; TypeArguments - : LESS TypeArgumentList GREATER { $$ = $2; } + : LESS GREATER { $$ = null; } + | LESS TypeArgumentList GREATER { $$ = $2; } ; TypeArgumentList @@ -1210,8 +1260,9 @@ FieldAccess ; ArrayAccess - : CompoundName LBRACKET Expression RBRACKET { $$ = new ArrayAccess(new SimpleReference($1),$3); } - | Primary LBRACKET Expression RBRACKET { $$ = new ArrayAccess($1,$3); } + : CompoundName Dim { $$ = new ArrayAccess(new SimpleReference($1),$2.expression); } + | Primary Dim { $$ = new ArrayAccess($1,$2.expression); } + | ArrayAccess Dim { $$ = null; /* $1.addDimension($2.expression);*/ } ; MethodInvocation @@ -1249,20 +1300,44 @@ MethodReference | Type DBL_COLON TypeArgumentsOpt NEW { $$ = null; } // not implemented yet ; -ArrayCreationExpression - : NEW Type DimExprs DimsOpt { $$ = null; } // not implemented yet - | NEW Type Dims ArrayInitializer { $$ = null; } // not implemented yet - ; +//ArrayCreationExpression +// : NEW UnannotatedType Dim { $2.addDimension($3); $$ = new ArrayCreation($2,null); } +// | NEW UnannotatedType Dim ArrayInitializer { $2.addDimension($3); $$ = new ArrayCreation($2,$4); } +// ; -DimExprs - : DimExpr - | DimExprs DimExpr +ArrayCreationExpression + : NEW PrimitiveType Dims ArrayInitializerOpt { PrimitiveType pt = new PrimitiveType($2); + pt.setDimensions($3); + $$ = new ArrayCreation(pt,$4); } + | NEW CompoundName Dims ArrayInitializerOpt { TypeName tn = new TypeName($2,null); + tn.setDimensions($3); + $$ = new ArrayCreation(tn,$4); } + | NEW CompoundName TypeArguments Dims ArrayInitializerOpt { TypeName tn = new TypeName($2,$3); + tn.setDimensions($4); + $$ = new ArrayCreation(tn,$5); } + ; + +ArrayInitializerOpt + : %empty { $$ = null; } + | ArrayInitializer { $$ = $1; } ; -DimExpr - : LBRACKET Expression RBRACKET - | AnnotationSeq LBRACKET Expression RBRACKET - ; +//ArrayCreationExpression +// : NEW NonArrayType DimExprs DimsOpt { $$ = new ArrayCreation($2,$3,$4); } +// | NEW NonArrayType Dims ArrayInitializer { $$ = new ArrayCreation($2,null,null); } // not implemented yet +// ; +// +// ===DimExp(s) productions were joined with Dim(s).=== +// +//DimExprs +// : DimExpr { $$ = new DimExprs($1); } +// | DimExprs DimExpr { $$ = $1.add($2); } +// ; +// +//DimExpr +// : LBRACKET Expression RBRACKET { $$ = new DimExpr(null,$2); } +// | AnnotationSeq LBRACKET Expression RBRACKET { $$ = new DimExpr($1,$3); } +// ; //// Expressions ////////////////////////////////////////////////// diff --git a/src/main/resources/codebase/TEST0.java b/src/main/resources/codebase/TEST0.java new file mode 100644 index 0000000..2bc3165 --- /dev/null +++ b/src/main/resources/codebase/TEST0.java @@ -0,0 +1,32 @@ +class Example +{ + double x = 12.34; + public int m1 = 5; + public T m2; + private static P1.P2.T m3; + + void message() + { + double x = 12.34; + а += 1; + static int z; + var f = 1; + var aaa = ((T)x).m; + f++; + ++f; + print("Hello",world+aaa,777*f); + var ee = f1 * ( f2 - f3)/4; + } + + public static void main(String[] args) + { + message(world/3); + message(+qqq); + // message(world); + } + + public enum D + { + West, East, South, North + } +} \ No newline at end of file diff --git a/src/main/resources/codebase/TEST1.java b/src/main/resources/codebase/TEST1.java new file mode 100644 index 0000000..122acfe --- /dev/null +++ b/src/main/resources/codebase/TEST1.java @@ -0,0 +1,33 @@ +class Example extends Object +{ + int m1; + P.T m2; + public T m3; + void message() { + int local = 1; + var x = 777; + + print("Hello"); + print(++a); + print(a+1); + print(a++); + print(1,2); + print(a,b); + print(a-1,a+1); + print(f(1)); + print(f()); + } + + public static void main(String[] args) { + if ( x > 0) x = 1; + int x = 777; + T m = 1; + T.m = 1; + int m; + x = x + 1; + x++; + ++w; + this.m3 = a + (b*c -1); + message(); + } +} \ No newline at end of file diff --git a/src/main/resources/codebase/TEST2.java b/src/main/resources/codebase/TEST2.java new file mode 100644 index 0000000..8b37e6d --- /dev/null +++ b/src/main/resources/codebase/TEST2.java @@ -0,0 +1,17 @@ +package org.polystat.j2eo.tests; + +public class Test { + boolean test() { + int x = 0; + int a, b; + int n = 5; + int m1[] = { 1, 2, 3 }; + int[] m2 = { 7, 8, 9 }; +// int m3[] = 1; + int[] m4 = 7; + Main main = new Main[10]; + Main main = new Main(1); +// new Main[]; + main.divide(4, 0); + } +} \ No newline at end of file diff --git a/src/main/resources/codebase/View.java b/src/main/resources/codebase/View.java new file mode 100644 index 0000000..8265f03 --- /dev/null +++ b/src/main/resources/codebase/View.java @@ -0,0 +1,13977 @@ + +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.view; +import android.content.ClipData; +import android.content.Context; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.Camera; +import android.graphics.Canvas; +import android.graphics.Interpolator; +import android.graphics.LinearGradient; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.PixelFormat; +import android.graphics.Point; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.Region; +import android.graphics.Shader; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.os.Parcel; +import android.os.Parcelable; +import android.os.RemoteException; +import android.os.SystemClock; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.util.FloatProperty; +import android.util.LocaleUtil; +import android.util.Log; +import android.util.Pool; +import android.util.Poolable; +import android.util.PoolableManager; +import android.util.Pools; +import android.util.Property; +import android.util.SparseArray; +import android.util.TypedValue; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityEventSource; +import android.view.accessibility.AccessibilityManager; +import android.view.accessibility.AccessibilityNodeInfo; +import android.view.accessibility.AccessibilityNodeProvider; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.view.animation.Transformation; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputConnection; +import android.view.inputmethod.InputMethodManager; +import android.widget.ScrollBarDrawable; +import static android.os.Build.VERSION_CODES.*; +import com.android.internal.R; +import com.android.internal.util.Predicate; +import com.android.internal.view.menu.MenuBuilder; +import java.lang.ref.WeakReference; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Locale; +import java.util.concurrent.CopyOnWriteArrayList; +/** + *

+ * This class represents the basic building block for user interface components. A View + * occupies a rectangular area on the screen and is responsible for drawing and + * event handling. View is the base class for widgets, which are + * used to create interactive UI components (buttons, text fields, etc.). The + * {@link android.view.ViewGroup} subclass is the base class for layouts, which + * are invisible containers that hold other Views (or other ViewGroups) and define + * their layout properties. + *

+ * + *
+ *

Developer Guides

+ *

For information about using this class to develop your application's user interface, + * read the User Interface developer guide. + *

+ * + * + *

Using Views

+ *

+ * All of the views in a window are arranged in a single tree. You can add views + * either from code or by specifying a tree of views in one or more XML layout + * files. There are many specialized subclasses of views that act as controls or + * are capable of displaying text, images, or other content. + *

+ *

+ * Once you have created a tree of views, there are typically a few types of + * common operations you may wish to perform: + *

    + *
  • Set properties: for example setting the text of a + * {@link android.widget.TextView}. The available properties and the methods + * that set them will vary among the different subclasses of views. Note that + * properties that are known at build time can be set in the XML layout + * files.
  • + *
  • Set focus: The framework will handled moving focus in + * response to user input. To force focus to a specific view, call + * {@link #requestFocus}.
  • + *
  • Set up listeners: Views allow clients to set listeners + * that will be notified when something interesting happens to the view. For + * example, all views will let you set a listener to be notified when the view + * gains or loses focus. You can register such a listener using + * {@link #setOnFocusChangeListener(android.view.View.OnFocusChangeListener)}. + * Other view subclasses offer more specialized listeners. For example, a Button + * exposes a listener to notify clients when the button is clicked.
  • + *
  • Set visibility: You can hide or show views using + * {@link #setVisibility(int)}.
  • + *
+ *

+ *

+ * Note: The Android framework is responsible for measuring, laying out and + * drawing views. You should not call methods that perform these actions on + * views yourself unless you are actually implementing a + * {@link android.view.ViewGroup}. + *

+ * + * + *

Implementing a Custom View

+ * + *

+ * To implement a custom view, you will usually begin by providing overrides for + * some of the standard methods that the framework calls on all views. You do + * not need to override all of these methods. In fact, you can start by just + * overriding {@link #onDraw(android.graphics.Canvas)}. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Category Methods Description
CreationConstructorsThere is a form of the constructor that are called when the view + * is created from code and a form that is called when the view is + * inflated from a layout file. The second form should parse and apply + * any attributes defined in the layout file. + *
{@link #onFinishInflate()}Called after a view and all of its children has been inflated + * from XML.
Layout{@link #onMeasure(int, int)}Called to determine the size requirements for this view and all + * of its children. + *
{@link #onLayout(boolean, int, int, int, int)}Called when this view should assign a size and position to all + * of its children. + *
{@link #onSizeChanged(int, int, int, int)}Called when the size of this view has changed. + *
Drawing{@link #onDraw(android.graphics.Canvas)}Called when the view should render its content. + *
Event processing{@link #onKeyDown(int, KeyEvent)}Called when a new key event occurs. + *
{@link #onKeyUp(int, KeyEvent)}Called when a key up event occurs. + *
{@link #onTrackballEvent(MotionEvent)}Called when a trackball motion event occurs. + *
{@link #onTouchEvent(MotionEvent)}Called when a touch screen motion event occurs. + *
Focus{@link #onFocusChanged(boolean, int, android.graphics.Rect)}Called when the view gains or loses focus. + *
{@link #onWindowFocusChanged(boolean)}Called when the window containing the view gains or loses focus. + *
Attaching{@link #onAttachedToWindow()}Called when the view is attached to a window. + *
{@link #onDetachedFromWindow}Called when the view is detached from its window. + *
{@link #onWindowVisibilityChanged(int)}Called when the visibility of the window containing the view + * has changed. + *
+ *

+ * + * + *

IDs

+ * Views may have an integer id associated with them. These ids are typically + * assigned in the layout XML files, and are used to find specific views within + * the view tree. A common pattern is to: + *
    + *
  • Define a Button in the layout file and assign it a unique ID. + *
    + * <Button
    + *     android:id="@+id/my_button"
    + *     android:layout_width="wrap_content"
    + *     android:layout_height="wrap_content"
    + *     android:text="@string/my_button_text"/>
    + * 
  • + *
  • From the onCreate method of an Activity, find the Button + *
    + *      Button myButton = (Button) findViewById(R.id.my_button);
    + * 
  • + *
+ *

+ * View IDs need not be unique throughout the tree, but it is good practice to + * ensure that they are at least unique within the part of the tree you are + * searching. + *

+ * + * + *

Position

+ *

+ * The geometry of a view is that of a rectangle. A view has a location, + * expressed as a pair of left and top coordinates, and + * two dimensions, expressed as a width and a height. The unit for location + * and dimensions is the pixel. + *

+ * + *

+ * It is possible to retrieve the location of a view by invoking the methods + * {@link #getLeft()} and {@link #getTop()}. The former returns the left, or X, + * coordinate of the rectangle representing the view. The latter returns the + * top, or Y, coordinate of the rectangle representing the view. These methods + * both return the location of the view relative to its parent. For instance, + * when getLeft() returns 20, that means the view is located 20 pixels to the + * right of the left edge of its direct parent. + *

+ * + *

+ * In addition, several convenience methods are offered to avoid unnecessary + * computations, namely {@link #getRight()} and {@link #getBottom()}. + * These methods return the coordinates of the right and bottom edges of the + * rectangle representing the view. For instance, calling {@link #getRight()} + * is similar to the following computation: getLeft() + getWidth() + * (see Size for more information about the width.) + *

+ * + * + *

Size, padding and margins

+ *

+ * The size of a view is expressed with a width and a height. A view actually + * possess two pairs of width and height values. + *

+ * + *

+ * The first pair is known as measured width and + * measured height. These dimensions define how big a view wants to be + * within its parent (see Layout for more details.) The + * measured dimensions can be obtained by calling {@link #getMeasuredWidth()} + * and {@link #getMeasuredHeight()}. + *

+ * + *

+ * The second pair is simply known as width and height, or + * sometimes drawing width and drawing height. These + * dimensions define the actual size of the view on screen, at drawing time and + * after layout. These values may, but do not have to, be different from the + * measured width and height. The width and height can be obtained by calling + * {@link #getWidth()} and {@link #getHeight()}. + *

+ * + *

+ * To measure its dimensions, a view takes into account its padding. The padding + * is expressed in pixels for the left, top, right and bottom parts of the view. + * Padding can be used to offset the content of the view by a specific amount of + * pixels. For instance, a left padding of 2 will push the view's content by + * 2 pixels to the right of the left edge. Padding can be set using the + * {@link #setPadding(int, int, int, int)} method and queried by calling + * {@link #getPaddingLeft()}, {@link #getPaddingTop()}, + * {@link #getPaddingRight()}, {@link #getPaddingBottom()}. + *

+ * + *

+ * Even though a view can define a padding, it does not provide any support for + * margins. However, view groups provide such a support. Refer to + * {@link android.view.ViewGroup} and + * {@link android.view.ViewGroup.MarginLayoutParams} for further information. + *

+ * + * + *

Layout

+ *

+ * Layout is a two pass process: a measure pass and a layout pass. The measuring + * pass is implemented in {@link #measure(int, int)} and is a top-down traversal + * of the view tree. Each view pushes dimension specifications down the tree + * during the recursion. At the end of the measure pass, every view has stored + * its measurements. The second pass happens in + * {@link #layout(int,int,int,int)} and is also top-down. During + * this pass each parent is responsible for positioning all of its children + * using the sizes computed in the measure pass. + *

+ * + *

+ * When a view's measure() method returns, its {@link #getMeasuredWidth()} and + * {@link #getMeasuredHeight()} values must be set, along with those for all of + * that view's descendants. A view's measured width and measured height values + * must respect the constraints imposed by the view's parents. This guarantees + * that at the end of the measure pass, all parents accept all of their + * children's measurements. A parent view may call measure() more than once on + * its children. For example, the parent may measure each child once with + * unspecified dimensions to find out how big they want to be, then call + * measure() on them again with actual numbers if the sum of all the children's + * unconstrained sizes is too big or too small. + *

+ * + *

+ * The measure pass uses two classes to communicate dimensions. The + * {@link MeasureSpec} class is used by views to tell their parents how they + * want to be measured and positioned. The base LayoutParams class just + * describes how big the view wants to be for both width and height. For each + * dimension, it can specify one of: + *

    + *
  • an exact number + *
  • MATCH_PARENT, which means the view wants to be as big as its parent + * (minus padding) + *
  • WRAP_CONTENT, which means that the view wants to be just big enough to + * enclose its content (plus padding). + *
+ * There are subclasses of LayoutParams for different subclasses of ViewGroup. + * For example, AbsoluteLayout has its own subclass of LayoutParams which adds + * an X and Y value. + *

+ * + *

+ * MeasureSpecs are used to push requirements down the tree from parent to + * child. A MeasureSpec can be in one of three modes: + *

    + *
  • UNSPECIFIED: This is used by a parent to determine the desired dimension + * of a child view. For example, a LinearLayout may call measure() on its child + * with the height set to UNSPECIFIED and a width of EXACTLY 240 to find out how + * tall the child view wants to be given a width of 240 pixels. + *
  • EXACTLY: This is used by the parent to impose an exact size on the + * child. The child must use this size, and guarantee that all of its + * descendants will fit within this size. + *
  • AT_MOST: This is used by the parent to impose a maximum size on the + * child. The child must gurantee that it and all of its descendants will fit + * within this size. + *
+ *

+ * + *

+ * To intiate a layout, call {@link #requestLayout}. This method is typically + * called by a view on itself when it believes that is can no longer fit within + * its current bounds. + *

+ * + * + *

Drawing

+ *

+ * Drawing is handled by walking the tree and rendering each view that + * intersects the invalid region. Because the tree is traversed in-order, + * this means that parents will draw before (i.e., behind) their children, with + * siblings drawn in the order they appear in the tree. + * If you set a background drawable for a View, then the View will draw it for you + * before calling back to its onDraw() method. + *

+ * + *

+ * Note that the framework will not draw views that are not in the invalid region. + *

+ * + *

+ * To force a view to draw, call {@link #invalidate()}. + *

+ * + * + *

Event Handling and Threading

+ *

+ * The basic cycle of a view is as follows: + *

    + *
  1. An event comes in and is dispatched to the appropriate view. The view + * handles the event and notifies any listeners.
  2. + *
  3. If in the course of processing the event, the view's bounds may need + * to be changed, the view will call {@link #requestLayout()}.
  4. + *
  5. Similarly, if in the course of processing the event the view's appearance + * may need to be changed, the view will call {@link #invalidate()}.
  6. + *
  7. If either {@link #requestLayout()} or {@link #invalidate()} were called, + * the framework will take care of measuring, laying out, and drawing the tree + * as appropriate.
  8. + *
+ *

+ * + *

Note: The entire view tree is single threaded. You must always be on + * the UI thread when calling any method on any view. + * If you are doing work on other threads and want to update the state of a view + * from that thread, you should use a {@link Handler}. + *

+ * + * + *

Focus Handling

+ *

+ * The framework will handle routine focus movement in response to user input. + * This includes changing the focus as views are removed or hidden, or as new + * views become available. Views indicate their willingness to take focus + * through the {@link #isFocusable} method. To change whether a view can take + * focus, call {@link #setFocusable(boolean)}. When in touch mode (see notes below) + * views indicate whether they still would like focus via {@link #isFocusableInTouchMode} + * and can change this via {@link #setFocusableInTouchMode(boolean)}. + *

+ *

+ * Focus movement is based on an algorithm which finds the nearest neighbor in a + * given direction. In rare cases, the default algorithm may not match the + * intended behavior of the developer. In these situations, you can provide + * explicit overrides by using these XML attributes in the layout file: + *

+ * nextFocusDown
+ * nextFocusLeft
+ * nextFocusRight
+ * nextFocusUp
+ * 
+ *

+ * + * + *

+ * To get a particular view to take focus, call {@link #requestFocus()}. + *

+ * + * + *

Touch Mode

+ *

+ * When a user is navigating a user interface via directional keys such as a D-pad, it is + * necessary to give focus to actionable items such as buttons so the user can see + * what will take input. If the device has touch capabilities, however, and the user + * begins interacting with the interface by touching it, it is no longer necessary to + * always highlight, or give focus to, a particular view. This motivates a mode + * for interaction named 'touch mode'. + *

+ *

+ * For a touch capable device, once the user touches the screen, the device + * will enter touch mode. From this point onward, only views for which + * {@link #isFocusableInTouchMode} is true will be focusable, such as text editing widgets. + * Other views that are touchable, like buttons, will not take focus when touched; they will + * only fire the on click listeners. + *

+ *

+ * Any time a user hits a directional key, such as a D-pad direction, the view device will + * exit touch mode, and find a view to take focus, so that the user may resume interacting + * with the user interface without touching the screen again. + *

+ *

+ * The touch mode state is maintained across {@link android.app.Activity}s. Call + * {@link #isInTouchMode} to see whether the device is currently in touch mode. + *

+ * + * + *

Scrolling

+ *

+ * The framework provides basic support for views that wish to internally + * scroll their content. This includes keeping track of the X and Y scroll + * offset as well as mechanisms for drawing scrollbars. See + * {@link #scrollBy(int, int)}, {@link #scrollTo(int, int)}, and + * {@link #awakenScrollBars()} for more details. + *

+ * + * + *

Tags

+ *

+ * Unlike IDs, tags are not used to identify views. Tags are essentially an + * extra piece of information that can be associated with a view. They are most + * often used as a convenience to store data related to views in the views + * themselves rather than by putting them in a separate structure. + *

+ * + * + *

Animation

+ *

+ * You can attach an {@link Animation} object to a view using + * {@link #setAnimation(Animation)} or + * {@link #startAnimation(Animation)}. The animation can alter the scale, + * rotation, translation and alpha of a view over time. If the animation is + * attached to a view that has children, the animation will affect the entire + * subtree rooted by that node. When an animation is started, the framework will + * take care of redrawing the appropriate views until the animation completes. + *

+ *

+ * Starting with Android 3.0, the preferred way of animating views is to use the + * {@link android.animation} package APIs. + *

+ * + * + *

Security

+ *

+ * Sometimes it is essential that an application be able to verify that an action + * is being performed with the full knowledge and consent of the user, such as + * granting a permission request, making a purchase or clicking on an advertisement. + * Unfortunately, a malicious application could try to spoof the user into + * performing these actions, unaware, by concealing the intended purpose of the view. + * As a remedy, the framework offers a touch filtering mechanism that can be used to + * improve the security of views that provide access to sensitive functionality. + *

+ * To enable touch filtering, call {@link #setFilterTouchesWhenObscured(boolean)} or set the + * android:filterTouchesWhenObscured layout attribute to true. When enabled, the framework + * will discard touches that are received whenever the view's window is obscured by + * another visible window. As a result, the view will not receive touches whenever a + * toast, dialog or other window appears above the view's window. + *

+ * For more fine-grained control over security, consider overriding the + * {@link #onFilterTouchEventForSecurity(MotionEvent)} method to implement your own + * security policy. See also {@link MotionEvent#FLAG_WINDOW_IS_OBSCURED}. + *

+ * + * @attr ref android.R.styleable#View_alpha + * @attr ref android.R.styleable#View_background + * @attr ref android.R.styleable#View_clickable + * @attr ref android.R.styleable#View_contentDescription + * @attr ref android.R.styleable#View_drawingCacheQuality + * @attr ref android.R.styleable#View_duplicateParentState + * @attr ref android.R.styleable#View_id + * @attr ref android.R.styleable#View_requiresFadingEdge + * @attr ref android.R.styleable#View_fadingEdgeLength + * @attr ref android.R.styleable#View_filterTouchesWhenObscured + * @attr ref android.R.styleable#View_fitsSystemWindows + * @attr ref android.R.styleable#View_isScrollContainer + * @attr ref android.R.styleable#View_focusable + * @attr ref android.R.styleable#View_focusableInTouchMode + * @attr ref android.R.styleable#View_hapticFeedbackEnabled + * @attr ref android.R.styleable#View_keepScreenOn + * @attr ref android.R.styleable#View_layerType + * @attr ref android.R.styleable#View_longClickable + * @attr ref android.R.styleable#View_minHeight + * @attr ref android.R.styleable#View_minWidth + * @attr ref android.R.styleable#View_nextFocusDown + * @attr ref android.R.styleable#View_nextFocusLeft + * @attr ref android.R.styleable#View_nextFocusRight + * @attr ref android.R.styleable#View_nextFocusUp + * @attr ref android.R.styleable#View_onClick + * @attr ref android.R.styleable#View_padding + * @attr ref android.R.styleable#View_paddingBottom + * @attr ref android.R.styleable#View_paddingLeft + * @attr ref android.R.styleable#View_paddingRight + * @attr ref android.R.styleable#View_paddingTop + * @attr ref android.R.styleable#View_saveEnabled + * @attr ref android.R.styleable#View_rotation + * @attr ref android.R.styleable#View_rotationX + * @attr ref android.R.styleable#View_rotationY + * @attr ref android.R.styleable#View_scaleX + * @attr ref android.R.styleable#View_scaleY + * @attr ref android.R.styleable#View_scrollX + * @attr ref android.R.styleable#View_scrollY + * @attr ref android.R.styleable#View_scrollbarSize + * @attr ref android.R.styleable#View_scrollbarStyle + * @attr ref android.R.styleable#View_scrollbars + * @attr ref android.R.styleable#View_scrollbarDefaultDelayBeforeFade + * @attr ref android.R.styleable#View_scrollbarFadeDuration + * @attr ref android.R.styleable#View_scrollbarTrackHorizontal + * @attr ref android.R.styleable#View_scrollbarThumbHorizontal + * @attr ref android.R.styleable#View_scrollbarThumbVertical + * @attr ref android.R.styleable#View_scrollbarTrackVertical + * @attr ref android.R.styleable#View_scrollbarAlwaysDrawHorizontalTrack + * @attr ref android.R.styleable#View_scrollbarAlwaysDrawVerticalTrack + * @attr ref android.R.styleable#View_soundEffectsEnabled + * @attr ref android.R.styleable#View_tag + * @attr ref android.R.styleable#View_transformPivotX + * @attr ref android.R.styleable#View_transformPivotY + * @attr ref android.R.styleable#View_translationX + * @attr ref android.R.styleable#View_translationY + * @attr ref android.R.styleable#View_visibility + * + * @see android.view.ViewGroup + */ +public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Callback, + AccessibilityEventSource { + private static final boolean DBG = false; + /** + * The logging tag used by this class with android.util.Log. + */ + protected static final String VIEW_LOG_TAG = "View"; + /** + * Used to mark a View that has no ID. + */ + public static final int NO_ID = -1; + /** + * This view does not want keystrokes. Use with TAKES_FOCUS_MASK when + * calling setFlags. + */ + private static final int NOT_FOCUSABLE = 0x00000000; + /** + * This view wants keystrokes. Use with TAKES_FOCUS_MASK when calling + * setFlags. + */ + private static final int FOCUSABLE = 0x00000001; + /** + * Mask for use with setFlags indicating bits used for focus. + */ + private static final int FOCUSABLE_MASK = 0x00000001; + /** + * This view will adjust its padding to fit sytem windows (e.g. status bar) + */ + private static final int FITS_SYSTEM_WINDOWS = 0x00000002; + /** + * This view is visible. + * Use with {@link #setVisibility} and {@code + * android:visibility}. + */ + public static final int VISIBLE = 0x00000000; + /** + * This view is invisible, but it still takes up space for layout purposes. + * Use with {@link #setVisibility} and {@code + * android:visibility}. + */ + public static final int INVISIBLE = 0x00000004; + /** + * This view is invisible, and it doesn't take any space for layout + * purposes. Use with {@link #setVisibility} and {@code + * android:visibility}. + */ + public static final int GONE = 0x00000008; + /** + * Mask for use with setFlags indicating bits used for visibility. + * {@hide} + */ + static final int VISIBILITY_MASK = 0x0000000C; + private static final int[] VISIBILITY_FLAGS = {VISIBLE, INVISIBLE, GONE}; + /** + * This view is enabled. Intrepretation varies by subclass. + * Use with ENABLED_MASK when calling setFlags. + * {@hide} + */ + static final int ENABLED = 0x00000000; + /** + * This view is disabled. Intrepretation varies by subclass. + * Use with ENABLED_MASK when calling setFlags. + * {@hide} + */ + static final int DISABLED = 0x00000020; + /** + * Mask for use with setFlags indicating bits used for indicating whether + * this view is enabled + * {@hide} + */ + static final int ENABLED_MASK = 0x00000020; + /** + * This view won't draw. {@link #onDraw(android.graphics.Canvas)} won't be + * called and further optimizations will be performed. It is okay to have + * this flag set and a background. Use with DRAW_MASK when calling setFlags. + * {@hide} + */ + static final int WILL_NOT_DRAW = 0x00000080; + /** + * Mask for use with setFlags indicating bits used for indicating whether + * this view is will draw + * {@hide} + */ + static final int DRAW_MASK = 0x00000080; + /** + *

This view doesn't show scrollbars.

+ * {@hide} + */ + static final int SCROLLBARS_NONE = 0x00000000; + /** + *

This view shows horizontal scrollbars.

+ * {@hide} + */ + static final int SCROLLBARS_HORIZONTAL = 0x00000100; + /** + *

This view shows vertical scrollbars.

+ * {@hide} + */ + static final int SCROLLBARS_VERTICAL = 0x00000200; + /** + *

Mask for use with setFlags indicating bits used for indicating which + * scrollbars are enabled.

+ * {@hide} + */ + static final int SCROLLBARS_MASK = 0x00000300; + /** + * Indicates that the view should filter touches when its window is obscured. + * Refer to the class comments for more information about this security feature. + * {@hide} + */ + static final int FILTER_TOUCHES_WHEN_OBSCURED = 0x00000400; + // note flag value 0x00000800 is now available for next flags... + /** + *

This view doesn't show fading edges.

+ * {@hide} + */ + static final int FADING_EDGE_NONE = 0x00000000; + /** + *

This view shows horizontal fading edges.

+ * {@hide} + */ + static final int FADING_EDGE_HORIZONTAL = 0x00001000; + /** + *

This view shows vertical fading edges.

+ * {@hide} + */ + static final int FADING_EDGE_VERTICAL = 0x00002000; + /** + *

Mask for use with setFlags indicating bits used for indicating which + * fading edges are enabled.

+ * {@hide} + */ + static final int FADING_EDGE_MASK = 0x00003000; + /** + *

Indicates this view can be clicked. When clickable, a View reacts + * to clicks by notifying the OnClickListener.

+ * {@hide} + */ + static final int CLICKABLE = 0x00004000; + /** + *

Indicates this view is caching its drawing into a bitmap.

+ * {@hide} + */ + static final int DRAWING_CACHE_ENABLED = 0x00008000; + /** + *

Indicates that no icicle should be saved for this view.

+ * {@hide} + */ + static final int SAVE_DISABLED = 0x000010000; + /** + *

Mask for use with setFlags indicating bits used for the saveEnabled + * property.

+ * {@hide} + */ + static final int SAVE_DISABLED_MASK = 0x000010000; + /** + *

Indicates that no drawing cache should ever be created for this view.

+ * {@hide} + */ + static final int WILL_NOT_CACHE_DRAWING = 0x000020000; + /** + *

Indicates this view can take / keep focus when int touch mode.

+ * {@hide} + */ + static final int FOCUSABLE_IN_TOUCH_MODE = 0x00040000; + /** + *

Enables low quality mode for the drawing cache.

+ */ + public static final int DRAWING_CACHE_QUALITY_LOW = 0x00080000; + /** + *

Enables high quality mode for the drawing cache.

+ */ + public static final int DRAWING_CACHE_QUALITY_HIGH = 0x00100000; + /** + *

Enables automatic quality mode for the drawing cache.

+ */ + public static final int DRAWING_CACHE_QUALITY_AUTO = 0x00000000; +// private static final int[] DRAWING_CACHE_QUALITY_FLAGS = { ///////////////////////////////////// +// DRAWING_CACHE_QUALITY_AUTO, DRAWING_CACHE_QUALITY_LOW, DRAWING_CACHE_QUALITY_HIGH +// }; + /** + *

Mask for use with setFlags indicating bits used for the cache + * quality property.

+ * {@hide} + */ + static final int DRAWING_CACHE_QUALITY_MASK = 0x00180000; + /** + *

+ * Indicates this view can be long clicked. When long clickable, a View + * reacts to long clicks by notifying the OnLongClickListener or showing a + * context menu. + *

+ * {@hide} + */ + static final int LONG_CLICKABLE = 0x00200000; + /** + *

Indicates that this view gets its drawable states from its direct parent + * and ignores its original internal states.

+ * + * @hide + */ + static final int DUPLICATE_PARENT_STATE = 0x00400000; + /** + * The scrollbar style to display the scrollbars inside the content area, + * without increasing the padding. The scrollbars will be overlaid with + * translucency on the view's content. + */ + public static final int SCROLLBARS_INSIDE_OVERLAY = 0; + /** + * The scrollbar style to display the scrollbars inside the padded area, + * increasing the padding of the view. The scrollbars will not overlap the + * content area of the view. + */ + public static final int SCROLLBARS_INSIDE_INSET = 0x01000000; + /** + * The scrollbar style to display the scrollbars at the edge of the view, + * without increasing the padding. The scrollbars will be overlaid with + * translucency. + */ + public static final int SCROLLBARS_OUTSIDE_OVERLAY = 0x02000000; + /** + * The scrollbar style to display the scrollbars at the edge of the view, + * increasing the padding of the view. The scrollbars will only overlap the + * background, if any. + */ + public static final int SCROLLBARS_OUTSIDE_INSET = 0x03000000; + /** + * Mask to check if the scrollbar style is overlay or inset. + * {@hide} + */ + static final int SCROLLBARS_INSET_MASK = 0x01000000; + /** + * Mask to check if the scrollbar style is inside or outside. + * {@hide} + */ + static final int SCROLLBARS_OUTSIDE_MASK = 0x02000000; + /** + * Mask for scrollbar style. + * {@hide} + */ + static final int SCROLLBARS_STYLE_MASK = 0x03000000; + /** + * View flag indicating that the screen should remain on while the + * window containing this view is visible to the user. This effectively + * takes care of automatically setting the WindowManager's + * {@link WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON}. + */ + public static final int KEEP_SCREEN_ON = 0x04000000; + /** + * View flag indicating whether this view should have sound effects enabled + * for events such as clicking and touching. + */ + public static final int SOUND_EFFECTS_ENABLED = 0x08000000; + /** + * View flag indicating whether this view should have haptic feedback + * enabled for events such as long presses. + */ + public static final int HAPTIC_FEEDBACK_ENABLED = 0x10000000; + /** + *

Indicates that the view hierarchy should stop saving state when + * it reaches this view. If state saving is initiated immediately at + * the view, it will be allowed. + * {@hide} + */ + static final int PARENT_SAVE_DISABLED = 0x20000000; + /** + *

Mask for use with setFlags indicating bits used for PARENT_SAVE_DISABLED.

+ * {@hide} + */ + static final int PARENT_SAVE_DISABLED_MASK = 0x20000000; + /** + * Horizontal direction of this view is from Left to Right. + * Use with {@link #setLayoutDirection}. + * {@hide} + */ + public static final int LAYOUT_DIRECTION_LTR = 0x00000000; + /** + * Horizontal direction of this view is from Right to Left. + * Use with {@link #setLayoutDirection}. + * {@hide} + */ + public static final int LAYOUT_DIRECTION_RTL = 0x40000000; + /** + * Horizontal direction of this view is inherited from its parent. + * Use with {@link #setLayoutDirection}. + * {@hide} + */ + public static final int LAYOUT_DIRECTION_INHERIT = 0x80000000; + /** + * Horizontal direction of this view is from deduced from the default language + * script for the locale. Use with {@link #setLayoutDirection}. + * {@hide} + */ + public static final int LAYOUT_DIRECTION_LOCALE = 0xC0000000; + /** + * Mask for use with setFlags indicating bits used for horizontalDirection. + * {@hide} + */ + static final int LAYOUT_DIRECTION_MASK = 0xC0000000; + /* + * Array of horizontal direction flags for mapping attribute "horizontalDirection" to correct + * flag value. + * {@hide} + */ +// private static final int[] LAYOUT_DIRECTION_FLAGS = {LAYOUT_DIRECTION_LTR, /////////////////////// +// LAYOUT_DIRECTION_RTL, LAYOUT_DIRECTION_INHERIT, LAYOUT_DIRECTION_LOCALE}; + /** + * Default horizontalDirection. + * {@hide} + */ + private static final int LAYOUT_DIRECTION_DEFAULT = LAYOUT_DIRECTION_INHERIT; + /** + * View flag indicating whether {@link #addFocusables(ArrayList, int, int)} + * should add all focusable Views regardless if they are focusable in touch mode. + */ + public static final int FOCUSABLES_ALL = 0x00000000; + /** + * View flag indicating whether {@link #addFocusables(ArrayList, int, int)} + * should add only Views focusable in touch mode. + */ + public static final int FOCUSABLES_TOUCH_MODE = 0x00000001; + /** + * Use with {@link #focusSearch(int)}. Move focus to the previous selectable + * item. + */ + public static final int FOCUS_BACKWARD = 0x00000001; + /** + * Use with {@link #focusSearch(int)}. Move focus to the next selectable + * item. + */ + public static final int FOCUS_FORWARD = 0x00000002; + /** + * Use with {@link #focusSearch(int)}. Move focus to the left. + */ + public static final int FOCUS_LEFT = 0x00000011; + /** + * Use with {@link #focusSearch(int)}. Move focus up. + */ + public static final int FOCUS_UP = 0x00000021; + /** + * Use with {@link #focusSearch(int)}. Move focus to the right. + */ + public static final int FOCUS_RIGHT = 0x00000042; + /** + * Use with {@link #focusSearch(int)}. Move focus down. + */ + public static final int FOCUS_DOWN = 0x00000082; + /** + * Bits of {@link #getMeasuredWidthAndState()} and + * {@link #getMeasuredWidthAndState()} that provide the actual measured size. + */ + public static final int MEASURED_SIZE_MASK = 0x00ffffff; + /** + * Bits of {@link #getMeasuredWidthAndState()} and + * {@link #getMeasuredWidthAndState()} that provide the additional state bits. + */ + public static final int MEASURED_STATE_MASK = 0xff000000; + /** + * Bit shift of {@link #MEASURED_STATE_MASK} to get to the height bits + * for functions that combine both width and height into a single int, + * such as {@link #getMeasuredState()} and the childState argument of + * {@link #resolveSizeAndState(int, int, int)}. + */ + public static final int MEASURED_HEIGHT_STATE_SHIFT = 16; + /** + * Bit of {@link #getMeasuredWidthAndState()} and + * {@link #getMeasuredWidthAndState()} that indicates the measured size + * is smaller that the space the view would like to have. + */ + public static final int MEASURED_STATE_TOO_SMALL = 0x01000000; + /** + * Base View state sets + */ + // Singles + /** + * Indicates the view has no states set. States are used with + * {@link android.graphics.drawable.Drawable} to change the drawing of the + * view depending on its state. + * + * @see android.graphics.drawable.Drawable + * @see #getDrawableState() + */ + protected static final int[] EMPTY_STATE_SET; + /** + * Indicates the view is enabled. States are used with + * {@link android.graphics.drawable.Drawable} to change the drawing of the + * view depending on its state. + * + * @see android.graphics.drawable.Drawable + * @see #getDrawableState() + */ + protected static final int[] ENABLED_STATE_SET; + /** + * Indicates the view is focused. States are used with + * {@link android.graphics.drawable.Drawable} to change the drawing of the + * view depending on its state. + * + * @see android.graphics.drawable.Drawable + * @see #getDrawableState() + */ + protected static final int[] FOCUSED_STATE_SET; + /** + * Indicates the view is selected. States are used with + * {@link android.graphics.drawable.Drawable} to change the drawing of the + * view depending on its state. + * + * @see android.graphics.drawable.Drawable + * @see #getDrawableState() + */ + protected static final int[] SELECTED_STATE_SET; + /** + * Indicates the view is pressed. States are used with + * {@link android.graphics.drawable.Drawable} to change the drawing of the + * view depending on its state. + * + * @see android.graphics.drawable.Drawable + * @see #getDrawableState() + * @hide + */ + protected static final int[] PRESSED_STATE_SET; + /** + * Indicates the view's window has focus. States are used with + * {@link android.graphics.drawable.Drawable} to change the drawing of the + * view depending on its state. + * + * @see android.graphics.drawable.Drawable + * @see #getDrawableState() + */ + protected static final int[] WINDOW_FOCUSED_STATE_SET; + // Doubles + /** + * Indicates the view is enabled and has the focus. + * + * @see #ENABLED_STATE_SET + * @see #FOCUSED_STATE_SET + */ + protected static final int[] ENABLED_FOCUSED_STATE_SET; + /** + * Indicates the view is enabled and selected. + * + * @see #ENABLED_STATE_SET + * @see #SELECTED_STATE_SET + */ + protected static final int[] ENABLED_SELECTED_STATE_SET; + /** + * Indicates the view is enabled and that its window has focus. + * + * @see #ENABLED_STATE_SET + * @see #WINDOW_FOCUSED_STATE_SET + */ + protected static final int[] ENABLED_WINDOW_FOCUSED_STATE_SET; + /** + * Indicates the view is focused and selected. + * + * @see #FOCUSED_STATE_SET + * @see #SELECTED_STATE_SET + */ + protected static final int[] FOCUSED_SELECTED_STATE_SET; + /** + * Indicates the view has the focus and that its window has the focus. + * + * @see #FOCUSED_STATE_SET + * @see #WINDOW_FOCUSED_STATE_SET + */ + protected static final int[] FOCUSED_WINDOW_FOCUSED_STATE_SET; + /** + * Indicates the view is selected and that its window has the focus. + * + * @see #SELECTED_STATE_SET + * @see #WINDOW_FOCUSED_STATE_SET + */ + protected static final int[] SELECTED_WINDOW_FOCUSED_STATE_SET; + // Triples + /** + * Indicates the view is enabled, focused and selected. + * + * @see #ENABLED_STATE_SET + * @see #FOCUSED_STATE_SET + * @see #SELECTED_STATE_SET + */ + protected static final int[] ENABLED_FOCUSED_SELECTED_STATE_SET; + /** + * Indicates the view is enabled, focused and its window has the focus. + * + * @see #ENABLED_STATE_SET + * @see #FOCUSED_STATE_SET + * @see #WINDOW_FOCUSED_STATE_SET + */ + protected static final int[] ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET; + /** + * Indicates the view is enabled, selected and its window has the focus. + * + * @see #ENABLED_STATE_SET + * @see #SELECTED_STATE_SET + * @see #WINDOW_FOCUSED_STATE_SET + */ + protected static final int[] ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET; + /** + * Indicates the view is focused, selected and its window has the focus. + * + * @see #FOCUSED_STATE_SET + * @see #SELECTED_STATE_SET + * @see #WINDOW_FOCUSED_STATE_SET + */ + protected static final int[] FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET; + /** + * Indicates the view is enabled, focused, selected and its window + * has the focus. + * + * @see #ENABLED_STATE_SET + * @see #FOCUSED_STATE_SET + * @see #SELECTED_STATE_SET + * @see #WINDOW_FOCUSED_STATE_SET + */ + protected static final int[] ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET; + /** + * Indicates the view is pressed and its window has the focus. + * + * @see #PRESSED_STATE_SET + * @see #WINDOW_FOCUSED_STATE_SET + */ + protected static final int[] PRESSED_WINDOW_FOCUSED_STATE_SET; + /** + * Indicates the view is pressed and selected. + * + * @see #PRESSED_STATE_SET + * @see #SELECTED_STATE_SET + */ + protected static final int[] PRESSED_SELECTED_STATE_SET; + /** + * Indicates the view is pressed, selected and its window has the focus. + * + * @see #PRESSED_STATE_SET + * @see #SELECTED_STATE_SET + * @see #WINDOW_FOCUSED_STATE_SET + */ + protected static final int[] PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET; + /** + * Indicates the view is pressed and focused. + * + * @see #PRESSED_STATE_SET + * @see #FOCUSED_STATE_SET + */ + protected static final int[] PRESSED_FOCUSED_STATE_SET; + /** + * Indicates the view is pressed, focused and its window has the focus. + * + * @see #PRESSED_STATE_SET + * @see #FOCUSED_STATE_SET + * @see #WINDOW_FOCUSED_STATE_SET + */ + protected static final int[] PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET; + /** + * Indicates the view is pressed, focused and selected. + * + * @see #PRESSED_STATE_SET + * @see #SELECTED_STATE_SET + * @see #FOCUSED_STATE_SET + */ + protected static final int[] PRESSED_FOCUSED_SELECTED_STATE_SET; + /** + * Indicates the view is pressed, focused, selected and its window has the focus. + * + * @see #PRESSED_STATE_SET + * @see #FOCUSED_STATE_SET + * @see #SELECTED_STATE_SET + * @see #WINDOW_FOCUSED_STATE_SET + */ + protected static final int[] PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET; + /** + * Indicates the view is pressed and enabled. + * + * @see #PRESSED_STATE_SET + * @see #ENABLED_STATE_SET + */ + protected static final int[] PRESSED_ENABLED_STATE_SET; + /** + * Indicates the view is pressed, enabled and its window has the focus. + * + * @see #PRESSED_STATE_SET + * @see #ENABLED_STATE_SET + * @see #WINDOW_FOCUSED_STATE_SET + */ + protected static final int[] PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET; + /** + * Indicates the view is pressed, enabled and selected. + * + * @see #PRESSED_STATE_SET + * @see #ENABLED_STATE_SET + * @see #SELECTED_STATE_SET + */ + protected static final int[] PRESSED_ENABLED_SELECTED_STATE_SET; + /** + * Indicates the view is pressed, enabled, selected and its window has the + * focus. + * + * @see #PRESSED_STATE_SET + * @see #ENABLED_STATE_SET + * @see #SELECTED_STATE_SET + * @see #WINDOW_FOCUSED_STATE_SET + */ + protected static final int[] PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET; + /** + * Indicates the view is pressed, enabled and focused. + * + * @see #PRESSED_STATE_SET + * @see #ENABLED_STATE_SET + * @see #FOCUSED_STATE_SET + */ + protected static final int[] PRESSED_ENABLED_FOCUSED_STATE_SET; + /** + * Indicates the view is pressed, enabled, focused and its window has the + * focus. + * + * @see #PRESSED_STATE_SET + * @see #ENABLED_STATE_SET + * @see #FOCUSED_STATE_SET + * @see #WINDOW_FOCUSED_STATE_SET + */ + protected static final int[] PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET; + /** + * Indicates the view is pressed, enabled, focused and selected. + * + * @see #PRESSED_STATE_SET + * @see #ENABLED_STATE_SET + * @see #SELECTED_STATE_SET + * @see #FOCUSED_STATE_SET + */ + protected static final int[] PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET; + /** + * Indicates the view is pressed, enabled, focused, selected and its window + * has the focus. + * + * @see #PRESSED_STATE_SET + * @see #ENABLED_STATE_SET + * @see #SELECTED_STATE_SET + * @see #FOCUSED_STATE_SET + * @see #WINDOW_FOCUSED_STATE_SET + */ + protected static final int[] PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET; + /** + * The order here is very important to {@link #getDrawableState()} + */ + private static final int[][] VIEW_STATE_SETS; + static final int VIEW_STATE_WINDOW_FOCUSED = 1; + static final int VIEW_STATE_SELECTED = 1 << 1; + static final int VIEW_STATE_FOCUSED = 1 << 2; + static final int VIEW_STATE_ENABLED = 1 << 3; + static final int VIEW_STATE_PRESSED = 1 << 4; + static final int VIEW_STATE_ACTIVATED = 1 << 5; + static final int VIEW_STATE_ACCELERATED = 1 << 6; + static final int VIEW_STATE_HOVERED = 1 << 7; + static final int VIEW_STATE_DRAG_CAN_ACCEPT = 1 << 8; + static final int VIEW_STATE_DRAG_HOVERED = 1 << 9; + /* /////////////////////////////////////// + static final int[] VIEW_STATE_IDS = new int[] { + R.attr.state_window_focused, VIEW_STATE_WINDOW_FOCUSED, + R.attr.state_selected, VIEW_STATE_SELECTED, + R.attr.state_focused, VIEW_STATE_FOCUSED, + R.attr.state_enabled, VIEW_STATE_ENABLED, + R.attr.state_pressed, VIEW_STATE_PRESSED, + R.attr.state_activated, VIEW_STATE_ACTIVATED, + R.attr.state_accelerated, VIEW_STATE_ACCELERATED, + R.attr.state_hovered, VIEW_STATE_HOVERED, + R.attr.state_drag_can_accept, VIEW_STATE_DRAG_CAN_ACCEPT, + R.attr.state_drag_hovered, VIEW_STATE_DRAG_HOVERED, + }; */ + static { + if ((VIEW_STATE_IDS.length/2) != R.styleable.ViewDrawableStates.length) { + throw new IllegalStateException( + "VIEW_STATE_IDs array length does not match ViewDrawableStates style array"); + } + int[] orderedIds = new int[VIEW_STATE_IDS.length]; + for (int i = 0; i < R.styleable.ViewDrawableStates.length; i++) { + int viewState = R.styleable.ViewDrawableStates[i]; + for (int j = 0; j sThreadLocal = new ThreadLocal(); + /** + * Map used to store views' tags. + */ + private SparseArray mKeyedTags; + /** + * The next available accessiiblity id. + */ + private static int sNextAccessibilityViewId; + /** + * The animation currently associated with this view. + * @hide + */ + protected Animation mCurrentAnimation = null; + /** + * Width as measured during measure pass. + * {@hide} + */ + @ViewDebug.ExportedProperty(category = "measurement") + int mMeasuredWidth; + /** + * Height as measured during measure pass. + * {@hide} + */ + @ViewDebug.ExportedProperty(category = "measurement") + int mMeasuredHeight; + /** + * Flag to indicate that this view was marked INVALIDATED, or had its display list + * invalidated, prior to the current drawing iteration. If true, the view must re-draw + * its display list. This flag, used only when hw accelerated, allows us to clear the + * flag while retaining this information until it's needed (at getDisplayList() time and + * in drawChild(), when we decide to draw a view's children's display lists into our own). + * + * {@hide} + */ + boolean mRecreateDisplayList = false; + /** + * The view's identifier. + * {@hide} + * + * @see #setId(int) + * @see #getId() + */ + @ViewDebug.ExportedProperty(resolveId = true) + int mID = NO_ID; + /** + * The stable ID of this view for accessibility purposes. + */ + int mAccessibilityViewId = NO_ID; + /** + * The view's tag. + * {@hide} + * + * @see #setTag(Object) + * @see #getTag() + */ + protected Object mTag; + // for mPrivateFlags: + /** {@hide} */ + static final int WANTS_FOCUS = 0x00000001; + /** {@hide} */ + static final int FOCUSED = 0x00000002; + /** {@hide} */ + static final int SELECTED = 0x00000004; + /** {@hide} */ + static final int IS_ROOT_NAMESPACE = 0x00000008; + /** {@hide} */ + static final int HAS_BOUNDS = 0x00000010; + /** {@hide} */ + static final int DRAWN = 0x00000020; + /** + * When this flag is set, this view is running an animation on behalf of its + * children and should therefore not cancel invalidate requests, even if they + * lie outside of this view's bounds. + * + * {@hide} + */ + static final int DRAW_ANIMATION = 0x00000040; + /** {@hide} */ + static final int SKIP_DRAW = 0x00000080; + /** {@hide} */ + static final int ONLY_DRAWS_BACKGROUND = 0x00000100; + /** {@hide} */ + static final int REQUEST_TRANSPARENT_REGIONS = 0x00000200; + /** {@hide} */ + static final int DRAWABLE_STATE_DIRTY = 0x00000400; + /** {@hide} */ + static final int MEASURED_DIMENSION_SET = 0x00000800; + /** {@hide} */ + static final int FORCE_LAYOUT = 0x00001000; + /** {@hide} */ + static final int LAYOUT_REQUIRED = 0x00002000; + private static final int PRESSED = 0x00004000; + /** {@hide} */ + static final int DRAWING_CACHE_VALID = 0x00008000; + /** + * Flag used to indicate that this view should be drawn once more (and only once + * more) after its animation has completed. + * {@hide} + */ + static final int ANIMATION_STARTED = 0x00010000; + private static final int SAVE_STATE_CALLED = 0x00020000; + /** + * Indicates that the View returned true when onSetAlpha() was called and that + * the alpha must be restored. + * {@hide} + */ + static final int ALPHA_SET = 0x00040000; + /** + * Set by {@link #setScrollContainer(boolean)}. + */ + static final int SCROLL_CONTAINER = 0x00080000; + /** + * Set by {@link #setScrollContainer(boolean)}. + */ + static final int SCROLL_CONTAINER_ADDED = 0x00100000; + /** + * View flag indicating whether this view was invalidated (fully or partially.) + * + * @hide + */ + static final int DIRTY = 0x00200000; + /** + * View flag indicating whether this view was invalidated by an opaque + * invalidate request. + * + * @hide + */ + static final int DIRTY_OPAQUE = 0x00400000; + /** + * Mask for {@link #DIRTY} and {@link #DIRTY_OPAQUE}. + * + * @hide + */ + static final int DIRTY_MASK = 0x00600000; + /** + * Indicates whether the background is opaque. + * + * @hide + */ + static final int OPAQUE_BACKGROUND = 0x00800000; + /** + * Indicates whether the scrollbars are opaque. + * + * @hide + */ + static final int OPAQUE_SCROLLBARS = 0x01000000; + /** + * Indicates whether the view is opaque. + * + * @hide + */ + static final int OPAQUE_MASK = 0x01800000; + /** + * Indicates a prepressed state; + * the short time between ACTION_DOWN and recognizing + * a 'real' press. Prepressed is used to recognize quick taps + * even when they are shorter than ViewConfiguration.getTapTimeout(). + * + * @hide + */ + private static final int PREPRESSED = 0x02000000; + /** + * Indicates whether the view is temporarily detached. + * + * @hide + */ + static final int CANCEL_NEXT_UP_EVENT = 0x04000000; + /** + * Indicates that we should awaken scroll bars once attached + * + * @hide + */ + private static final int AWAKEN_SCROLL_BARS_ON_ATTACH = 0x08000000; + /** + * Indicates that the view has received HOVER_ENTER. Cleared on HOVER_EXIT. + * @hide + */ + private static final int HOVERED = 0x10000000; + /** + * Indicates that pivotX or pivotY were explicitly set and we should not assume the center + * for transform operations + * + * @hide + */ + private static final int PIVOT_EXPLICITLY_SET = 0x20000000; + /** {@hide} */ + static final int ACTIVATED = 0x40000000; + /** + * Indicates that this view was specifically invalidated, not just dirtied because some + * child view was invalidated. The flag is used to determine when we need to recreate + * a view's display list (as opposed to just returning a reference to its existing + * display list). + * + * @hide + */ + static final int INVALIDATED = 0x80000000; + /* Masks for mPrivateFlags2 */ + /** + * Indicates that this view has reported that it can accept the current drag's content. + * Cleared when the drag operation concludes. + * @hide + */ + static final int DRAG_CAN_ACCEPT = 0x00000001; + /** + * Indicates that this view is currently directly under the drag location in a + * drag-and-drop operation involving content that it can accept. Cleared when + * the drag exits the view, or when the drag operation concludes. + * @hide + */ + static final int DRAG_HOVERED = 0x00000002; + /** + * Indicates whether the view layout direction has been resolved and drawn to the + * right-to-left direction. + * + * @hide + */ + static final int LAYOUT_DIRECTION_RESOLVED_RTL = 0x00000004; + /** + * Indicates whether the view layout direction has been resolved. + * + * @hide + */ + static final int LAYOUT_DIRECTION_RESOLVED = 0x00000008; + /* End of masks for mPrivateFlags2 */ + static final int DRAG_MASK = DRAG_CAN_ACCEPT | DRAG_HOVERED; + /** + * Always allow a user to over-scroll this view, provided it is a + * view that can scroll. + * + * @see #getOverScrollMode() + * @see #setOverScrollMode(int) + */ + public static final int OVER_SCROLL_ALWAYS = 0; + /** + * Allow a user to over-scroll this view only if the content is large + * enough to meaningfully scroll, provided it is a view that can scroll. + * + * @see #getOverScrollMode() + * @see #setOverScrollMode(int) + */ + public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1; + /** + * Never allow a user to over-scroll this view. + * + * @see #getOverScrollMode() + * @see #setOverScrollMode(int) + */ + public static final int OVER_SCROLL_NEVER = 2; + /** + * View has requested the system UI (status bar) to be visible (the default). + * + * @see #setSystemUiVisibility(int) + */ + public static final int SYSTEM_UI_FLAG_VISIBLE = 0; + /** + * View has requested the system UI to enter an unobtrusive "low profile" mode. + * + * This is for use in games, book readers, video players, or any other "immersive" application + * where the usual system chrome is deemed too distracting. + * + * In low profile mode, the status bar and/or navigation icons may dim. + * + * @see #setSystemUiVisibility(int) + */ + public static final int SYSTEM_UI_FLAG_LOW_PROFILE = 0x00000001; + /** + * View has requested that the system navigation be temporarily hidden. + * + * This is an even less obtrusive state than that called for by + * {@link #SYSTEM_UI_FLAG_LOW_PROFILE}; on devices that draw essential navigation controls + * (Home, Back, and the like) on screen, SYSTEM_UI_FLAG_HIDE_NAVIGATION will cause + * those to disappear. This is useful (in conjunction with the + * {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN FLAG_FULLSCREEN} and + * {@link android.view.WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN FLAG_LAYOUT_IN_SCREEN} + * window flags) for displaying content using every last pixel on the display. + * + * There is a limitation: because navigation controls are so important, the least user + * interaction will cause them to reappear immediately. + * + * @see #setSystemUiVisibility(int) + */ + public static final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 0x00000002; + /** + * @deprecated Use {@link #SYSTEM_UI_FLAG_LOW_PROFILE} instead. + */ + public static final int STATUS_BAR_HIDDEN = SYSTEM_UI_FLAG_LOW_PROFILE; + /** + * @deprecated Use {@link #SYSTEM_UI_FLAG_VISIBLE} instead. + */ + public static final int STATUS_BAR_VISIBLE = SYSTEM_UI_FLAG_VISIBLE; + /** + * @hide + * + * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked + * out of the public fields to keep the undefined bits out of the developer's way. + * + * Flag to make the status bar not expandable. Unless you also + * set {@link #STATUS_BAR_DISABLE_NOTIFICATION_ICONS}, new notifications will continue to show. + */ + public static final int STATUS_BAR_DISABLE_EXPAND = 0x00010000; + /** + * @hide + * + * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked + * out of the public fields to keep the undefined bits out of the developer's way. + * + * Flag to hide notification icons and scrolling ticker text. + */ + public static final int STATUS_BAR_DISABLE_NOTIFICATION_ICONS = 0x00020000; + /** + * @hide + * + * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked + * out of the public fields to keep the undefined bits out of the developer's way. + * + * Flag to disable incoming notification alerts. This will not block + * icons, but it will block sound, vibrating and other visual or aural notifications. + */ + public static final int STATUS_BAR_DISABLE_NOTIFICATION_ALERTS = 0x00040000; + /** + * @hide + * + * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked + * out of the public fields to keep the undefined bits out of the developer's way. + * + * Flag to hide only the scrolling ticker. Note that + * {@link #STATUS_BAR_DISABLE_NOTIFICATION_ICONS} implies + * {@link #STATUS_BAR_DISABLE_NOTIFICATION_TICKER}. + */ + public static final int STATUS_BAR_DISABLE_NOTIFICATION_TICKER = 0x00080000; + /** + * @hide + * + * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked + * out of the public fields to keep the undefined bits out of the developer's way. + * + * Flag to hide the center system info area. + */ + public static final int STATUS_BAR_DISABLE_SYSTEM_INFO = 0x00100000; + /** + * @hide + * + * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked + * out of the public fields to keep the undefined bits out of the developer's way. + * + * Flag to hide only the home button. Don't use this + * unless you're a special part of the system UI (i.e., setup wizard, keyguard). + */ + public static final int STATUS_BAR_DISABLE_HOME = 0x00200000; + /** + * @hide + * + * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked + * out of the public fields to keep the undefined bits out of the developer's way. + * + * Flag to hide only the back button. Don't use this + * unless you're a special part of the system UI (i.e., setup wizard, keyguard). + */ + public static final int STATUS_BAR_DISABLE_BACK = 0x00400000; + /** + * @hide + * + * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked + * out of the public fields to keep the undefined bits out of the developer's way. + * + * Flag to hide only the clock. You might use this if your activity has + * its own clock making the status bar's clock redundant. + */ + public static final int STATUS_BAR_DISABLE_CLOCK = 0x00800000; + /** + * @hide + * + * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked + * out of the public fields to keep the undefined bits out of the developer's way. + * + * Flag to hide only the recent apps button. Don't use this + * unless you're a special part of the system UI (i.e., setup wizard, keyguard). + */ + public static final int STATUS_BAR_DISABLE_RECENT = 0x01000000; + /** + * @hide + * + * NOTE: This flag may only be used in subtreeSystemUiVisibility, etc. etc. + * + * This hides HOME and RECENT and is provided for compatibility with interim implementations. + */ + @Deprecated + public static final int STATUS_BAR_DISABLE_NAVIGATION = + STATUS_BAR_DISABLE_HOME | STATUS_BAR_DISABLE_RECENT; + /** + * @hide + */ + public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x0000FFFF; + /** + * These are the system UI flags that can be cleared by events outside + * of an application. Currently this is just the ability to tap on the + * screen while hiding the navigation bar to have it return. + * @hide + */ + public static final int SYSTEM_UI_CLEARABLE_FLAGS = + SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_HIDE_NAVIGATION; + /** + * Find views that render the specified text. + * + * @see #findViewsWithText(ArrayList, CharSequence, int) + */ + public static final int FIND_VIEWS_WITH_TEXT = 0x00000001; + /** + * Find find views that contain the specified content description. + * + * @see #findViewsWithText(ArrayList, CharSequence, int) + */ + public static final int FIND_VIEWS_WITH_CONTENT_DESCRIPTION = 0x00000002; + /** + * Find views that contain {@link AccessibilityNodeProvider}. Such + * a View is a root of virtual view hierarchy and may contain the searched + * text. If this flag is set Views with providers are automatically + * added and it is a responsibility of the client to call the APIs of + * the provider to determine whether the virtual tree rooted at this View + * contains the text, i.e. getting the list of {@link AccessibilityNodeInfo}s + * represeting the virtual views with this text. + * + * @see #findViewsWithText(ArrayList, CharSequence, int) + * + * @hide + */ + public static final int FIND_VIEWS_WITH_ACCESSIBILITY_NODE_PROVIDERS = 0x00000004; + /** + * Controls the over-scroll mode for this view. + * See {@link #overScrollBy(int, int, int, int, int, int, int, int, boolean)}, + * {@link #OVER_SCROLL_ALWAYS}, {@link #OVER_SCROLL_IF_CONTENT_SCROLLS}, + * and {@link #OVER_SCROLL_NEVER}. + */ + private int mOverScrollMode; + /** + * The parent this view is attached to. + * {@hide} + * + * @see #getParent() + */ + protected ViewParent mParent; + /** + * {@hide} + */ + AttachInfo mAttachInfo; + /** + * {@hide} + */ + @ViewDebug.ExportedProperty(flagMapping = { + @ViewDebug.FlagToString(mask = FORCE_LAYOUT, equals = FORCE_LAYOUT, + name = "FORCE_LAYOUT"), + @ViewDebug.FlagToString(mask = LAYOUT_REQUIRED, equals = LAYOUT_REQUIRED, + name = "LAYOUT_REQUIRED"), + @ViewDebug.FlagToString(mask = DRAWING_CACHE_VALID, equals = DRAWING_CACHE_VALID, + name = "DRAWING_CACHE_INVALID", outputIf = false), + @ViewDebug.FlagToString(mask = DRAWN, equals = DRAWN, name = "DRAWN", outputIf = true), + @ViewDebug.FlagToString(mask = DRAWN, equals = DRAWN, name = "NOT_DRAWN", outputIf = false), + @ViewDebug.FlagToString(mask = DIRTY_MASK, equals = DIRTY_OPAQUE, name = "DIRTY_OPAQUE"), + @ViewDebug.FlagToString(mask = DIRTY_MASK, equals = DIRTY, name = "DIRTY") + }) + int mPrivateFlags; + int mPrivateFlags2; + /** + * This view's request for the visibility of the status bar. + * @hide + */ + @ViewDebug.ExportedProperty(flagMapping = { + @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_LOW_PROFILE, + equals = SYSTEM_UI_FLAG_LOW_PROFILE, + name = "SYSTEM_UI_FLAG_LOW_PROFILE", outputIf = true), + @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_HIDE_NAVIGATION, + equals = SYSTEM_UI_FLAG_HIDE_NAVIGATION, + name = "SYSTEM_UI_FLAG_HIDE_NAVIGATION", outputIf = true), + @ViewDebug.FlagToString(mask = PUBLIC_STATUS_BAR_VISIBILITY_MASK, + equals = SYSTEM_UI_FLAG_VISIBLE, + name = "SYSTEM_UI_FLAG_VISIBLE", outputIf = true) + }) + int mSystemUiVisibility; + /** + * Count of how many windows this view has been attached to. + */ + int mWindowAttachCount; + /** + * The layout parameters associated with this view and used by the parent + * {@link android.view.ViewGroup} to determine how this view should be + * laid out. + * {@hide} + */ + protected ViewGroup.LayoutParams mLayoutParams; + /** + * The view flags hold various views states. + * {@hide} + */ + @ViewDebug.ExportedProperty + int mViewFlags; + static class TransformationInfo { + /** + * The transform matrix for the View. This transform is calculated internally + * based on the rotation, scaleX, and scaleY properties. The identity matrix + * is used by default. Do *not* use this variable directly; instead call + * getMatrix(), which will automatically recalculate the matrix if necessary + * to get the correct matrix based on the latest rotation and scale properties. + */ + private final Matrix mMatrix = new Matrix(); + /** + * The transform matrix for the View. This transform is calculated internally + * based on the rotation, scaleX, and scaleY properties. The identity matrix + * is used by default. Do *not* use this variable directly; instead call + * getInverseMatrix(), which will automatically recalculate the matrix if necessary + * to get the correct matrix based on the latest rotation and scale properties. + */ + private Matrix mInverseMatrix; + /** + * An internal variable that tracks whether we need to recalculate the + * transform matrix, based on whether the rotation or scaleX/Y properties + * have changed since the matrix was last calculated. + */ + boolean mMatrixDirty = false; + /** + * An internal variable that tracks whether we need to recalculate the + * transform matrix, based on whether the rotation or scaleX/Y properties + * have changed since the matrix was last calculated. + */ + private boolean mInverseMatrixDirty = true; + /** + * A variable that tracks whether we need to recalculate the + * transform matrix, based on whether the rotation or scaleX/Y properties + * have changed since the matrix was last calculated. This variable + * is only valid after a call to updateMatrix() or to a function that + * calls it such as getMatrix(), hasIdentityMatrix() and getInverseMatrix(). + */ + private boolean mMatrixIsIdentity = true; + /** + * The Camera object is used to compute a 3D matrix when rotationX or rotationY are set. + */ + private Camera mCamera = null; + /** + * This matrix is used when computing the matrix for 3D rotations. + */ + private Matrix matrix3D = null; + /** + * These prev values are used to recalculate a centered pivot point when necessary. The + * pivot point is only used in matrix operations (when rotation, scale, or translation are + * set), so thes values are only used then as well. + */ + private int mPrevWidth = -1; + private int mPrevHeight = -1; + + /** + * The degrees rotation around the vertical axis through the pivot point. + */ + @ViewDebug.ExportedProperty + float mRotationY = 0f; + /** + * The degrees rotation around the horizontal axis through the pivot point. + */ + @ViewDebug.ExportedProperty + float mRotationX = 0f; + /** + * The degrees rotation around the pivot point. + */ + @ViewDebug.ExportedProperty + float mRotation = 0f; + /** + * The amount of translation of the object away from its left property (post-layout). + */ + @ViewDebug.ExportedProperty + float mTranslationX = 0f; + /** + * The amount of translation of the object away from its top property (post-layout). + */ + @ViewDebug.ExportedProperty + float mTranslationY = 0f; + /** + * The amount of scale in the x direction around the pivot point. A + * value of 1 means no scaling is applied. + */ + @ViewDebug.ExportedProperty + float mScaleX = 1f; + /** + * The amount of scale in the y direction around the pivot point. A + * value of 1 means no scaling is applied. + */ + @ViewDebug.ExportedProperty + float mScaleY = 1f; + /** + * The x location of the point around which the view is rotated and scaled. + */ + @ViewDebug.ExportedProperty + float mPivotX = 0f; + /** + * The y location of the point around which the view is rotated and scaled. + */ + @ViewDebug.ExportedProperty + float mPivotY = 0f; + /** + * The opacity of the View. This is a value from 0 to 1, where 0 means + * completely transparent and 1 means completely opaque. + */ + @ViewDebug.ExportedProperty + float mAlpha = 1f; + } + TransformationInfo mTransformationInfo; + private boolean mLastIsOpaque; + /** + * Convenience value to check for float values that are close enough to zero to be considered + * zero. + */ + private static final float NONZERO_EPSILON = .001f; + /** + * The distance in pixels from the left edge of this view's parent + * to the left edge of this view. + * {@hide} + */ + @ViewDebug.ExportedProperty(category = "layout") + protected int mLeft; + /** + * The distance in pixels from the left edge of this view's parent + * to the right edge of this view. + * {@hide} + */ + @ViewDebug.ExportedProperty(category = "layout") + protected int mRight; + /** + * The distance in pixels from the top edge of this view's parent + * to the top edge of this view. + * {@hide} + */ + @ViewDebug.ExportedProperty(category = "layout") + protected int mTop; + /** + * The distance in pixels from the top edge of this view's parent + * to the bottom edge of this view. + * {@hide} + */ + @ViewDebug.ExportedProperty(category = "layout") + protected int mBottom; + /** + * The offset, in pixels, by which the content of this view is scrolled + * horizontally. + * {@hide} + */ + @ViewDebug.ExportedProperty(category = "scrolling") + protected int mScrollX; + /** + * The offset, in pixels, by which the content of this view is scrolled + * vertically. + * {@hide} + */ + @ViewDebug.ExportedProperty(category = "scrolling") + protected int mScrollY; + /** + * The left padding in pixels, that is the distance in pixels between the + * left edge of this view and the left edge of its content. + * {@hide} + */ + @ViewDebug.ExportedProperty(category = "padding") + protected int mPaddingLeft; + /** + * The right padding in pixels, that is the distance in pixels between the + * right edge of this view and the right edge of its content. + * {@hide} + */ + @ViewDebug.ExportedProperty(category = "padding") + protected int mPaddingRight; + /** + * The top padding in pixels, that is the distance in pixels between the + * top edge of this view and the top edge of its content. + * {@hide} + */ + @ViewDebug.ExportedProperty(category = "padding") + protected int mPaddingTop; + /** + * The bottom padding in pixels, that is the distance in pixels between the + * bottom edge of this view and the bottom edge of its content. + * {@hide} + */ + @ViewDebug.ExportedProperty(category = "padding") + protected int mPaddingBottom; + /** + * Briefly describes the view and is primarily used for accessibility support. + */ + private CharSequence mContentDescription; + /** + * Cache the paddingRight set by the user to append to the scrollbar's size. + * + * @hide + */ + @ViewDebug.ExportedProperty(category = "padding") + protected int mUserPaddingRight; + /** + * Cache the paddingBottom set by the user to append to the scrollbar's size. + * + * @hide + */ + @ViewDebug.ExportedProperty(category = "padding") + protected int mUserPaddingBottom; + /** + * Cache the paddingLeft set by the user to append to the scrollbar's size. + * + * @hide + */ + @ViewDebug.ExportedProperty(category = "padding") + protected int mUserPaddingLeft; + /** + * Cache if the user padding is relative. + * + */ + @ViewDebug.ExportedProperty(category = "padding") + boolean mUserPaddingRelative; + /** + * Cache the paddingStart set by the user to append to the scrollbar's size. + * + */ + @ViewDebug.ExportedProperty(category = "padding") + int mUserPaddingStart; + /** + * Cache the paddingEnd set by the user to append to the scrollbar's size. + * + */ + @ViewDebug.ExportedProperty(category = "padding") + int mUserPaddingEnd; + /** + * @hide + */ + int mOldWidthMeasureSpec = Integer.MIN_VALUE; + /** + * @hide + */ + int mOldHeightMeasureSpec = Integer.MIN_VALUE; + private Drawable mBGDrawable; + private int mBackgroundResource; + private boolean mBackgroundSizeChanged; + static class ListenerInfo { + /** + * Listener used to dispatch focus change events. + * This field should be made private, so it is hidden from the SDK. + * {@hide} + */ + protected OnFocusChangeListener mOnFocusChangeListener; + /** + * Listeners for layout change events. + */ + private ArrayList mOnLayoutChangeListeners; + /** + * Listeners for attach events. + */ + private CopyOnWriteArrayList mOnAttachStateChangeListeners; + /** + * Listener used to dispatch click events. + * This field should be made private, so it is hidden from the SDK. + * {@hide} + */ + public OnClickListener mOnClickListener; + /** + * Listener used to dispatch long click events. + * This field should be made private, so it is hidden from the SDK. + * {@hide} + */ + protected OnLongClickListener mOnLongClickListener; + /** + * Listener used to build the context menu. + * This field should be made private, so it is hidden from the SDK. + * {@hide} + */ + protected OnCreateContextMenuListener mOnCreateContextMenuListener; + private OnKeyListener mOnKeyListener; + private OnTouchListener mOnTouchListener; + private OnHoverListener mOnHoverListener; + private OnGenericMotionListener mOnGenericMotionListener; + private OnDragListener mOnDragListener; + private OnSystemUiVisibilityChangeListener mOnSystemUiVisibilityChangeListener; + } + ListenerInfo mListenerInfo; + /** + * The application environment this view lives in. + * This field should be made private, so it is hidden from the SDK. + * {@hide} + */ + protected Context mContext; + private final Resources mResources; + private ScrollabilityCache mScrollCache; + private int[] mDrawableState = null; + /** + * Set to true when drawing cache is enabled and cannot be created. + * + * @hide + */ + public boolean mCachingFailed; + private Bitmap mDrawingCache; + private Bitmap mUnscaledDrawingCache; + private HardwareLayer mHardwareLayer; + DisplayList mDisplayList; + /** + * When this view has focus and the next focus is {@link #FOCUS_LEFT}, + * the user may specify which view to go to next. + */ + private int mNextFocusLeftId = View.NO_ID; + /** + * When this view has focus and the next focus is {@link #FOCUS_RIGHT}, + * the user may specify which view to go to next. + */ + private int mNextFocusRightId = View.NO_ID; + /** + * When this view has focus and the next focus is {@link #FOCUS_UP}, + * the user may specify which view to go to next. + */ + private int mNextFocusUpId = View.NO_ID; + /** + * When this view has focus and the next focus is {@link #FOCUS_DOWN}, + * the user may specify which view to go to next. + */ + private int mNextFocusDownId = View.NO_ID; + /** + * When this view has focus and the next focus is {@link #FOCUS_FORWARD}, + * the user may specify which view to go to next. + */ + int mNextFocusForwardId = View.NO_ID; + private CheckForLongPress mPendingCheckForLongPress; + private CheckForTap mPendingCheckForTap = null; + private PerformClick mPerformClick; + private SendViewScrolledAccessibilityEvent mSendViewScrolledAccessibilityEvent; + private UnsetPressedState mUnsetPressedState; + /** + * Whether the long press's action has been invoked. The tap's action is invoked on the + * up event while a long press is invoked as soon as the long press duration is reached, so + * a long press could be performed before the tap is checked, in which case the tap's action + * should not be invoked. + */ + private boolean mHasPerformedLongPress; + /** + * The minimum height of the view. We'll try our best to have the height + * of this view to at least this amount. + */ + @ViewDebug.ExportedProperty(category = "measurement") + private int mMinHeight; + /** + * The minimum width of the view. We'll try our best to have the width + * of this view to at least this amount. + */ + @ViewDebug.ExportedProperty(category = "measurement") + private int mMinWidth; + /** + * The delegate to handle touch events that are physically in this view + * but should be handled by another view. + */ + private TouchDelegate mTouchDelegate = null; + /** + * Solid color to use as a background when creating the drawing cache. Enables + * the cache to use 16 bit bitmaps instead of 32 bit. + */ + private int mDrawingCacheBackgroundColor = 0; + /** + * Special tree observer used when mAttachInfo is null. + */ + private ViewTreeObserver mFloatingTreeObserver; + /** + * Cache the touch slop from the context that created the view. + */ + private int mTouchSlop; + /** + * Object that handles automatic animation of view properties. + */ + private ViewPropertyAnimator mAnimator = null; + /** + * Flag indicating that a drag can cross window boundaries. When + * {@link #startDrag(ClipData, DragShadowBuilder, Object, int)} is called + * with this flag set, all visible applications will be able to participate + * in the drag operation and receive the dragged content. + * + * @hide + */ + public static final int DRAG_FLAG_GLOBAL = 1; + /** + * Vertical scroll factor cached by {@link #getVerticalScrollFactor}. + */ + private float mVerticalScrollFactor; + /** + * Position of the vertical scroll bar. + */ + private int mVerticalScrollbarPosition; + /** + * Position the scroll bar at the default position as determined by the system. + */ + public static final int SCROLLBAR_POSITION_DEFAULT = 0; + /** + * Position the scroll bar along the left edge. + */ + public static final int SCROLLBAR_POSITION_LEFT = 1; + /** + * Position the scroll bar along the right edge. + */ + public static final int SCROLLBAR_POSITION_RIGHT = 2; + /** + * Indicates that the view does not have a layer. + * + * @see #getLayerType() + * @see #setLayerType(int, android.graphics.Paint) + * @see #LAYER_TYPE_SOFTWARE + * @see #LAYER_TYPE_HARDWARE + */ + public static final int LAYER_TYPE_NONE = 0; + /** + *

Indicates that the view has a software layer. A software layer is backed + * by a bitmap and causes the view to be rendered using Android's software + * rendering pipeline, even if hardware acceleration is enabled.

+ * + *

Software layers have various usages:

+ *

When the application is not using hardware acceleration, a software layer + * is useful to apply a specific color filter and/or blending mode and/or + * translucency to a view and all its children.

+ *

When the application is using hardware acceleration, a software layer + * is useful to render drawing primitives not supported by the hardware + * accelerated pipeline. It can also be used to cache a complex view tree + * into a texture and reduce the complexity of drawing operations. For instance, + * when animating a complex view tree with a translation, a software layer can + * be used to render the view tree only once.

+ *

Software layers should be avoided when the affected view tree updates + * often. Every update will require to re-render the software layer, which can + * potentially be slow (particularly when hardware acceleration is turned on + * since the layer will have to be uploaded into a hardware texture after every + * update.)

+ * + * @see #getLayerType() + * @see #setLayerType(int, android.graphics.Paint) + * @see #LAYER_TYPE_NONE + * @see #LAYER_TYPE_HARDWARE + */ + public static final int LAYER_TYPE_SOFTWARE = 1; + /** + *

Indicates that the view has a hardware layer. A hardware layer is backed + * by a hardware specific texture (generally Frame Buffer Objects or FBO on + * OpenGL hardware) and causes the view to be rendered using Android's hardware + * rendering pipeline, but only if hardware acceleration is turned on for the + * view hierarchy. When hardware acceleration is turned off, hardware layers + * behave exactly as {@link #LAYER_TYPE_SOFTWARE software layers}.

+ * + *

A hardware layer is useful to apply a specific color filter and/or + * blending mode and/or translucency to a view and all its children.

+ *

A hardware layer can be used to cache a complex view tree into a + * texture and reduce the complexity of drawing operations. For instance, + * when animating a complex view tree with a translation, a hardware layer can + * be used to render the view tree only once.

+ *

A hardware layer can also be used to increase the rendering quality when + * rotation transformations are applied on a view. It can also be used to + * prevent potential clipping issues when applying 3D transforms on a view.

+ * + * @see #getLayerType() + * @see #setLayerType(int, android.graphics.Paint) + * @see #LAYER_TYPE_NONE + * @see #LAYER_TYPE_SOFTWARE + */ + public static final int LAYER_TYPE_HARDWARE = 2; + @ViewDebug.ExportedProperty(category = "drawing", mapping = { + @ViewDebug.IntToString(from = LAYER_TYPE_NONE, to = "NONE"), + @ViewDebug.IntToString(from = LAYER_TYPE_SOFTWARE, to = "SOFTWARE"), + @ViewDebug.IntToString(from = LAYER_TYPE_HARDWARE, to = "HARDWARE") + }) + int mLayerType = LAYER_TYPE_NONE; + Paint mLayerPaint; + Rect mLocalDirtyRect; + /** + * Set to true when the view is sending hover accessibility events because it + * is the innermost hovered view. + */ + private boolean mSendingHoverAccessibilityEvents; + /** + * Delegate for injecting accessiblity functionality. + */ + AccessibilityDelegate mAccessibilityDelegate; + /** + * Text direction is inherited thru {@link ViewGroup} + */ + public static final int TEXT_DIRECTION_INHERIT = 0; + /** + * Text direction is using "first strong algorithm". The first strong directional character + * determines the paragraph direction. If there is no strong directional character, the + * paragraph direction is the view's resolved layout direction. + * + */ + public static final int TEXT_DIRECTION_FIRST_STRONG = 1; + /** + * Text direction is using "any-RTL" algorithm. The paragraph direction is RTL if it contains + * any strong RTL character, otherwise it is LTR if it contains any strong LTR characters. + * If there are neither, the paragraph direction is the view's resolved layout direction. + * + */ + public static final int TEXT_DIRECTION_ANY_RTL = 2; + /** + * Text direction is forced to LTR. + * + */ + public static final int TEXT_DIRECTION_LTR = 3; + /** + * Text direction is forced to RTL. + * + */ + public static final int TEXT_DIRECTION_RTL = 4; + /** + * Text direction is coming from the system Locale. + * + */ + public static final int TEXT_DIRECTION_LOCALE = 5; + /** + * Default text direction is inherited + * + */ + protected static int DEFAULT_TEXT_DIRECTION = TEXT_DIRECTION_INHERIT; + /** + * The text direction that has been defined by {@link #setTextDirection(int)}. + * + */ + @ViewDebug.ExportedProperty(category = "text", mapping = { + @ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"), + @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG, to = "FIRST_STRONG"), + @ViewDebug.IntToString(from = TEXT_DIRECTION_ANY_RTL, to = "ANY_RTL"), + @ViewDebug.IntToString(from = TEXT_DIRECTION_LTR, to = "LTR"), + @ViewDebug.IntToString(from = TEXT_DIRECTION_RTL, to = "RTL"), + @ViewDebug.IntToString(from = TEXT_DIRECTION_LOCALE, to = "LOCALE") + }) + private int mTextDirection = DEFAULT_TEXT_DIRECTION; + /** + * The resolved text direction. This needs resolution if the value is + * TEXT_DIRECTION_INHERIT. The resolution matches mTextDirection if it is + * not TEXT_DIRECTION_INHERIT, otherwise resolution proceeds up the parent + * chain of the view. + * + */ + @ViewDebug.ExportedProperty(category = "text", mapping = { + @ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"), + @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG, to = "FIRST_STRONG"), + @ViewDebug.IntToString(from = TEXT_DIRECTION_ANY_RTL, to = "ANY_RTL"), + @ViewDebug.IntToString(from = TEXT_DIRECTION_LTR, to = "LTR"), + @ViewDebug.IntToString(from = TEXT_DIRECTION_RTL, to = "RTL"), + @ViewDebug.IntToString(from = TEXT_DIRECTION_LOCALE, to = "LOCALE") + }) + private int mResolvedTextDirection = TEXT_DIRECTION_INHERIT; + /** + * Consistency verifier for debugging purposes. + * @hide + */ + protected final InputEventConsistencyVerifier mInputEventConsistencyVerifier = + InputEventConsistencyVerifier.isInstrumentationEnabled() ? + new InputEventConsistencyVerifier(this, 0) : null; + /** + * Simple constructor to use when creating a view from code. + * + * @param context The Context the view is running in, through which it can + * access the current theme, resources, etc. + */ + public View(Context context) { + mContext = context; + mResources = context != null ? context.getResources() : null; + mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED | LAYOUT_DIRECTION_INHERIT; + mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); + setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS); + mUserPaddingStart = -1; + mUserPaddingEnd = -1; + mUserPaddingRelative = false; + } + /** + * Constructor that is called when inflating a view from XML. This is called + * when a view is being constructed from an XML file, supplying attributes + * that were specified in the XML file. This version uses a default style of + * 0, so the only attribute values applied are those in the Context's Theme + * and the given AttributeSet. + * + *

+ * The method onFinishInflate() will be called after all children have been + * added. + * + * @param context The Context the view is running in, through which it can + * access the current theme, resources, etc. + * @param attrs The attributes of the XML tag that is inflating the view. + * @see #View(Context, AttributeSet, int) + */ + public View(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + /** + * Perform inflation from XML and apply a class-specific base style. This + * constructor of View allows subclasses to use their own base style when + * they are inflating. For example, a Button class's constructor would call + * this version of the super class constructor and supply + * R.attr.buttonStyle for defStyle; this allows + * the theme's button style to modify all of the base view attributes (in + * particular its background) as well as the Button class's attributes. + * + * @param context The Context the view is running in, through which it can + * access the current theme, resources, etc. + * @param attrs The attributes of the XML tag that is inflating the view. + * @param defStyle The default style to apply to this view. If 0, no style + * will be applied (beyond what is included in the theme). This may + * either be an attribute resource, whose value will be retrieved + * from the current theme, or an explicit style resource. + * @see #View(Context, AttributeSet) + */ + public View(Context context, AttributeSet attrs, int defStyle) { + this(context); + TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.View, + defStyle, 0); + Drawable background = null; + int leftPadding = -1; + int topPadding = -1; + int rightPadding = -1; + int bottomPadding = -1; + int startPadding = -1; + int endPadding = -1; + int padding = -1; + int viewFlagValues = 0; + int viewFlagMasks = 0; + boolean setScrollContainer = false; + int x = 0; + int y = 0; + float tx = 0; + float ty = 0; + float rotation = 0; + float rotationX = 0; + float rotationY = 0; + float sx = 1f; + float sy = 1f; + boolean transformSet = false; + int scrollbarStyle = SCROLLBARS_INSIDE_OVERLAY; + int overScrollMode = mOverScrollMode; + final int N = a.getIndexCount(); + for (int i = 0; i < N; i++) { + int attr = a.getIndex(i); + switch (attr) { + case com.android.internal.R.styleable.View_background: + background = a.getDrawable(attr); + break; + case com.android.internal.R.styleable.View_padding: + padding = a.getDimensionPixelSize(attr, -1); + break; + case com.android.internal.R.styleable.View_paddingLeft: + leftPadding = a.getDimensionPixelSize(attr, -1); + break; + case com.android.internal.R.styleable.View_paddingTop: + topPadding = a.getDimensionPixelSize(attr, -1); + break; + case com.android.internal.R.styleable.View_paddingRight: + rightPadding = a.getDimensionPixelSize(attr, -1); + break; + case com.android.internal.R.styleable.View_paddingBottom: + bottomPadding = a.getDimensionPixelSize(attr, -1); + break; + case com.android.internal.R.styleable.View_paddingStart: + startPadding = a.getDimensionPixelSize(attr, -1); + break; + case com.android.internal.R.styleable.View_paddingEnd: + endPadding = a.getDimensionPixelSize(attr, -1); + break; + case com.android.internal.R.styleable.View_scrollX: + x = a.getDimensionPixelOffset(attr, 0); + break; + case com.android.internal.R.styleable.View_scrollY: + y = a.getDimensionPixelOffset(attr, 0); + break; + case com.android.internal.R.styleable.View_alpha: + setAlpha(a.getFloat(attr, 1f)); + break; + case com.android.internal.R.styleable.View_transformPivotX: + setPivotX(a.getDimensionPixelOffset(attr, 0)); + break; + case com.android.internal.R.styleable.View_transformPivotY: + setPivotY(a.getDimensionPixelOffset(attr, 0)); + break; + case com.android.internal.R.styleable.View_translationX: + tx = a.getDimensionPixelOffset(attr, 0); + transformSet = true; + break; + case com.android.internal.R.styleable.View_translationY: + ty = a.getDimensionPixelOffset(attr, 0); + transformSet = true; + break; + case com.android.internal.R.styleable.View_rotation: + rotation = a.getFloat(attr, 0); + transformSet = true; + break; + case com.android.internal.R.styleable.View_rotationX: + rotationX = a.getFloat(attr, 0); + transformSet = true; + break; + case com.android.internal.R.styleable.View_rotationY: + rotationY = a.getFloat(attr, 0); + transformSet = true; + break; + case com.android.internal.R.styleable.View_scaleX: + sx = a.getFloat(attr, 1f); + transformSet = true; + break; + case com.android.internal.R.styleable.View_scaleY: + sy = a.getFloat(attr, 1f); + transformSet = true; + break; + case com.android.internal.R.styleable.View_id: + mID = a.getResourceId(attr, NO_ID); + break; + case com.android.internal.R.styleable.View_tag: + mTag = a.getText(attr); + break; + case com.android.internal.R.styleable.View_fitsSystemWindows: + if (a.getBoolean(attr, false)) { + viewFlagValues |= FITS_SYSTEM_WINDOWS; + viewFlagMasks |= FITS_SYSTEM_WINDOWS; + } + break; + case com.android.internal.R.styleable.View_focusable: + if (a.getBoolean(attr, false)) { + viewFlagValues |= FOCUSABLE; + viewFlagMasks |= FOCUSABLE_MASK; + } + break; + case com.android.internal.R.styleable.View_focusableInTouchMode: + if (a.getBoolean(attr, false)) { + viewFlagValues |= FOCUSABLE_IN_TOUCH_MODE | FOCUSABLE; + viewFlagMasks |= FOCUSABLE_IN_TOUCH_MODE | FOCUSABLE_MASK; + } + break; + case com.android.internal.R.styleable.View_clickable: + if (a.getBoolean(attr, false)) { + viewFlagValues |= CLICKABLE; + viewFlagMasks |= CLICKABLE; + } + break; + case com.android.internal.R.styleable.View_longClickable: + if (a.getBoolean(attr, false)) { + viewFlagValues |= LONG_CLICKABLE; + viewFlagMasks |= LONG_CLICKABLE; + } + break; + case com.android.internal.R.styleable.View_saveEnabled: + if (!a.getBoolean(attr, true)) { + viewFlagValues |= SAVE_DISABLED; + viewFlagMasks |= SAVE_DISABLED_MASK; + } + break; + case com.android.internal.R.styleable.View_duplicateParentState: + if (a.getBoolean(attr, false)) { + viewFlagValues |= DUPLICATE_PARENT_STATE; + viewFlagMasks |= DUPLICATE_PARENT_STATE; + } + break; + case com.android.internal.R.styleable.View_visibility: + final int visibility = a.getInt(attr, 0); + if (visibility != 0) { + viewFlagValues |= VISIBILITY_FLAGS[visibility]; + viewFlagMasks |= VISIBILITY_MASK; + } + break; + case com.android.internal.R.styleable.View_layoutDirection: + // Clear any HORIZONTAL_DIRECTION flag already set + viewFlagValues &= ~LAYOUT_DIRECTION_MASK; + // Set the HORIZONTAL_DIRECTION flags depending on the value of the attribute + final int layoutDirection = a.getInt(attr, -1); + if (layoutDirection != -1) { + viewFlagValues |= LAYOUT_DIRECTION_FLAGS[layoutDirection]; + } else { + // Set to default (LAYOUT_DIRECTION_INHERIT) + viewFlagValues |= LAYOUT_DIRECTION_DEFAULT; + } + viewFlagMasks |= LAYOUT_DIRECTION_MASK; + break; + case com.android.internal.R.styleable.View_drawingCacheQuality: + final int cacheQuality = a.getInt(attr, 0); + if (cacheQuality != 0) { + viewFlagValues |= DRAWING_CACHE_QUALITY_FLAGS[cacheQuality]; + viewFlagMasks |= DRAWING_CACHE_QUALITY_MASK; + } + break; + case com.android.internal.R.styleable.View_contentDescription: + mContentDescription = a.getString(attr); + break; + case com.android.internal.R.styleable.View_soundEffectsEnabled: + if (!a.getBoolean(attr, true)) { + viewFlagValues &= ~SOUND_EFFECTS_ENABLED; + viewFlagMasks |= SOUND_EFFECTS_ENABLED; + } + break; + case com.android.internal.R.styleable.View_hapticFeedbackEnabled: + if (!a.getBoolean(attr, true)) { + viewFlagValues &= ~HAPTIC_FEEDBACK_ENABLED; + viewFlagMasks |= HAPTIC_FEEDBACK_ENABLED; + } + break; + case R.styleable.View_scrollbars: + final int scrollbars = a.getInt(attr, SCROLLBARS_NONE); + if (scrollbars != SCROLLBARS_NONE) { + viewFlagValues |= scrollbars; + viewFlagMasks |= SCROLLBARS_MASK; + initializeScrollbars(a); + } + break; + //noinspection deprecation + case R.styleable.View_fadingEdge: + if (context.getApplicationInfo().targetSdkVersion >= ICE_CREAM_SANDWICH) { + // Ignore the attribute starting with ICS + break; + } + // With builds < ICS, fall through and apply fading edges + case R.styleable.View_requiresFadingEdge: + final int fadingEdge = a.getInt(attr, FADING_EDGE_NONE); + if (fadingEdge != FADING_EDGE_NONE) { + viewFlagValues |= fadingEdge; + viewFlagMasks |= FADING_EDGE_MASK; + initializeFadingEdge(a); + } + break; + case R.styleable.View_scrollbarStyle: + scrollbarStyle = a.getInt(attr, SCROLLBARS_INSIDE_OVERLAY); + if (scrollbarStyle != SCROLLBARS_INSIDE_OVERLAY) { + viewFlagValues |= scrollbarStyle & SCROLLBARS_STYLE_MASK; + viewFlagMasks |= SCROLLBARS_STYLE_MASK; + } + break; + case R.styleable.View_isScrollContainer: + setScrollContainer = true; + if (a.getBoolean(attr, false)) { + setScrollContainer(true); + } + break; + case com.android.internal.R.styleable.View_keepScreenOn: + if (a.getBoolean(attr, false)) { + viewFlagValues |= KEEP_SCREEN_ON; + viewFlagMasks |= KEEP_SCREEN_ON; + } + break; + case R.styleable.View_filterTouchesWhenObscured: + if (a.getBoolean(attr, false)) { + viewFlagValues |= FILTER_TOUCHES_WHEN_OBSCURED; + viewFlagMasks |= FILTER_TOUCHES_WHEN_OBSCURED; + } + break; + case R.styleable.View_nextFocusLeft: + mNextFocusLeftId = a.getResourceId(attr, View.NO_ID); + break; + case R.styleable.View_nextFocusRight: + mNextFocusRightId = a.getResourceId(attr, View.NO_ID); + break; + case R.styleable.View_nextFocusUp: + mNextFocusUpId = a.getResourceId(attr, View.NO_ID); + break; + case R.styleable.View_nextFocusDown: + mNextFocusDownId = a.getResourceId(attr, View.NO_ID); + break; + case R.styleable.View_nextFocusForward: + mNextFocusForwardId = a.getResourceId(attr, View.NO_ID); + break; + case R.styleable.View_minWidth: + mMinWidth = a.getDimensionPixelSize(attr, 0); + break; + case R.styleable.View_minHeight: + mMinHeight = a.getDimensionPixelSize(attr, 0); + break; + case R.styleable.View_onClick: + if (context.isRestricted()) { + throw new IllegalStateException("The android:onClick attribute cannot " + + "be used within a restricted context"); + } + final String handlerName = a.getString(attr); + if (handlerName != null) { + setOnClickListener(new OnClickListener() { + private Method mHandler; + public void onClick(View v) { + if (mHandler == null) { + try { + mHandler = getContext().getClass().getMethod(handlerName, + View.class); + } catch (NoSuchMethodException e) { + int id = getId(); + String idText = id == NO_ID ? "" : " with id '" + + getContext().getResources().getResourceEntryName( + id) + "'"; + throw new IllegalStateException("Could not find a method " + + handlerName + "(View) in the activity " + + getContext().getClass() + " for onClick handler" + + " on view " + View.this.getClass() + idText, e); + } + } + try { + mHandler.invoke(getContext(), View.this); + } catch (IllegalAccessException e) { + throw new IllegalStateException("Could not execute non " + + "public method of the activity", e); + } catch (InvocationTargetException e) { + throw new IllegalStateException("Could not execute " + + "method of the activity", e); + } + } + }); + } + break; + case R.styleable.View_overScrollMode: + overScrollMode = a.getInt(attr, OVER_SCROLL_IF_CONTENT_SCROLLS); + break; + case R.styleable.View_verticalScrollbarPosition: + mVerticalScrollbarPosition = a.getInt(attr, SCROLLBAR_POSITION_DEFAULT); + break; + case R.styleable.View_layerType: + setLayerType(a.getInt(attr, LAYER_TYPE_NONE), null); + break; + case R.styleable.View_textDirection: + mTextDirection = a.getInt(attr, DEFAULT_TEXT_DIRECTION); + break; + } + } + a.recycle(); + setOverScrollMode(overScrollMode); + if (background != null) { + setBackgroundDrawable(background); + } + mUserPaddingRelative = (startPadding >= 0 || endPadding >= 0); + // Cache user padding as we cannot fully resolve padding here (we dont have yet the resolved + // layout direction). Those cached values will be used later during padding resolution. + mUserPaddingStart = startPadding; + mUserPaddingEnd = endPadding; + if (padding >= 0) { + leftPadding = padding; + topPadding = padding; + rightPadding = padding; + bottomPadding = padding; + } + // If the user specified the padding (either with android:padding or + // android:paddingLeft/Top/Right/Bottom), use this padding, otherwise + // use the default padding or the padding from the background drawable + // (stored at this point in mPadding*) + setPadding(leftPadding >= 0 ? leftPadding : mPaddingLeft, + topPadding >= 0 ? topPadding : mPaddingTop, + rightPadding >= 0 ? rightPadding : mPaddingRight, + bottomPadding >= 0 ? bottomPadding : mPaddingBottom); + if (viewFlagMasks != 0) { + setFlags(viewFlagValues, viewFlagMasks); + } + // Needs to be called after mViewFlags is set + if (scrollbarStyle != SCROLLBARS_INSIDE_OVERLAY) { + recomputePadding(); + } + if (x != 0 || y != 0) { + scrollTo(x, y); + } + if (transformSet) { + setTranslationX(tx); + setTranslationY(ty); + setRotation(rotation); + setRotationX(rotationX); + setRotationY(rotationY); + setScaleX(sx); + setScaleY(sy); + } + if (!setScrollContainer && (viewFlagValues&SCROLLBARS_VERTICAL) != 0) { + setScrollContainer(true); + } + computeOpaqueFlags(); + } + /** + * Non-public constructor for use in testing + */ + View() { + mResources = null; + } + /** + *

+ * Initializes the fading edges from a given set of styled attributes. This + * method should be called by subclasses that need fading edges and when an + * instance of these subclasses is created programmatically rather than + * being inflated from XML. This method is automatically called when the XML + * is inflated. + *

+ * + * @param a the styled attributes set to initialize the fading edges from + */ + protected void initializeFadingEdge(TypedArray a) { + initScrollCache(); + mScrollCache.fadingEdgeLength = a.getDimensionPixelSize( + R.styleable.View_fadingEdgeLength, + ViewConfiguration.get(mContext).getScaledFadingEdgeLength()); + } + /** + * Returns the size of the vertical faded edges used to indicate that more + * content in this view is visible. + * + * @return The size in pixels of the vertical faded edge or 0 if vertical + * faded edges are not enabled for this view. + * @attr ref android.R.styleable#View_fadingEdgeLength + */ + public int getVerticalFadingEdgeLength() { + if (isVerticalFadingEdgeEnabled()) { + ScrollabilityCache cache = mScrollCache; + if (cache != null) { + return cache.fadingEdgeLength; + } + } + return 0; + } + /** + * Set the size of the faded edge used to indicate that more content in this + * view is available. Will not change whether the fading edge is enabled; use + * {@link #setVerticalFadingEdgeEnabled(boolean)} or + * {@link #setHorizontalFadingEdgeEnabled(boolean)} to enable the fading edge + * for the vertical or horizontal fading edges. + * + * @param length The size in pixels of the faded edge used to indicate that more + * content in this view is visible. + */ + public void setFadingEdgeLength(int length) { + initScrollCache(); + mScrollCache.fadingEdgeLength = length; + } + /** + * Returns the size of the horizontal faded edges used to indicate that more + * content in this view is visible. + * + * @return The size in pixels of the horizontal faded edge or 0 if horizontal + * faded edges are not enabled for this view. + * @attr ref android.R.styleable#View_fadingEdgeLength + */ + public int getHorizontalFadingEdgeLength() { + if (isHorizontalFadingEdgeEnabled()) { + ScrollabilityCache cache = mScrollCache; + if (cache != null) { + return cache.fadingEdgeLength; + } + } + return 0; + } + /** + * Returns the width of the vertical scrollbar. + * + * @return The width in pixels of the vertical scrollbar or 0 if there + * is no vertical scrollbar. + */ + public int getVerticalScrollbarWidth() { + ScrollabilityCache cache = mScrollCache; + if (cache != null) { + ScrollBarDrawable scrollBar = cache.scrollBar; + if (scrollBar != null) { + int size = scrollBar.getSize(true); + if (size <= 0) { + size = cache.scrollBarSize; + } + return size; + } + return 0; + } + return 0; + } + /** + * Returns the height of the horizontal scrollbar. + * + * @return The height in pixels of the horizontal scrollbar or 0 if + * there is no horizontal scrollbar. + */ + protected int getHorizontalScrollbarHeight() { + ScrollabilityCache cache = mScrollCache; + if (cache != null) { + ScrollBarDrawable scrollBar = cache.scrollBar; + if (scrollBar != null) { + int size = scrollBar.getSize(false); + if (size <= 0) { + size = cache.scrollBarSize; + } + return size; + } + return 0; + } + return 0; + } + /** + *

+ * Initializes the scrollbars from a given set of styled attributes. This + * method should be called by subclasses that need scrollbars and when an + * instance of these subclasses is created programmatically rather than + * being inflated from XML. This method is automatically called when the XML + * is inflated. + *

+ * + * @param a the styled attributes set to initialize the scrollbars from + */ + protected void initializeScrollbars(TypedArray a) { + initScrollCache(); + final ScrollabilityCache scrollabilityCache = mScrollCache; + if (scrollabilityCache.scrollBar == null) { + scrollabilityCache.scrollBar = new ScrollBarDrawable(); + } + final boolean fadeScrollbars = a.getBoolean(R.styleable.View_fadeScrollbars, true); + if (!fadeScrollbars) { + scrollabilityCache.state = ScrollabilityCache.ON; + } + scrollabilityCache.fadeScrollBars = fadeScrollbars; + scrollabilityCache.scrollBarFadeDuration = a.getInt( + R.styleable.View_scrollbarFadeDuration, ViewConfiguration + .getScrollBarFadeDuration()); + scrollabilityCache.scrollBarDefaultDelayBeforeFade = a.getInt( + R.styleable.View_scrollbarDefaultDelayBeforeFade, + ViewConfiguration.getScrollDefaultDelay()); + scrollabilityCache.scrollBarSize = a.getDimensionPixelSize( + com.android.internal.R.styleable.View_scrollbarSize, + ViewConfiguration.get(mContext).getScaledScrollBarSize()); + Drawable track = a.getDrawable(R.styleable.View_scrollbarTrackHorizontal); + scrollabilityCache.scrollBar.setHorizontalTrackDrawable(track); + Drawable thumb = a.getDrawable(R.styleable.View_scrollbarThumbHorizontal); + if (thumb != null) { + scrollabilityCache.scrollBar.setHorizontalThumbDrawable(thumb); + } + boolean alwaysDraw = a.getBoolean(R.styleable.View_scrollbarAlwaysDrawHorizontalTrack, + false); + if (alwaysDraw) { + scrollabilityCache.scrollBar.setAlwaysDrawHorizontalTrack(true); + } + track = a.getDrawable(R.styleable.View_scrollbarTrackVertical); + scrollabilityCache.scrollBar.setVerticalTrackDrawable(track); + thumb = a.getDrawable(R.styleable.View_scrollbarThumbVertical); + if (thumb != null) { + scrollabilityCache.scrollBar.setVerticalThumbDrawable(thumb); + } + alwaysDraw = a.getBoolean(R.styleable.View_scrollbarAlwaysDrawVerticalTrack, + false); + if (alwaysDraw) { + scrollabilityCache.scrollBar.setAlwaysDrawVerticalTrack(true); + } + // Re-apply user/background padding so that scrollbar(s) get added + resolvePadding(); + } + /** + *

+ * Initalizes the scrollability cache if necessary. + *

+ */ + private void initScrollCache() { + if (mScrollCache == null) { + mScrollCache = new ScrollabilityCache(ViewConfiguration.get(mContext), this); + } + } + /** + * Set the position of the vertical scroll bar. Should be one of + * {@link #SCROLLBAR_POSITION_DEFAULT}, {@link #SCROLLBAR_POSITION_LEFT} or + * {@link #SCROLLBAR_POSITION_RIGHT}. + * + * @param position Where the vertical scroll bar should be positioned. + */ + public void setVerticalScrollbarPosition(int position) { + if (mVerticalScrollbarPosition != position) { + mVerticalScrollbarPosition = position; + computeOpaqueFlags(); + resolvePadding(); + } + } + /** + * @return The position where the vertical scroll bar will show, if applicable. + * @see #setVerticalScrollbarPosition(int) + */ + public int getVerticalScrollbarPosition() { + return mVerticalScrollbarPosition; + } + ListenerInfo getListenerInfo() { + if (mListenerInfo != null) { + return mListenerInfo; + } + mListenerInfo = new ListenerInfo(); + return mListenerInfo; + } + /** + * Register a callback to be invoked when focus of this view changed. + * + * @param l The callback that will run. + */ + public void setOnFocusChangeListener(OnFocusChangeListener l) { + getListenerInfo().mOnFocusChangeListener = l; + } + /** + * Add a listener that will be called when the bounds of the view change due to + * layout processing. + * + * @param listener The listener that will be called when layout bounds change. + */ + public void addOnLayoutChangeListener(OnLayoutChangeListener listener) { + ListenerInfo li = getListenerInfo(); + if (li.mOnLayoutChangeListeners == null) { + li.mOnLayoutChangeListeners = new ArrayList(); + } + if (!li.mOnLayoutChangeListeners.contains(listener)) { + li.mOnLayoutChangeListeners.add(listener); + } + } + /** + * Remove a listener for layout changes. + * + * @param listener The listener for layout bounds change. + */ + public void removeOnLayoutChangeListener(OnLayoutChangeListener listener) { + ListenerInfo li = mListenerInfo; + if (li == null || li.mOnLayoutChangeListeners == null) { + return; + } + li.mOnLayoutChangeListeners.remove(listener); + } + /** + * Add a listener for attach state changes. + * + * This listener will be called whenever this view is attached or detached + * from a window. Remove the listener using + * {@link #removeOnAttachStateChangeListener(OnAttachStateChangeListener)}. + * + * @param listener Listener to attach + * @see #removeOnAttachStateChangeListener(OnAttachStateChangeListener) + */ + public void addOnAttachStateChangeListener(OnAttachStateChangeListener listener) { + ListenerInfo li = getListenerInfo(); + if (li.mOnAttachStateChangeListeners == null) { + li.mOnAttachStateChangeListeners + = new CopyOnWriteArrayList(); + } + li.mOnAttachStateChangeListeners.add(listener); + } + /** + * Remove a listener for attach state changes. The listener will receive no further + * notification of window attach/detach events. + * + * @param listener Listener to remove + * @see #addOnAttachStateChangeListener(OnAttachStateChangeListener) + */ + public void removeOnAttachStateChangeListener(OnAttachStateChangeListener listener) { + ListenerInfo li = mListenerInfo; + if (li == null || li.mOnAttachStateChangeListeners == null) { + return; + } + li.mOnAttachStateChangeListeners.remove(listener); + } + /** + * Returns the focus-change callback registered for this view. + * + * @return The callback, or null if one is not registered. + */ + public OnFocusChangeListener getOnFocusChangeListener() { + ListenerInfo li = mListenerInfo; + return li != null ? li.mOnFocusChangeListener : null; + } + /** + * Register a callback to be invoked when this view is clicked. If this view is not + * clickable, it becomes clickable. + * + * @param l The callback that will run + * + * @see #setClickable(boolean) + */ + public void setOnClickListener(OnClickListener l) { + if (!isClickable()) { + setClickable(true); + } + getListenerInfo().mOnClickListener = l; + } + /** + * Return whether this view has an attached OnClickListener. Returns + * true if there is a listener, false if there is none. + */ + public boolean hasOnClickListeners() { + ListenerInfo li = mListenerInfo; + return (li != null && li.mOnClickListener != null); + } + /** + * Register a callback to be invoked when this view is clicked and held. If this view is not + * long clickable, it becomes long clickable. + * + * @param l The callback that will run + * + * @see #setLongClickable(boolean) + */ + public void setOnLongClickListener(OnLongClickListener l) { + if (!isLongClickable()) { + setLongClickable(true); + } + getListenerInfo().mOnLongClickListener = l; + } + /** + * Register a callback to be invoked when the context menu for this view is + * being built. If this view is not long clickable, it becomes long clickable. + * + * @param l The callback that will run + * + */ + public void setOnCreateContextMenuListener(OnCreateContextMenuListener l) { + if (!isLongClickable()) { + setLongClickable(true); + } + getListenerInfo().mOnCreateContextMenuListener = l; + } + /** + * Call this view's OnClickListener, if it is defined. Performs all normal + * actions associated with clicking: reporting accessibility event, playing + * a sound, etc. + * + * @return True there was an assigned OnClickListener that was called, false + * otherwise is returned. + */ + public boolean performClick() { + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); + ListenerInfo li = mListenerInfo; + if (li != null && li.mOnClickListener != null) { + playSoundEffect(SoundEffectConstants.CLICK); + li.mOnClickListener.onClick(this); + return true; + } + return false; + } + /** + * Directly call any attached OnClickListener. Unlike {@link #performClick()}, + * this only calls the listener, and does not do any associated clicking + * actions like reporting an accessibility event. + * + * @return True there was an assigned OnClickListener that was called, false + * otherwise is returned. + */ + public boolean callOnClick() { + ListenerInfo li = mListenerInfo; + if (li != null && li.mOnClickListener != null) { + li.mOnClickListener.onClick(this); + return true; + } + return false; + } + /** + * Call this view's OnLongClickListener, if it is defined. Invokes the context menu if the + * OnLongClickListener did not consume the event. + * + * @return True if one of the above receivers consumed the event, false otherwise. + */ + public boolean performLongClick() { + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED); + boolean handled = false; + ListenerInfo li = mListenerInfo; + if (li != null && li.mOnLongClickListener != null) { + handled = li.mOnLongClickListener.onLongClick(View.this); + } + if (!handled) { + handled = showContextMenu(); + } + if (handled) { + performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); + } + return handled; + } + /** + * Performs button-related actions during a touch down event. + * + * @param event The event. + * @return True if the down was consumed. + * + * @hide + */ + protected boolean performButtonActionOnTouchDown(MotionEvent event) { + if ((event.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0) { + if (showContextMenu(event.getX(), event.getY(), event.getMetaState())) { + return true; + } + } + return false; + } + /** + * Bring up the context menu for this view. + * + * @return Whether a context menu was displayed. + */ + public boolean showContextMenu() { + return getParent().showContextMenuForChild(this); + } + /** + * Bring up the context menu for this view, referring to the item under the specified point. + * + * @param x The referenced x coordinate. + * @param y The referenced y coordinate. + * @param metaState The keyboard modifiers that were pressed. + * @return Whether a context menu was displayed. + * + * @hide + */ + public boolean showContextMenu(float x, float y, int metaState) { + return showContextMenu(); + } + /** + * Start an action mode. + * + * @param callback Callback that will control the lifecycle of the action mode + * @return The new action mode if it is started, null otherwise + * + * @see ActionMode + */ + public ActionMode startActionMode(ActionMode.Callback callback) { + return getParent().startActionModeForChild(this, callback); + } + /** + * Register a callback to be invoked when a key is pressed in this view. + * @param l the key listener to attach to this view + */ + public void setOnKeyListener(OnKeyListener l) { + getListenerInfo().mOnKeyListener = l; + } + /** + * Register a callback to be invoked when a touch event is sent to this view. + * @param l the touch listener to attach to this view + */ + public void setOnTouchListener(OnTouchListener l) { + getListenerInfo().mOnTouchListener = l; + } + /** + * Register a callback to be invoked when a generic motion event is sent to this view. + * @param l the generic motion listener to attach to this view + */ + public void setOnGenericMotionListener(OnGenericMotionListener l) { + getListenerInfo().mOnGenericMotionListener = l; + } + /** + * Register a callback to be invoked when a hover event is sent to this view. + * @param l the hover listener to attach to this view + */ + public void setOnHoverListener(OnHoverListener l) { + getListenerInfo().mOnHoverListener = l; + } + /** + * Register a drag event listener callback object for this View. The parameter is + * an implementation of {@link android.view.View.OnDragListener}. To send a drag event to a + * View, the system calls the + * {@link android.view.View.OnDragListener#onDrag(View,DragEvent)} method. + * @param l An implementation of {@link android.view.View.OnDragListener}. + */ + public void setOnDragListener(OnDragListener l) { + getListenerInfo().mOnDragListener = l; + } + /** + * Give this view focus. This will cause + * {@link #onFocusChanged(boolean, int, android.graphics.Rect)} to be called. + * + * Note: this does not check whether this {@link View} should get focus, it just + * gives it focus no matter what. It should only be called internally by framework + * code that knows what it is doing, namely {@link #requestFocus(int, Rect)}. + * + * @param direction values are {@link View#FOCUS_UP}, {@link View#FOCUS_DOWN}, + * {@link View#FOCUS_LEFT} or {@link View#FOCUS_RIGHT}. This is the direction which + * focus moved when requestFocus() is called. It may not always + * apply, in which case use the default View.FOCUS_DOWN. + * @param previouslyFocusedRect The rectangle of the view that had focus + * prior in this View's coordinate system. + */ + void handleFocusGainInternal(int direction, Rect previouslyFocusedRect) { + if (DBG) { + System.out.println(this + " requestFocus()"); + } + if ((mPrivateFlags & FOCUSED) == 0) { + mPrivateFlags |= FOCUSED; + if (mParent != null) { + mParent.requestChildFocus(this, this); + } + onFocusChanged(true, direction, previouslyFocusedRect); + refreshDrawableState(); + } + } + /** + * Request that a rectangle of this view be visible on the screen, + * scrolling if necessary just enough. + * + *

A View should call this if it maintains some notion of which part + * of its content is interesting. For example, a text editing view + * should call this when its cursor moves. + * + * @param rectangle The rectangle. + * @return Whether any parent scrolled. + */ + public boolean requestRectangleOnScreen(Rect rectangle) { + return requestRectangleOnScreen(rectangle, false); + } + /** + * Request that a rectangle of this view be visible on the screen, + * scrolling if necessary just enough. + * + *

A View should call this if it maintains some notion of which part + * of its content is interesting. For example, a text editing view + * should call this when its cursor moves. + * + *

When immediate is set to true, scrolling will not be + * animated. + * + * @param rectangle The rectangle. + * @param immediate True to forbid animated scrolling, false otherwise + * @return Whether any parent scrolled. + */ + public boolean requestRectangleOnScreen(Rect rectangle, boolean immediate) { + View child = this; + ViewParent parent = mParent; + boolean scrolled = false; + while (parent != null) { + scrolled |= parent.requestChildRectangleOnScreen(child, + rectangle, immediate); + // offset rect so next call has the rectangle in the + // coordinate system of its direct child. + rectangle.offset(child.getLeft(), child.getTop()); + rectangle.offset(-child.getScrollX(), -child.getScrollY()); + if (!(parent instanceof View)) { + break; + } + child = (View) parent; + parent = child.getParent(); + } + return scrolled; + } + /** + * Called when this view wants to give up focus. If focus is cleared + * {@link #onFocusChanged(boolean, int, android.graphics.Rect)} is called. + *

+ * Note: When a View clears focus the framework is trying + * to give focus to the first focusable View from the top. Hence, if this + * View is the first from the top that can take focus, then its focus will + * not be cleared nor will the focus change callback be invoked. + *

+ */ + public void clearFocus() { + if (DBG) { + System.out.println(this + " clearFocus()"); + } + if ((mPrivateFlags & FOCUSED) != 0) { + mPrivateFlags &= ~FOCUSED; + if (mParent != null) { + mParent.clearChildFocus(this); + } + onFocusChanged(false, 0, null); + refreshDrawableState(); + } + } + /** + * Called to clear the focus of a view that is about to be removed. + * Doesn't call clearChildFocus, which prevents this view from taking + * focus again before it has been removed from the parent + */ + void clearFocusForRemoval() { + if ((mPrivateFlags & FOCUSED) != 0) { + mPrivateFlags &= ~FOCUSED; + onFocusChanged(false, 0, null); + refreshDrawableState(); + // The view cleared focus and invoked the callbacks, so now is the + // time to give focus to the the first focusable from the top to + // ensure that the gain focus is announced after clear focus. + getRootView().requestFocus(FOCUS_FORWARD); + } + } + /** + * Called internally by the view system when a new view is getting focus. + * This is what clears the old focus. + */ + void unFocus() { + if (DBG) { + System.out.println(this + " unFocus()"); + } + if ((mPrivateFlags & FOCUSED) != 0) { + mPrivateFlags &= ~FOCUSED; + onFocusChanged(false, 0, null); + refreshDrawableState(); + } + } + /** + * Returns true if this view has focus iteself, or is the ancestor of the + * view that has focus. + * + * @return True if this view has or contains focus, false otherwise. + */ + @ViewDebug.ExportedProperty(category = "focus") + public boolean hasFocus() { + return (mPrivateFlags & FOCUSED) != 0; + } + /** + * Returns true if this view is focusable or if it contains a reachable View + * for which {@link #hasFocusable()} returns true. A "reachable hasFocusable()" + * is a View whose parents do not block descendants focus. + * + * Only {@link #VISIBLE} views are considered focusable. + * + * @return True if the view is focusable or if the view contains a focusable + * View, false otherwise. + * + * @see ViewGroup#FOCUS_BLOCK_DESCENDANTS + */ + public boolean hasFocusable() { + return (mViewFlags & VISIBILITY_MASK) == VISIBLE && isFocusable(); + } + /** + * Called by the view system when the focus state of this view changes. + * When the focus change event is caused by directional navigation, direction + * and previouslyFocusedRect provide insight into where the focus is coming from. + * When overriding, be sure to call up through to the super class so that + * the standard focus handling will occur. + * + * @param gainFocus True if the View has focus; false otherwise. + * @param direction The direction focus has moved when requestFocus() + * is called to give this view focus. Values are + * {@link #FOCUS_UP}, {@link #FOCUS_DOWN}, {@link #FOCUS_LEFT}, + * {@link #FOCUS_RIGHT}, {@link #FOCUS_FORWARD}, or {@link #FOCUS_BACKWARD}. + * It may not always apply, in which case use the default. + * @param previouslyFocusedRect The rectangle, in this view's coordinate + * system, of the previously focused view. If applicable, this will be + * passed in as finer grained information about where the focus is coming + * from (in addition to direction). Will be null otherwise. + */ + protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { + if (gainFocus) { + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED); + } + InputMethodManager imm = InputMethodManager.peekInstance(); + if (!gainFocus) { + if (isPressed()) { + setPressed(false); + } + if (imm != null && mAttachInfo != null + && mAttachInfo.mHasWindowFocus) { + imm.focusOut(this); + } + onFocusLost(); + } else if (imm != null && mAttachInfo != null + && mAttachInfo.mHasWindowFocus) { + imm.focusIn(this); + } + invalidate(true); + ListenerInfo li = mListenerInfo; + if (li != null && li.mOnFocusChangeListener != null) { + li.mOnFocusChangeListener.onFocusChange(this, gainFocus); + } + if (mAttachInfo != null) { + mAttachInfo.mKeyDispatchState.reset(this); + } + } + /** + * Sends an accessibility event of the given type. If accessiiblity is + * not enabled this method has no effect. The default implementation calls + * {@link #onInitializeAccessibilityEvent(AccessibilityEvent)} first + * to populate information about the event source (this View), then calls + * {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)} to + * populate the text content of the event source including its descendants, + * and last calls + * {@link ViewParent#requestSendAccessibilityEvent(View, AccessibilityEvent)} + * on its parent to resuest sending of the event to interested parties. + *

+ * If an {@link AccessibilityDelegate} has been specified via calling + * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its + * {@link AccessibilityDelegate#sendAccessibilityEvent(View, int)} is + * responsible for handling this call. + *

+ * + * @param eventType The type of the event to send, as defined by several types from + * {@link android.view.accessibility.AccessibilityEvent}, such as + * {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED} or + * {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}. + * + * @see #onInitializeAccessibilityEvent(AccessibilityEvent) + * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent) + * @see ViewParent#requestSendAccessibilityEvent(View, AccessibilityEvent) + * @see AccessibilityDelegate + */ + public void sendAccessibilityEvent(int eventType) { + if (mAccessibilityDelegate != null) { + mAccessibilityDelegate.sendAccessibilityEvent(this, eventType); + } else { + sendAccessibilityEventInternal(eventType); + } + } + /** + * @see #sendAccessibilityEvent(int) + * + * Note: Called from the default {@link AccessibilityDelegate}. + */ + void sendAccessibilityEventInternal(int eventType) { + if (AccessibilityManager.getInstance(mContext).isEnabled()) { + sendAccessibilityEventUnchecked(AccessibilityEvent.obtain(eventType)); + } + } + /** + * This method behaves exactly as {@link #sendAccessibilityEvent(int)} but + * takes as an argument an empty {@link AccessibilityEvent} and does not + * perform a check whether accessibility is enabled. + *

+ * If an {@link AccessibilityDelegate} has been specified via calling + * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its + * {@link AccessibilityDelegate#sendAccessibilityEventUnchecked(View, AccessibilityEvent)} + * is responsible for handling this call. + *

+ * + * @param event The event to send. + * + * @see #sendAccessibilityEvent(int) + */ + public void sendAccessibilityEventUnchecked(AccessibilityEvent event) { + if (mAccessibilityDelegate != null) { + mAccessibilityDelegate.sendAccessibilityEventUnchecked(this, event); + } else { + sendAccessibilityEventUncheckedInternal(event); + } + } + /** + * @see #sendAccessibilityEventUnchecked(AccessibilityEvent) + * + * Note: Called from the default {@link AccessibilityDelegate}. + */ + void sendAccessibilityEventUncheckedInternal(AccessibilityEvent event) { + if (!isShown()) { + return; + } + onInitializeAccessibilityEvent(event); + // Only a subset of accessibility events populates text content. + if ((event.getEventType() & POPULATING_ACCESSIBILITY_EVENT_TYPES) != 0) { + dispatchPopulateAccessibilityEvent(event); + } + // In the beginning we called #isShown(), so we know that getParent() is not null. + getParent().requestSendAccessibilityEvent(this, event); + } + /** + * Dispatches an {@link AccessibilityEvent} to the {@link View} first and then + * to its children for adding their text content to the event. Note that the + * event text is populated in a separate dispatch path since we add to the + * event not only the text of the source but also the text of all its descendants. + * A typical implementation will call + * {@link #onPopulateAccessibilityEvent(AccessibilityEvent)} on the this view + * and then call the {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)} + * on each child. Override this method if custom population of the event text + * content is required. + *

+ * If an {@link AccessibilityDelegate} has been specified via calling + * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its + * {@link AccessibilityDelegate#dispatchPopulateAccessibilityEvent(View, AccessibilityEvent)} + * is responsible for handling this call. + *

+ *

+ * Note: Accessibility events of certain types are not dispatched for + * populating the event text via this method. For details refer to {@link AccessibilityEvent}. + *

+ * + * @param event The event. + * + * @return True if the event population was completed. + */ + public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { + if (mAccessibilityDelegate != null) { + return mAccessibilityDelegate.dispatchPopulateAccessibilityEvent(this, event); + } else { + return dispatchPopulateAccessibilityEventInternal(event); + } + } + /** + * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent) + * + * Note: Called from the default {@link AccessibilityDelegate}. + */ + boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) { + onPopulateAccessibilityEvent(event); + return false; + } + /** + * Called from {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)} + * giving a chance to this View to populate the accessibility event with its + * text content. While this method is free to modify event + * attributes other than text content, doing so should normally be performed in + * {@link #onInitializeAccessibilityEvent(AccessibilityEvent)}. + *

+ * Example: Adding formatted date string to an accessibility event in addition + * to the text added by the super implementation: + *

 public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+     *     super.onPopulateAccessibilityEvent(event);
+     *     final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY;
+     *     String selectedDateUtterance = DateUtils.formatDateTime(mContext,
+     *         mCurrentDate.getTimeInMillis(), flags);
+     *     event.getText().add(selectedDateUtterance);
+     * }
+ *

+ * If an {@link AccessibilityDelegate} has been specified via calling + * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its + * {@link AccessibilityDelegate#onPopulateAccessibilityEvent(View, AccessibilityEvent)} + * is responsible for handling this call. + *

+ *

Note: Always call the super implementation before adding + * information to the event, in case the default implementation has basic information to add. + *

+ * + * @param event The accessibility event which to populate. + * + * @see #sendAccessibilityEvent(int) + * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent) + */ + public void onPopulateAccessibilityEvent(AccessibilityEvent event) { + if (mAccessibilityDelegate != null) { + mAccessibilityDelegate.onPopulateAccessibilityEvent(this, event); + } else { + onPopulateAccessibilityEventInternal(event); + } + } + /** + * @see #onPopulateAccessibilityEvent(AccessibilityEvent) + * + * Note: Called from the default {@link AccessibilityDelegate}. + */ + void onPopulateAccessibilityEventInternal(AccessibilityEvent event) { + } + /** + * Initializes an {@link AccessibilityEvent} with information about + * this View which is the event source. In other words, the source of + * an accessibility event is the view whose state change triggered firing + * the event. + *

+ * Example: Setting the password property of an event in addition + * to properties set by the super implementation: + *

 public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+     *     super.onInitializeAccessibilityEvent(event);
+     *     event.setPassword(true);
+     * }
+ *

+ * If an {@link AccessibilityDelegate} has been specified via calling + * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its + * {@link AccessibilityDelegate#onInitializeAccessibilityEvent(View, AccessibilityEvent)} + * is responsible for handling this call. + *

+ *

Note: Always call the super implementation before adding + * information to the event, in case the default implementation has basic information to add. + *

+ * @param event The event to initialize. + * + * @see #sendAccessibilityEvent(int) + * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent) + */ + public void onInitializeAccessibilityEvent(AccessibilityEvent event) { + if (mAccessibilityDelegate != null) { + mAccessibilityDelegate.onInitializeAccessibilityEvent(this, event); + } else { + onInitializeAccessibilityEventInternal(event); + } + } + /** + * @see #onInitializeAccessibilityEvent(AccessibilityEvent) + * + * Note: Called from the default {@link AccessibilityDelegate}. + */ + void onInitializeAccessibilityEventInternal(AccessibilityEvent event) { + event.setSource(this); + event.setClassName(View.class.getName()); + event.setPackageName(getContext().getPackageName()); + event.setEnabled(isEnabled()); + event.setContentDescription(mContentDescription); + if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED && mAttachInfo != null) { + ArrayList focusablesTempList = mAttachInfo.mFocusablesTempList; + getRootView().addFocusables(focusablesTempList, View.FOCUS_FORWARD, + FOCUSABLES_ALL); + event.setItemCount(focusablesTempList.size()); + event.setCurrentItemIndex(focusablesTempList.indexOf(this)); + focusablesTempList.clear(); + } + } + /** + * Returns an {@link AccessibilityNodeInfo} representing this view from the + * point of view of an {@link android.accessibilityservice.AccessibilityService}. + * This method is responsible for obtaining an accessibility node info from a + * pool of reusable instances and calling + * {@link #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} on this view to + * initialize the former. + *

+ * Note: The client is responsible for recycling the obtained instance by calling + * {@link AccessibilityNodeInfo#recycle()} to minimize object creation. + *

+ * + * @return A populated {@link AccessibilityNodeInfo}. + * + * @see AccessibilityNodeInfo + */ + public AccessibilityNodeInfo createAccessibilityNodeInfo() { + AccessibilityNodeProvider provider = getAccessibilityNodeProvider(); + if (provider != null) { + return provider.createAccessibilityNodeInfo(View.NO_ID); + } else { + AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain(this); + onInitializeAccessibilityNodeInfo(info); + return info; + } + } + /** + * Initializes an {@link AccessibilityNodeInfo} with information about this view. + * The base implementation sets: + *
    + *
  • {@link AccessibilityNodeInfo#setParent(View)},
  • + *
  • {@link AccessibilityNodeInfo#setBoundsInParent(Rect)},
  • + *
  • {@link AccessibilityNodeInfo#setBoundsInScreen(Rect)},
  • + *
  • {@link AccessibilityNodeInfo#setPackageName(CharSequence)},
  • + *
  • {@link AccessibilityNodeInfo#setClassName(CharSequence)},
  • + *
  • {@link AccessibilityNodeInfo#setContentDescription(CharSequence)},
  • + *
  • {@link AccessibilityNodeInfo#setEnabled(boolean)},
  • + *
  • {@link AccessibilityNodeInfo#setClickable(boolean)},
  • + *
  • {@link AccessibilityNodeInfo#setFocusable(boolean)},
  • + *
  • {@link AccessibilityNodeInfo#setFocused(boolean)},
  • + *
  • {@link AccessibilityNodeInfo#setLongClickable(boolean)},
  • + *
  • {@link AccessibilityNodeInfo#setSelected(boolean)},
  • + *
+ *

+ * Subclasses should override this method, call the super implementation, + * and set additional attributes. + *

+ *

+ * If an {@link AccessibilityDelegate} has been specified via calling + * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its + * {@link AccessibilityDelegate#onInitializeAccessibilityNodeInfo(View, AccessibilityNodeInfo)} + * is responsible for handling this call. + *

+ * + * @param info The instance to initialize. + */ + public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { + if (mAccessibilityDelegate != null) { + mAccessibilityDelegate.onInitializeAccessibilityNodeInfo(this, info); + } else { + onInitializeAccessibilityNodeInfoInternal(info); + } + } + /** + * @see #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo) + * + * Note: Called from the default {@link AccessibilityDelegate}. + */ + void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) { + Rect bounds = mAttachInfo.mTmpInvalRect; + getDrawingRect(bounds); + info.setBoundsInParent(bounds); + int[] locationOnScreen = mAttachInfo.mInvalidateChildLocation; + getLocationOnScreen(locationOnScreen); + bounds.offsetTo(0, 0); + bounds.offset(locationOnScreen[0], locationOnScreen[1]); + info.setBoundsInScreen(bounds); + if ((mPrivateFlags & IS_ROOT_NAMESPACE) == 0) { + ViewParent parent = getParent(); + if (parent instanceof View) { + View parentView = (View) parent; + info.setParent(parentView); + } + } + info.setPackageName(mContext.getPackageName()); + info.setClassName(View.class.getName()); + info.setContentDescription(getContentDescription()); + info.setEnabled(isEnabled()); + info.setClickable(isClickable()); + info.setFocusable(isFocusable()); + info.setFocused(isFocused()); + info.setSelected(isSelected()); + info.setLongClickable(isLongClickable()); + // TODO: These make sense only if we are in an AdapterView but all + // views can be selected. Maybe from accessiiblity perspective + // we should report as selectable view in an AdapterView. + info.addAction(AccessibilityNodeInfo.ACTION_SELECT); + info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_SELECTION); + if (isFocusable()) { + if (isFocused()) { + info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_FOCUS); + } else { + info.addAction(AccessibilityNodeInfo.ACTION_FOCUS); + } + } + } + /** + * Sets a delegate for implementing accessibility support via compositon as + * opposed to inheritance. The delegate's primary use is for implementing + * backwards compatible widgets. For more details see {@link AccessibilityDelegate}. + * + * @param delegate The delegate instance. + * + * @see AccessibilityDelegate + */ + public void setAccessibilityDelegate(AccessibilityDelegate delegate) { + mAccessibilityDelegate = delegate; + } + /** + * Gets the provider for managing a virtual view hierarchy rooted at this View + * and reported to {@link android.accessibilityservice.AccessibilityService}s + * that explore the window content. + *

+ * If this method returns an instance, this instance is responsible for managing + * {@link AccessibilityNodeInfo}s describing the virtual sub-tree rooted at this + * View including the one representing the View itself. Similarly the returned + * instance is responsible for performing accessibility actions on any virtual + * view or the root view itself. + *

+ *

+ * If an {@link AccessibilityDelegate} has been specified via calling + * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its + * {@link AccessibilityDelegate#getAccessibilityNodeProvider(View)} + * is responsible for handling this call. + *

+ * + * @return The provider. + * + * @see AccessibilityNodeProvider + */ + public AccessibilityNodeProvider getAccessibilityNodeProvider() { + if (mAccessibilityDelegate != null) { + return mAccessibilityDelegate.getAccessibilityNodeProvider(this); + } else { + return null; + } + } + /** + * Gets the unique identifier of this view on the screen for accessibility purposes. + * If this {@link View} is not attached to any window, {@value #NO_ID} is returned. + * + * @return The view accessibility id. + * + * @hide + */ + public int getAccessibilityViewId() { + if (mAccessibilityViewId == NO_ID) { + mAccessibilityViewId = sNextAccessibilityViewId++; + } + return mAccessibilityViewId; + } + /** + * Gets the unique identifier of the window in which this View reseides. + * + * @return The window accessibility id. + * + * @hide + */ + public int getAccessibilityWindowId() { + return mAttachInfo != null ? mAttachInfo.mAccessibilityWindowId : NO_ID; + } + /** + * Gets the {@link View} description. It briefly describes the view and is + * primarily used for accessibility support. Set this property to enable + * better accessibility support for your application. This is especially + * true for views that do not have textual representation (For example, + * ImageButton). + * + * @return The content descriptiopn. + * + * @attr ref android.R.styleable#View_contentDescription + */ + public CharSequence getContentDescription() { + return mContentDescription; + } + /** + * Sets the {@link View} description. It briefly describes the view and is + * primarily used for accessibility support. Set this property to enable + * better accessibility support for your application. This is especially + * true for views that do not have textual representation (For example, + * ImageButton). + * + * @param contentDescription The content description. + * + * @attr ref android.R.styleable#View_contentDescription + */ + @RemotableViewMethod + public void setContentDescription(CharSequence contentDescription) { + mContentDescription = contentDescription; + } + /** + * Invoked whenever this view loses focus, either by losing window focus or by losing + * focus within its window. This method can be used to clear any state tied to the + * focus. For instance, if a button is held pressed with the trackball and the window + * loses focus, this method can be used to cancel the press. + * + * Subclasses of View overriding this method should always call super.onFocusLost(). + * + * @see #onFocusChanged(boolean, int, android.graphics.Rect) + * @see #onWindowFocusChanged(boolean) + * + * @hide pending API council approval + */ + protected void onFocusLost() { + resetPressedState(); + } + private void resetPressedState() { + if ((mViewFlags & ENABLED_MASK) == DISABLED) { + return; + } + if (isPressed()) { + setPressed(false); + if (!mHasPerformedLongPress) { + removeLongPressCallback(); + } + } + } + /** + * Returns true if this view has focus + * + * @return True if this view has focus, false otherwise. + */ + @ViewDebug.ExportedProperty(category = "focus") + public boolean isFocused() { + return (mPrivateFlags & FOCUSED) != 0; + } + /** + * Find the view in the hierarchy rooted at this view that currently has + * focus. + * + * @return The view that currently has focus, or null if no focused view can + * be found. + */ + public View findFocus() { + return (mPrivateFlags & FOCUSED) != 0 ? this : null; + } + /** + * Change whether this view is one of the set of scrollable containers in + * its window. This will be used to determine whether the window can + * resize or must pan when a soft input area is open -- scrollable + * containers allow the window to use resize mode since the container + * will appropriately shrink. + */ + public void setScrollContainer(boolean isScrollContainer) { + if (isScrollContainer) { + if (mAttachInfo != null && (mPrivateFlags&SCROLL_CONTAINER_ADDED) == 0) { + mAttachInfo.mScrollContainers.add(this); + mPrivateFlags |= SCROLL_CONTAINER_ADDED; + } + mPrivateFlags |= SCROLL_CONTAINER; + } else { + if ((mPrivateFlags&SCROLL_CONTAINER_ADDED) != 0) { + mAttachInfo.mScrollContainers.remove(this); + } + mPrivateFlags &= ~(SCROLL_CONTAINER|SCROLL_CONTAINER_ADDED); + } + } + /** + * Returns the quality of the drawing cache. + * + * @return One of {@link #DRAWING_CACHE_QUALITY_AUTO}, + * {@link #DRAWING_CACHE_QUALITY_LOW}, or {@link #DRAWING_CACHE_QUALITY_HIGH} + * + * @see #setDrawingCacheQuality(int) + * @see #setDrawingCacheEnabled(boolean) + * @see #isDrawingCacheEnabled() + * + * @attr ref android.R.styleable#View_drawingCacheQuality + */ + public int getDrawingCacheQuality() { + return mViewFlags & DRAWING_CACHE_QUALITY_MASK; + } + /** + * Set the drawing cache quality of this view. This value is used only when the + * drawing cache is enabled + * + * @param quality One of {@link #DRAWING_CACHE_QUALITY_AUTO}, + * {@link #DRAWING_CACHE_QUALITY_LOW}, or {@link #DRAWING_CACHE_QUALITY_HIGH} + * + * @see #getDrawingCacheQuality() + * @see #setDrawingCacheEnabled(boolean) + * @see #isDrawingCacheEnabled() + * + * @attr ref android.R.styleable#View_drawingCacheQuality + */ + public void setDrawingCacheQuality(int quality) { + setFlags(quality, DRAWING_CACHE_QUALITY_MASK); + } + /** + * Returns whether the screen should remain on, corresponding to the current + * value of {@link #KEEP_SCREEN_ON}. + * + * @return Returns true if {@link #KEEP_SCREEN_ON} is set. + * + * @see #setKeepScreenOn(boolean) + * + * @attr ref android.R.styleable#View_keepScreenOn + */ + public boolean getKeepScreenOn() { + return (mViewFlags & KEEP_SCREEN_ON) != 0; + } + /** + * Controls whether the screen should remain on, modifying the + * value of {@link #KEEP_SCREEN_ON}. + * + * @param keepScreenOn Supply true to set {@link #KEEP_SCREEN_ON}. + * + * @see #getKeepScreenOn() + * + * @attr ref android.R.styleable#View_keepScreenOn + */ + public void setKeepScreenOn(boolean keepScreenOn) { + setFlags(keepScreenOn ? KEEP_SCREEN_ON : 0, KEEP_SCREEN_ON); + } + /** + * Gets the id of the view to use when the next focus is {@link #FOCUS_LEFT}. + * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically. + * + * @attr ref android.R.styleable#View_nextFocusLeft + */ + public int getNextFocusLeftId() { + return mNextFocusLeftId; + } + /** + * Sets the id of the view to use when the next focus is {@link #FOCUS_LEFT}. + * @param nextFocusLeftId The next focus ID, or {@link #NO_ID} if the framework should + * decide automatically. + * + * @attr ref android.R.styleable#View_nextFocusLeft + */ + public void setNextFocusLeftId(int nextFocusLeftId) { + mNextFocusLeftId = nextFocusLeftId; + } + /** + * Gets the id of the view to use when the next focus is {@link #FOCUS_RIGHT}. + * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically. + * + * @attr ref android.R.styleable#View_nextFocusRight + */ + public int getNextFocusRightId() { + return mNextFocusRightId; + } + /** + * Sets the id of the view to use when the next focus is {@link #FOCUS_RIGHT}. + * @param nextFocusRightId The next focus ID, or {@link #NO_ID} if the framework should + * decide automatically. + * + * @attr ref android.R.styleable#View_nextFocusRight + */ + public void setNextFocusRightId(int nextFocusRightId) { + mNextFocusRightId = nextFocusRightId; + } + /** + * Gets the id of the view to use when the next focus is {@link #FOCUS_UP}. + * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically. + * + * @attr ref android.R.styleable#View_nextFocusUp + */ + public int getNextFocusUpId() { + return mNextFocusUpId; + } + /** + * Sets the id of the view to use when the next focus is {@link #FOCUS_UP}. + * @param nextFocusUpId The next focus ID, or {@link #NO_ID} if the framework should + * decide automatically. + * + * @attr ref android.R.styleable#View_nextFocusUp + */ + public void setNextFocusUpId(int nextFocusUpId) { + mNextFocusUpId = nextFocusUpId; + } + /** + * Gets the id of the view to use when the next focus is {@link #FOCUS_DOWN}. + * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically. + * + * @attr ref android.R.styleable#View_nextFocusDown + */ + public int getNextFocusDownId() { + return mNextFocusDownId; + } + /** + * Sets the id of the view to use when the next focus is {@link #FOCUS_DOWN}. + * @param nextFocusDownId The next focus ID, or {@link #NO_ID} if the framework should + * decide automatically. + * + * @attr ref android.R.styleable#View_nextFocusDown + */ + public void setNextFocusDownId(int nextFocusDownId) { + mNextFocusDownId = nextFocusDownId; + } + /** + * Gets the id of the view to use when the next focus is {@link #FOCUS_FORWARD}. + * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically. + * + * @attr ref android.R.styleable#View_nextFocusForward + */ + public int getNextFocusForwardId() { + return mNextFocusForwardId; + } + /** + * Sets the id of the view to use when the next focus is {@link #FOCUS_FORWARD}. + * @param nextFocusForwardId The next focus ID, or {@link #NO_ID} if the framework should + * decide automatically. + * + * @attr ref android.R.styleable#View_nextFocusForward + */ + public void setNextFocusForwardId(int nextFocusForwardId) { + mNextFocusForwardId = nextFocusForwardId; + } + /** + * Returns the visibility of this view and all of its ancestors + * + * @return True if this view and all of its ancestors are {@link #VISIBLE} + */ + public boolean isShown() { + View current = this; + //noinspection ConstantConditions + do { + if ((current.mViewFlags & VISIBILITY_MASK) != VISIBLE) { + return false; + } + ViewParent parent = current.mParent; + if (parent == null) { + return false; // We are not attached to the view root + } + if (!(parent instanceof View)) { + return true; + } + current = (View) parent; + } while (current != null); + return false; + } + /** + * Apply the insets for system windows to this view, if the FITS_SYSTEM_WINDOWS flag + * is set + * + * @param insets Insets for system windows + * + * @return True if this view applied the insets, false otherwise + */ + protected boolean fitSystemWindows(Rect insets) { + if ((mViewFlags & FITS_SYSTEM_WINDOWS) == FITS_SYSTEM_WINDOWS) { + mPaddingLeft = insets.left; + mPaddingTop = insets.top; + mPaddingRight = insets.right; + mPaddingBottom = insets.bottom; + requestLayout(); + return true; + } + return false; + } + /** + * Set whether or not this view should account for system screen decorations + * such as the status bar and inset its content. This allows this view to be + * positioned in absolute screen coordinates and remain visible to the user. + * + *

This should only be used by top-level window decor views. + * + * @param fitSystemWindows true to inset content for system screen decorations, false for + * default behavior. + * + * @attr ref android.R.styleable#View_fitsSystemWindows + */ + public void setFitsSystemWindows(boolean fitSystemWindows) { + setFlags(fitSystemWindows ? FITS_SYSTEM_WINDOWS : 0, FITS_SYSTEM_WINDOWS); + } + /** + * Check for the FITS_SYSTEM_WINDOWS flag. If this method returns true, this view + * will account for system screen decorations such as the status bar and inset its + * content. This allows the view to be positioned in absolute screen coordinates + * and remain visible to the user. + * + * @return true if this view will adjust its content bounds for system screen decorations. + * + * @attr ref android.R.styleable#View_fitsSystemWindows + */ + public boolean fitsSystemWindows() { + return (mViewFlags & FITS_SYSTEM_WINDOWS) == FITS_SYSTEM_WINDOWS; + } + /** + * Returns the visibility status for this view. + * + * @return One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}. + * @attr ref android.R.styleable#View_visibility + */ + @ViewDebug.ExportedProperty(mapping = { + @ViewDebug.IntToString(from = VISIBLE, to = "VISIBLE"), + @ViewDebug.IntToString(from = INVISIBLE, to = "INVISIBLE"), + @ViewDebug.IntToString(from = GONE, to = "GONE") + }) + public int getVisibility() { + return mViewFlags & VISIBILITY_MASK; + } + /** + * Set the enabled state of this view. + * + * @param visibility One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}. + * @attr ref android.R.styleable#View_visibility + */ + @RemotableViewMethod + public void setVisibility(int visibility) { + setFlags(visibility, VISIBILITY_MASK); + if (mBGDrawable != null) mBGDrawable.setVisible(visibility == VISIBLE, false); + } + /** + * Returns the enabled status for this view. The interpretation of the + * enabled state varies by subclass. + * + * @return True if this view is enabled, false otherwise. + */ + @ViewDebug.ExportedProperty + public boolean isEnabled() { + return (mViewFlags & ENABLED_MASK) == ENABLED; + } + /** + * Set the enabled state of this view. The interpretation of the enabled + * state varies by subclass. + * + * @param enabled True if this view is enabled, false otherwise. + */ + @RemotableViewMethod + public void setEnabled(boolean enabled) { + if (enabled == isEnabled()) return; + setFlags(enabled ? ENABLED : DISABLED, ENABLED_MASK); + /* + * The View most likely has to change its appearance, so refresh + * the drawable state. + */ + refreshDrawableState(); + // Invalidate too, since the default behavior for views is to be + // be drawn at 50% alpha rather than to change the drawable. + invalidate(true); + } + /** + * Set whether this view can receive the focus. + * + * Setting this to false will also ensure that this view is not focusable + * in touch mode. + * + * @param focusable If true, this view can receive the focus. + * + * @see #setFocusableInTouchMode(boolean) + * @attr ref android.R.styleable#View_focusable + */ + public void setFocusable(boolean focusable) { + if (!focusable) { + setFlags(0, FOCUSABLE_IN_TOUCH_MODE); + } + setFlags(focusable ? FOCUSABLE : NOT_FOCUSABLE, FOCUSABLE_MASK); + } + /** + * Set whether this view can receive focus while in touch mode. + * + * Setting this to true will also ensure that this view is focusable. + * + * @param focusableInTouchMode If true, this view can receive the focus while + * in touch mode. + * + * @see #setFocusable(boolean) + * @attr ref android.R.styleable#View_focusableInTouchMode + */ + public void setFocusableInTouchMode(boolean focusableInTouchMode) { + // Focusable in touch mode should always be set before the focusable flag + // otherwise, setting the focusable flag will trigger a focusableViewAvailable() + // which, in touch mode, will not successfully request focus on this view + // because the focusable in touch mode flag is not set + setFlags(focusableInTouchMode ? FOCUSABLE_IN_TOUCH_MODE : 0, FOCUSABLE_IN_TOUCH_MODE); + if (focusableInTouchMode) { + setFlags(FOCUSABLE, FOCUSABLE_MASK); + } + } + /** + * Set whether this view should have sound effects enabled for events such as + * clicking and touching. + * + *

You may wish to disable sound effects for a view if you already play sounds, + * for instance, a dial key that plays dtmf tones. + * + * @param soundEffectsEnabled whether sound effects are enabled for this view. + * @see #isSoundEffectsEnabled() + * @see #playSoundEffect(int) + * @attr ref android.R.styleable#View_soundEffectsEnabled + */ + public void setSoundEffectsEnabled(boolean soundEffectsEnabled) { + setFlags(soundEffectsEnabled ? SOUND_EFFECTS_ENABLED: 0, SOUND_EFFECTS_ENABLED); + } + /** + * @return whether this view should have sound effects enabled for events such as + * clicking and touching. + * + * @see #setSoundEffectsEnabled(boolean) + * @see #playSoundEffect(int) + * @attr ref android.R.styleable#View_soundEffectsEnabled + */ + @ViewDebug.ExportedProperty + public boolean isSoundEffectsEnabled() { + return SOUND_EFFECTS_ENABLED == (mViewFlags & SOUND_EFFECTS_ENABLED); + } + /** + * Set whether this view should have haptic feedback for events such as + * long presses. + * + *

You may wish to disable haptic feedback if your view already controls + * its own haptic feedback. + * + * @param hapticFeedbackEnabled whether haptic feedback enabled for this view. + * @see #isHapticFeedbackEnabled() + * @see #performHapticFeedback(int) + * @attr ref android.R.styleable#View_hapticFeedbackEnabled + */ + public void setHapticFeedbackEnabled(boolean hapticFeedbackEnabled) { + setFlags(hapticFeedbackEnabled ? HAPTIC_FEEDBACK_ENABLED: 0, HAPTIC_FEEDBACK_ENABLED); + } + /** + * @return whether this view should have haptic feedback enabled for events + * long presses. + * + * @see #setHapticFeedbackEnabled(boolean) + * @see #performHapticFeedback(int) + * @attr ref android.R.styleable#View_hapticFeedbackEnabled + */ + @ViewDebug.ExportedProperty + public boolean isHapticFeedbackEnabled() { + return HAPTIC_FEEDBACK_ENABLED == (mViewFlags & HAPTIC_FEEDBACK_ENABLED); + } + /** + * Returns the layout direction for this view. + * + * @return One of {@link #LAYOUT_DIRECTION_LTR}, + * {@link #LAYOUT_DIRECTION_RTL}, + * {@link #LAYOUT_DIRECTION_INHERIT} or + * {@link #LAYOUT_DIRECTION_LOCALE}. + * @attr ref android.R.styleable#View_layoutDirection + * + * @hide + */ + @ViewDebug.ExportedProperty(category = "layout", mapping = { + @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LTR, to = "LTR"), + @ViewDebug.IntToString(from = LAYOUT_DIRECTION_RTL, to = "RTL"), + @ViewDebug.IntToString(from = LAYOUT_DIRECTION_INHERIT, to = "INHERIT"), + @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LOCALE, to = "LOCALE") + }) + public int getLayoutDirection() { + return mViewFlags & LAYOUT_DIRECTION_MASK; + } + /** + * Set the layout direction for this view. This will propagate a reset of layout direction + * resolution to the view's children and resolve layout direction for this view. + * + * @param layoutDirection One of {@link #LAYOUT_DIRECTION_LTR}, + * {@link #LAYOUT_DIRECTION_RTL}, + * {@link #LAYOUT_DIRECTION_INHERIT} or + * {@link #LAYOUT_DIRECTION_LOCALE}. + * + * @attr ref android.R.styleable#View_layoutDirection + * + * @hide + */ + @RemotableViewMethod + public void setLayoutDirection(int layoutDirection) { + if (getLayoutDirection() != layoutDirection) { + resetResolvedLayoutDirection(); + // Setting the flag will also request a layout. + setFlags(layoutDirection, LAYOUT_DIRECTION_MASK); + } + } + /** + * Returns the resolved layout direction for this view. + * + * @return {@link #LAYOUT_DIRECTION_RTL} if the layout direction is RTL or returns + * {@link #LAYOUT_DIRECTION_LTR} id the layout direction is not RTL. + * + * @hide + */ + @ViewDebug.ExportedProperty(category = "layout", mapping = { + @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LTR, to = "RESOLVED_DIRECTION_LTR"), + @ViewDebug.IntToString(from = LAYOUT_DIRECTION_RTL, to = "RESOLVED_DIRECTION_RTL") + }) + public int getResolvedLayoutDirection() { + resolveLayoutDirectionIfNeeded(); + return ((mPrivateFlags2 & LAYOUT_DIRECTION_RESOLVED_RTL) == LAYOUT_DIRECTION_RESOLVED_RTL) ? + LAYOUT_DIRECTION_RTL : LAYOUT_DIRECTION_LTR; + } + /** + *

Indicates whether or not this view's layout is right-to-left. This is resolved from + * layout attribute and/or the inherited value from the parent.

+ * + * @return true if the layout is right-to-left. + * + * @hide + */ + @ViewDebug.ExportedProperty(category = "layout") + public boolean isLayoutRtl() { + return (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL); + } + /** + * If this view doesn't do any drawing on its own, set this flag to + * allow further optimizations. By default, this flag is not set on + * View, but could be set on some View subclasses such as ViewGroup. + * + * Typically, if you override {@link #onDraw(android.graphics.Canvas)} + * you should clear this flag. + * + * @param willNotDraw whether or not this View draw on its own + */ + public void setWillNotDraw(boolean willNotDraw) { + setFlags(willNotDraw ? WILL_NOT_DRAW : 0, DRAW_MASK); + } + /** + * Returns whether or not this View draws on its own. + * + * @return true if this view has nothing to draw, false otherwise + */ + @ViewDebug.ExportedProperty(category = "drawing") + public boolean willNotDraw() { + return (mViewFlags & DRAW_MASK) == WILL_NOT_DRAW; + } + /** + * When a View's drawing cache is enabled, drawing is redirected to an + * offscreen bitmap. Some views, like an ImageView, must be able to + * bypass this mechanism if they already draw a single bitmap, to avoid + * unnecessary usage of the memory. + * + * @param willNotCacheDrawing true if this view does not cache its + * drawing, false otherwise + */ + public void setWillNotCacheDrawing(boolean willNotCacheDrawing) { + setFlags(willNotCacheDrawing ? WILL_NOT_CACHE_DRAWING : 0, WILL_NOT_CACHE_DRAWING); + } + /** + * Returns whether or not this View can cache its drawing or not. + * + * @return true if this view does not cache its drawing, false otherwise + */ + @ViewDebug.ExportedProperty(category = "drawing") + public boolean willNotCacheDrawing() { + return (mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING; + } + /** + * Indicates whether this view reacts to click events or not. + * + * @return true if the view is clickable, false otherwise + * + * @see #setClickable(boolean) + * @attr ref android.R.styleable#View_clickable + */ + @ViewDebug.ExportedProperty + public boolean isClickable() { + return (mViewFlags & CLICKABLE) == CLICKABLE; + } + /** + * Enables or disables click events for this view. When a view + * is clickable it will change its state to "pressed" on every click. + * Subclasses should set the view clickable to visually react to + * user's clicks. + * + * @param clickable true to make the view clickable, false otherwise + * + * @see #isClickable() + * @attr ref android.R.styleable#View_clickable + */ + public void setClickable(boolean clickable) { + setFlags(clickable ? CLICKABLE : 0, CLICKABLE); + } + /** + * Indicates whether this view reacts to long click events or not. + * + * @return true if the view is long clickable, false otherwise + * + * @see #setLongClickable(boolean) + * @attr ref android.R.styleable#View_longClickable + */ + public boolean isLongClickable() { + return (mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE; + } + /** + * Enables or disables long click events for this view. When a view is long + * clickable it reacts to the user holding down the button for a longer + * duration than a tap. This event can either launch the listener or a + * context menu. + * + * @param longClickable true to make the view long clickable, false otherwise + * @see #isLongClickable() + * @attr ref android.R.styleable#View_longClickable + */ + public void setLongClickable(boolean longClickable) { + setFlags(longClickable ? LONG_CLICKABLE : 0, LONG_CLICKABLE); + } + /** + * Sets the pressed state for this view. + * + * @see #isClickable() + * @see #setClickable(boolean) + * + * @param pressed Pass true to set the View's internal state to "pressed", or false to reverts + * the View's internal state from a previously set "pressed" state. + */ + public void setPressed(boolean pressed) { + if (pressed) { + mPrivateFlags |= PRESSED; + } else { + mPrivateFlags &= ~PRESSED; + } + refreshDrawableState(); + dispatchSetPressed(pressed); + } + /** + * Dispatch setPressed to all of this View's children. + * + * @see #setPressed(boolean) + * + * @param pressed The new pressed state + */ + protected void dispatchSetPressed(boolean pressed) { + } + /** + * Indicates whether the view is currently in pressed state. Unless + * {@link #setPressed(boolean)} is explicitly called, only clickable views can enter + * the pressed state. + * + * @see #setPressed(boolean) + * @see #isClickable() + * @see #setClickable(boolean) + * + * @return true if the view is currently pressed, false otherwise + */ + public boolean isPressed() { + return (mPrivateFlags & PRESSED) == PRESSED; + } + /** + * Indicates whether this view will save its state (that is, + * whether its {@link #onSaveInstanceState} method will be called). + * + * @return Returns true if the view state saving is enabled, else false. + * + * @see #setSaveEnabled(boolean) + * @attr ref android.R.styleable#View_saveEnabled + */ + public boolean isSaveEnabled() { + return (mViewFlags & SAVE_DISABLED_MASK) != SAVE_DISABLED; + } + /** + * Controls whether the saving of this view's state is + * enabled (that is, whether its {@link #onSaveInstanceState} method + * will be called). Note that even if freezing is enabled, the + * view still must have an id assigned to it (via {@link #setId(int)}) + * for its state to be saved. This flag can only disable the + * saving of this view; any child views may still have their state saved. + * + * @param enabled Set to false to disable state saving, or true + * (the default) to allow it. + * + * @see #isSaveEnabled() + * @see #setId(int) + * @see #onSaveInstanceState() + * @attr ref android.R.styleable#View_saveEnabled + */ + public void setSaveEnabled(boolean enabled) { + setFlags(enabled ? 0 : SAVE_DISABLED, SAVE_DISABLED_MASK); + } + /** + * Gets whether the framework should discard touches when the view's + * window is obscured by another visible window. + * Refer to the {@link View} security documentation for more details. + * + * @return True if touch filtering is enabled. + * + * @see #setFilterTouchesWhenObscured(boolean) + * @attr ref android.R.styleable#View_filterTouchesWhenObscured + */ + @ViewDebug.ExportedProperty + public boolean getFilterTouchesWhenObscured() { + return (mViewFlags & FILTER_TOUCHES_WHEN_OBSCURED) != 0; + } + /** + * Sets whether the framework should discard touches when the view's + * window is obscured by another visible window. + * Refer to the {@link View} security documentation for more details. + * + * @param enabled True if touch filtering should be enabled. + * + * @see #getFilterTouchesWhenObscured + * @attr ref android.R.styleable#View_filterTouchesWhenObscured + */ + public void setFilterTouchesWhenObscured(boolean enabled) { + setFlags(enabled ? 0 : FILTER_TOUCHES_WHEN_OBSCURED, + FILTER_TOUCHES_WHEN_OBSCURED); + } + /** + * Indicates whether the entire hierarchy under this view will save its + * state when a state saving traversal occurs from its parent. The default + * is true; if false, these views will not be saved unless + * {@link #saveHierarchyState(SparseArray)} is called directly on this view. + * + * @return Returns true if the view state saving from parent is enabled, else false. + * + * @see #setSaveFromParentEnabled(boolean) + */ + public boolean isSaveFromParentEnabled() { + return (mViewFlags & PARENT_SAVE_DISABLED_MASK) != PARENT_SAVE_DISABLED; + } + /** + * Controls whether the entire hierarchy under this view will save its + * state when a state saving traversal occurs from its parent. The default + * is true; if false, these views will not be saved unless + * {@link #saveHierarchyState(SparseArray)} is called directly on this view. + * + * @param enabled Set to false to disable state saving, or true + * (the default) to allow it. + * + * @see #isSaveFromParentEnabled() + * @see #setId(int) + * @see #onSaveInstanceState() + */ + public void setSaveFromParentEnabled(boolean enabled) { + setFlags(enabled ? 0 : PARENT_SAVE_DISABLED, PARENT_SAVE_DISABLED_MASK); + } + /** + * Returns whether this View is able to take focus. + * + * @return True if this view can take focus, or false otherwise. + * @attr ref android.R.styleable#View_focusable + */ + @ViewDebug.ExportedProperty(category = "focus") + public final boolean isFocusable() { + return FOCUSABLE == (mViewFlags & FOCUSABLE_MASK); + } + /** + * When a view is focusable, it may not want to take focus when in touch mode. + * For example, a button would like focus when the user is navigating via a D-pad + * so that the user can click on it, but once the user starts touching the screen, + * the button shouldn't take focus + * @return Whether the view is focusable in touch mode. + * @attr ref android.R.styleable#View_focusableInTouchMode + */ + @ViewDebug.ExportedProperty + public final boolean isFocusableInTouchMode() { + return FOCUSABLE_IN_TOUCH_MODE == (mViewFlags & FOCUSABLE_IN_TOUCH_MODE); + } + /** + * Find the nearest view in the specified direction that can take focus. + * This does not actually give focus to that view. + * + * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT + * + * @return The nearest focusable in the specified direction, or null if none + * can be found. + */ + public View focusSearch(int direction) { + if (mParent != null) { + return mParent.focusSearch(this, direction); + } else { + return null; + } + } + /** + * This method is the last chance for the focused view and its ancestors to + * respond to an arrow key. This is called when the focused view did not + * consume the key internally, nor could the view system find a new view in + * the requested direction to give focus to. + * + * @param focused The currently focused view. + * @param direction The direction focus wants to move. One of FOCUS_UP, + * FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT. + * @return True if the this view consumed this unhandled move. + */ + public boolean dispatchUnhandledMove(View focused, int direction) { + return false; + } + /** + * If a user manually specified the next view id for a particular direction, + * use the root to look up the view. + * @param root The root view of the hierarchy containing this view. + * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT, FOCUS_FORWARD, + * or FOCUS_BACKWARD. + * @return The user specified next view, or null if there is none. + */ + View findUserSetNextFocus(View root, int direction) { + switch (direction) { + case FOCUS_LEFT: + if (mNextFocusLeftId == View.NO_ID) return null; + return findViewInsideOutShouldExist(root, mNextFocusLeftId); + case FOCUS_RIGHT: + if (mNextFocusRightId == View.NO_ID) return null; + return findViewInsideOutShouldExist(root, mNextFocusRightId); + case FOCUS_UP: + if (mNextFocusUpId == View.NO_ID) return null; + return findViewInsideOutShouldExist(root, mNextFocusUpId); + case FOCUS_DOWN: + if (mNextFocusDownId == View.NO_ID) return null; + return findViewInsideOutShouldExist(root, mNextFocusDownId); + case FOCUS_FORWARD: + if (mNextFocusForwardId == View.NO_ID) return null; + return findViewInsideOutShouldExist(root, mNextFocusForwardId); + case FOCUS_BACKWARD: { + final int id = mID; + return root.findViewByPredicateInsideOut(this, new Predicate() { + @Override + public boolean apply(View t) { + return t.mNextFocusForwardId == id; + } + }); + } + } + return null; + } + private View findViewInsideOutShouldExist(View root, final int childViewId) { + View result = root.findViewByPredicateInsideOut(this, new Predicate() { + @Override + public boolean apply(View t) { + return t.mID == childViewId; + } + }); + if (result == null) { + Log.w(VIEW_LOG_TAG, "couldn't find next focus view specified " + + "by user for id " + childViewId); + } + return result; + } + /** + * Find and return all focusable views that are descendants of this view, + * possibly including this view if it is focusable itself. + * + * @param direction The direction of the focus + * @return A list of focusable views + */ + public ArrayList getFocusables(int direction) { + ArrayList result = new ArrayList(24); + addFocusables(result, direction); + return result; + } + /** + * Add any focusable views that are descendants of this view (possibly + * including this view if it is focusable itself) to views. If we are in touch mode, + * only add views that are also focusable in touch mode. + * + * @param views Focusable views found so far + * @param direction The direction of the focus + */ + public void addFocusables(ArrayList views, int direction) { + addFocusables(views, direction, FOCUSABLES_TOUCH_MODE); + } + /** + * Adds any focusable views that are descendants of this view (possibly + * including this view if it is focusable itself) to views. This method + * adds all focusable views regardless if we are in touch mode or + * only views focusable in touch mode if we are in touch mode depending on + * the focusable mode paramater. + * + * @param views Focusable views found so far or null if all we are interested is + * the number of focusables. + * @param direction The direction of the focus. + * @param focusableMode The type of focusables to be added. + * + * @see #FOCUSABLES_ALL + * @see #FOCUSABLES_TOUCH_MODE + */ + public void addFocusables(ArrayList views, int direction, int focusableMode) { + if (!isFocusable()) { + return; + } + if ((focusableMode & FOCUSABLES_TOUCH_MODE) == FOCUSABLES_TOUCH_MODE && + isInTouchMode() && !isFocusableInTouchMode()) { + return; + } + if (views != null) { + views.add(this); + } + } + /** + * Finds the Views that contain given text. The containment is case insensitive. + * The search is performed by either the text that the View renders or the content + * description that describes the view for accessibility purposes and the view does + * not render or both. Clients can specify how the search is to be performed via + * passing the {@link #FIND_VIEWS_WITH_TEXT} and + * {@link #FIND_VIEWS_WITH_CONTENT_DESCRIPTION} flags. + * + * @param outViews The output list of matching Views. + * @param searched The text to match against. + * + * @see #FIND_VIEWS_WITH_TEXT + * @see #FIND_VIEWS_WITH_CONTENT_DESCRIPTION + * @see #setContentDescription(CharSequence) + */ + public void findViewsWithText(ArrayList outViews, CharSequence searched, int flags) { + if (getAccessibilityNodeProvider() != null) { + if ((flags & FIND_VIEWS_WITH_ACCESSIBILITY_NODE_PROVIDERS) != 0) { + outViews.add(this); + } + } else if ((flags & FIND_VIEWS_WITH_CONTENT_DESCRIPTION) != 0 + && !TextUtils.isEmpty(searched) && !TextUtils.isEmpty(mContentDescription)) { + String searchedLowerCase = searched.toString().toLowerCase(); + String contentDescriptionLowerCase = mContentDescription.toString().toLowerCase(); + if (contentDescriptionLowerCase.contains(searchedLowerCase)) { + outViews.add(this); + } + } + } + /** + * Find and return all touchable views that are descendants of this view, + * possibly including this view if it is touchable itself. + * + * @return A list of touchable views + */ + public ArrayList getTouchables() { + ArrayList result = new ArrayList(); + addTouchables(result); + return result; + } + /** + * Add any touchable views that are descendants of this view (possibly + * including this view if it is touchable itself) to views. + * + * @param views Touchable views found so far + */ + public void addTouchables(ArrayList views) { + final int viewFlags = mViewFlags; + if (((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) + && (viewFlags & ENABLED_MASK) == ENABLED) { + views.add(this); + } + } + /** + * Call this to try to give focus to a specific view or to one of its + * descendants. + * + * A view will not actually take focus if it is not focusable ({@link #isFocusable} returns + * false), or if it is focusable and it is not focusable in touch mode + * ({@link #isFocusableInTouchMode}) while the device is in touch mode. + * + * See also {@link #focusSearch(int)}, which is what you call to say that you + * have focus, and you want your parent to look for the next one. + * + * This is equivalent to calling {@link #requestFocus(int, Rect)} with arguments + * {@link #FOCUS_DOWN} and null. + * + * @return Whether this view or one of its descendants actually took focus. + */ + public final boolean requestFocus() { + return requestFocus(View.FOCUS_DOWN); + } + /** + * Call this to try to give focus to a specific view or to one of its + * descendants and give it a hint about what direction focus is heading. + * + * A view will not actually take focus if it is not focusable ({@link #isFocusable} returns + * false), or if it is focusable and it is not focusable in touch mode + * ({@link #isFocusableInTouchMode}) while the device is in touch mode. + * + * See also {@link #focusSearch(int)}, which is what you call to say that you + * have focus, and you want your parent to look for the next one. + * + * This is equivalent to calling {@link #requestFocus(int, Rect)} with + * null set for the previously focused rectangle. + * + * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT + * @return Whether this view or one of its descendants actually took focus. + */ + public final boolean requestFocus(int direction) { + return requestFocus(direction, null); + } + /** + * Call this to try to give focus to a specific view or to one of its descendants + * and give it hints about the direction and a specific rectangle that the focus + * is coming from. The rectangle can help give larger views a finer grained hint + * about where focus is coming from, and therefore, where to show selection, or + * forward focus change internally. + * + * A view will not actually take focus if it is not focusable ({@link #isFocusable} returns + * false), or if it is focusable and it is not focusable in touch mode + * ({@link #isFocusableInTouchMode}) while the device is in touch mode. + * + * A View will not take focus if it is not visible. + * + * A View will not take focus if one of its parents has + * {@link android.view.ViewGroup#getDescendantFocusability()} equal to + * {@link ViewGroup#FOCUS_BLOCK_DESCENDANTS}. + * + * See also {@link #focusSearch(int)}, which is what you call to say that you + * have focus, and you want your parent to look for the next one. + * + * You may wish to override this method if your custom {@link View} has an internal + * {@link View} that it wishes to forward the request to. + * + * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT + * @param previouslyFocusedRect The rectangle (in this View's coordinate system) + * to give a finer grained hint about where focus is coming from. May be null + * if there is no hint. + * @return Whether this view or one of its descendants actually took focus. + */ + public boolean requestFocus(int direction, Rect previouslyFocusedRect) { + // need to be focusable + if ((mViewFlags & FOCUSABLE_MASK) != FOCUSABLE || + (mViewFlags & VISIBILITY_MASK) != VISIBLE) { + return false; + } + // need to be focusable in touch mode if in touch mode + if (isInTouchMode() && + (FOCUSABLE_IN_TOUCH_MODE != (mViewFlags & FOCUSABLE_IN_TOUCH_MODE))) { + return false; + } + // need to not have any parents blocking us + if (hasAncestorThatBlocksDescendantFocus()) { + return false; + } + handleFocusGainInternal(direction, previouslyFocusedRect); + return true; + } + /** + * Call this to try to give focus to a specific view or to one of its descendants. This is a + * special variant of {@link #requestFocus() } that will allow views that are not focuable in + * touch mode to request focus when they are touched. + * + * @return Whether this view or one of its descendants actually took focus. + * + * @see #isInTouchMode() + * + */ + public final boolean requestFocusFromTouch() { + // Leave touch mode if we need to + if (isInTouchMode()) { + ViewRootImpl viewRoot = getViewRootImpl(); + if (viewRoot != null) { + viewRoot.ensureTouchMode(false); + } + } + return requestFocus(View.FOCUS_DOWN); + } + /** + * @return Whether any ancestor of this view blocks descendant focus. + */ + private boolean hasAncestorThatBlocksDescendantFocus() { + ViewParent ancestor = mParent; + while (ancestor instanceof ViewGroup) { + final ViewGroup vgAncestor = (ViewGroup) ancestor; + if (vgAncestor.getDescendantFocusability() == ViewGroup.FOCUS_BLOCK_DESCENDANTS) { + return true; + } else { + ancestor = vgAncestor.getParent(); + } + } + return false; + } + /** + * @hide + */ + public void dispatchStartTemporaryDetach() { + onStartTemporaryDetach(); + } + /** + * This is called when a container is going to temporarily detach a child, with + * {@link ViewGroup#detachViewFromParent(View) ViewGroup.detachViewFromParent}. + * It will either be followed by {@link #onFinishTemporaryDetach()} or + * {@link #onDetachedFromWindow()} when the container is done. + */ + public void onStartTemporaryDetach() { + removeUnsetPressCallback(); + mPrivateFlags |= CANCEL_NEXT_UP_EVENT; + } + /** + * @hide + */ + public void dispatchFinishTemporaryDetach() { + onFinishTemporaryDetach(); + } + /** + * Called after {@link #onStartTemporaryDetach} when the container is done + * changing the view. + */ + public void onFinishTemporaryDetach() { + } + /** + * Return the global {@link KeyEvent.DispatcherState KeyEvent.DispatcherState} + * for this view's window. Returns null if the view is not currently attached + * to the window. Normally you will not need to use this directly, but + * just use the standard high-level event callbacks like + * {@link #onKeyDown(int, KeyEvent)}. + */ + public KeyEvent.DispatcherState getKeyDispatcherState() { + return mAttachInfo != null ? mAttachInfo.mKeyDispatchState : null; + } + /** + * Dispatch a key event before it is processed by any input method + * associated with the view hierarchy. This can be used to intercept + * key events in special situations before the IME consumes them; a + * typical example would be handling the BACK key to update the application's + * UI instead of allowing the IME to see it and close itself. + * + * @param event The key event to be dispatched. + * @return True if the event was handled, false otherwise. + */ + public boolean dispatchKeyEventPreIme(KeyEvent event) { + return onKeyPreIme(event.getKeyCode(), event); + } + /** + * Dispatch a key event to the next view on the focus path. This path runs + * from the top of the view tree down to the currently focused view. If this + * view has focus, it will dispatch to itself. Otherwise it will dispatch + * the next node down the focus path. This method also fires any key + * listeners. + * + * @param event The key event to be dispatched. + * @return True if the event was handled, false otherwise. + */ + public boolean dispatchKeyEvent(KeyEvent event) { + if (mInputEventConsistencyVerifier != null) { + mInputEventConsistencyVerifier.onKeyEvent(event, 0); + } + // Give any attached key listener a first crack at the event. + //noinspection SimplifiableIfStatement + ListenerInfo li = mListenerInfo; + if (li != null && li.mOnKeyListener != null && (mViewFlags & ENABLED_MASK) == ENABLED + && li.mOnKeyListener.onKey(this, event.getKeyCode(), event)) { + return true; + } + if (event.dispatch(this, mAttachInfo != null + ? mAttachInfo.mKeyDispatchState : null, this)) { + return true; + } + if (mInputEventConsistencyVerifier != null) { + mInputEventConsistencyVerifier.onUnhandledEvent(event, 0); + } + return false; + } + /** + * Dispatches a key shortcut event. + * + * @param event The key event to be dispatched. + * @return True if the event was handled by the view, false otherwise. + */ + public boolean dispatchKeyShortcutEvent(KeyEvent event) { + return onKeyShortcut(event.getKeyCode(), event); + } + /** + * Pass the touch screen motion event down to the target view, or this + * view if it is the target. + * + * @param event The motion event to be dispatched. + * @return True if the event was handled by the view, false otherwise. + */ + public boolean dispatchTouchEvent(MotionEvent event) { + if (mInputEventConsistencyVerifier != null) { + mInputEventConsistencyVerifier.onTouchEvent(event, 0); + } + if (onFilterTouchEventForSecurity(event)) { + //noinspection SimplifiableIfStatement + ListenerInfo li = mListenerInfo; + if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED + && li.mOnTouchListener.onTouch(this, event)) { + return true; + } + if (onTouchEvent(event)) { + return true; + } + } + if (mInputEventConsistencyVerifier != null) { + mInputEventConsistencyVerifier.onUnhandledEvent(event, 0); + } + return false; + } + /** + * Filter the touch event to apply security policies. + * + * @param event The motion event to be filtered. + * @return True if the event should be dispatched, false if the event should be dropped. + * + * @see #getFilterTouchesWhenObscured + */ + public boolean onFilterTouchEventForSecurity(MotionEvent event) { + //noinspection RedundantIfStatement + if ((mViewFlags & FILTER_TOUCHES_WHEN_OBSCURED) != 0 + && (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0) { + // Window is obscured, drop this touch. + return false; + } + return true; + } + /** + * Pass a trackball motion event down to the focused view. + * + * @param event The motion event to be dispatched. + * @return True if the event was handled by the view, false otherwise. + */ + public boolean dispatchTrackballEvent(MotionEvent event) { + if (mInputEventConsistencyVerifier != null) { + mInputEventConsistencyVerifier.onTrackballEvent(event, 0); + } + return onTrackballEvent(event); + } + /** + * Dispatch a generic motion event. + *

+ * Generic motion events with source class {@link InputDevice#SOURCE_CLASS_POINTER} + * are delivered to the view under the pointer. All other generic motion events are + * delivered to the focused view. Hover events are handled specially and are delivered + * to {@link #onHoverEvent(MotionEvent)}. + *

+ * + * @param event The motion event to be dispatched. + * @return True if the event was handled by the view, false otherwise. + */ + public boolean dispatchGenericMotionEvent(MotionEvent event) { + if (mInputEventConsistencyVerifier != null) { + mInputEventConsistencyVerifier.onGenericMotionEvent(event, 0); + } + final int source = event.getSource(); + if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) { + final int action = event.getAction(); + if (action == MotionEvent.ACTION_HOVER_ENTER + || action == MotionEvent.ACTION_HOVER_MOVE + || action == MotionEvent.ACTION_HOVER_EXIT) { + if (dispatchHoverEvent(event)) { + return true; + } + } else if (dispatchGenericPointerEvent(event)) { + return true; + } + } else if (dispatchGenericFocusedEvent(event)) { + return true; + } + if (dispatchGenericMotionEventInternal(event)) { + return true; + } + if (mInputEventConsistencyVerifier != null) { + mInputEventConsistencyVerifier.onUnhandledEvent(event, 0); + } + return false; + } + private boolean dispatchGenericMotionEventInternal(MotionEvent event) { + //noinspection SimplifiableIfStatement + ListenerInfo li = mListenerInfo; + if (li != null && li.mOnGenericMotionListener != null + && (mViewFlags & ENABLED_MASK) == ENABLED + && li.mOnGenericMotionListener.onGenericMotion(this, event)) { + return true; + } + if (onGenericMotionEvent(event)) { + return true; + } + if (mInputEventConsistencyVerifier != null) { + mInputEventConsistencyVerifier.onUnhandledEvent(event, 0); + } + return false; + } + /** + * Dispatch a hover event. + *

+ * Do not call this method directly. + * Call {@link #dispatchGenericMotionEvent(MotionEvent)} instead. + *

+ * + * @param event The motion event to be dispatched. + * @return True if the event was handled by the view, false otherwise. + */ + protected boolean dispatchHoverEvent(MotionEvent event) { + //noinspection SimplifiableIfStatement + ListenerInfo li = mListenerInfo; + if (li != null && li.mOnHoverListener != null + && (mViewFlags & ENABLED_MASK) == ENABLED + && li.mOnHoverListener.onHover(this, event)) { + return true; + } + return onHoverEvent(event); + } + /** + * Returns true if the view has a child to which it has recently sent + * {@link MotionEvent#ACTION_HOVER_ENTER}. If this view is hovered and + * it does not have a hovered child, then it must be the innermost hovered view. + * @hide + */ + protected boolean hasHoveredChild() { + return false; + } + /** + * Dispatch a generic motion event to the view under the first pointer. + *

+ * Do not call this method directly. + * Call {@link #dispatchGenericMotionEvent(MotionEvent)} instead. + *

+ * + * @param event The motion event to be dispatched. + * @return True if the event was handled by the view, false otherwise. + */ + protected boolean dispatchGenericPointerEvent(MotionEvent event) { + return false; + } + /** + * Dispatch a generic motion event to the currently focused view. + *

+ * Do not call this method directly. + * Call {@link #dispatchGenericMotionEvent(MotionEvent)} instead. + *

+ * + * @param event The motion event to be dispatched. + * @return True if the event was handled by the view, false otherwise. + */ + protected boolean dispatchGenericFocusedEvent(MotionEvent event) { + return false; + } + /** + * Dispatch a pointer event. + *

+ * Dispatches touch related pointer events to {@link #onTouchEvent(MotionEvent)} and all + * other events to {@link #onGenericMotionEvent(MotionEvent)}. This separation of concerns + * reinforces the invariant that {@link #onTouchEvent(MotionEvent)} is really about touches + * and should not be expected to handle other pointing device features. + *

+ * + * @param event The motion event to be dispatched. + * @return True if the event was handled by the view, false otherwise. + * @hide + */ + public final boolean dispatchPointerEvent(MotionEvent event) { + if (event.isTouchEvent()) { + return dispatchTouchEvent(event); + } else { + return dispatchGenericMotionEvent(event); + } + } + /** + * Called when the window containing this view gains or loses window focus. + * ViewGroups should override to route to their children. + * + * @param hasFocus True if the window containing this view now has focus, + * false otherwise. + */ + public void dispatchWindowFocusChanged(boolean hasFocus) { + onWindowFocusChanged(hasFocus); + } + /** + * Called when the window containing this view gains or loses focus. Note + * that this is separate from view focus: to receive key events, both + * your view and its window must have focus. If a window is displayed + * on top of yours that takes input focus, then your own window will lose + * focus but the view focus will remain unchanged. + * + * @param hasWindowFocus True if the window containing this view now has + * focus, false otherwise. + */ + public void onWindowFocusChanged(boolean hasWindowFocus) { + InputMethodManager imm = InputMethodManager.peekInstance(); + if (!hasWindowFocus) { + if (isPressed()) { + setPressed(false); + } + if (imm != null && (mPrivateFlags & FOCUSED) != 0) { + imm.focusOut(this); + } + removeLongPressCallback(); + removeTapCallback(); + onFocusLost(); + } else if (imm != null && (mPrivateFlags & FOCUSED) != 0) { + imm.focusIn(this); + } + refreshDrawableState(); + } + /** + * Returns true if this view is in a window that currently has window focus. + * Note that this is not the same as the view itself having focus. + * + * @return True if this view is in a window that currently has window focus. + */ + public boolean hasWindowFocus() { + return mAttachInfo != null && mAttachInfo.mHasWindowFocus; + } + /** + * Dispatch a view visibility change down the view hierarchy. + * ViewGroups should override to route to their children. + * @param changedView The view whose visibility changed. Could be 'this' or + * an ancestor view. + * @param visibility The new visibility of changedView: {@link #VISIBLE}, + * {@link #INVISIBLE} or {@link #GONE}. + */ + protected void dispatchVisibilityChanged(View changedView, int visibility) { + onVisibilityChanged(changedView, visibility); + } + /** + * Called when the visibility of the view or an ancestor of the view is changed. + * @param changedView The view whose visibility changed. Could be 'this' or + * an ancestor view. + * @param visibility The new visibility of changedView: {@link #VISIBLE}, + * {@link #INVISIBLE} or {@link #GONE}. + */ + protected void onVisibilityChanged(View changedView, int visibility) { + if (visibility == VISIBLE) { + if (mAttachInfo != null) { + initialAwakenScrollBars(); + } else { + mPrivateFlags |= AWAKEN_SCROLL_BARS_ON_ATTACH; + } + } + } + /** + * Dispatch a hint about whether this view is displayed. For instance, when + * a View moves out of the screen, it might receives a display hint indicating + * the view is not displayed. Applications should not rely on this hint + * as there is no guarantee that they will receive one. + * + * @param hint A hint about whether or not this view is displayed: + * {@link #VISIBLE} or {@link #INVISIBLE}. + */ + public void dispatchDisplayHint(int hint) { + onDisplayHint(hint); + } + /** + * Gives this view a hint about whether is displayed or not. For instance, when + * a View moves out of the screen, it might receives a display hint indicating + * the view is not displayed. Applications should not rely on this hint + * as there is no guarantee that they will receive one. + * + * @param hint A hint about whether or not this view is displayed: + * {@link #VISIBLE} or {@link #INVISIBLE}. + */ + protected void onDisplayHint(int hint) { + } + /** + * Dispatch a window visibility change down the view hierarchy. + * ViewGroups should override to route to their children. + * + * @param visibility The new visibility of the window. + * + * @see #onWindowVisibilityChanged(int) + */ + public void dispatchWindowVisibilityChanged(int visibility) { + onWindowVisibilityChanged(visibility); + } + /** + * Called when the window containing has change its visibility + * (between {@link #GONE}, {@link #INVISIBLE}, and {@link #VISIBLE}). Note + * that this tells you whether or not your window is being made visible + * to the window manager; this does not tell you whether or not + * your window is obscured by other windows on the screen, even if it + * is itself visible. + * + * @param visibility The new visibility of the window. + */ + protected void onWindowVisibilityChanged(int visibility) { + if (visibility == VISIBLE) { + initialAwakenScrollBars(); + } + } + /** + * Returns the current visibility of the window this view is attached to + * (either {@link #GONE}, {@link #INVISIBLE}, or {@link #VISIBLE}). + * + * @return Returns the current visibility of the view's window. + */ + public int getWindowVisibility() { + return mAttachInfo != null ? mAttachInfo.mWindowVisibility : GONE; + } + /** + * Retrieve the overall visible display size in which the window this view is + * attached to has been positioned in. This takes into account screen + * decorations above the window, for both cases where the window itself + * is being position inside of them or the window is being placed under + * then and covered insets are used for the window to position its content + * inside. In effect, this tells you the available area where content can + * be placed and remain visible to users. + * + *

This function requires an IPC back to the window manager to retrieve + * the requested information, so should not be used in performance critical + * code like drawing. + * + * @param outRect Filled in with the visible display frame. If the view + * is not attached to a window, this is simply the raw display size. + */ + public void getWindowVisibleDisplayFrame(Rect outRect) { + if (mAttachInfo != null) { + try { + mAttachInfo.mSession.getDisplayFrame(mAttachInfo.mWindow, outRect); + } catch (RemoteException e) { + return; + } + // XXX This is really broken, and probably all needs to be done + // in the window manager, and we need to know more about whether + // we want the area behind or in front of the IME. + final Rect insets = mAttachInfo.mVisibleInsets; + outRect.left += insets.left; + outRect.top += insets.top; + outRect.right -= insets.right; + outRect.bottom -= insets.bottom; + return; + } + Display d = WindowManagerImpl.getDefault().getDefaultDisplay(); + d.getRectSize(outRect); + } + /** + * Dispatch a notification about a resource configuration change down + * the view hierarchy. + * ViewGroups should override to route to their children. + * + * @param newConfig The new resource configuration. + * + * @see #onConfigurationChanged(android.content.res.Configuration) + */ + public void dispatchConfigurationChanged(Configuration newConfig) { + onConfigurationChanged(newConfig); + } + /** + * Called when the current configuration of the resources being used + * by the application have changed. You can use this to decide when + * to reload resources that can changed based on orientation and other + * configuration characterstics. You only need to use this if you are + * not relying on the normal {@link android.app.Activity} mechanism of + * recreating the activity instance upon a configuration change. + * + * @param newConfig The new resource configuration. + */ + protected void onConfigurationChanged(Configuration newConfig) { + } + /** + * Private function to aggregate all per-view attributes in to the view + * root. + */ + void dispatchCollectViewAttributes(int visibility) { + performCollectViewAttributes(visibility); + } + void performCollectViewAttributes(int visibility) { + if ((visibility & VISIBILITY_MASK) == VISIBLE && mAttachInfo != null) { + if ((mViewFlags & KEEP_SCREEN_ON) == KEEP_SCREEN_ON) { + mAttachInfo.mKeepScreenOn = true; + } + mAttachInfo.mSystemUiVisibility |= mSystemUiVisibility; + ListenerInfo li = mListenerInfo; + if (li != null && li.mOnSystemUiVisibilityChangeListener != null) { + mAttachInfo.mHasSystemUiListeners = true; + } + } + } + void needGlobalAttributesUpdate(boolean force) { + final AttachInfo ai = mAttachInfo; + if (ai != null) { + if (force || ai.mKeepScreenOn || (ai.mSystemUiVisibility != 0) + || ai.mHasSystemUiListeners) { + ai.mRecomputeGlobalAttributes = true; + } + } + } + /** + * Returns whether the device is currently in touch mode. Touch mode is entered + * once the user begins interacting with the device by touch, and affects various + * things like whether focus is always visible to the user. + * + * @return Whether the device is in touch mode. + */ + @ViewDebug.ExportedProperty + public boolean isInTouchMode() { + if (mAttachInfo != null) { + return mAttachInfo.mInTouchMode; + } else { + return ViewRootImpl.isInTouchMode(); + } + } + /** + * Returns the context the view is running in, through which it can + * access the current theme, resources, etc. + * + * @return The view's Context. + */ + @ViewDebug.CapturedViewProperty + public final Context getContext() { + return mContext; + } + /** + * Handle a key event before it is processed by any input method + * associated with the view hierarchy. This can be used to intercept + * key events in special situations before the IME consumes them; a + * typical example would be handling the BACK key to update the application's + * UI instead of allowing the IME to see it and close itself. + * + * @param keyCode The value in event.getKeyCode(). + * @param event Description of the key event. + * @return If you handled the event, return true. If you want to allow the + * event to be handled by the next receiver, return false. + */ + public boolean onKeyPreIme(int keyCode, KeyEvent event) { + return false; + } + /** + * Default implementation of {@link KeyEvent.Callback#onKeyDown(int, KeyEvent) + * KeyEvent.Callback.onKeyDown()}: perform press of the view + * when {@link KeyEvent#KEYCODE_DPAD_CENTER} or {@link KeyEvent#KEYCODE_ENTER} + * is released, if the view is enabled and clickable. + * + * @param keyCode A key code that represents the button pressed, from + * {@link android.view.KeyEvent}. + * @param event The KeyEvent object that defines the button action. + */ + public boolean onKeyDown(int keyCode, KeyEvent event) { + boolean result = false; + switch (keyCode) { + case KeyEvent.KEYCODE_DPAD_CENTER: + case KeyEvent.KEYCODE_ENTER: { + if ((mViewFlags & ENABLED_MASK) == DISABLED) { + return true; + } + // Long clickable items don't necessarily have to be clickable + if (((mViewFlags & CLICKABLE) == CLICKABLE || + (mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) && + (event.getRepeatCount() == 0)) { + setPressed(true); + checkForLongClick(0); + return true; + } + break; + } + } + return result; + } + /** + * Default implementation of {@link KeyEvent.Callback#onKeyLongPress(int, KeyEvent) + * KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle + * the event). + */ + public boolean onKeyLongPress(int keyCode, KeyEvent event) { + return false; + } + /** + * Default implementation of {@link KeyEvent.Callback#onKeyUp(int, KeyEvent) + * KeyEvent.Callback.onKeyUp()}: perform clicking of the view + * when {@link KeyEvent#KEYCODE_DPAD_CENTER} or + * {@link KeyEvent#KEYCODE_ENTER} is released. + * + * @param keyCode A key code that represents the button pressed, from + * {@link android.view.KeyEvent}. + * @param event The KeyEvent object that defines the button action. + */ + public boolean onKeyUp(int keyCode, KeyEvent event) { + boolean result = false; + switch (keyCode) { + case KeyEvent.KEYCODE_DPAD_CENTER: + case KeyEvent.KEYCODE_ENTER: { + if ((mViewFlags & ENABLED_MASK) == DISABLED) { + return true; + } + if ((mViewFlags & CLICKABLE) == CLICKABLE && isPressed()) { + setPressed(false); + if (!mHasPerformedLongPress) { + // This is a tap, so remove the longpress check + removeLongPressCallback(); + result = performClick(); + } + } + break; + } + } + return result; + } + /** + * Default implementation of {@link KeyEvent.Callback#onKeyMultiple(int, int, KeyEvent) + * KeyEvent.Callback.onKeyMultiple()}: always returns false (doesn't handle + * the event). + * + * @param keyCode A key code that represents the button pressed, from + * {@link android.view.KeyEvent}. + * @param repeatCount The number of times the action was made. + * @param event The KeyEvent object that defines the button action. + */ + public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { + return false; + } + /** + * Called on the focused view when a key shortcut event is not handled. + * Override this method to implement local key shortcuts for the View. + * Key shortcuts can also be implemented by setting the + * {@link MenuItem#setShortcut(char, char) shortcut} property of menu items. + * + * @param keyCode The value in event.getKeyCode(). + * @param event Description of the key event. + * @return If you handled the event, return true. If you want to allow the + * event to be handled by the next receiver, return false. + */ + public boolean onKeyShortcut(int keyCode, KeyEvent event) { + return false; + } + /** + * Check whether the called view is a text editor, in which case it + * would make sense to automatically display a soft input window for + * it. Subclasses should override this if they implement + * {@link #onCreateInputConnection(EditorInfo)} to return true if + * a call on that method would return a non-null InputConnection, and + * they are really a first-class editor that the user would normally + * start typing on when the go into a window containing your view. + * + *

The default implementation always returns false. This does + * not mean that its {@link #onCreateInputConnection(EditorInfo)} + * will not be called or the user can not otherwise perform edits on your + * view; it is just a hint to the system that this is not the primary + * purpose of this view. + * + * @return Returns true if this view is a text editor, else false. + */ + public boolean onCheckIsTextEditor() { + return false; + } + /** + * Create a new InputConnection for an InputMethod to interact + * with the view. The default implementation returns null, since it doesn't + * support input methods. You can override this to implement such support. + * This is only needed for views that take focus and text input. + * + *

When implementing this, you probably also want to implement + * {@link #onCheckIsTextEditor()} to indicate you will return a + * non-null InputConnection. + * + * @param outAttrs Fill in with attribute information about the connection. + */ + public InputConnection onCreateInputConnection(EditorInfo outAttrs) { + return null; + } + /** + * Called by the {@link android.view.inputmethod.InputMethodManager} + * when a view who is not the current + * input connection target is trying to make a call on the manager. The + * default implementation returns false; you can override this to return + * true for certain views if you are performing InputConnection proxying + * to them. + * @param view The View that is making the InputMethodManager call. + * @return Return true to allow the call, false to reject. + */ + public boolean checkInputConnectionProxy(View view) { + return false; + } + /** + * Show the context menu for this view. It is not safe to hold on to the + * menu after returning from this method. + * + * You should normally not overload this method. Overload + * {@link #onCreateContextMenu(ContextMenu)} or define an + * {@link OnCreateContextMenuListener} to add items to the context menu. + * + * @param menu The context menu to populate + */ + public void createContextMenu(ContextMenu menu) { + ContextMenuInfo menuInfo = getContextMenuInfo(); + // Sets the current menu info so all items added to menu will have + // my extra info set. + ((MenuBuilder)menu).setCurrentMenuInfo(menuInfo); + onCreateContextMenu(menu); + ListenerInfo li = mListenerInfo; + if (li != null && li.mOnCreateContextMenuListener != null) { + li.mOnCreateContextMenuListener.onCreateContextMenu(menu, this, menuInfo); + } + // Clear the extra information so subsequent items that aren't mine don't + // have my extra info. + ((MenuBuilder)menu).setCurrentMenuInfo(null); + if (mParent != null) { + mParent.createContextMenu(menu); + } + } + /** + * Views should implement this if they have extra information to associate + * with the context menu. The return result is supplied as a parameter to + * the {@link OnCreateContextMenuListener#onCreateContextMenu(ContextMenu, View, ContextMenuInfo)} + * callback. + * + * @return Extra information about the item for which the context menu + * should be shown. This information will vary across different + * subclasses of View. + */ + protected ContextMenuInfo getContextMenuInfo() { + return null; + } + /** + * Views should implement this if the view itself is going to add items to + * the context menu. + * + * @param menu the context menu to populate + */ + protected void onCreateContextMenu(ContextMenu menu) { + } + /** + * Implement this method to handle trackball motion events. The + * relative movement of the trackball since the last event + * can be retrieve with {@link MotionEvent#getX MotionEvent.getX()} and + * {@link MotionEvent#getY MotionEvent.getY()}. These are normalized so + * that a movement of 1 corresponds to the user pressing one DPAD key (so + * they will often be fractional values, representing the more fine-grained + * movement information available from a trackball). + * + * @param event The motion event. + * @return True if the event was handled, false otherwise. + */ + public boolean onTrackballEvent(MotionEvent event) { + return false; + } + /** + * Implement this method to handle generic motion events. + *

+ * Generic motion events describe joystick movements, mouse hovers, track pad + * touches, scroll wheel movements and other input events. The + * {@link MotionEvent#getSource() source} of the motion event specifies + * the class of input that was received. Implementations of this method + * must examine the bits in the source before processing the event. + * The following code example shows how this is done. + *

+ * Generic motion events with source class {@link InputDevice#SOURCE_CLASS_POINTER} + * are delivered to the view under the pointer. All other generic motion events are + * delivered to the focused view. + *

+ *
 public boolean onGenericMotionEvent(MotionEvent event) {
+     *     if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
+     *         if (event.getAction() == MotionEvent.ACTION_MOVE) {
+     *             // process the joystick movement...
+     *             return true;
+     *         }
+     *     }
+     *     if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+     *         switch (event.getAction()) {
+     *             case MotionEvent.ACTION_HOVER_MOVE:
+     *                 // process the mouse hover movement...
+     *                 return true;
+     *             case MotionEvent.ACTION_SCROLL:
+     *                 // process the scroll wheel movement...
+     *                 return true;
+     *         }
+     *     }
+     *     return super.onGenericMotionEvent(event);
+     * }
+ * + * @param event The generic motion event being processed. + * @return True if the event was handled, false otherwise. + */ + public boolean onGenericMotionEvent(MotionEvent event) { + return false; + } + /** + * Implement this method to handle hover events. + *

+ * This method is called whenever a pointer is hovering into, over, or out of the + * bounds of a view and the view is not currently being touched. + * Hover events are represented as pointer events with action + * {@link MotionEvent#ACTION_HOVER_ENTER}, {@link MotionEvent#ACTION_HOVER_MOVE}, + * or {@link MotionEvent#ACTION_HOVER_EXIT}. + *

+ *
    + *
  • The view receives a hover event with action {@link MotionEvent#ACTION_HOVER_ENTER} + * when the pointer enters the bounds of the view.
  • + *
  • The view receives a hover event with action {@link MotionEvent#ACTION_HOVER_MOVE} + * when the pointer has already entered the bounds of the view and has moved.
  • + *
  • The view receives a hover event with action {@link MotionEvent#ACTION_HOVER_EXIT} + * when the pointer has exited the bounds of the view or when the pointer is + * about to go down due to a button click, tap, or similar user action that + * causes the view to be touched.
  • + *
+ *

+ * The view should implement this method to return true to indicate that it is + * handling the hover event, such as by changing its drawable state. + *

+ * The default implementation calls {@link #setHovered} to update the hovered state + * of the view when a hover enter or hover exit event is received, if the view + * is enabled and is clickable. The default implementation also sends hover + * accessibility events. + *

+ * + * @param event The motion event that describes the hover. + * @return True if the view handled the hover event. + * + * @see #isHovered + * @see #setHovered + * @see #onHoverChanged + */ + public boolean onHoverEvent(MotionEvent event) { + // The root view may receive hover (or touch) events that are outside the bounds of + // the window. This code ensures that we only send accessibility events for + // hovers that are actually within the bounds of the root view. + final int action = event.getAction(); + if (!mSendingHoverAccessibilityEvents) { + if ((action == MotionEvent.ACTION_HOVER_ENTER + || action == MotionEvent.ACTION_HOVER_MOVE) + && !hasHoveredChild() + && pointInView(event.getX(), event.getY())) { + mSendingHoverAccessibilityEvents = true; + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER); + } + } else { + if (action == MotionEvent.ACTION_HOVER_EXIT + || (action == MotionEvent.ACTION_HOVER_MOVE + && !pointInView(event.getX(), event.getY()))) { + mSendingHoverAccessibilityEvents = false; + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT); + } + } + if (isHoverable()) { + switch (action) { + case MotionEvent.ACTION_HOVER_ENTER: + setHovered(true); + break; + case MotionEvent.ACTION_HOVER_EXIT: + setHovered(false); + break; + } + // Dispatch the event to onGenericMotionEvent before returning true. + // This is to provide compatibility with existing applications that + // handled HOVER_MOVE events in onGenericMotionEvent and that would + // break because of the new default handling for hoverable views + // in onHoverEvent. + // Note that onGenericMotionEvent will be called by default when + // onHoverEvent returns false (refer to dispatchGenericMotionEvent). + dispatchGenericMotionEventInternal(event); + return true; + } + return false; + } + /** + * Returns true if the view should handle {@link #onHoverEvent} + * by calling {@link #setHovered} to change its hovered state. + * + * @return True if the view is hoverable. + */ + private boolean isHoverable() { + final int viewFlags = mViewFlags; + //noinspection SimplifiableIfStatement + if ((viewFlags & ENABLED_MASK) == DISABLED) { + return false; + } + return (viewFlags & CLICKABLE) == CLICKABLE + || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE; + } + /** + * Returns true if the view is currently hovered. + * + * @return True if the view is currently hovered. + * + * @see #setHovered + * @see #onHoverChanged + */ + @ViewDebug.ExportedProperty + public boolean isHovered() { + return (mPrivateFlags & HOVERED) != 0; + } + /** + * Sets whether the view is currently hovered. + *

+ * Calling this method also changes the drawable state of the view. This + * enables the view to react to hover by using different drawable resources + * to change its appearance. + *

+ * The {@link #onHoverChanged} method is called when the hovered state changes. + *

+ * + * @param hovered True if the view is hovered. + * + * @see #isHovered + * @see #onHoverChanged + */ + public void setHovered(boolean hovered) { + if (hovered) { + if ((mPrivateFlags & HOVERED) == 0) { + mPrivateFlags |= HOVERED; + refreshDrawableState(); + onHoverChanged(true); + } + } else { + if ((mPrivateFlags & HOVERED) != 0) { + mPrivateFlags &= ~HOVERED; + refreshDrawableState(); + onHoverChanged(false); + } + } + } + /** + * Implement this method to handle hover state changes. + *

+ * This method is called whenever the hover state changes as a result of a + * call to {@link #setHovered}. + *

+ * + * @param hovered The current hover state, as returned by {@link #isHovered}. + * + * @see #isHovered + * @see #setHovered + */ + public void onHoverChanged(boolean hovered) { + } + /** + * Implement this method to handle touch screen motion events. + * + * @param event The motion event. + * @return True if the event was handled, false otherwise. + */ + public boolean onTouchEvent(MotionEvent event) { + final int viewFlags = mViewFlags; + if ((viewFlags & ENABLED_MASK) == DISABLED) { + if (event.getAction() == MotionEvent.ACTION_UP && (mPrivateFlags & PRESSED) != 0) { + mPrivateFlags &= ~PRESSED; + refreshDrawableState(); + } + // A disabled view that is clickable still consumes the touch + // events, it just doesn't respond to them. + return (((viewFlags & CLICKABLE) == CLICKABLE || + (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)); + } + if (mTouchDelegate != null) { + if (mTouchDelegate.onTouchEvent(event)) { + return true; + } + } + if (((viewFlags & CLICKABLE) == CLICKABLE || + (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) { + switch (event.getAction()) { + case MotionEvent.ACTION_UP: + boolean prepressed = (mPrivateFlags & PREPRESSED) != 0; + if ((mPrivateFlags & PRESSED) != 0 || prepressed) { + // take focus if we don't have it already and we should in + // touch mode. + boolean focusTaken = false; + if (isFocusable() && isFocusableInTouchMode() && !isFocused()) { + focusTaken = requestFocus(); + } + if (prepressed) { + // The button is being released before we actually + // showed it as pressed. Make it show the pressed + // state now (before scheduling the click) to ensure + // the user sees it. + mPrivateFlags |= PRESSED; + refreshDrawableState(); + } + if (!mHasPerformedLongPress) { + // This is a tap, so remove the longpress check + removeLongPressCallback(); + // Only perform take click actions if we were in the pressed state + if (!focusTaken) { + // Use a Runnable and post this rather than calling + // performClick directly. This lets other visual state + // of the view update before click actions start. + if (mPerformClick == null) { + mPerformClick = new PerformClick(); + } + if (!post(mPerformClick)) { + performClick(); + } + } + } + if (mUnsetPressedState == null) { + mUnsetPressedState = new UnsetPressedState(); + } + if (prepressed) { + postDelayed(mUnsetPressedState, + ViewConfiguration.getPressedStateDuration()); + } else if (!post(mUnsetPressedState)) { + // If the post failed, unpress right now + mUnsetPressedState.run(); + } + removeTapCallback(); + } + break; + case MotionEvent.ACTION_DOWN: + mHasPerformedLongPress = false; + if (performButtonActionOnTouchDown(event)) { + break; + } + // Walk up the hierarchy to determine if we're inside a scrolling container. + boolean isInScrollingContainer = isInScrollingContainer(); + // For views inside a scrolling container, delay the pressed feedback for + // a short period in case this is a scroll. + if (isInScrollingContainer) { + mPrivateFlags |= PREPRESSED; + if (mPendingCheckForTap == null) { + mPendingCheckForTap = new CheckForTap(); + } + postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout()); + } else { + // Not inside a scrolling container, so show the feedback right away + mPrivateFlags |= PRESSED; + refreshDrawableState(); + checkForLongClick(0); + } + break; + case MotionEvent.ACTION_CANCEL: + mPrivateFlags &= ~PRESSED; + refreshDrawableState(); + removeTapCallback(); + break; + case MotionEvent.ACTION_MOVE: + final int x = (int) event.getX(); + final int y = (int) event.getY(); + // Be lenient about moving outside of buttons + if (!pointInView(x, y, mTouchSlop)) { + // Outside button + removeTapCallback(); + if ((mPrivateFlags & PRESSED) != 0) { + // Remove any future long press/tap checks + removeLongPressCallback(); + // Need to switch from pressed to not pressed + mPrivateFlags &= ~PRESSED; + refreshDrawableState(); + } + } + break; + } + return true; + } + return false; + } + /** + * @hide + */ + public boolean isInScrollingContainer() { + ViewParent p = getParent(); + while (p != null && p instanceof ViewGroup) { + if (((ViewGroup) p).shouldDelayChildPressedState()) { + return true; + } + p = p.getParent(); + } + return false; + } + /** + * Remove the longpress detection timer. + */ + private void removeLongPressCallback() { + if (mPendingCheckForLongPress != null) { + removeCallbacks(mPendingCheckForLongPress); + } + } + /** + * Remove the pending click action + */ + private void removePerformClickCallback() { + if (mPerformClick != null) { + removeCallbacks(mPerformClick); + } + } + /** + * Remove the prepress detection timer. + */ + private void removeUnsetPressCallback() { + if ((mPrivateFlags & PRESSED) != 0 && mUnsetPressedState != null) { + setPressed(false); + removeCallbacks(mUnsetPressedState); + } + } + /** + * Remove the tap detection timer. + */ + private void removeTapCallback() { + if (mPendingCheckForTap != null) { + mPrivateFlags &= ~PREPRESSED; + removeCallbacks(mPendingCheckForTap); + } + } + /** + * Cancels a pending long press. Your subclass can use this if you + * want the context menu to come up if the user presses and holds + * at the same place, but you don't want it to come up if they press + * and then move around enough to cause scrolling. + */ + public void cancelLongPress() { + removeLongPressCallback(); + /* + * The prepressed state handled by the tap callback is a display + * construct, but the tap callback will post a long press callback + * less its own timeout. Remove it here. + */ + removeTapCallback(); + } + /** + * Remove the pending callback for sending a + * {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} accessibility event. + */ + private void removeSendViewScrolledAccessibilityEventCallback() { + if (mSendViewScrolledAccessibilityEvent != null) { + removeCallbacks(mSendViewScrolledAccessibilityEvent); + } + } + /** + * Sets the TouchDelegate for this View. + */ + public void setTouchDelegate(TouchDelegate delegate) { + mTouchDelegate = delegate; + } + /** + * Gets the TouchDelegate for this View. + */ + public TouchDelegate getTouchDelegate() { + return mTouchDelegate; + } + /** + * Set flags controlling behavior of this view. + * + * @param flags Constant indicating the value which should be set + * @param mask Constant indicating the bit range that should be changed + */ + void setFlags(int flags, int mask) { + int old = mViewFlags; + mViewFlags = (mViewFlags & ~mask) | (flags & mask); + int changed = mViewFlags ^ old; + if (changed == 0) { + return; + } + int privateFlags = mPrivateFlags; + /* Check if the FOCUSABLE bit has changed */ + if (((changed & FOCUSABLE_MASK) != 0) && + ((privateFlags & HAS_BOUNDS) !=0)) { + if (((old & FOCUSABLE_MASK) == FOCUSABLE) + && ((privateFlags & FOCUSED) != 0)) { + /* Give up focus if we are no longer focusable */ + clearFocus(); + } else if (((old & FOCUSABLE_MASK) == NOT_FOCUSABLE) + && ((privateFlags & FOCUSED) == 0)) { + /* + * Tell the view system that we are now available to take focus + * if no one else already has it. + */ + if (mParent != null) mParent.focusableViewAvailable(this); + } + } + if ((flags & VISIBILITY_MASK) == VISIBLE) { + if ((changed & VISIBILITY_MASK) != 0) { + /* + * If this view is becoming visible, invalidate it in case it changed while + * it was not visible. Marking it drawn ensures that the invalidation will + * go through. + */ + mPrivateFlags |= DRAWN; + invalidate(true); + needGlobalAttributesUpdate(true); + // a view becoming visible is worth notifying the parent + // about in case nothing has focus. even if this specific view + // isn't focusable, it may contain something that is, so let + // the root view try to give this focus if nothing else does. + if ((mParent != null) && (mBottom > mTop) && (mRight > mLeft)) { + mParent.focusableViewAvailable(this); + } + } + } + /* Check if the GONE bit has changed */ + if ((changed & GONE) != 0) { + needGlobalAttributesUpdate(false); + requestLayout(); + if (((mViewFlags & VISIBILITY_MASK) == GONE)) { + if (hasFocus()) clearFocus(); + destroyDrawingCache(); + if (mParent instanceof View) { + // GONE views noop invalidation, so invalidate the parent + ((View) mParent).invalidate(true); + } + // Mark the view drawn to ensure that it gets invalidated properly the next + // time it is visible and gets invalidated + mPrivateFlags |= DRAWN; + } + if (mAttachInfo != null) { + mAttachInfo.mViewVisibilityChanged = true; + } + } + /* Check if the VISIBLE bit has changed */ + if ((changed & INVISIBLE) != 0) { + needGlobalAttributesUpdate(false); + /* + * If this view is becoming invisible, set the DRAWN flag so that + * the next invalidate() will not be skipped. + */ + mPrivateFlags |= DRAWN; + if (((mViewFlags & VISIBILITY_MASK) == INVISIBLE) && hasFocus()) { + // root view becoming invisible shouldn't clear focus + if (getRootView() != this) { + clearFocus(); + } + } + if (mAttachInfo != null) { + mAttachInfo.mViewVisibilityChanged = true; + } + } + if ((changed & VISIBILITY_MASK) != 0) { + if (mParent instanceof ViewGroup) { + ((ViewGroup) mParent).onChildVisibilityChanged(this, (changed & VISIBILITY_MASK), + (flags & VISIBILITY_MASK)); + ((View) mParent).invalidate(true); + } else if (mParent != null) { + mParent.invalidateChild(this, null); + } + dispatchVisibilityChanged(this, (flags & VISIBILITY_MASK)); + } + if ((changed & WILL_NOT_CACHE_DRAWING) != 0) { + destroyDrawingCache(); + } + if ((changed & DRAWING_CACHE_ENABLED) != 0) { + destroyDrawingCache(); + mPrivateFlags &= ~DRAWING_CACHE_VALID; + invalidateParentCaches(); + } + if ((changed & DRAWING_CACHE_QUALITY_MASK) != 0) { + destroyDrawingCache(); + mPrivateFlags &= ~DRAWING_CACHE_VALID; + } + if ((changed & DRAW_MASK) != 0) { + if ((mViewFlags & WILL_NOT_DRAW) != 0) { + if (mBGDrawable != null) { + mPrivateFlags &= ~SKIP_DRAW; + mPrivateFlags |= ONLY_DRAWS_BACKGROUND; + } else { + mPrivateFlags |= SKIP_DRAW; + } + } else { + mPrivateFlags &= ~SKIP_DRAW; + } + requestLayout(); + invalidate(true); + } + if ((changed & KEEP_SCREEN_ON) != 0) { + if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) { + mParent.recomputeViewAttributes(this); + } + } + if ((changed & LAYOUT_DIRECTION_MASK) != 0) { + requestLayout(); + } + } + /** + * Change the view's z order in the tree, so it's on top of other sibling + * views + */ + public void bringToFront() { + if (mParent != null) { + mParent.bringChildToFront(this); + } + } + /** + * This is called in response to an internal scroll in this view (i.e., the + * view scrolled its own contents). This is typically as a result of + * {@link #scrollBy(int, int)} or {@link #scrollTo(int, int)} having been + * called. + * + * @param l Current horizontal scroll origin. + * @param t Current vertical scroll origin. + * @param oldl Previous horizontal scroll origin. + * @param oldt Previous vertical scroll origin. + */ + protected void onScrollChanged(int l, int t, int oldl, int oldt) { + if (AccessibilityManager.getInstance(mContext).isEnabled()) { + postSendViewScrolledAccessibilityEventCallback(); + } + mBackgroundSizeChanged = true; + final AttachInfo ai = mAttachInfo; + if (ai != null) { + ai.mViewScrollChanged = true; + } + } + /** + * Interface definition for a callback to be invoked when the layout bounds of a view + * changes due to layout processing. + */ + public interface OnLayoutChangeListener { + /** + * Called when the focus state of a view has changed. + * + * @param v The view whose state has changed. + * @param left The new value of the view's left property. + * @param top The new value of the view's top property. + * @param right The new value of the view's right property. + * @param bottom The new value of the view's bottom property. + * @param oldLeft The previous value of the view's left property. + * @param oldTop The previous value of the view's top property. + * @param oldRight The previous value of the view's right property. + * @param oldBottom The previous value of the view's bottom property. + */ + void onLayoutChange(View v, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom); + } + /** + * This is called during layout when the size of this view has changed. If + * you were just added to the view hierarchy, you're called with the old + * values of 0. + * + * @param w Current width of this view. + * @param h Current height of this view. + * @param oldw Old width of this view. + * @param oldh Old height of this view. + */ + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + } + /** + * Called by draw to draw the child views. This may be overridden + * by derived classes to gain control just before its children are drawn + * (but after its own view has been drawn). + * @param canvas the canvas on which to draw the view + */ + protected void dispatchDraw(Canvas canvas) { + } + /** + * Gets the parent of this view. Note that the parent is a + * ViewParent and not necessarily a View. + * + * @return Parent of this view. + */ + public final ViewParent getParent() { + return mParent; + } + /** + * Set the horizontal scrolled position of your view. This will cause a call to + * {@link #onScrollChanged(int, int, int, int)} and the view will be + * invalidated. + * @param value the x position to scroll to + */ + public void setScrollX(int value) { + scrollTo(value, mScrollY); + } + /** + * Set the vertical scrolled position of your view. This will cause a call to + * {@link #onScrollChanged(int, int, int, int)} and the view will be + * invalidated. + * @param value the y position to scroll to + */ + public void setScrollY(int value) { + scrollTo(mScrollX, value); + } + /** + * Return the scrolled left position of this view. This is the left edge of + * the displayed part of your view. You do not need to draw any pixels + * farther left, since those are outside of the frame of your view on + * screen. + * + * @return The left edge of the displayed part of your view, in pixels. + */ + public final int getScrollX() { + return mScrollX; + } + /** + * Return the scrolled top position of this view. This is the top edge of + * the displayed part of your view. You do not need to draw any pixels above + * it, since those are outside of the frame of your view on screen. + * + * @return The top edge of the displayed part of your view, in pixels. + */ + public final int getScrollY() { + return mScrollY; + } + /** + * Return the width of the your view. + * + * @return The width of your view, in pixels. + */ + @ViewDebug.ExportedProperty(category = "layout") + public final int getWidth() { + return mRight - mLeft; + } + /** + * Return the height of your view. + * + * @return The height of your view, in pixels. + */ + @ViewDebug.ExportedProperty(category = "layout") + public final int getHeight() { + return mBottom - mTop; + } + /** + * Return the visible drawing bounds of your view. Fills in the output + * rectangle with the values from getScrollX(), getScrollY(), + * getWidth(), and getHeight(). + * + * @param outRect The (scrolled) drawing bounds of the view. + */ + public void getDrawingRect(Rect outRect) { + outRect.left = mScrollX; + outRect.top = mScrollY; + outRect.right = mScrollX + (mRight - mLeft); + outRect.bottom = mScrollY + (mBottom - mTop); + } + /** + * Like {@link #getMeasuredWidthAndState()}, but only returns the + * raw width component (that is the result is masked by + * {@link #MEASURED_SIZE_MASK}). + * + * @return The raw measured width of this view. + */ + public final int getMeasuredWidth() { + return mMeasuredWidth & MEASURED_SIZE_MASK; + } + /** + * Return the full width measurement information for this view as computed + * by the most recent call to {@link #measure(int, int)}. This result is a bit mask + * as defined by {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}. + * This should be used during measurement and layout calculations only. Use + * {@link #getWidth()} to see how wide a view is after layout. + * + * @return The measured width of this view as a bit mask. + */ + public final int getMeasuredWidthAndState() { + return mMeasuredWidth; + } + /** + * Like {@link #getMeasuredHeightAndState()}, but only returns the + * raw width component (that is the result is masked by + * {@link #MEASURED_SIZE_MASK}). + * + * @return The raw measured height of this view. + */ + public final int getMeasuredHeight() { + return mMeasuredHeight & MEASURED_SIZE_MASK; + } + /** + * Return the full height measurement information for this view as computed + * by the most recent call to {@link #measure(int, int)}. This result is a bit mask + * as defined by {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}. + * This should be used during measurement and layout calculations only. Use + * {@link #getHeight()} to see how wide a view is after layout. + * + * @return The measured width of this view as a bit mask. + */ + public final int getMeasuredHeightAndState() { + return mMeasuredHeight; + } + /** + * Return only the state bits of {@link #getMeasuredWidthAndState()} + * and {@link #getMeasuredHeightAndState()}, combined into one integer. + * The width component is in the regular bits {@link #MEASURED_STATE_MASK} + * and the height component is at the shifted bits + * {@link #MEASURED_HEIGHT_STATE_SHIFT}>>{@link #MEASURED_STATE_MASK}. + */ + public final int getMeasuredState() { + return (mMeasuredWidth&MEASURED_STATE_MASK) + | ((mMeasuredHeight>>MEASURED_HEIGHT_STATE_SHIFT) + & (MEASURED_STATE_MASK>>MEASURED_HEIGHT_STATE_SHIFT)); + } + /** + * The transform matrix of this view, which is calculated based on the current + * roation, scale, and pivot properties. + * + * @see #getRotation() + * @see #getScaleX() + * @see #getScaleY() + * @see #getPivotX() + * @see #getPivotY() + * @return The current transform matrix for the view + */ + public Matrix getMatrix() { + if (mTransformationInfo != null) { + updateMatrix(); + return mTransformationInfo.mMatrix; + } + return Matrix.IDENTITY_MATRIX; + } + /** + * Utility function to determine if the value is far enough away from zero to be + * considered non-zero. + * @param value A floating point value to check for zero-ness + * @return whether the passed-in value is far enough away from zero to be considered non-zero + */ + private static boolean nonzero(float value) { + return (value < -NONZERO_EPSILON || value > NONZERO_EPSILON); + } + /** + * Returns true if the transform matrix is the identity matrix. + * Recomputes the matrix if necessary. + * + * @return True if the transform matrix is the identity matrix, false otherwise. + */ + final boolean hasIdentityMatrix() { + if (mTransformationInfo != null) { + updateMatrix(); + return mTransformationInfo.mMatrixIsIdentity; + } + return true; + } + void ensureTransformationInfo() { + if (mTransformationInfo == null) { + mTransformationInfo = new TransformationInfo(); + } + } + /** + * Recomputes the transform matrix if necessary. + */ + private void updateMatrix() { + final TransformationInfo info = mTransformationInfo; + if (info == null) { + return; + } + if (info.mMatrixDirty) { + // transform-related properties have changed since the last time someone + // asked for the matrix; recalculate it with the current values + // Figure out if we need to update the pivot point + if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) { + if ((mRight - mLeft) != info.mPrevWidth || (mBottom - mTop) != info.mPrevHeight) { + info.mPrevWidth = mRight - mLeft; + info.mPrevHeight = mBottom - mTop; + info.mPivotX = info.mPrevWidth / 2f; + info.mPivotY = info.mPrevHeight / 2f; + } + } + info.mMatrix.reset(); + if (!nonzero(info.mRotationX) && !nonzero(info.mRotationY)) { + info.mMatrix.setTranslate(info.mTranslationX, info.mTranslationY); + info.mMatrix.preRotate(info.mRotation, info.mPivotX, info.mPivotY); + info.mMatrix.preScale(info.mScaleX, info.mScaleY, info.mPivotX, info.mPivotY); + } else { + if (info.mCamera == null) { + info.mCamera = new Camera(); + info.matrix3D = new Matrix(); + } + info.mCamera.save(); + info.mMatrix.preScale(info.mScaleX, info.mScaleY, info.mPivotX, info.mPivotY); + info.mCamera.rotate(info.mRotationX, info.mRotationY, -info.mRotation); + info.mCamera.getMatrix(info.matrix3D); + info.matrix3D.preTranslate(-info.mPivotX, -info.mPivotY); + info.matrix3D.postTranslate(info.mPivotX + info.mTranslationX, + info.mPivotY + info.mTranslationY); + info.mMatrix.postConcat(info.matrix3D); + info.mCamera.restore(); + } + info.mMatrixDirty = false; + info.mMatrixIsIdentity = info.mMatrix.isIdentity(); + info.mInverseMatrixDirty = true; + } + } + /** + * Utility method to retrieve the inverse of the current mMatrix property. + * We cache the matrix to avoid recalculating it when transform properties + * have not changed. + * + * @return The inverse of the current matrix of this view. + */ + final Matrix getInverseMatrix() { + final TransformationInfo info = mTransformationInfo; + if (info != null) { + updateMatrix(); + if (info.mInverseMatrixDirty) { + if (info.mInverseMatrix == null) { + info.mInverseMatrix = new Matrix(); + } + info.mMatrix.invert(info.mInverseMatrix); + info.mInverseMatrixDirty = false; + } + return info.mInverseMatrix; + } + return Matrix.IDENTITY_MATRIX; + } + /** + *

Sets the distance along the Z axis (orthogonal to the X/Y plane on which + * views are drawn) from the camera to this view. The camera's distance + * affects 3D transformations, for instance rotations around the X and Y + * axis. If the rotationX or rotationY properties are changed and this view is + * large (more than half the size of the screen), it is recommended to always + * use a camera distance that's greater than the height (X axis rotation) or + * the width (Y axis rotation) of this view.

+ * + *

The distance of the camera from the view plane can have an affect on the + * perspective distortion of the view when it is rotated around the x or y axis. + * For example, a large distance will result in a large viewing angle, and there + * will not be much perspective distortion of the view as it rotates. A short + * distance may cause much more perspective distortion upon rotation, and can + * also result in some drawing artifacts if the rotated view ends up partially + * behind the camera (which is why the recommendation is to use a distance at + * least as far as the size of the view, if the view is to be rotated.)

+ * + *

The distance is expressed in "depth pixels." The default distance depends + * on the screen density. For instance, on a medium density display, the + * default distance is 1280. On a high density display, the default distance + * is 1920.

+ * + *

If you want to specify a distance that leads to visually consistent + * results across various densities, use the following formula:

+ *
+     * float scale = context.getResources().getDisplayMetrics().density;
+     * view.setCameraDistance(distance * scale);
+     * 
+ * + *

The density scale factor of a high density display is 1.5, + * and 1920 = 1280 * 1.5.

+ * + * @param distance The distance in "depth pixels", if negative the opposite + * value is used + * + * @see #setRotationX(float) + * @see #setRotationY(float) + */ + public void setCameraDistance(float distance) { + invalidateParentCaches(); + invalidate(false); + ensureTransformationInfo(); + final float dpi = mResources.getDisplayMetrics().densityDpi; + final TransformationInfo info = mTransformationInfo; + if (info.mCamera == null) { + info.mCamera = new Camera(); + info.matrix3D = new Matrix(); + } + info.mCamera.setLocation(0.0f, 0.0f, -Math.abs(distance) / dpi); + info.mMatrixDirty = true; + invalidate(false); + } + /** + * The degrees that the view is rotated around the pivot point. + * + * @see #setRotation(float) + * @see #getPivotX() + * @see #getPivotY() + * + * @return The degrees of rotation. + */ + @ViewDebug.ExportedProperty(category = "drawing") + public float getRotation() { + return mTransformationInfo != null ? mTransformationInfo.mRotation : 0; + } + /** + * Sets the degrees that the view is rotated around the pivot point. Increasing values + * result in clockwise rotation. + * + * @param rotation The degrees of rotation. + * + * @see #getRotation() + * @see #getPivotX() + * @see #getPivotY() + * @see #setRotationX(float) + * @see #setRotationY(float) + * + * @attr ref android.R.styleable#View_rotation + */ + public void setRotation(float rotation) { + ensureTransformationInfo(); + final TransformationInfo info = mTransformationInfo; + if (info.mRotation != rotation) { + invalidateParentCaches(); + // Double-invalidation is necessary to capture view's old and new areas + invalidate(false); + info.mRotation = rotation; + info.mMatrixDirty = true; + mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + invalidate(false); + } + } + /** + * The degrees that the view is rotated around the vertical axis through the pivot point. + * + * @see #getPivotX() + * @see #getPivotY() + * @see #setRotationY(float) + * + * @return The degrees of Y rotation. + */ + @ViewDebug.ExportedProperty(category = "drawing") + public float getRotationY() { + return mTransformationInfo != null ? mTransformationInfo.mRotationY : 0; + } + /** + * Sets the degrees that the view is rotated around the vertical axis through the pivot point. + * Increasing values result in counter-clockwise rotation from the viewpoint of looking + * down the y axis. + * + * When rotating large views, it is recommended to adjust the camera distance + * accordingly. Refer to {@link #setCameraDistance(float)} for more information. + * + * @param rotationY The degrees of Y rotation. + * + * @see #getRotationY() + * @see #getPivotX() + * @see #getPivotY() + * @see #setRotation(float) + * @see #setRotationX(float) + * @see #setCameraDistance(float) + * + * @attr ref android.R.styleable#View_rotationY + */ + public void setRotationY(float rotationY) { + ensureTransformationInfo(); + final TransformationInfo info = mTransformationInfo; + if (info.mRotationY != rotationY) { + invalidateParentCaches(); + // Double-invalidation is necessary to capture view's old and new areas + invalidate(false); + info.mRotationY = rotationY; + info.mMatrixDirty = true; + mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + invalidate(false); + } + } + /** + * The degrees that the view is rotated around the horizontal axis through the pivot point. + * + * @see #getPivotX() + * @see #getPivotY() + * @see #setRotationX(float) + * + * @return The degrees of X rotation. + */ + @ViewDebug.ExportedProperty(category = "drawing") + public float getRotationX() { + return mTransformationInfo != null ? mTransformationInfo.mRotationX : 0; + } + /** + * Sets the degrees that the view is rotated around the horizontal axis through the pivot point. + * Increasing values result in clockwise rotation from the viewpoint of looking down the + * x axis. + * + * When rotating large views, it is recommended to adjust the camera distance + * accordingly. Refer to {@link #setCameraDistance(float)} for more information. + * + * @param rotationX The degrees of X rotation. + * + * @see #getRotationX() + * @see #getPivotX() + * @see #getPivotY() + * @see #setRotation(float) + * @see #setRotationY(float) + * @see #setCameraDistance(float) + * + * @attr ref android.R.styleable#View_rotationX + */ + public void setRotationX(float rotationX) { + ensureTransformationInfo(); + final TransformationInfo info = mTransformationInfo; + if (info.mRotationX != rotationX) { + invalidateParentCaches(); + // Double-invalidation is necessary to capture view's old and new areas + invalidate(false); + info.mRotationX = rotationX; + info.mMatrixDirty = true; + mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + invalidate(false); + } + } + /** + * The amount that the view is scaled in x around the pivot point, as a proportion of + * the view's unscaled width. A value of 1, the default, means that no scaling is applied. + * + *

By default, this is 1.0f. + * + * @see #getPivotX() + * @see #getPivotY() + * @return The scaling factor. + */ + @ViewDebug.ExportedProperty(category = "drawing") + public float getScaleX() { + return mTransformationInfo != null ? mTransformationInfo.mScaleX : 1; + } + /** + * Sets the amount that the view is scaled in x around the pivot point, as a proportion of + * the view's unscaled width. A value of 1 means that no scaling is applied. + * + * @param scaleX The scaling factor. + * @see #getPivotX() + * @see #getPivotY() + * + * @attr ref android.R.styleable#View_scaleX + */ + public void setScaleX(float scaleX) { + ensureTransformationInfo(); + final TransformationInfo info = mTransformationInfo; + if (info.mScaleX != scaleX) { + invalidateParentCaches(); + // Double-invalidation is necessary to capture view's old and new areas + invalidate(false); + info.mScaleX = scaleX; + info.mMatrixDirty = true; + mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + invalidate(false); + } + } + /** + * The amount that the view is scaled in y around the pivot point, as a proportion of + * the view's unscaled height. A value of 1, the default, means that no scaling is applied. + * + *

By default, this is 1.0f. + * + * @see #getPivotX() + * @see #getPivotY() + * @return The scaling factor. + */ + @ViewDebug.ExportedProperty(category = "drawing") + public float getScaleY() { + return mTransformationInfo != null ? mTransformationInfo.mScaleY : 1; + } + /** + * Sets the amount that the view is scaled in Y around the pivot point, as a proportion of + * the view's unscaled width. A value of 1 means that no scaling is applied. + * + * @param scaleY The scaling factor. + * @see #getPivotX() + * @see #getPivotY() + * + * @attr ref android.R.styleable#View_scaleY + */ + public void setScaleY(float scaleY) { + ensureTransformationInfo(); + final TransformationInfo info = mTransformationInfo; + if (info.mScaleY != scaleY) { + invalidateParentCaches(); + // Double-invalidation is necessary to capture view's old and new areas + invalidate(false); + info.mScaleY = scaleY; + info.mMatrixDirty = true; + mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + invalidate(false); + } + } + /** + * The x location of the point around which the view is {@link #setRotation(float) rotated} + * and {@link #setScaleX(float) scaled}. + * + * @see #getRotation() + * @see #getScaleX() + * @see #getScaleY() + * @see #getPivotY() + * @return The x location of the pivot point. + */ + @ViewDebug.ExportedProperty(category = "drawing") + public float getPivotX() { + return mTransformationInfo != null ? mTransformationInfo.mPivotX : 0; + } + /** + * Sets the x location of the point around which the view is + * {@link #setRotation(float) rotated} and {@link #setScaleX(float) scaled}. + * By default, the pivot point is centered on the object. + * Setting this property disables this behavior and causes the view to use only the + * explicitly set pivotX and pivotY values. + * + * @param pivotX The x location of the pivot point. + * @see #getRotation() + * @see #getScaleX() + * @see #getScaleY() + * @see #getPivotY() + * + * @attr ref android.R.styleable#View_transformPivotX + */ + public void setPivotX(float pivotX) { + ensureTransformationInfo(); + mPrivateFlags |= PIVOT_EXPLICITLY_SET; + final TransformationInfo info = mTransformationInfo; + if (info.mPivotX != pivotX) { + invalidateParentCaches(); + // Double-invalidation is necessary to capture view's old and new areas + invalidate(false); + info.mPivotX = pivotX; + info.mMatrixDirty = true; + mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + invalidate(false); + } + } + /** + * The y location of the point around which the view is {@link #setRotation(float) rotated} + * and {@link #setScaleY(float) scaled}. + * + * @see #getRotation() + * @see #getScaleX() + * @see #getScaleY() + * @see #getPivotY() + * @return The y location of the pivot point. + */ + @ViewDebug.ExportedProperty(category = "drawing") + public float getPivotY() { + return mTransformationInfo != null ? mTransformationInfo.mPivotY : 0; + } + /** + * Sets the y location of the point around which the view is {@link #setRotation(float) rotated} + * and {@link #setScaleY(float) scaled}. By default, the pivot point is centered on the object. + * Setting this property disables this behavior and causes the view to use only the + * explicitly set pivotX and pivotY values. + * + * @param pivotY The y location of the pivot point. + * @see #getRotation() + * @see #getScaleX() + * @see #getScaleY() + * @see #getPivotY() + * + * @attr ref android.R.styleable#View_transformPivotY + */ + public void setPivotY(float pivotY) { + ensureTransformationInfo(); + mPrivateFlags |= PIVOT_EXPLICITLY_SET; + final TransformationInfo info = mTransformationInfo; + if (info.mPivotY != pivotY) { + invalidateParentCaches(); + // Double-invalidation is necessary to capture view's old and new areas + invalidate(false); + info.mPivotY = pivotY; + info.mMatrixDirty = true; + mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + invalidate(false); + } + } + /** + * The opacity of the view. This is a value from 0 to 1, where 0 means the view is + * completely transparent and 1 means the view is completely opaque. + * + *

By default this is 1.0f. + * @return The opacity of the view. + */ + @ViewDebug.ExportedProperty(category = "drawing") + public float getAlpha() { + return mTransformationInfo != null ? mTransformationInfo.mAlpha : 1; + } + /** + *

Sets the opacity of the view. This is a value from 0 to 1, where 0 means the view is + * completely transparent and 1 means the view is completely opaque.

+ * + *

If this view overrides {@link #onSetAlpha(int)} to return true, then this view is + * responsible for applying the opacity itself. Otherwise, calling this method is + * equivalent to calling {@link #setLayerType(int, android.graphics.Paint)} and + * setting a hardware layer.

+ * + *

Note that setting alpha to a translucent value (0 < alpha < 1) may have + * performance implications. It is generally best to use the alpha property sparingly and + * transiently, as in the case of fading animations.

+ * + * @param alpha The opacity of the view. + * + * @see #setLayerType(int, android.graphics.Paint) + * + * @attr ref android.R.styleable#View_alpha + */ + public void setAlpha(float alpha) { + ensureTransformationInfo(); + if (mTransformationInfo.mAlpha != alpha) { + mTransformationInfo.mAlpha = alpha; + invalidateParentCaches(); + if (onSetAlpha((int) (alpha * 255))) { + mPrivateFlags |= ALPHA_SET; + // subclass is handling alpha - don't optimize rendering cache invalidation + invalidate(true); + } else { + mPrivateFlags &= ~ALPHA_SET; + invalidate(false); + } + } + } + /** + * Faster version of setAlpha() which performs the same steps except there are + * no calls to invalidate(). The caller of this function should perform proper invalidation + * on the parent and this object. The return value indicates whether the subclass handles + * alpha (the return value for onSetAlpha()). + * + * @param alpha The new value for the alpha property + * @return true if the View subclass handles alpha (the return value for onSetAlpha()) and + * the new value for the alpha property is different from the old value + */ + boolean setAlphaNoInvalidation(float alpha) { + ensureTransformationInfo(); + if (mTransformationInfo.mAlpha != alpha) { + mTransformationInfo.mAlpha = alpha; + boolean subclassHandlesAlpha = onSetAlpha((int) (alpha * 255)); + if (subclassHandlesAlpha) { + mPrivateFlags |= ALPHA_SET; + return true; + } else { + mPrivateFlags &= ~ALPHA_SET; + } + } + return false; + } + /** + * Top position of this view relative to its parent. + * + * @return The top of this view, in pixels. + */ + @ViewDebug.CapturedViewProperty + public final int getTop() { + return mTop; + } + /** + * Sets the top position of this view relative to its parent. This method is meant to be called + * by the layout system and should not generally be called otherwise, because the property + * may be changed at any time by the layout. + * + * @param top The top of this view, in pixels. + */ + public final void setTop(int top) { + if (top != mTop) { + updateMatrix(); + final boolean matrixIsIdentity = mTransformationInfo == null + || mTransformationInfo.mMatrixIsIdentity; + if (matrixIsIdentity) { + if (mAttachInfo != null) { + int minTop; + int yLoc; + if (top < mTop) { + minTop = top; + yLoc = top - mTop; + } else { + minTop = mTop; + yLoc = 0; + } + invalidate(0, yLoc, mRight - mLeft, mBottom - minTop); + } + } else { + // Double-invalidation is necessary to capture view's old and new areas + invalidate(true); + } + int width = mRight - mLeft; + int oldHeight = mBottom - mTop; + mTop = top; + onSizeChanged(width, mBottom - mTop, width, oldHeight); + if (!matrixIsIdentity) { + if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) { + // A change in dimension means an auto-centered pivot point changes, too + mTransformationInfo.mMatrixDirty = true; + } + mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + invalidate(true); + } + mBackgroundSizeChanged = true; + invalidateParentIfNeeded(); + } + } + /** + * Bottom position of this view relative to its parent. + * + * @return The bottom of this view, in pixels. + */ + @ViewDebug.CapturedViewProperty + public final int getBottom() { + return mBottom; + } + /** + * True if this view has changed since the last time being drawn. + * + * @return The dirty state of this view. + */ + public boolean isDirty() { + return (mPrivateFlags & DIRTY_MASK) != 0; + } + /** + * Sets the bottom position of this view relative to its parent. This method is meant to be + * called by the layout system and should not generally be called otherwise, because the + * property may be changed at any time by the layout. + * + * @param bottom The bottom of this view, in pixels. + */ + public final void setBottom(int bottom) { + if (bottom != mBottom) { + updateMatrix(); + final boolean matrixIsIdentity = mTransformationInfo == null + || mTransformationInfo.mMatrixIsIdentity; + if (matrixIsIdentity) { + if (mAttachInfo != null) { + int maxBottom; + if (bottom < mBottom) { + maxBottom = mBottom; + } else { + maxBottom = bottom; + } + invalidate(0, 0, mRight - mLeft, maxBottom - mTop); + } + } else { + // Double-invalidation is necessary to capture view's old and new areas + invalidate(true); + } + int width = mRight - mLeft; + int oldHeight = mBottom - mTop; + mBottom = bottom; + onSizeChanged(width, mBottom - mTop, width, oldHeight); + if (!matrixIsIdentity) { + if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) { + // A change in dimension means an auto-centered pivot point changes, too + mTransformationInfo.mMatrixDirty = true; + } + mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + invalidate(true); + } + mBackgroundSizeChanged = true; + invalidateParentIfNeeded(); + } + } + /** + * Left position of this view relative to its parent. + * + * @return The left edge of this view, in pixels. + */ + @ViewDebug.CapturedViewProperty + public final int getLeft() { + return mLeft; + } + /** + * Sets the left position of this view relative to its parent. This method is meant to be called + * by the layout system and should not generally be called otherwise, because the property + * may be changed at any time by the layout. + * + * @param left The bottom of this view, in pixels. + */ + public final void setLeft(int left) { + if (left != mLeft) { + updateMatrix(); + final boolean matrixIsIdentity = mTransformationInfo == null + || mTransformationInfo.mMatrixIsIdentity; + if (matrixIsIdentity) { + if (mAttachInfo != null) { + int minLeft; + int xLoc; + if (left < mLeft) { + minLeft = left; + xLoc = left - mLeft; + } else { + minLeft = mLeft; + xLoc = 0; + } + invalidate(xLoc, 0, mRight - minLeft, mBottom - mTop); + } + } else { + // Double-invalidation is necessary to capture view's old and new areas + invalidate(true); + } + int oldWidth = mRight - mLeft; + int height = mBottom - mTop; + mLeft = left; + onSizeChanged(mRight - mLeft, height, oldWidth, height); + if (!matrixIsIdentity) { + if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) { + // A change in dimension means an auto-centered pivot point changes, too + mTransformationInfo.mMatrixDirty = true; + } + mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + invalidate(true); + } + mBackgroundSizeChanged = true; + invalidateParentIfNeeded(); + } + } + /** + * Right position of this view relative to its parent. + * + * @return The right edge of this view, in pixels. + */ + @ViewDebug.CapturedViewProperty + public final int getRight() { + return mRight; + } + /** + * Sets the right position of this view relative to its parent. This method is meant to be called + * by the layout system and should not generally be called otherwise, because the property + * may be changed at any time by the layout. + * + * @param right The bottom of this view, in pixels. + */ + public final void setRight(int right) { + if (right != mRight) { + updateMatrix(); + final boolean matrixIsIdentity = mTransformationInfo == null + || mTransformationInfo.mMatrixIsIdentity; + if (matrixIsIdentity) { + if (mAttachInfo != null) { + int maxRight; + if (right < mRight) { + maxRight = mRight; + } else { + maxRight = right; + } + invalidate(0, 0, maxRight - mLeft, mBottom - mTop); + } + } else { + // Double-invalidation is necessary to capture view's old and new areas + invalidate(true); + } + int oldWidth = mRight - mLeft; + int height = mBottom - mTop; + mRight = right; + onSizeChanged(mRight - mLeft, height, oldWidth, height); + if (!matrixIsIdentity) { + if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) { + // A change in dimension means an auto-centered pivot point changes, too + mTransformationInfo.mMatrixDirty = true; + } + mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + invalidate(true); + } + mBackgroundSizeChanged = true; + invalidateParentIfNeeded(); + } + } + /** + * The visual x position of this view, in pixels. This is equivalent to the + * {@link #setTranslationX(float) translationX} property plus the current + * {@link #getLeft() left} property. + * + * @return The visual x position of this view, in pixels. + */ + @ViewDebug.ExportedProperty(category = "drawing") + public float getX() { + return mLeft + (mTransformationInfo != null ? mTransformationInfo.mTranslationX : 0); + } + /** + * Sets the visual x position of this view, in pixels. This is equivalent to setting the + * {@link #setTranslationX(float) translationX} property to be the difference between + * the x value passed in and the current {@link #getLeft() left} property. + * + * @param x The visual x position of this view, in pixels. + */ + public void setX(float x) { + setTranslationX(x - mLeft); + } + /** + * The visual y position of this view, in pixels. This is equivalent to the + * {@link #setTranslationY(float) translationY} property plus the current + * {@link #getTop() top} property. + * + * @return The visual y position of this view, in pixels. + */ + @ViewDebug.ExportedProperty(category = "drawing") + public float getY() { + return mTop + (mTransformationInfo != null ? mTransformationInfo.mTranslationY : 0); + } + /** + * Sets the visual y position of this view, in pixels. This is equivalent to setting the + * {@link #setTranslationY(float) translationY} property to be the difference between + * the y value passed in and the current {@link #getTop() top} property. + * + * @param y The visual y position of this view, in pixels. + */ + public void setY(float y) { + setTranslationY(y - mTop); + } + /** + * The horizontal location of this view relative to its {@link #getLeft() left} position. + * This position is post-layout, in addition to wherever the object's + * layout placed it. + * + * @return The horizontal position of this view relative to its left position, in pixels. + */ + @ViewDebug.ExportedProperty(category = "drawing") + public float getTranslationX() { + return mTransformationInfo != null ? mTransformationInfo.mTranslationX : 0; + } + /** + * Sets the horizontal location of this view relative to its {@link #getLeft() left} position. + * This effectively positions the object post-layout, in addition to wherever the object's + * layout placed it. + * + * @param translationX The horizontal position of this view relative to its left position, + * in pixels. + * + * @attr ref android.R.styleable#View_translationX + */ + public void setTranslationX(float translationX) { + ensureTransformationInfo(); + final TransformationInfo info = mTransformationInfo; + if (info.mTranslationX != translationX) { + invalidateParentCaches(); + // Double-invalidation is necessary to capture view's old and new areas + invalidate(false); + info.mTranslationX = translationX; + info.mMatrixDirty = true; + mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + invalidate(false); + } + } + /** + * The horizontal location of this view relative to its {@link #getTop() top} position. + * This position is post-layout, in addition to wherever the object's + * layout placed it. + * + * @return The vertical position of this view relative to its top position, + * in pixels. + */ + @ViewDebug.ExportedProperty(category = "drawing") + public float getTranslationY() { + return mTransformationInfo != null ? mTransformationInfo.mTranslationY : 0; + } + /** + * Sets the vertical location of this view relative to its {@link #getTop() top} position. + * This effectively positions the object post-layout, in addition to wherever the object's + * layout placed it. + * + * @param translationY The vertical position of this view relative to its top position, + * in pixels. + * + * @attr ref android.R.styleable#View_translationY + */ + public void setTranslationY(float translationY) { + ensureTransformationInfo(); + final TransformationInfo info = mTransformationInfo; + if (info.mTranslationY != translationY) { + invalidateParentCaches(); + // Double-invalidation is necessary to capture view's old and new areas + invalidate(false); + info.mTranslationY = translationY; + info.mMatrixDirty = true; + mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + invalidate(false); + } + } + /** + * Hit rectangle in parent's coordinates + * + * @param outRect The hit rectangle of the view. + */ + public void getHitRect(Rect outRect) { + updateMatrix(); + final TransformationInfo info = mTransformationInfo; + if (info == null || info.mMatrixIsIdentity || mAttachInfo == null) { + outRect.set(mLeft, mTop, mRight, mBottom); + } else { + final RectF tmpRect = mAttachInfo.mTmpTransformRect; + tmpRect.set(-info.mPivotX, -info.mPivotY, + getWidth() - info.mPivotX, getHeight() - info.mPivotY); + info.mMatrix.mapRect(tmpRect); + outRect.set((int) tmpRect.left + mLeft, (int) tmpRect.top + mTop, + (int) tmpRect.right + mLeft, (int) tmpRect.bottom + mTop); + } + } + /** + * Determines whether the given point, in local coordinates is inside the view. + */ + /*package*/ final boolean pointInView(float localX, float localY) { + return localX >= 0 && localX < (mRight - mLeft) + && localY >= 0 && localY < (mBottom - mTop); + } + /** + * Utility method to determine whether the given point, in local coordinates, + * is inside the view, where the area of the view is expanded by the slop factor. + * This method is called while processing touch-move events to determine if the event + * is still within the view. + */ + private boolean pointInView(float localX, float localY, float slop) { + return localX >= -slop && localY >= -slop && localX < ((mRight - mLeft) + slop) && + localY < ((mBottom - mTop) + slop); + } + /** + * When a view has focus and the user navigates away from it, the next view is searched for + * starting from the rectangle filled in by this method. + * + * By default, the rectange is the {@link #getDrawingRect(android.graphics.Rect)}) + * of the view. However, if your view maintains some idea of internal selection, + * such as a cursor, or a selected row or column, you should override this method and + * fill in a more specific rectangle. + * + * @param r The rectangle to fill in, in this view's coordinates. + */ + public void getFocusedRect(Rect r) { + getDrawingRect(r); + } + /** + * If some part of this view is not clipped by any of its parents, then + * return that area in r in global (root) coordinates. To convert r to local + * coordinates (without taking possible View rotations into account), offset + * it by -globalOffset (e.g. r.offset(-globalOffset.x, -globalOffset.y)). + * If the view is completely clipped or translated out, return false. + * + * @param r If true is returned, r holds the global coordinates of the + * visible portion of this view. + * @param globalOffset If true is returned, globalOffset holds the dx,dy + * between this view and its root. globalOffet may be null. + * @return true if r is non-empty (i.e. part of the view is visible at the + * root level. + */ + public boolean getGlobalVisibleRect(Rect r, Point globalOffset) { + int width = mRight - mLeft; + int height = mBottom - mTop; + if (width > 0 && height > 0) { + r.set(0, 0, width, height); + if (globalOffset != null) { + globalOffset.set(-mScrollX, -mScrollY); + } + return mParent == null || mParent.getChildVisibleRect(this, r, globalOffset); + } + return false; + } + public final boolean getGlobalVisibleRect(Rect r) { + return getGlobalVisibleRect(r, null); + } + public final boolean getLocalVisibleRect(Rect r) { + Point offset = new Point(); + if (getGlobalVisibleRect(r, offset)) { + r.offset(-offset.x, -offset.y); // make r local + return true; + } + return false; + } + /** + * Offset this view's vertical location by the specified number of pixels. + * + * @param offset the number of pixels to offset the view by + */ + public void offsetTopAndBottom(int offset) { + if (offset != 0) { + updateMatrix(); + final boolean matrixIsIdentity = mTransformationInfo == null + || mTransformationInfo.mMatrixIsIdentity; + if (matrixIsIdentity) { + final ViewParent p = mParent; + if (p != null && mAttachInfo != null) { + final Rect r = mAttachInfo.mTmpInvalRect; + int minTop; + int maxBottom; + int yLoc; + if (offset < 0) { + minTop = mTop + offset; + maxBottom = mBottom; + yLoc = offset; + } else { + minTop = mTop; + maxBottom = mBottom + offset; + yLoc = 0; + } + r.set(0, yLoc, mRight - mLeft, maxBottom - minTop); + p.invalidateChild(this, r); + } + } else { + invalidate(false); + } + mTop += offset; + mBottom += offset; + if (!matrixIsIdentity) { + mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + invalidate(false); + } + invalidateParentIfNeeded(); + } + } + /** + * Offset this view's horizontal location by the specified amount of pixels. + * + * @param offset the numer of pixels to offset the view by + */ + public void offsetLeftAndRight(int offset) { + if (offset != 0) { + updateMatrix(); + final boolean matrixIsIdentity = mTransformationInfo == null + || mTransformationInfo.mMatrixIsIdentity; + if (matrixIsIdentity) { + final ViewParent p = mParent; + if (p != null && mAttachInfo != null) { + final Rect r = mAttachInfo.mTmpInvalRect; + int minLeft; + int maxRight; + if (offset < 0) { + minLeft = mLeft + offset; + maxRight = mRight; + } else { + minLeft = mLeft; + maxRight = mRight + offset; + } + r.set(0, 0, maxRight - minLeft, mBottom - mTop); + p.invalidateChild(this, r); + } + } else { + invalidate(false); + } + mLeft += offset; + mRight += offset; + if (!matrixIsIdentity) { + mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + invalidate(false); + } + invalidateParentIfNeeded(); + } + } + /** + * Get the LayoutParams associated with this view. All views should have + * layout parameters. These supply parameters to the parent of this + * view specifying how it should be arranged. There are many subclasses of + * ViewGroup.LayoutParams, and these correspond to the different subclasses + * of ViewGroup that are responsible for arranging their children. + * + * This method may return null if this View is not attached to a parent + * ViewGroup or {@link #setLayoutParams(android.view.ViewGroup.LayoutParams)} + * was not invoked successfully. When a View is attached to a parent + * ViewGroup, this method must not return null. + * + * @return The LayoutParams associated with this view, or null if no + * parameters have been set yet + */ + @ViewDebug.ExportedProperty(deepExport = true, prefix = "layout_") + public ViewGroup.LayoutParams getLayoutParams() { + return mLayoutParams; + } + /** + * Set the layout parameters associated with this view. These supply + * parameters to the parent of this view specifying how it should be + * arranged. There are many subclasses of ViewGroup.LayoutParams, and these + * correspond to the different subclasses of ViewGroup that are responsible + * for arranging their children. + * + * @param params The layout parameters for this view, cannot be null + */ + public void setLayoutParams(ViewGroup.LayoutParams params) { + if (params == null) { + throw new NullPointerException("Layout parameters cannot be null"); + } + mLayoutParams = params; + if (mParent instanceof ViewGroup) { + ((ViewGroup) mParent).onSetLayoutParams(this, params); + } + requestLayout(); + } + /** + * Set the scrolled position of your view. This will cause a call to + * {@link #onScrollChanged(int, int, int, int)} and the view will be + * invalidated. + * @param x the x position to scroll to + * @param y the y position to scroll to + */ + public void scrollTo(int x, int y) { + if (mScrollX != x || mScrollY != y) { + int oldX = mScrollX; + int oldY = mScrollY; + mScrollX = x; + mScrollY = y; + invalidateParentCaches(); + onScrollChanged(mScrollX, mScrollY, oldX, oldY); + if (!awakenScrollBars()) { + invalidate(true); + } + } + } + /** + * Move the scrolled position of your view. This will cause a call to + * {@link #onScrollChanged(int, int, int, int)} and the view will be + * invalidated. + * @param x the amount of pixels to scroll by horizontally + * @param y the amount of pixels to scroll by vertically + */ + public void scrollBy(int x, int y) { + scrollTo(mScrollX + x, mScrollY + y); + } + /** + *

Trigger the scrollbars to draw. When invoked this method starts an + * animation to fade the scrollbars out after a default delay. If a subclass + * provides animated scrolling, the start delay should equal the duration + * of the scrolling animation.

+ * + *

The animation starts only if at least one of the scrollbars is + * enabled, as specified by {@link #isHorizontalScrollBarEnabled()} and + * {@link #isVerticalScrollBarEnabled()}. When the animation is started, + * this method returns true, and false otherwise. If the animation is + * started, this method calls {@link #invalidate()}; in that case the + * caller should not call {@link #invalidate()}.

+ * + *

This method should be invoked every time a subclass directly updates + * the scroll parameters.

+ * + *

This method is automatically invoked by {@link #scrollBy(int, int)} + * and {@link #scrollTo(int, int)}.

+ * + * @return true if the animation is played, false otherwise + * + * @see #awakenScrollBars(int) + * @see #scrollBy(int, int) + * @see #scrollTo(int, int) + * @see #isHorizontalScrollBarEnabled() + * @see #isVerticalScrollBarEnabled() + * @see #setHorizontalScrollBarEnabled(boolean) + * @see #setVerticalScrollBarEnabled(boolean) + */ + protected boolean awakenScrollBars() { + return mScrollCache != null && + awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade, true); + } + /** + * Trigger the scrollbars to draw. + * This method differs from awakenScrollBars() only in its default duration. + * initialAwakenScrollBars() will show the scroll bars for longer than + * usual to give the user more of a chance to notice them. + * + * @return true if the animation is played, false otherwise. + */ + private boolean initialAwakenScrollBars() { + return mScrollCache != null && + awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade * 4, true); + } + /** + *

+ * Trigger the scrollbars to draw. When invoked this method starts an + * animation to fade the scrollbars out after a fixed delay. If a subclass + * provides animated scrolling, the start delay should equal the duration of + * the scrolling animation. + *

+ * + *

+ * The animation starts only if at least one of the scrollbars is enabled, + * as specified by {@link #isHorizontalScrollBarEnabled()} and + * {@link #isVerticalScrollBarEnabled()}. When the animation is started, + * this method returns true, and false otherwise. If the animation is + * started, this method calls {@link #invalidate()}; in that case the caller + * should not call {@link #invalidate()}. + *

+ * + *

+ * This method should be invoked everytime a subclass directly updates the + * scroll parameters. + *

+ * + * @param startDelay the delay, in milliseconds, after which the animation + * should start; when the delay is 0, the animation starts + * immediately + * @return true if the animation is played, false otherwise + * + * @see #scrollBy(int, int) + * @see #scrollTo(int, int) + * @see #isHorizontalScrollBarEnabled() + * @see #isVerticalScrollBarEnabled() + * @see #setHorizontalScrollBarEnabled(boolean) + * @see #setVerticalScrollBarEnabled(boolean) + */ + protected boolean awakenScrollBars(int startDelay) { + return awakenScrollBars(startDelay, true); + } + /** + *

+ * Trigger the scrollbars to draw. When invoked this method starts an + * animation to fade the scrollbars out after a fixed delay. If a subclass + * provides animated scrolling, the start delay should equal the duration of + * the scrolling animation. + *

+ * + *

+ * The animation starts only if at least one of the scrollbars is enabled, + * as specified by {@link #isHorizontalScrollBarEnabled()} and + * {@link #isVerticalScrollBarEnabled()}. When the animation is started, + * this method returns true, and false otherwise. If the animation is + * started, this method calls {@link #invalidate()} if the invalidate parameter + * is set to true; in that case the caller + * should not call {@link #invalidate()}. + *

+ * + *

+ * This method should be invoked everytime a subclass directly updates the + * scroll parameters. + *

+ * + * @param startDelay the delay, in milliseconds, after which the animation + * should start; when the delay is 0, the animation starts + * immediately + * + * @param invalidate Wheter this method should call invalidate + * + * @return true if the animation is played, false otherwise + * + * @see #scrollBy(int, int) + * @see #scrollTo(int, int) + * @see #isHorizontalScrollBarEnabled() + * @see #isVerticalScrollBarEnabled() + * @see #setHorizontalScrollBarEnabled(boolean) + * @see #setVerticalScrollBarEnabled(boolean) + */ + protected boolean awakenScrollBars(int startDelay, boolean invalidate) { + final ScrollabilityCache scrollCache = mScrollCache; + if (scrollCache == null || !scrollCache.fadeScrollBars) { + return false; + } + if (scrollCache.scrollBar == null) { + scrollCache.scrollBar = new ScrollBarDrawable(); + } + if (isHorizontalScrollBarEnabled() || isVerticalScrollBarEnabled()) { + if (invalidate) { + // Invalidate to show the scrollbars + invalidate(true); + } + if (scrollCache.state == ScrollabilityCache.OFF) { + // FIXME: this is copied from WindowManagerService. + // We should get this value from the system when it + // is possible to do so. + final int KEY_REPEAT_FIRST_DELAY = 750; + startDelay = Math.max(KEY_REPEAT_FIRST_DELAY, startDelay); + } + // Tell mScrollCache when we should start fading. This may + // extend the fade start time if one was already scheduled + long fadeStartTime = AnimationUtils.currentAnimationTimeMillis() + startDelay; + scrollCache.fadeStartTime = fadeStartTime; + scrollCache.state = ScrollabilityCache.ON; + // Schedule our fader to run, unscheduling any old ones first + if (mAttachInfo != null) { + mAttachInfo.mHandler.removeCallbacks(scrollCache); + mAttachInfo.mHandler.postAtTime(scrollCache, fadeStartTime); + } + return true; + } + return false; + } + /** + * Do not invalidate views which are not visible and which are not running an animation. They + * will not get drawn and they should not set dirty flags as if they will be drawn + */ + private boolean skipInvalidate() { + return (mViewFlags & VISIBILITY_MASK) != VISIBLE && mCurrentAnimation == null && + (!(mParent instanceof ViewGroup) || + !((ViewGroup) mParent).isViewTransitioning(this)); + } + /** + * Mark the area defined by dirty as needing to be drawn. If the view is + * visible, {@link #onDraw(android.graphics.Canvas)} will be called at some point + * in the future. This must be called from a UI thread. To call from a non-UI + * thread, call {@link #postInvalidate()}. + * + * WARNING: This method is destructive to dirty. + * @param dirty the rectangle representing the bounds of the dirty region + */ + public void invalidate(Rect dirty) { + if (ViewDebug.TRACE_HIERARCHY) { + ViewDebug.trace(this, ViewDebug.HierarchyTraceType.INVALIDATE); + } + if (skipInvalidate()) { + return; + } + if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) || + (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID || + (mPrivateFlags & INVALIDATED) != INVALIDATED) { + mPrivateFlags &= ~DRAWING_CACHE_VALID; + mPrivateFlags |= INVALIDATED; + mPrivateFlags |= DIRTY; + final ViewParent p = mParent; + final AttachInfo ai = mAttachInfo; + //noinspection PointlessBooleanExpression,ConstantConditions + if (!HardwareRenderer.RENDER_DIRTY_REGIONS) { + if (p != null && ai != null && ai.mHardwareAccelerated) { + // fast-track for GL-enabled applications; just invalidate the whole hierarchy + // with a null dirty rect, which tells the ViewAncestor to redraw everything + p.invalidateChild(this, null); + return; + } + } + if (p != null && ai != null) { + final int scrollX = mScrollX; + final int scrollY = mScrollY; + final Rect r = ai.mTmpInvalRect; + r.set(dirty.left - scrollX, dirty.top - scrollY, + dirty.right - scrollX, dirty.bottom - scrollY); + mParent.invalidateChild(this, r); + } + } + } + /** + * Mark the area defined by the rect (l,t,r,b) as needing to be drawn. + * The coordinates of the dirty rect are relative to the view. + * If the view is visible, {@link #onDraw(android.graphics.Canvas)} + * will be called at some point in the future. This must be called from + * a UI thread. To call from a non-UI thread, call {@link #postInvalidate()}. + * @param l the left position of the dirty region + * @param t the top position of the dirty region + * @param r the right position of the dirty region + * @param b the bottom position of the dirty region + */ + public void invalidate(int l, int t, int r, int b) { + if (ViewDebug.TRACE_HIERARCHY) { + ViewDebug.trace(this, ViewDebug.HierarchyTraceType.INVALIDATE); + } + if (skipInvalidate()) { + return; + } + if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) || + (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID || + (mPrivateFlags & INVALIDATED) != INVALIDATED) { + mPrivateFlags &= ~DRAWING_CACHE_VALID; + mPrivateFlags |= INVALIDATED; + mPrivateFlags |= DIRTY; + final ViewParent p = mParent; + final AttachInfo ai = mAttachInfo; + //noinspection PointlessBooleanExpression,ConstantConditions + if (!HardwareRenderer.RENDER_DIRTY_REGIONS) { + if (p != null && ai != null && ai.mHardwareAccelerated) { + // fast-track for GL-enabled applications; just invalidate the whole hierarchy + // with a null dirty rect, which tells the ViewAncestor to redraw everything + p.invalidateChild(this, null); + return; + } + } + if (p != null && ai != null && l < r && t < b) { + final int scrollX = mScrollX; + final int scrollY = mScrollY; + final Rect tmpr = ai.mTmpInvalRect; + tmpr.set(l - scrollX, t - scrollY, r - scrollX, b - scrollY); + p.invalidateChild(this, tmpr); + } + } + } + /** + * Invalidate the whole view. If the view is visible, + * {@link #onDraw(android.graphics.Canvas)} will be called at some point in + * the future. This must be called from a UI thread. To call from a non-UI thread, + * call {@link #postInvalidate()}. + */ + public void invalidate() { + invalidate(true); + } + /** + * This is where the invalidate() work actually happens. A full invalidate() + * causes the drawing cache to be invalidated, but this function can be called with + * invalidateCache set to false to skip that invalidation step for cases that do not + * need it (for example, a component that remains at the same dimensions with the same + * content). + * + * @param invalidateCache Whether the drawing cache for this view should be invalidated as + * well. This is usually true for a full invalidate, but may be set to false if the + * View's contents or dimensions have not changed. + */ + void invalidate(boolean invalidateCache) { + if (ViewDebug.TRACE_HIERARCHY) { + ViewDebug.trace(this, ViewDebug.HierarchyTraceType.INVALIDATE); + } + if (skipInvalidate()) { + return; + } + if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) || + (invalidateCache && (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID) || + (mPrivateFlags & INVALIDATED) != INVALIDATED || isOpaque() != mLastIsOpaque) { + mLastIsOpaque = isOpaque(); + mPrivateFlags &= ~DRAWN; + mPrivateFlags |= DIRTY; + if (invalidateCache) { + mPrivateFlags |= INVALIDATED; + mPrivateFlags &= ~DRAWING_CACHE_VALID; + } + final AttachInfo ai = mAttachInfo; + final ViewParent p = mParent; + //noinspection PointlessBooleanExpression,ConstantConditions + if (!HardwareRenderer.RENDER_DIRTY_REGIONS) { + if (p != null && ai != null && ai.mHardwareAccelerated) { + // fast-track for GL-enabled applications; just invalidate the whole hierarchy + // with a null dirty rect, which tells the ViewAncestor to redraw everything + p.invalidateChild(this, null); + return; + } + } + if (p != null && ai != null) { + final Rect r = ai.mTmpInvalRect; + r.set(0, 0, mRight - mLeft, mBottom - mTop); + // Don't call invalidate -- we don't want to internally scroll + // our own bounds + p.invalidateChild(this, r); + } + } + } + /** + * Used to indicate that the parent of this view should clear its caches. This functionality + * is used to force the parent to rebuild its display list (when hardware-accelerated), + * which is necessary when various parent-managed properties of the view change, such as + * alpha, translationX/Y, scrollX/Y, scaleX/Y, and rotation/X/Y. This method only + * clears the parent caches and does not causes an invalidate event. + * + * @hide + */ + protected void invalidateParentCaches() { + if (mParent instanceof View) { + ((View) mParent).mPrivateFlags |= INVALIDATED; + } + } + /** + * Used to indicate that the parent of this view should be invalidated. This functionality + * is used to force the parent to rebuild its display list (when hardware-accelerated), + * which is necessary when various parent-managed properties of the view change, such as + * alpha, translationX/Y, scrollX/Y, scaleX/Y, and rotation/X/Y. This method will propagate + * an invalidation event to the parent. + * + * @hide + */ + protected void invalidateParentIfNeeded() { + if (isHardwareAccelerated() && mParent instanceof View) { + ((View) mParent).invalidate(true); + } + } + /** + * Indicates whether this View is opaque. An opaque View guarantees that it will + * draw all the pixels overlapping its bounds using a fully opaque color. + * + * Subclasses of View should override this method whenever possible to indicate + * whether an instance is opaque. Opaque Views are treated in a special way by + * the View hierarchy, possibly allowing it to perform optimizations during + * invalidate/draw passes. + * + * @return True if this View is guaranteed to be fully opaque, false otherwise. + */ + @ViewDebug.ExportedProperty(category = "drawing") + public boolean isOpaque() { + return (mPrivateFlags & OPAQUE_MASK) == OPAQUE_MASK && + ((mTransformationInfo != null ? mTransformationInfo.mAlpha : 1) + >= 1.0f - ViewConfiguration.ALPHA_THRESHOLD); + } + /** + * @hide + */ + protected void computeOpaqueFlags() { + // Opaque if: + // - Has a background + // - Background is opaque + // - Doesn't have scrollbars or scrollbars are inside overlay + if (mBGDrawable != null && mBGDrawable.getOpacity() == PixelFormat.OPAQUE) { + mPrivateFlags |= OPAQUE_BACKGROUND; + } else { + mPrivateFlags &= ~OPAQUE_BACKGROUND; + } + final int flags = mViewFlags; + if (((flags & SCROLLBARS_VERTICAL) == 0 && (flags & SCROLLBARS_HORIZONTAL) == 0) || + (flags & SCROLLBARS_STYLE_MASK) == SCROLLBARS_INSIDE_OVERLAY) { + mPrivateFlags |= OPAQUE_SCROLLBARS; + } else { + mPrivateFlags &= ~OPAQUE_SCROLLBARS; + } + } + /** + * @hide + */ + protected boolean hasOpaqueScrollbars() { + return (mPrivateFlags & OPAQUE_SCROLLBARS) == OPAQUE_SCROLLBARS; + } + /** + * @return A handler associated with the thread running the View. This + * handler can be used to pump events in the UI events queue. + */ + public Handler getHandler() { + if (mAttachInfo != null) { + return mAttachInfo.mHandler; + } + return null; + } + /** + * Gets the view root associated with the View. + * @return The view root, or null if none. + * @hide + */ + public ViewRootImpl getViewRootImpl() { + if (mAttachInfo != null) { + return mAttachInfo.mViewRootImpl; + } + return null; + } + /** + *

Causes the Runnable to be added to the message queue. + * The runnable will be run on the user interface thread.

+ * + *

This method can be invoked from outside of the UI thread + * only when this View is attached to a window.

+ * + * @param action The Runnable that will be executed. + * + * @return Returns true if the Runnable was successfully placed in to the + * message queue. Returns false on failure, usually because the + * looper processing the message queue is exiting. + */ + public boolean post(Runnable action) { + final AttachInfo attachInfo = mAttachInfo; + if (attachInfo != null) { + return attachInfo.mHandler.post(action); + } + // Assume that post will succeed later + ViewRootImpl.getRunQueue().post(action); + return true; + } + /** + *

Causes the Runnable to be added to the message queue, to be run + * after the specified amount of time elapses. + * The runnable will be run on the user interface thread.

+ * + *

This method can be invoked from outside of the UI thread + * only when this View is attached to a window.

+ * + * @param action The Runnable that will be executed. + * @param delayMillis The delay (in milliseconds) until the Runnable + * will be executed. + * + * @return true if the Runnable was successfully placed in to the + * message queue. Returns false on failure, usually because the + * looper processing the message queue is exiting. Note that a + * result of true does not mean the Runnable will be processed -- + * if the looper is quit before the delivery time of the message + * occurs then the message will be dropped. + */ + public boolean postDelayed(Runnable action, long delayMillis) { + final AttachInfo attachInfo = mAttachInfo; + if (attachInfo != null) { + return attachInfo.mHandler.postDelayed(action, delayMillis); + } + // Assume that post will succeed later + ViewRootImpl.getRunQueue().postDelayed(action, delayMillis); + return true; + } + /** + *

Removes the specified Runnable from the message queue.

+ * + *

This method can be invoked from outside of the UI thread + * only when this View is attached to a window.

+ * + * @param action The Runnable to remove from the message handling queue + * + * @return true if this view could ask the Handler to remove the Runnable, + * false otherwise. When the returned value is true, the Runnable + * may or may not have been actually removed from the message queue + * (for instance, if the Runnable was not in the queue already.) + */ + public boolean removeCallbacks(Runnable action) { + final AttachInfo attachInfo = mAttachInfo; + if (attachInfo != null) { + attachInfo.mHandler.removeCallbacks(action); + } else { + // Assume that post will succeed later + ViewRootImpl.getRunQueue().removeCallbacks(action); + } + return true; + } + /** + *

Cause an invalidate to happen on a subsequent cycle through the event loop. + * Use this to invalidate the View from a non-UI thread.

+ * + *

This method can be invoked from outside of the UI thread + * only when this View is attached to a window.

+ * + * @see #invalidate() + */ + public void postInvalidate() { + postInvalidateDelayed(0); + } + /** + *

Cause an invalidate of the specified area to happen on a subsequent cycle + * through the event loop. Use this to invalidate the View from a non-UI thread.

+ * + *

This method can be invoked from outside of the UI thread + * only when this View is attached to a window.

+ * + * @param left The left coordinate of the rectangle to invalidate. + * @param top The top coordinate of the rectangle to invalidate. + * @param right The right coordinate of the rectangle to invalidate. + * @param bottom The bottom coordinate of the rectangle to invalidate. + * + * @see #invalidate(int, int, int, int) + * @see #invalidate(Rect) + */ + public void postInvalidate(int left, int top, int right, int bottom) { + postInvalidateDelayed(0, left, top, right, bottom); + } + /** + *

Cause an invalidate to happen on a subsequent cycle through the event + * loop. Waits for the specified amount of time.

+ * + *

This method can be invoked from outside of the UI thread + * only when this View is attached to a window.

+ * + * @param delayMilliseconds the duration in milliseconds to delay the + * invalidation by + */ + public void postInvalidateDelayed(long delayMilliseconds) { + // We try only with the AttachInfo because there's no point in invalidating + // if we are not attached to our window + final AttachInfo attachInfo = mAttachInfo; + if (attachInfo != null) { + attachInfo.mViewRootImpl.dispatchInvalidateDelayed(this, delayMilliseconds); + } + } + /** + *

Cause an invalidate of the specified area to happen on a subsequent cycle + * through the event loop. Waits for the specified amount of time.

+ * + *

This method can be invoked from outside of the UI thread + * only when this View is attached to a window.

+ * + * @param delayMilliseconds the duration in milliseconds to delay the + * invalidation by + * @param left The left coordinate of the rectangle to invalidate. + * @param top The top coordinate of the rectangle to invalidate. + * @param right The right coordinate of the rectangle to invalidate. + * @param bottom The bottom coordinate of the rectangle to invalidate. + */ + public void postInvalidateDelayed(long delayMilliseconds, int left, int top, + int right, int bottom) { + // We try only with the AttachInfo because there's no point in invalidating + // if we are not attached to our window + final AttachInfo attachInfo = mAttachInfo; + if (attachInfo != null) { + final AttachInfo.InvalidateInfo info = AttachInfo.InvalidateInfo.acquire(); + info.target = this; + info.left = left; + info.top = top; + info.right = right; + info.bottom = bottom; + attachInfo.mViewRootImpl.dispatchInvalidateRectDelayed(info, delayMilliseconds); + } + } + /** + * Post a callback to send a {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} event. + * This event is sent at most once every + * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}. + */ + private void postSendViewScrolledAccessibilityEventCallback() { + if (mSendViewScrolledAccessibilityEvent == null) { + mSendViewScrolledAccessibilityEvent = new SendViewScrolledAccessibilityEvent(); + } + if (!mSendViewScrolledAccessibilityEvent.mIsPending) { + mSendViewScrolledAccessibilityEvent.mIsPending = true; + postDelayed(mSendViewScrolledAccessibilityEvent, + ViewConfiguration.getSendRecurringAccessibilityEventsInterval()); + } + } + /** + * Called by a parent to request that a child update its values for mScrollX + * and mScrollY if necessary. This will typically be done if the child is + * animating a scroll using a {@link android.widget.Scroller Scroller} + * object. + */ + public void computeScroll() { + } + /** + *

Indicate whether the horizontal edges are faded when the view is + * scrolled horizontally.

+ * + * @return true if the horizontal edges should are faded on scroll, false + * otherwise + * + * @see #setHorizontalFadingEdgeEnabled(boolean) + * @attr ref android.R.styleable#View_requiresFadingEdge + */ + public boolean isHorizontalFadingEdgeEnabled() { + return (mViewFlags & FADING_EDGE_HORIZONTAL) == FADING_EDGE_HORIZONTAL; + } + /** + *

Define whether the horizontal edges should be faded when this view + * is scrolled horizontally.

+ * + * @param horizontalFadingEdgeEnabled true if the horizontal edges should + * be faded when the view is scrolled + * horizontally + * + * @see #isHorizontalFadingEdgeEnabled() + * @attr ref android.R.styleable#View_requiresFadingEdge + */ + public void setHorizontalFadingEdgeEnabled(boolean horizontalFadingEdgeEnabled) { + if (isHorizontalFadingEdgeEnabled() != horizontalFadingEdgeEnabled) { + if (horizontalFadingEdgeEnabled) { + initScrollCache(); + } + mViewFlags ^= FADING_EDGE_HORIZONTAL; + } + } + /** + *

Indicate whether the vertical edges are faded when the view is + * scrolled horizontally.

+ * + * @return true if the vertical edges should are faded on scroll, false + * otherwise + * + * @see #setVerticalFadingEdgeEnabled(boolean) + * @attr ref android.R.styleable#View_requiresFadingEdge + */ + public boolean isVerticalFadingEdgeEnabled() { + return (mViewFlags & FADING_EDGE_VERTICAL) == FADING_EDGE_VERTICAL; + } + /** + *

Define whether the vertical edges should be faded when this view + * is scrolled vertically.

+ * + * @param verticalFadingEdgeEnabled true if the vertical edges should + * be faded when the view is scrolled + * vertically + * + * @see #isVerticalFadingEdgeEnabled() + * @attr ref android.R.styleable#View_requiresFadingEdge + */ + public void setVerticalFadingEdgeEnabled(boolean verticalFadingEdgeEnabled) { + if (isVerticalFadingEdgeEnabled() != verticalFadingEdgeEnabled) { + if (verticalFadingEdgeEnabled) { + initScrollCache(); + } + mViewFlags ^= FADING_EDGE_VERTICAL; + } + } + /** + * Returns the strength, or intensity, of the top faded edge. The strength is + * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation + * returns 0.0 or 1.0 but no value in between. + * + * Subclasses should override this method to provide a smoother fade transition + * when scrolling occurs. + * + * @return the intensity of the top fade as a float between 0.0f and 1.0f + */ + protected float getTopFadingEdgeStrength() { + return computeVerticalScrollOffset() > 0 ? 1.0f : 0.0f; + } + /** + * Returns the strength, or intensity, of the bottom faded edge. The strength is + * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation + * returns 0.0 or 1.0 but no value in between. + * + * Subclasses should override this method to provide a smoother fade transition + * when scrolling occurs. + * + * @return the intensity of the bottom fade as a float between 0.0f and 1.0f + */ + protected float getBottomFadingEdgeStrength() { + return computeVerticalScrollOffset() + computeVerticalScrollExtent() < + computeVerticalScrollRange() ? 1.0f : 0.0f; + } + /** + * Returns the strength, or intensity, of the left faded edge. The strength is + * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation + * returns 0.0 or 1.0 but no value in between. + * + * Subclasses should override this method to provide a smoother fade transition + * when scrolling occurs. + * + * @return the intensity of the left fade as a float between 0.0f and 1.0f + */ + protected float getLeftFadingEdgeStrength() { + return computeHorizontalScrollOffset() > 0 ? 1.0f : 0.0f; + } + /** + * Returns the strength, or intensity, of the right faded edge. The strength is + * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation + * returns 0.0 or 1.0 but no value in between. + * + * Subclasses should override this method to provide a smoother fade transition + * when scrolling occurs. + * + * @return the intensity of the right fade as a float between 0.0f and 1.0f + */ + protected float getRightFadingEdgeStrength() { + return computeHorizontalScrollOffset() + computeHorizontalScrollExtent() < + computeHorizontalScrollRange() ? 1.0f : 0.0f; + } + /** + *

Indicate whether the horizontal scrollbar should be drawn or not. The + * scrollbar is not drawn by default.

+ * + * @return true if the horizontal scrollbar should be painted, false + * otherwise + * + * @see #setHorizontalScrollBarEnabled(boolean) + */ + public boolean isHorizontalScrollBarEnabled() { + return (mViewFlags & SCROLLBARS_HORIZONTAL) == SCROLLBARS_HORIZONTAL; + } + /** + *

Define whether the horizontal scrollbar should be drawn or not. The + * scrollbar is not drawn by default.

+ * + * @param horizontalScrollBarEnabled true if the horizontal scrollbar should + * be painted + * + * @see #isHorizontalScrollBarEnabled() + */ + public void setHorizontalScrollBarEnabled(boolean horizontalScrollBarEnabled) { + if (isHorizontalScrollBarEnabled() != horizontalScrollBarEnabled) { + mViewFlags ^= SCROLLBARS_HORIZONTAL; + computeOpaqueFlags(); + resolvePadding(); + } + } + /** + *

Indicate whether the vertical scrollbar should be drawn or not. The + * scrollbar is not drawn by default.

+ * + * @return true if the vertical scrollbar should be painted, false + * otherwise + * + * @see #setVerticalScrollBarEnabled(boolean) + */ + public boolean isVerticalScrollBarEnabled() { + return (mViewFlags & SCROLLBARS_VERTICAL) == SCROLLBARS_VERTICAL; + } + /** + *

Define whether the vertical scrollbar should be drawn or not. The + * scrollbar is not drawn by default.

+ * + * @param verticalScrollBarEnabled true if the vertical scrollbar should + * be painted + * + * @see #isVerticalScrollBarEnabled() + */ + public void setVerticalScrollBarEnabled(boolean verticalScrollBarEnabled) { + if (isVerticalScrollBarEnabled() != verticalScrollBarEnabled) { + mViewFlags ^= SCROLLBARS_VERTICAL; + computeOpaqueFlags(); + resolvePadding(); + } + } + /** + * @hide + */ + protected void recomputePadding() { + setPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight, mUserPaddingBottom); + } + /** + * Define whether scrollbars will fade when the view is not scrolling. + * + * @param fadeScrollbars wheter to enable fading + * + */ + public void setScrollbarFadingEnabled(boolean fadeScrollbars) { + initScrollCache(); + final ScrollabilityCache scrollabilityCache = mScrollCache; + scrollabilityCache.fadeScrollBars = fadeScrollbars; + if (fadeScrollbars) { + scrollabilityCache.state = ScrollabilityCache.OFF; + } else { + scrollabilityCache.state = ScrollabilityCache.ON; + } + } + /** + * + * Returns true if scrollbars will fade when this view is not scrolling + * + * @return true if scrollbar fading is enabled + */ + public boolean isScrollbarFadingEnabled() { + return mScrollCache != null && mScrollCache.fadeScrollBars; + } + /** + *

Specify the style of the scrollbars. The scrollbars can be overlaid or + * inset. When inset, they add to the padding of the view. And the scrollbars + * can be drawn inside the padding area or on the edge of the view. For example, + * if a view has a background drawable and you want to draw the scrollbars + * inside the padding specified by the drawable, you can use + * SCROLLBARS_INSIDE_OVERLAY or SCROLLBARS_INSIDE_INSET. If you want them to + * appear at the edge of the view, ignoring the padding, then you can use + * SCROLLBARS_OUTSIDE_OVERLAY or SCROLLBARS_OUTSIDE_INSET.

+ * @param style the style of the scrollbars. Should be one of + * SCROLLBARS_INSIDE_OVERLAY, SCROLLBARS_INSIDE_INSET, + * SCROLLBARS_OUTSIDE_OVERLAY or SCROLLBARS_OUTSIDE_INSET. + * @see #SCROLLBARS_INSIDE_OVERLAY + * @see #SCROLLBARS_INSIDE_INSET + * @see #SCROLLBARS_OUTSIDE_OVERLAY + * @see #SCROLLBARS_OUTSIDE_INSET + */ + public void setScrollBarStyle(int style) { + if (style != (mViewFlags & SCROLLBARS_STYLE_MASK)) { + mViewFlags = (mViewFlags & ~SCROLLBARS_STYLE_MASK) | (style & SCROLLBARS_STYLE_MASK); + computeOpaqueFlags(); + resolvePadding(); + } + } + /** + *

Returns the current scrollbar style.

+ * @return the current scrollbar style + * @see #SCROLLBARS_INSIDE_OVERLAY + * @see #SCROLLBARS_INSIDE_INSET + * @see #SCROLLBARS_OUTSIDE_OVERLAY + * @see #SCROLLBARS_OUTSIDE_INSET + */ + @ViewDebug.ExportedProperty(mapping = { + @ViewDebug.IntToString(from = SCROLLBARS_INSIDE_OVERLAY, to = "INSIDE_OVERLAY"), + @ViewDebug.IntToString(from = SCROLLBARS_INSIDE_INSET, to = "INSIDE_INSET"), + @ViewDebug.IntToString(from = SCROLLBARS_OUTSIDE_OVERLAY, to = "OUTSIDE_OVERLAY"), + @ViewDebug.IntToString(from = SCROLLBARS_OUTSIDE_INSET, to = "OUTSIDE_INSET") + }) + public int getScrollBarStyle() { + return mViewFlags & SCROLLBARS_STYLE_MASK; + } + /** + *

Compute the horizontal range that the horizontal scrollbar + * represents.

+ * + *

The range is expressed in arbitrary units that must be the same as the + * units used by {@link #computeHorizontalScrollExtent()} and + * {@link #computeHorizontalScrollOffset()}.

+ * + *

The default range is the drawing width of this view.

+ * + * @return the total horizontal range represented by the horizontal + * scrollbar + * + * @see #computeHorizontalScrollExtent() + * @see #computeHorizontalScrollOffset() + * @see android.widget.ScrollBarDrawable + */ + protected int computeHorizontalScrollRange() { + return getWidth(); + } + /** + *

Compute the horizontal offset of the horizontal scrollbar's thumb + * within the horizontal range. This value is used to compute the position + * of the thumb within the scrollbar's track.

+ * + *

The range is expressed in arbitrary units that must be the same as the + * units used by {@link #computeHorizontalScrollRange()} and + * {@link #computeHorizontalScrollExtent()}.

+ * + *

The default offset is the scroll offset of this view.

+ * + * @return the horizontal offset of the scrollbar's thumb + * + * @see #computeHorizontalScrollRange() + * @see #computeHorizontalScrollExtent() + * @see android.widget.ScrollBarDrawable + */ + protected int computeHorizontalScrollOffset() { + return mScrollX; + } + /** + *

Compute the horizontal extent of the horizontal scrollbar's thumb + * within the horizontal range. This value is used to compute the length + * of the thumb within the scrollbar's track.

+ * + *

The range is expressed in arbitrary units that must be the same as the + * units used by {@link #computeHorizontalScrollRange()} and + * {@link #computeHorizontalScrollOffset()}.

+ * + *

The default extent is the drawing width of this view.

+ * + * @return the horizontal extent of the scrollbar's thumb + * + * @see #computeHorizontalScrollRange() + * @see #computeHorizontalScrollOffset() + * @see android.widget.ScrollBarDrawable + */ + protected int computeHorizontalScrollExtent() { + return getWidth(); + } + /** + *

Compute the vertical range that the vertical scrollbar represents.

+ * + *

The range is expressed in arbitrary units that must be the same as the + * units used by {@link #computeVerticalScrollExtent()} and + * {@link #computeVerticalScrollOffset()}.

+ * + * @return the total vertical range represented by the vertical scrollbar + * + *

The default range is the drawing height of this view.

+ * + * @see #computeVerticalScrollExtent() + * @see #computeVerticalScrollOffset() + * @see android.widget.ScrollBarDrawable + */ + protected int computeVerticalScrollRange() { + return getHeight(); + } + /** + *

Compute the vertical offset of the vertical scrollbar's thumb + * within the horizontal range. This value is used to compute the position + * of the thumb within the scrollbar's track.

+ * + *

The range is expressed in arbitrary units that must be the same as the + * units used by {@link #computeVerticalScrollRange()} and + * {@link #computeVerticalScrollExtent()}.

+ * + *

The default offset is the scroll offset of this view.

+ * + * @return the vertical offset of the scrollbar's thumb + * + * @see #computeVerticalScrollRange() + * @see #computeVerticalScrollExtent() + * @see android.widget.ScrollBarDrawable + */ + protected int computeVerticalScrollOffset() { + return mScrollY; + } + /** + *

Compute the vertical extent of the horizontal scrollbar's thumb + * within the vertical range. This value is used to compute the length + * of the thumb within the scrollbar's track.

+ * + *

The range is expressed in arbitrary units that must be the same as the + * units used by {@link #computeVerticalScrollRange()} and + * {@link #computeVerticalScrollOffset()}.

+ * + *

The default extent is the drawing height of this view.

+ * + * @return the vertical extent of the scrollbar's thumb + * + * @see #computeVerticalScrollRange() + * @see #computeVerticalScrollOffset() + * @see android.widget.ScrollBarDrawable + */ + protected int computeVerticalScrollExtent() { + return getHeight(); + } + /** + * Check if this view can be scrolled horizontally in a certain direction. + * + * @param direction Negative to check scrolling left, positive to check scrolling right. + * @return true if this view can be scrolled in the specified direction, false otherwise. + */ + public boolean canScrollHorizontally(int direction) { + final int offset = computeHorizontalScrollOffset(); + final int range = computeHorizontalScrollRange() - computeHorizontalScrollExtent(); + if (range == 0) return false; + if (direction < 0) { + return offset > 0; + } else { + return offset < range - 1; + } + } + /** + * Check if this view can be scrolled vertically in a certain direction. + * + * @param direction Negative to check scrolling up, positive to check scrolling down. + * @return true if this view can be scrolled in the specified direction, false otherwise. + */ + public boolean canScrollVertically(int direction) { + final int offset = computeVerticalScrollOffset(); + final int range = computeVerticalScrollRange() - computeVerticalScrollExtent(); + if (range == 0) return false; + if (direction < 0) { + return offset > 0; + } else { + return offset < range - 1; + } + } + /** + *

Request the drawing of the horizontal and the vertical scrollbar. The + * scrollbars are painted only if they have been awakened first.

+ * + * @param canvas the canvas on which to draw the scrollbars + * + * @see #awakenScrollBars(int) + */ + protected final void onDrawScrollBars(Canvas canvas) { + // scrollbars are drawn only when the animation is running + final ScrollabilityCache cache = mScrollCache; + if (cache != null) { + int state = cache.state; + if (state == ScrollabilityCache.OFF) { + return; + } + boolean invalidate = false; + if (state == ScrollabilityCache.FADING) { + // We're fading -- get our fade interpolation + if (cache.interpolatorValues == null) { + cache.interpolatorValues = new float[1]; + } + float[] values = cache.interpolatorValues; + // Stops the animation if we're done + if (cache.scrollBarInterpolator.timeToValues(values) == + Interpolator.Result.FREEZE_END) { + cache.state = ScrollabilityCache.OFF; + } else { + cache.scrollBar.setAlpha(Math.round(values[0])); + } + // This will make the scroll bars inval themselves after + // drawing. We only want this when we're fading so that + // we prevent excessive redraws + invalidate = true; + } else { + // We're just on -- but we may have been fading before so + // reset alpha + cache.scrollBar.setAlpha(255); + } + final int viewFlags = mViewFlags; + final boolean drawHorizontalScrollBar = + (viewFlags & SCROLLBARS_HORIZONTAL) == SCROLLBARS_HORIZONTAL; + final boolean drawVerticalScrollBar = + (viewFlags & SCROLLBARS_VERTICAL) == SCROLLBARS_VERTICAL + && !isVerticalScrollBarHidden(); + if (drawVerticalScrollBar || drawHorizontalScrollBar) { + final int width = mRight - mLeft; + final int height = mBottom - mTop; + final ScrollBarDrawable scrollBar = cache.scrollBar; + final int scrollX = mScrollX; + final int scrollY = mScrollY; + final int inside = (viewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0; + int left, top, right, bottom; + if (drawHorizontalScrollBar) { + int size = scrollBar.getSize(false); + if (size <= 0) { + size = cache.scrollBarSize; + } + scrollBar.setParameters(computeHorizontalScrollRange(), + computeHorizontalScrollOffset(), + computeHorizontalScrollExtent(), false); + final int verticalScrollBarGap = drawVerticalScrollBar ? + getVerticalScrollbarWidth() : 0; + top = scrollY + height - size - (mUserPaddingBottom & inside); + left = scrollX + (mPaddingLeft & inside); + right = scrollX + width - (mUserPaddingRight & inside) - verticalScrollBarGap; + bottom = top + size; + onDrawHorizontalScrollBar(canvas, scrollBar, left, top, right, bottom); + if (invalidate) { + invalidate(left, top, right, bottom); + } + } + if (drawVerticalScrollBar) { + int size = scrollBar.getSize(true); + if (size <= 0) { + size = cache.scrollBarSize; + } + scrollBar.setParameters(computeVerticalScrollRange(), + computeVerticalScrollOffset(), + computeVerticalScrollExtent(), true); + switch (mVerticalScrollbarPosition) { + default: + case SCROLLBAR_POSITION_DEFAULT: + case SCROLLBAR_POSITION_RIGHT: + left = scrollX + width - size - (mUserPaddingRight & inside); + break; + case SCROLLBAR_POSITION_LEFT: + left = scrollX + (mUserPaddingLeft & inside); + break; + } + top = scrollY + (mPaddingTop & inside); + right = left + size; + bottom = scrollY + height - (mUserPaddingBottom & inside); + onDrawVerticalScrollBar(canvas, scrollBar, left, top, right, bottom); + if (invalidate) { + invalidate(left, top, right, bottom); + } + } + } + } + } + /** + * Override this if the vertical scrollbar needs to be hidden in a subclass, like when + * FastScroller is visible. + * @return whether to temporarily hide the vertical scrollbar + * @hide + */ + protected boolean isVerticalScrollBarHidden() { + return false; + } + /** + *

Draw the horizontal scrollbar if + * {@link #isHorizontalScrollBarEnabled()} returns true.

+ * + * @param canvas the canvas on which to draw the scrollbar + * @param scrollBar the scrollbar's drawable + * + * @see #isHorizontalScrollBarEnabled() + * @see #computeHorizontalScrollRange() + * @see #computeHorizontalScrollExtent() + * @see #computeHorizontalScrollOffset() + * @see android.widget.ScrollBarDrawable + * @hide + */ + protected void onDrawHorizontalScrollBar(Canvas canvas, Drawable scrollBar, + int l, int t, int r, int b) { + scrollBar.setBounds(l, t, r, b); + scrollBar.draw(canvas); + } + /** + *

Draw the vertical scrollbar if {@link #isVerticalScrollBarEnabled()} + * returns true.

+ * + * @param canvas the canvas on which to draw the scrollbar + * @param scrollBar the scrollbar's drawable + * + * @see #isVerticalScrollBarEnabled() + * @see #computeVerticalScrollRange() + * @see #computeVerticalScrollExtent() + * @see #computeVerticalScrollOffset() + * @see android.widget.ScrollBarDrawable + * @hide + */ + protected void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar, + int l, int t, int r, int b) { + scrollBar.setBounds(l, t, r, b); + scrollBar.draw(canvas); + } + /** + * Implement this to do your drawing. + * + * @param canvas the canvas on which the background will be drawn + */ + protected void onDraw(Canvas canvas) { + } + /* + * Caller is responsible for calling requestLayout if necessary. + * (This allows addViewInLayout to not request a new layout.) + */ + void assignParent(ViewParent parent) { + if (mParent == null) { + mParent = parent; + } else if (parent == null) { + mParent = null; + } else { + throw new RuntimeException("view " + this + " being added, but" + + " it already has a parent"); + } + } + /** + * This is called when the view is attached to a window. At this point it + * has a Surface and will start drawing. Note that this function is + * guaranteed to be called before {@link #onDraw(android.graphics.Canvas)}, + * however it may be called any time before the first onDraw -- including + * before or after {@link #onMeasure(int, int)}. + * + * @see #onDetachedFromWindow() + */ + protected void onAttachedToWindow() { + if ((mPrivateFlags & REQUEST_TRANSPARENT_REGIONS) != 0) { + mParent.requestTransparentRegion(this); + } + if ((mPrivateFlags & AWAKEN_SCROLL_BARS_ON_ATTACH) != 0) { + initialAwakenScrollBars(); + mPrivateFlags &= ~AWAKEN_SCROLL_BARS_ON_ATTACH; + } + jumpDrawablesToCurrentState(); + // Order is important here: LayoutDirection MUST be resolved before Padding + // and TextDirection + resolveLayoutDirectionIfNeeded(); + resolvePadding(); + resolveTextDirection(); + if (isFocused()) { + InputMethodManager imm = InputMethodManager.peekInstance(); + imm.focusIn(this); + } + } + /** + * Resolve and cache the layout direction. LTR is set initially. This is implicitly supposing + * that the parent directionality can and will be resolved before its children. + */ + private void resolveLayoutDirectionIfNeeded() { + // Do not resolve if it is not needed + if ((mPrivateFlags2 & LAYOUT_DIRECTION_RESOLVED) == LAYOUT_DIRECTION_RESOLVED) return; + // Clear any previous layout direction resolution + mPrivateFlags2 &= ~LAYOUT_DIRECTION_RESOLVED_RTL; + // Reset also TextDirection as a change into LayoutDirection may impact the selected + // TextDirectionHeuristic + resetResolvedTextDirection(); + // Set resolved depending on layout direction + switch (getLayoutDirection()) { + case LAYOUT_DIRECTION_INHERIT: + // We cannot do the resolution if there is no parent + if (mParent == null) return; + // If this is root view, no need to look at parent's layout dir. + if (mParent instanceof ViewGroup) { + ViewGroup viewGroup = ((ViewGroup) mParent); + // Check if the parent view group can resolve + if (! viewGroup.canResolveLayoutDirection()) { + return; + } + if (viewGroup.getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) { + mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED_RTL; + } + } + break; + case LAYOUT_DIRECTION_RTL: + mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED_RTL; + break; + case LAYOUT_DIRECTION_LOCALE: + if(isLayoutDirectionRtl(Locale.getDefault())) { + mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED_RTL; + } + break; + default: + // Nothing to do, LTR by default + } + // Set to resolved + mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED; + } + /** + * @hide + */ + protected void resolvePadding() { + // If the user specified the absolute padding (either with android:padding or + // android:paddingLeft/Top/Right/Bottom), use this padding, otherwise + // use the default padding or the padding from the background drawable + // (stored at this point in mPadding*) + switch (getResolvedLayoutDirection()) { + case LAYOUT_DIRECTION_RTL: + // Start user padding override Right user padding. Otherwise, if Right user + // padding is not defined, use the default Right padding. If Right user padding + // is defined, just use it. + if (mUserPaddingStart >= 0) { + mUserPaddingRight = mUserPaddingStart; + } else if (mUserPaddingRight < 0) { + mUserPaddingRight = mPaddingRight; + } + if (mUserPaddingEnd >= 0) { + mUserPaddingLeft = mUserPaddingEnd; + } else if (mUserPaddingLeft < 0) { + mUserPaddingLeft = mPaddingLeft; + } + break; + case LAYOUT_DIRECTION_LTR: + default: + // Start user padding override Left user padding. Otherwise, if Left user + // padding is not defined, use the default left padding. If Left user padding + // is defined, just use it. + if (mUserPaddingStart >= 0) { + mUserPaddingLeft = mUserPaddingStart; + } else if (mUserPaddingLeft < 0) { + mUserPaddingLeft = mPaddingLeft; + } + if (mUserPaddingEnd >= 0) { + mUserPaddingRight = mUserPaddingEnd; + } else if (mUserPaddingRight < 0) { + mUserPaddingRight = mPaddingRight; + } + } + mUserPaddingBottom = (mUserPaddingBottom >= 0) ? mUserPaddingBottom : mPaddingBottom; + recomputePadding(); + } + /** + * Return true if layout direction resolution can be done + * + * @hide + */ + protected boolean canResolveLayoutDirection() { + switch (getLayoutDirection()) { + case LAYOUT_DIRECTION_INHERIT: + return (mParent != null); + default: + return true; + } + } + /** + * Reset the resolved layout direction. + * + * Subclasses need to override this method to clear cached information that depends on the + * resolved layout direction, or to inform child views that inherit their layout direction. + * Overrides must also call the superclass implementation at the start of their implementation. + * + * @hide + */ + protected void resetResolvedLayoutDirection() { + // Reset the current View resolution + mPrivateFlags2 &= ~LAYOUT_DIRECTION_RESOLVED; + } + /** + * Check if a Locale is corresponding to a RTL script. + * + * @param locale Locale to check + * @return true if a Locale is corresponding to a RTL script. + * + * @hide + */ + protected static boolean isLayoutDirectionRtl(Locale locale) { + return (LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE == + LocaleUtil.getLayoutDirectionFromLocale(locale)); + } + /** + * This is called when the view is detached from a window. At this point it + * no longer has a surface for drawing. + * + * @see #onAttachedToWindow() + */ + protected void onDetachedFromWindow() { + mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT; + removeUnsetPressCallback(); + removeLongPressCallback(); + removePerformClickCallback(); + removeSendViewScrolledAccessibilityEventCallback(); + destroyDrawingCache(); + destroyLayer(); + if (mDisplayList != null) { + mDisplayList.invalidate(); + } + if (mAttachInfo != null) { + mAttachInfo.mViewRootImpl.cancelInvalidate(this); + } + mCurrentAnimation = null; + resetResolvedLayoutDirection(); + resetResolvedTextDirection(); + } + /** + * @return The number of times this view has been attached to a window + */ + protected int getWindowAttachCount() { + return mWindowAttachCount; + } + /** + * Retrieve a unique token identifying the window this view is attached to. + * @return Return the window's token for use in + * {@link WindowManager.LayoutParams#token WindowManager.LayoutParams.token}. + */ + public IBinder getWindowToken() { + return mAttachInfo != null ? mAttachInfo.mWindowToken : null; + } + /** + * Retrieve a unique token identifying the top-level "real" window of + * the window that this view is attached to. That is, this is like + * {@link #getWindowToken}, except if the window this view in is a panel + * window (attached to another containing window), then the token of + * the containing window is returned instead. + * + * @return Returns the associated window token, either + * {@link #getWindowToken()} or the containing window's token. + */ + public IBinder getApplicationWindowToken() { + AttachInfo ai = mAttachInfo; + if (ai != null) { + IBinder appWindowToken = ai.mPanelParentWindowToken; + if (appWindowToken == null) { + appWindowToken = ai.mWindowToken; + } + return appWindowToken; + } + return null; + } + /** + * Retrieve private session object this view hierarchy is using to + * communicate with the window manager. + * @return the session object to communicate with the window manager + */ + /*package*/ IWindowSession getWindowSession() { + return mAttachInfo != null ? mAttachInfo.mSession : null; + } + /** + * @param info the {@link android.view.View.AttachInfo} to associated with + * this view + */ + void dispatchAttachedToWindow(AttachInfo info, int visibility) { + //System.out.println("Attached! " + this); + mAttachInfo = info; + mWindowAttachCount++; + // We will need to evaluate the drawable state at least once. + mPrivateFlags |= DRAWABLE_STATE_DIRTY; + if (mFloatingTreeObserver != null) { + info.mTreeObserver.merge(mFloatingTreeObserver); + mFloatingTreeObserver = null; + } + if ((mPrivateFlags&SCROLL_CONTAINER) != 0) { + mAttachInfo.mScrollContainers.add(this); + mPrivateFlags |= SCROLL_CONTAINER_ADDED; + } + performCollectViewAttributes(visibility); + onAttachedToWindow(); + ListenerInfo li = mListenerInfo; + final CopyOnWriteArrayList listeners = + li != null ? li.mOnAttachStateChangeListeners : null; + if (listeners != null && listeners.size() > 0) { + // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to + // perform the dispatching. The iterator is a safe guard against listeners that + // could mutate the list by calling the various add/remove methods. This prevents + // the array from being modified while we iterate it. + for (OnAttachStateChangeListener listener : listeners) { + listener.onViewAttachedToWindow(this); + } + } + int vis = info.mWindowVisibility; + if (vis != GONE) { + onWindowVisibilityChanged(vis); + } + if ((mPrivateFlags&DRAWABLE_STATE_DIRTY) != 0) { + // If nobody has evaluated the drawable state yet, then do it now. + refreshDrawableState(); + } + } + void dispatchDetachedFromWindow() { + AttachInfo info = mAttachInfo; + if (info != null) { + int vis = info.mWindowVisibility; + if (vis != GONE) { + onWindowVisibilityChanged(GONE); + } + } + onDetachedFromWindow(); + ListenerInfo li = mListenerInfo; + final CopyOnWriteArrayList listeners = + li != null ? li.mOnAttachStateChangeListeners : null; + if (listeners != null && listeners.size() > 0) { + // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to + // perform the dispatching. The iterator is a safe guard against listeners that + // could mutate the list by calling the various add/remove methods. This prevents + // the array from being modified while we iterate it. + for (OnAttachStateChangeListener listener : listeners) { + listener.onViewDetachedFromWindow(this); + } + } + if ((mPrivateFlags & SCROLL_CONTAINER_ADDED) != 0) { + mAttachInfo.mScrollContainers.remove(this); + mPrivateFlags &= ~SCROLL_CONTAINER_ADDED; + } + mAttachInfo = null; + } + /** + * Store this view hierarchy's frozen state into the given container. + * + * @param container The SparseArray in which to save the view's state. + * + * @see #restoreHierarchyState(android.util.SparseArray) + * @see #dispatchSaveInstanceState(android.util.SparseArray) + * @see #onSaveInstanceState() + */ + public void saveHierarchyState(SparseArray container) { + dispatchSaveInstanceState(container); + } + /** + * Called by {@link #saveHierarchyState(android.util.SparseArray)} to store the state for + * this view and its children. May be overridden to modify how freezing happens to a + * view's children; for example, some views may want to not store state for their children. + * + * @param container The SparseArray in which to save the view's state. + * + * @see #dispatchRestoreInstanceState(android.util.SparseArray) + * @see #saveHierarchyState(android.util.SparseArray) + * @see #onSaveInstanceState() + */ + protected void dispatchSaveInstanceState(SparseArray container) { + if (mID != NO_ID && (mViewFlags & SAVE_DISABLED_MASK) == 0) { + mPrivateFlags &= ~SAVE_STATE_CALLED; + Parcelable state = onSaveInstanceState(); + if ((mPrivateFlags & SAVE_STATE_CALLED) == 0) { + throw new IllegalStateException( + "Derived class did not call super.onSaveInstanceState()"); + } + if (state != null) { + // Log.i("View", "Freezing #" + Integer.toHexString(mID) + // + ": " + state); + container.put(mID, state); + } + } + } + /** + * Hook allowing a view to generate a representation of its internal state + * that can later be used to create a new instance with that same state. + * This state should only contain information that is not persistent or can + * not be reconstructed later. For example, you will never store your + * current position on screen because that will be computed again when a + * new instance of the view is placed in its view hierarchy. + *

+ * Some examples of things you may store here: the current cursor position + * in a text view (but usually not the text itself since that is stored in a + * content provider or other persistent storage), the currently selected + * item in a list view. + * + * @return Returns a Parcelable object containing the view's current dynamic + * state, or null if there is nothing interesting to save. The + * default implementation returns null. + * @see #onRestoreInstanceState(android.os.Parcelable) + * @see #saveHierarchyState(android.util.SparseArray) + * @see #dispatchSaveInstanceState(android.util.SparseArray) + * @see #setSaveEnabled(boolean) + */ + protected Parcelable onSaveInstanceState() { + mPrivateFlags |= SAVE_STATE_CALLED; + return BaseSavedState.EMPTY_STATE; + } + /** + * Restore this view hierarchy's frozen state from the given container. + * + * @param container The SparseArray which holds previously frozen states. + * + * @see #saveHierarchyState(android.util.SparseArray) + * @see #dispatchRestoreInstanceState(android.util.SparseArray) + * @see #onRestoreInstanceState(android.os.Parcelable) + */ + public void restoreHierarchyState(SparseArray container) { + dispatchRestoreInstanceState(container); + } + /** + * Called by {@link #restoreHierarchyState(android.util.SparseArray)} to retrieve the + * state for this view and its children. May be overridden to modify how restoring + * happens to a view's children; for example, some views may want to not store state + * for their children. + * + * @param container The SparseArray which holds previously saved state. + * + * @see #dispatchSaveInstanceState(android.util.SparseArray) + * @see #restoreHierarchyState(android.util.SparseArray) + * @see #onRestoreInstanceState(android.os.Parcelable) + */ + protected void dispatchRestoreInstanceState(SparseArray container) { + if (mID != NO_ID) { + Parcelable state = container.get(mID); + if (state != null) { + // Log.i("View", "Restoreing #" + Integer.toHexString(mID) + // + ": " + state); + mPrivateFlags &= ~SAVE_STATE_CALLED; + onRestoreInstanceState(state); + if ((mPrivateFlags & SAVE_STATE_CALLED) == 0) { + throw new IllegalStateException( + "Derived class did not call super.onRestoreInstanceState()"); + } + } + } + } + /** + * Hook allowing a view to re-apply a representation of its internal state that had previously + * been generated by {@link #onSaveInstanceState}. This function will never be called with a + * null state. + * + * @param state The frozen state that had previously been returned by + * {@link #onSaveInstanceState}. + * + * @see #onSaveInstanceState() + * @see #restoreHierarchyState(android.util.SparseArray) + * @see #dispatchRestoreInstanceState(android.util.SparseArray) + */ + protected void onRestoreInstanceState(Parcelable state) { + mPrivateFlags |= SAVE_STATE_CALLED; + if (state != BaseSavedState.EMPTY_STATE && state != null) { + throw new IllegalArgumentException("Wrong state class, expecting View State but " + + "received " + state.getClass().toString() + " instead. This usually happens " + + "when two views of different type have the same id in the same hierarchy. " + + "This view's id is " + ViewDebug.resolveId(mContext, getId()) + ". Make sure " + + "other views do not use the same id."); + } + } + /** + *

Return the time at which the drawing of the view hierarchy started.

+ * + * @return the drawing start time in milliseconds + */ + public long getDrawingTime() { + return mAttachInfo != null ? mAttachInfo.mDrawingTime : 0; + } + /** + *

Enables or disables the duplication of the parent's state into this view. When + * duplication is enabled, this view gets its drawable state from its parent rather + * than from its own internal properties.

+ * + *

Note: in the current implementation, setting this property to true after the + * view was added to a ViewGroup might have no effect at all. This property should + * always be used from XML or set to true before adding this view to a ViewGroup.

+ * + *

Note: if this view's parent addStateFromChildren property is enabled and this + * property is enabled, an exception will be thrown.

+ * + *

Note: if the child view uses and updates additionnal states which are unknown to the + * parent, these states should not be affected by this method.

+ * + * @param enabled True to enable duplication of the parent's drawable state, false + * to disable it. + * + * @see #getDrawableState() + * @see #isDuplicateParentStateEnabled() + */ + public void setDuplicateParentStateEnabled(boolean enabled) { + setFlags(enabled ? DUPLICATE_PARENT_STATE : 0, DUPLICATE_PARENT_STATE); + } + /** + *

Indicates whether this duplicates its drawable state from its parent.

+ * + * @return True if this view's drawable state is duplicated from the parent, + * false otherwise + * + * @see #getDrawableState() + * @see #setDuplicateParentStateEnabled(boolean) + */ + public boolean isDuplicateParentStateEnabled() { + return (mViewFlags & DUPLICATE_PARENT_STATE) == DUPLICATE_PARENT_STATE; + } + /** + *

Specifies the type of layer backing this view. The layer can be + * {@link #LAYER_TYPE_NONE disabled}, {@link #LAYER_TYPE_SOFTWARE software} or + * {@link #LAYER_TYPE_HARDWARE hardware}.

+ * + *

A layer is associated with an optional {@link android.graphics.Paint} + * instance that controls how the layer is composed on screen. The following + * properties of the paint are taken into account when composing the layer:

+ *
    + *
  • {@link android.graphics.Paint#getAlpha() Translucency (alpha)}
  • + *
  • {@link android.graphics.Paint#getXfermode() Blending mode}
  • + *
  • {@link android.graphics.Paint#getColorFilter() Color filter}
  • + *
+ * + *

If this view has an alpha value set to < 1.0 by calling + * {@link #setAlpha(float)}, the alpha value of the layer's paint is replaced by + * this view's alpha value. Calling {@link #setAlpha(float)} is therefore + * equivalent to setting a hardware layer on this view and providing a paint with + * the desired alpha value.

+ * + *

Refer to the documentation of {@link #LAYER_TYPE_NONE disabled}, + * {@link #LAYER_TYPE_SOFTWARE software} and {@link #LAYER_TYPE_HARDWARE hardware} + * for more information on when and how to use layers.

+ * + * @param layerType The ype of layer to use with this view, must be one of + * {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or + * {@link #LAYER_TYPE_HARDWARE} + * @param paint The paint used to compose the layer. This argument is optional + * and can be null. It is ignored when the layer type is + * {@link #LAYER_TYPE_NONE} + * + * @see #getLayerType() + * @see #LAYER_TYPE_NONE + * @see #LAYER_TYPE_SOFTWARE + * @see #LAYER_TYPE_HARDWARE + * @see #setAlpha(float) + * + * @attr ref android.R.styleable#View_layerType + */ + public void setLayerType(int layerType, Paint paint) { + if (layerType < LAYER_TYPE_NONE || layerType > LAYER_TYPE_HARDWARE) { + throw new IllegalArgumentException("Layer type can only be one of: LAYER_TYPE_NONE, " + + "LAYER_TYPE_SOFTWARE or LAYER_TYPE_HARDWARE"); + } + if (layerType == mLayerType) { + if (layerType != LAYER_TYPE_NONE && paint != mLayerPaint) { + mLayerPaint = paint == null ? new Paint() : paint; + invalidateParentCaches(); + invalidate(true); + } + return; + } + // Destroy any previous software drawing cache if needed + switch (mLayerType) { + case LAYER_TYPE_HARDWARE: + destroyLayer(); + // fall through - non-accelerated views may use software layer mechanism instead + case LAYER_TYPE_SOFTWARE: + destroyDrawingCache(); + break; + default: + break; + } + mLayerType = layerType; + final boolean layerDisabled = mLayerType == LAYER_TYPE_NONE; + mLayerPaint = layerDisabled ? null : (paint == null ? new Paint() : paint); + mLocalDirtyRect = layerDisabled ? null : new Rect(); + invalidateParentCaches(); + invalidate(true); + } + /** + * Indicates whether this view has a static layer. A view with layer type + * {@link #LAYER_TYPE_NONE} is a static layer. Other types of layers are + * dynamic. + */ + boolean hasStaticLayer() { + return mLayerType == LAYER_TYPE_NONE; + } + /** + * Indicates what type of layer is currently associated with this view. By default + * a view does not have a layer, and the layer type is {@link #LAYER_TYPE_NONE}. + * Refer to the documentation of {@link #setLayerType(int, android.graphics.Paint)} + * for more information on the different types of layers. + * + * @return {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or + * {@link #LAYER_TYPE_HARDWARE} + * + * @see #setLayerType(int, android.graphics.Paint) + * @see #buildLayer() + * @see #LAYER_TYPE_NONE + * @see #LAYER_TYPE_SOFTWARE + * @see #LAYER_TYPE_HARDWARE + */ + public int getLayerType() { + return mLayerType; + } + /** + * Forces this view's layer to be created and this view to be rendered + * into its layer. If this view's layer type is set to {@link #LAYER_TYPE_NONE}, + * invoking this method will have no effect. + * + * This method can for instance be used to render a view into its layer before + * starting an animation. If this view is complex, rendering into the layer + * before starting the animation will avoid skipping frames. + * + * @throws IllegalStateException If this view is not attached to a window + * + * @see #setLayerType(int, android.graphics.Paint) + */ + public void buildLayer() { + if (mLayerType == LAYER_TYPE_NONE) return; + if (mAttachInfo == null) { + throw new IllegalStateException("This view must be attached to a window first"); + } + switch (mLayerType) { + case LAYER_TYPE_HARDWARE: + if (mAttachInfo.mHardwareRenderer != null && + mAttachInfo.mHardwareRenderer.isEnabled() && + mAttachInfo.mHardwareRenderer.validate()) { + getHardwareLayer(); + } + break; + case LAYER_TYPE_SOFTWARE: + buildDrawingCache(true); + break; + } + } + + // Make sure the HardwareRenderer.validate() was invoked before calling this method + void flushLayer() { + if (mLayerType == LAYER_TYPE_HARDWARE && mHardwareLayer != null) { + mHardwareLayer.flush(); + } + } + /** + *

Returns a hardware layer that can be used to draw this view again + * without executing its draw method.

+ * + * @return A HardwareLayer ready to render, or null if an error occurred. + */ + HardwareLayer getHardwareLayer() { + if (mAttachInfo == null || mAttachInfo.mHardwareRenderer == null || + !mAttachInfo.mHardwareRenderer.isEnabled()) { + return null; + } + + if (!mAttachInfo.mHardwareRenderer.validate()) return null; + final int width = mRight - mLeft; + final int height = mBottom - mTop; + if (width == 0 || height == 0) { + return null; + } + if ((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || mHardwareLayer == null) { + if (mHardwareLayer == null) { + mHardwareLayer = mAttachInfo.mHardwareRenderer.createHardwareLayer( + width, height, isOpaque()); + mLocalDirtyRect.setEmpty(); + } else if (mHardwareLayer.getWidth() != width || mHardwareLayer.getHeight() != height) { + mHardwareLayer.resize(width, height); + mLocalDirtyRect.setEmpty(); + } + // The layer is not valid if the underlying GPU resources cannot be allocated + if (!mHardwareLayer.isValid()) { + return null; + } + HardwareCanvas currentCanvas = mAttachInfo.mHardwareCanvas; + final HardwareCanvas canvas = mHardwareLayer.start(currentCanvas); + // Make sure all the GPU resources have been properly allocated + if (canvas == null) { + mHardwareLayer.end(currentCanvas); + return null; + } + mAttachInfo.mHardwareCanvas = canvas; + try { + canvas.setViewport(width, height); + canvas.onPreDraw(mLocalDirtyRect); + mLocalDirtyRect.setEmpty(); + final int restoreCount = canvas.save(); + computeScroll(); + canvas.translate(-mScrollX, -mScrollY); + mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID; + // Fast path for layouts with no backgrounds + if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) { + mPrivateFlags &= ~DIRTY_MASK; + dispatchDraw(canvas); + } else { + draw(canvas); + } + canvas.restoreToCount(restoreCount); + } finally { + canvas.onPostDraw(); + mHardwareLayer.end(currentCanvas); + mAttachInfo.mHardwareCanvas = currentCanvas; + } + } + return mHardwareLayer; + } + /** + * Destroys this View's hardware layer if possible. + * + * @return True if the layer was destroyed, false otherwise. + * + * @see #setLayerType(int, android.graphics.Paint) + * @see #LAYER_TYPE_HARDWARE + */ + boolean destroyLayer() { + if (mHardwareLayer != null) { + AttachInfo info = mAttachInfo; + if (info != null && info.mHardwareRenderer != null && + info.mHardwareRenderer.isEnabled() && info.mHardwareRenderer.validate()) { + mHardwareLayer.destroy(); + mHardwareLayer = null; + invalidate(true); + invalidateParentCaches(); + } + return true; + } + return false; + } + /** + * Destroys all hardware rendering resources. This method is invoked + * when the system needs to reclaim resources. Upon execution of this + * method, you should free any OpenGL resources created by the view. + * + * Note: you must call + * super.destroyHardwareResources() when overriding + * this method. + * + * @hide + */ + protected void destroyHardwareResources() { + destroyLayer(); + } + /** + *

Enables or disables the drawing cache. When the drawing cache is enabled, the next call + * to {@link #getDrawingCache()} or {@link #buildDrawingCache()} will draw the view in a + * bitmap. Calling {@link #draw(android.graphics.Canvas)} will not draw from the cache when + * the cache is enabled. To benefit from the cache, you must request the drawing cache by + * calling {@link #getDrawingCache()} and draw it on screen if the returned bitmap is not + * null.

+ * + *

Enabling the drawing cache is similar to + * {@link #setLayerType(int, android.graphics.Paint) setting a layer} when hardware + * acceleration is turned off. When hardware acceleration is turned on, enabling the + * drawing cache has no effect on rendering because the system uses a different mechanism + * for acceleration which ignores the flag. If you want to use a Bitmap for the view, even + * when hardware acceleration is enabled, see {@link #setLayerType(int, android.graphics.Paint)} + * for information on how to enable software and hardware layers.

+ * + *

This API can be used to manually generate + * a bitmap copy of this view, by setting the flag to true and calling + * {@link #getDrawingCache()}.

+ * + * @param enabled true to enable the drawing cache, false otherwise + * + * @see #isDrawingCacheEnabled() + * @see #getDrawingCache() + * @see #buildDrawingCache() + * @see #setLayerType(int, android.graphics.Paint) + */ + public void setDrawingCacheEnabled(boolean enabled) { + mCachingFailed = false; + setFlags(enabled ? DRAWING_CACHE_ENABLED : 0, DRAWING_CACHE_ENABLED); + } + /** + *

Indicates whether the drawing cache is enabled for this view.

+ * + * @return true if the drawing cache is enabled + * + * @see #setDrawingCacheEnabled(boolean) + * @see #getDrawingCache() + */ + @ViewDebug.ExportedProperty(category = "drawing") + public boolean isDrawingCacheEnabled() { + return (mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED; + } + /** + * Debugging utility which recursively outputs the dirty state of a view and its + * descendants. + * + * @hide + */ + @SuppressWarnings({"UnusedDeclaration"}) + public void outputDirtyFlags(String indent, boolean clear, int clearMask) { + Log.d("View", indent + this + " DIRTY(" + (mPrivateFlags & View.DIRTY_MASK) + + ") DRAWN(" + (mPrivateFlags & DRAWN) + ")" + " CACHE_VALID(" + + (mPrivateFlags & View.DRAWING_CACHE_VALID) + + ") INVALIDATED(" + (mPrivateFlags & INVALIDATED) + ")"); + if (clear) { + mPrivateFlags &= clearMask; + } + if (this instanceof ViewGroup) { + ViewGroup parent = (ViewGroup) this; + final int count = parent.getChildCount(); + for (int i = 0; i < count; i++) { + final View child = parent.getChildAt(i); + child.outputDirtyFlags(indent + " ", clear, clearMask); + } + } + } + /** + * This method is used by ViewGroup to cause its children to restore or recreate their + * display lists. It is called by getDisplayList() when the parent ViewGroup does not need + * to recreate its own display list, which would happen if it went through the normal + * draw/dispatchDraw mechanisms. + * + * @hide + */ + protected void dispatchGetDisplayList() {} + /** + * A view that is not attached or hardware accelerated cannot create a display list. + * This method checks these conditions and returns the appropriate result. + * + * @return true if view has the ability to create a display list, false otherwise. + * + * @hide + */ + public boolean canHaveDisplayList() { + return !(mAttachInfo == null || mAttachInfo.mHardwareRenderer == null); + } + /** + * @return The HardwareRenderer associated with that view or null if hardware rendering + * is not supported or this this has not been attached to a window. + * + * @hide + */ + public HardwareRenderer getHardwareRenderer() { + if (mAttachInfo != null) { + return mAttachInfo.mHardwareRenderer; + } + return null; + } + /** + *

Returns a display list that can be used to draw this view again + * without executing its draw method.

+ * + * @return A DisplayList ready to replay, or null if caching is not enabled. + * + * @hide + */ + public DisplayList getDisplayList() { + if (!canHaveDisplayList()) { + return null; + } + if (((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || + mDisplayList == null || !mDisplayList.isValid() || + mRecreateDisplayList)) { + // Don't need to recreate the display list, just need to tell our + // children to restore/recreate theirs + if (mDisplayList != null && mDisplayList.isValid() && + !mRecreateDisplayList) { + mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID; + mPrivateFlags &= ~DIRTY_MASK; + dispatchGetDisplayList(); + return mDisplayList; + } + // If we got here, we're recreating it. Mark it as such to ensure that + // we copy in child display lists into ours in drawChild() + mRecreateDisplayList = true; + if (mDisplayList == null) { + final String name = getClass().getSimpleName(); + mDisplayList = mAttachInfo.mHardwareRenderer.createDisplayList(name); + // If we're creating a new display list, make sure our parent gets invalidated + // since they will need to recreate their display list to account for this + // new child display list. + invalidateParentCaches(); + } + final HardwareCanvas canvas = mDisplayList.start(); + int restoreCount = 0; + try { + int width = mRight - mLeft; + int height = mBottom - mTop; + canvas.setViewport(width, height); + // The dirty rect should always be null for a display list + canvas.onPreDraw(null); + computeScroll(); + restoreCount = canvas.save(); + canvas.translate(-mScrollX, -mScrollY); + mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID; + mPrivateFlags &= ~DIRTY_MASK; + // Fast path for layouts with no backgrounds + if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) { + dispatchDraw(canvas); + } else { + draw(canvas); + } + } finally { + canvas.restoreToCount(restoreCount); + canvas.onPostDraw(); + mDisplayList.end(); + } + } else { + mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID; + mPrivateFlags &= ~DIRTY_MASK; + } + return mDisplayList; + } + /** + *

Calling this method is equivalent to calling getDrawingCache(false).

+ * + * @return A non-scaled bitmap representing this view or null if cache is disabled. + * + * @see #getDrawingCache(boolean) + */ + public Bitmap getDrawingCache() { + return getDrawingCache(false); + } + /** + *

Returns the bitmap in which this view drawing is cached. The returned bitmap + * is null when caching is disabled. If caching is enabled and the cache is not ready, + * this method will create it. Calling {@link #draw(android.graphics.Canvas)} will not + * draw from the cache when the cache is enabled. To benefit from the cache, you must + * request the drawing cache by calling this method and draw it on screen if the + * returned bitmap is not null.

+ * + *

Note about auto scaling in compatibility mode: When auto scaling is not enabled, + * this method will create a bitmap of the same size as this view. Because this bitmap + * will be drawn scaled by the parent ViewGroup, the result on screen might show + * scaling artifacts. To avoid such artifacts, you should call this method by setting + * the auto scaling to true. Doing so, however, will generate a bitmap of a different + * size than the view. This implies that your application must be able to handle this + * size.

+ * + * @param autoScale Indicates whether the generated bitmap should be scaled based on + * the current density of the screen when the application is in compatibility + * mode. + * + * @return A bitmap representing this view or null if cache is disabled. + * + * @see #setDrawingCacheEnabled(boolean) + * @see #isDrawingCacheEnabled() + * @see #buildDrawingCache(boolean) + * @see #destroyDrawingCache() + */ + public Bitmap getDrawingCache(boolean autoScale) { + if ((mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING) { + return null; + } + if ((mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED) { + buildDrawingCache(autoScale); + } + return autoScale ? mDrawingCache : mUnscaledDrawingCache; + } + /** + *

Frees the resources used by the drawing cache. If you call + * {@link #buildDrawingCache()} manually without calling + * {@link #setDrawingCacheEnabled(boolean) setDrawingCacheEnabled(true)}, you + * should cleanup the cache with this method afterwards.

+ * + * @see #setDrawingCacheEnabled(boolean) + * @see #buildDrawingCache() + * @see #getDrawingCache() + */ + public void destroyDrawingCache() { + if (mDrawingCache != null) { + mDrawingCache.recycle(); + mDrawingCache = null; + } + if (mUnscaledDrawingCache != null) { + mUnscaledDrawingCache.recycle(); + mUnscaledDrawingCache = null; + } + } + /** + * Setting a solid background color for the drawing cache's bitmaps will improve + * performance and memory usage. Note, though that this should only be used if this + * view will always be drawn on top of a solid color. + * + * @param color The background color to use for the drawing cache's bitmap + * + * @see #setDrawingCacheEnabled(boolean) + * @see #buildDrawingCache() + * @see #getDrawingCache() + */ + public void setDrawingCacheBackgroundColor(int color) { + if (color != mDrawingCacheBackgroundColor) { + mDrawingCacheBackgroundColor = color; + mPrivateFlags &= ~DRAWING_CACHE_VALID; + } + } + /** + * @see #setDrawingCacheBackgroundColor(int) + * + * @return The background color to used for the drawing cache's bitmap + */ + public int getDrawingCacheBackgroundColor() { + return mDrawingCacheBackgroundColor; + } + /** + *

Calling this method is equivalent to calling buildDrawingCache(false).

+ * + * @see #buildDrawingCache(boolean) + */ + public void buildDrawingCache() { + buildDrawingCache(false); + } + /** + *

Forces the drawing cache to be built if the drawing cache is invalid.

+ * + *

If you call {@link #buildDrawingCache()} manually without calling + * {@link #setDrawingCacheEnabled(boolean) setDrawingCacheEnabled(true)}, you + * should cleanup the cache by calling {@link #destroyDrawingCache()} afterwards.

+ * + *

Note about auto scaling in compatibility mode: When auto scaling is not enabled, + * this method will create a bitmap of the same size as this view. Because this bitmap + * will be drawn scaled by the parent ViewGroup, the result on screen might show + * scaling artifacts. To avoid such artifacts, you should call this method by setting + * the auto scaling to true. Doing so, however, will generate a bitmap of a different + * size than the view. This implies that your application must be able to handle this + * size.

+ * + *

You should avoid calling this method when hardware acceleration is enabled. If + * you do not need the drawing cache bitmap, calling this method will increase memory + * usage and cause the view to be rendered in software once, thus negatively impacting + * performance.

+ * + * @see #getDrawingCache() + * @see #destroyDrawingCache() + */ + public void buildDrawingCache(boolean autoScale) { + if ((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || (autoScale ? + mDrawingCache == null : mUnscaledDrawingCache == null)) { + mCachingFailed = false; + if (ViewDebug.TRACE_HIERARCHY) { + ViewDebug.trace(this, ViewDebug.HierarchyTraceType.BUILD_CACHE); + } + int width = mRight - mLeft; + int height = mBottom - mTop; + final AttachInfo attachInfo = mAttachInfo; + final boolean scalingRequired = attachInfo != null && attachInfo.mScalingRequired; + if (autoScale && scalingRequired) { + width = (int) ((width * attachInfo.mApplicationScale) + 0.5f); + height = (int) ((height * attachInfo.mApplicationScale) + 0.5f); + } + final int drawingCacheBackgroundColor = mDrawingCacheBackgroundColor; + final boolean opaque = drawingCacheBackgroundColor != 0 || isOpaque(); + final boolean use32BitCache = attachInfo != null && attachInfo.mUse32BitDrawingCache; + if (width <= 0 || height <= 0 || + // Projected bitmap size in bytes + (width * height * (opaque && !use32BitCache ? 2 : 4) > + ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize())) { + destroyDrawingCache(); + mCachingFailed = true; + return; + } + boolean clear = true; + Bitmap bitmap = autoScale ? mDrawingCache : mUnscaledDrawingCache; + if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) { + Bitmap.Config quality; + if (!opaque) { + // Never pick ARGB_4444 because it looks awful + // Keep the DRAWING_CACHE_QUALITY_LOW flag just in case + switch (mViewFlags & DRAWING_CACHE_QUALITY_MASK) { + case DRAWING_CACHE_QUALITY_AUTO: + quality = Bitmap.Config.ARGB_8888; + break; + case DRAWING_CACHE_QUALITY_LOW: + quality = Bitmap.Config.ARGB_8888; + break; + case DRAWING_CACHE_QUALITY_HIGH: + quality = Bitmap.Config.ARGB_8888; + break; + default: + quality = Bitmap.Config.ARGB_8888; + break; + } + } else { + // Optimization for translucent windows + // If the window is translucent, use a 32 bits bitmap to benefit from memcpy() + quality = use32BitCache ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565; + } + // Try to cleanup memory + if (bitmap != null) bitmap.recycle(); + try { + bitmap = Bitmap.createBitmap(width, height, quality); + bitmap.setDensity(getResources().getDisplayMetrics().densityDpi); + if (autoScale) { + mDrawingCache = bitmap; + } else { + mUnscaledDrawingCache = bitmap; + } + if (opaque && use32BitCache) bitmap.setHasAlpha(false); + } catch (OutOfMemoryError e) { + // If there is not enough memory to create the bitmap cache, just + // ignore the issue as bitmap caches are not required to draw the + // view hierarchy + if (autoScale) { + mDrawingCache = null; + } else { + mUnscaledDrawingCache = null; + } + mCachingFailed = true; + return; + } + clear = drawingCacheBackgroundColor != 0; + } + Canvas canvas; + if (attachInfo != null) { + canvas = attachInfo.mCanvas; + if (canvas == null) { + canvas = new Canvas(); + } + canvas.setBitmap(bitmap); + // Temporarily clobber the cached Canvas in case one of our children + // is also using a drawing cache. Without this, the children would + // steal the canvas by attaching their own bitmap to it and bad, bad + // thing would happen (invisible views, corrupted drawings, etc.) + attachInfo.mCanvas = null; + } else { + // This case should hopefully never or seldom happen + canvas = new Canvas(bitmap); + } + if (clear) { + bitmap.eraseColor(drawingCacheBackgroundColor); + } + computeScroll(); + final int restoreCount = canvas.save(); + if (autoScale && scalingRequired) { + final float scale = attachInfo.mApplicationScale; + canvas.scale(scale, scale); + } + canvas.translate(-mScrollX, -mScrollY); + mPrivateFlags |= DRAWN; + if (mAttachInfo == null || !mAttachInfo.mHardwareAccelerated || + mLayerType != LAYER_TYPE_NONE) { + mPrivateFlags |= DRAWING_CACHE_VALID; + } + // Fast path for layouts with no backgrounds + if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) { + if (ViewDebug.TRACE_HIERARCHY) { + ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW); + } + mPrivateFlags &= ~DIRTY_MASK; + dispatchDraw(canvas); + } else { + draw(canvas); + } + canvas.restoreToCount(restoreCount); + canvas.setBitmap(null); + if (attachInfo != null) { + // Restore the cached Canvas for our siblings + attachInfo.mCanvas = canvas; + } + } + } + /** + * Create a snapshot of the view into a bitmap. We should probably make + * some form of this public, but should think about the API. + */ + Bitmap createSnapshot(Bitmap.Config quality, int backgroundColor, boolean skipChildren) { + int width = mRight - mLeft; + int height = mBottom - mTop; + final AttachInfo attachInfo = mAttachInfo; + final float scale = attachInfo != null ? attachInfo.mApplicationScale : 1.0f; + width = (int) ((width * scale) + 0.5f); + height = (int) ((height * scale) + 0.5f); + Bitmap bitmap = Bitmap.createBitmap(width > 0 ? width : 1, height > 0 ? height : 1, quality); + if (bitmap == null) { + throw new OutOfMemoryError(); + } + Resources resources = getResources(); + if (resources != null) { + bitmap.setDensity(resources.getDisplayMetrics().densityDpi); + } + Canvas canvas; + if (attachInfo != null) { + canvas = attachInfo.mCanvas; + if (canvas == null) { + canvas = new Canvas(); + } + canvas.setBitmap(bitmap); + // Temporarily clobber the cached Canvas in case one of our children + // is also using a drawing cache. Without this, the children would + // steal the canvas by attaching their own bitmap to it and bad, bad + // things would happen (invisible views, corrupted drawings, etc.) + attachInfo.mCanvas = null; + } else { + // This case should hopefully never or seldom happen + canvas = new Canvas(bitmap); + } + if ((backgroundColor & 0xff000000) != 0) { + bitmap.eraseColor(backgroundColor); + } + computeScroll(); + final int restoreCount = canvas.save(); + canvas.scale(scale, scale); + canvas.translate(-mScrollX, -mScrollY); + // Temporarily remove the dirty mask + int flags = mPrivateFlags; + mPrivateFlags &= ~DIRTY_MASK; + // Fast path for layouts with no backgrounds + if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) { + dispatchDraw(canvas); + } else { + draw(canvas); + } + mPrivateFlags = flags; + canvas.restoreToCount(restoreCount); + canvas.setBitmap(null); + if (attachInfo != null) { + // Restore the cached Canvas for our siblings + attachInfo.mCanvas = canvas; + } + return bitmap; + } + /** + * Indicates whether this View is currently in edit mode. A View is usually + * in edit mode when displayed within a developer tool. For instance, if + * this View is being drawn by a visual user interface builder, this method + * should return true. + * + * Subclasses should check the return value of this method to provide + * different behaviors if their normal behavior might interfere with the + * host environment. For instance: the class spawns a thread in its + * constructor, the drawing code relies on device-specific features, etc. + * + * This method is usually checked in the drawing code of custom widgets. + * + * @return True if this View is in edit mode, false otherwise. + */ + public boolean isInEditMode() { + return false; + } + /** + * If the View draws content inside its padding and enables fading edges, + * it needs to support padding offsets. Padding offsets are added to the + * fading edges to extend the length of the fade so that it covers pixels + * drawn inside the padding. + * + * Subclasses of this class should override this method if they need + * to draw content inside the padding. + * + * @return True if padding offset must be applied, false otherwise. + * + * @see #getLeftPaddingOffset() + * @see #getRightPaddingOffset() + * @see #getTopPaddingOffset() + * @see #getBottomPaddingOffset() + * + * @since CURRENT + */ + protected boolean isPaddingOffsetRequired() { + return false; + } + /** + * Amount by which to extend the left fading region. Called only when + * {@link #isPaddingOffsetRequired()} returns true. + * + * @return The left padding offset in pixels. + * + * @see #isPaddingOffsetRequired() + * + * @since CURRENT + */ + protected int getLeftPaddingOffset() { + return 0; + } + /** + * Amount by which to extend the right fading region. Called only when + * {@link #isPaddingOffsetRequired()} returns true. + * + * @return The right padding offset in pixels. + * + * @see #isPaddingOffsetRequired() + * + * @since CURRENT + */ + protected int getRightPaddingOffset() { + return 0; + } + /** + * Amount by which to extend the top fading region. Called only when + * {@link #isPaddingOffsetRequired()} returns true. + * + * @return The top padding offset in pixels. + * + * @see #isPaddingOffsetRequired() + * + * @since CURRENT + */ + protected int getTopPaddingOffset() { + return 0; + } + /** + * Amount by which to extend the bottom fading region. Called only when + * {@link #isPaddingOffsetRequired()} returns true. + * + * @return The bottom padding offset in pixels. + * + * @see #isPaddingOffsetRequired() + * + * @since CURRENT + */ + protected int getBottomPaddingOffset() { + return 0; + } + /** + * @hide + * @param offsetRequired + */ + protected int getFadeTop(boolean offsetRequired) { + int top = mPaddingTop; + if (offsetRequired) top += getTopPaddingOffset(); + return top; + } + + /** + * @hide + * @param offsetRequired + */ + protected int getFadeHeight(boolean offsetRequired) { + int padding = mPaddingTop; + if (offsetRequired) padding += getTopPaddingOffset(); + return mBottom - mTop - mPaddingBottom - padding; + } + + /** + *

Indicates whether this view is attached to an hardware accelerated + * window or not.

+ * + *

Even if this method returns true, it does not mean that every call + * to {@link #draw(android.graphics.Canvas)} will be made with an hardware + * accelerated {@link android.graphics.Canvas}. For instance, if this view + * is drawn onto an offscren {@link android.graphics.Bitmap} and its + * window is hardware accelerated, + * {@link android.graphics.Canvas#isHardwareAccelerated()} will likely + * return false, and this method will return true.

+ * + * @return True if the view is attached to a window and the window is + * hardware accelerated; false in any other case. + */ + public boolean isHardwareAccelerated() { + return mAttachInfo != null && mAttachInfo.mHardwareAccelerated; + } + /** + * Utility function, called by draw(canvas, parent, drawingTime) to handle the less common + * case of an active Animation being run on the view. + */ + private boolean drawAnimation(ViewGroup parent, long drawingTime, + Animation a, boolean scalingRequired) { + Transformation invalidationTransform; + final int flags = parent.mGroupFlags; + final boolean initialized = a.isInitialized(); + if (!initialized) { + a.initialize(mRight - mLeft, mBottom - mTop, getWidth(), getHeight()); + a.initializeInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop); + onAnimationStart(); + } + boolean more = a.getTransformation(drawingTime, parent.mChildTransformation, 1f); + if (scalingRequired && mAttachInfo.mApplicationScale != 1f) { + if (parent.mInvalidationTransformation == null) { + parent.mInvalidationTransformation = new Transformation(); + } + invalidationTransform = parent.mInvalidationTransformation; + a.getTransformation(drawingTime, invalidationTransform, 1f); + } else { + invalidationTransform = parent.mChildTransformation; + } + if (more) { + if (!a.willChangeBounds()) { + if ((flags & (parent.FLAG_OPTIMIZE_INVALIDATE | parent.FLAG_ANIMATION_DONE)) == + parent.FLAG_OPTIMIZE_INVALIDATE) { + parent.mGroupFlags |= parent.FLAG_INVALIDATE_REQUIRED; + } else if ((flags & parent.FLAG_INVALIDATE_REQUIRED) == 0) { + // The child need to draw an animation, potentially offscreen, so + // make sure we do not cancel invalidate requests + parent.mPrivateFlags |= DRAW_ANIMATION; + parent.invalidate(mLeft, mTop, mRight, mBottom); + } + } else { + if (parent.mInvalidateRegion == null) { + parent.mInvalidateRegion = new RectF(); + } + final RectF region = parent.mInvalidateRegion; + a.getInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop, region, + invalidationTransform); + // The child need to draw an animation, potentially offscreen, so + // make sure we do not cancel invalidate requests + parent.mPrivateFlags |= DRAW_ANIMATION; + final int left = mLeft + (int) region.left; + final int top = mTop + (int) region.top; + parent.invalidate(left, top, left + (int) (region.width() + .5f), + top + (int) (region.height() + .5f)); + } + } + return more; + } + /** + * This method is called by ViewGroup.drawChild() to have each child view draw itself. + * This draw() method is an implementation detail and is not intended to be overridden or + * to be called from anywhere else other than ViewGroup.drawChild(). + */ + boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) { + boolean more = false; + final boolean childHasIdentityMatrix = hasIdentityMatrix(); + final int flags = parent.mGroupFlags; + if ((flags & parent.FLAG_CLEAR_TRANSFORMATION) == parent.FLAG_CLEAR_TRANSFORMATION) { + parent.mChildTransformation.clear(); + parent.mGroupFlags &= ~parent.FLAG_CLEAR_TRANSFORMATION; + } + Transformation transformToApply = null; + boolean concatMatrix = false; + boolean scalingRequired = false; + boolean caching; + int layerType = parent.mDrawLayers ? getLayerType() : LAYER_TYPE_NONE; + final boolean hardwareAccelerated = canvas.isHardwareAccelerated(); + if ((flags & parent.FLAG_CHILDREN_DRAWN_WITH_CACHE) == parent.FLAG_CHILDREN_DRAWN_WITH_CACHE || + (flags & parent.FLAG_ALWAYS_DRAWN_WITH_CACHE) == parent.FLAG_ALWAYS_DRAWN_WITH_CACHE) { + caching = true; + if (mAttachInfo != null) scalingRequired = mAttachInfo.mScalingRequired; + } else { + caching = (layerType != LAYER_TYPE_NONE) || hardwareAccelerated; + } + final Animation a = getAnimation(); + if (a != null) { + more = drawAnimation(parent, drawingTime, a, scalingRequired); + concatMatrix = a.willChangeTransformationMatrix(); + transformToApply = parent.mChildTransformation; + } else if ((flags & parent.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) == + parent.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) { + final boolean hasTransform = + parent.getChildStaticTransformation(this, parent.mChildTransformation); + if (hasTransform) { + final int transformType = parent.mChildTransformation.getTransformationType(); + transformToApply = transformType != Transformation.TYPE_IDENTITY ? + parent.mChildTransformation : null; + concatMatrix = (transformType & Transformation.TYPE_MATRIX) != 0; + } + } + concatMatrix |= !childHasIdentityMatrix; + // Sets the flag as early as possible to allow draw() implementations + // to call invalidate() successfully when doing animations + mPrivateFlags |= DRAWN; + if (!concatMatrix && canvas.quickReject(mLeft, mTop, mRight, mBottom, Canvas.EdgeType.BW) && + (mPrivateFlags & DRAW_ANIMATION) == 0) { + return more; + } + if (hardwareAccelerated) { + // Clear INVALIDATED flag to allow invalidation to occur during rendering, but + // retain the flag's value temporarily in the mRecreateDisplayList flag + mRecreateDisplayList = (mPrivateFlags & INVALIDATED) == INVALIDATED; + mPrivateFlags &= ~INVALIDATED; + } + computeScroll(); + final int sx = mScrollX; + final int sy = mScrollY; + DisplayList displayList = null; + Bitmap cache = null; + boolean hasDisplayList = false; + if (caching) { + if (!hardwareAccelerated) { + if (layerType != LAYER_TYPE_NONE) { + layerType = LAYER_TYPE_SOFTWARE; + buildDrawingCache(true); + } + cache = getDrawingCache(true); + } else { + switch (layerType) { + case LAYER_TYPE_SOFTWARE: + buildDrawingCache(true); + cache = getDrawingCache(true); + break; + case LAYER_TYPE_NONE: + // Delay getting the display list until animation-driven alpha values are + // set up and possibly passed on to the view + hasDisplayList = canHaveDisplayList(); + break; + } + } + } + final boolean hasNoCache = cache == null || hasDisplayList; + final boolean offsetForScroll = cache == null && !hasDisplayList && + layerType != LAYER_TYPE_HARDWARE; + final int restoreTo = canvas.save(); + if (offsetForScroll) { + canvas.translate(mLeft - sx, mTop - sy); + } else { + canvas.translate(mLeft, mTop); + if (scalingRequired) { + // mAttachInfo cannot be null, otherwise scalingRequired == false + final float scale = 1.0f / mAttachInfo.mApplicationScale; + canvas.scale(scale, scale); + } + } + float alpha = getAlpha(); + if (transformToApply != null || alpha < 1.0f || !hasIdentityMatrix()) { + if (transformToApply != null || !childHasIdentityMatrix) { + int transX = 0; + int transY = 0; + if (offsetForScroll) { + transX = -sx; + transY = -sy; + } + if (transformToApply != null) { + if (concatMatrix) { + // Undo the scroll translation, apply the transformation matrix, + // then redo the scroll translate to get the correct result. + canvas.translate(-transX, -transY); + canvas.concat(transformToApply.getMatrix()); + canvas.translate(transX, transY); + parent.mGroupFlags |= parent.FLAG_CLEAR_TRANSFORMATION; + } + float transformAlpha = transformToApply.getAlpha(); + if (transformAlpha < 1.0f) { + alpha *= transformToApply.getAlpha(); + parent.mGroupFlags |= parent.FLAG_CLEAR_TRANSFORMATION; + } + } + if (!childHasIdentityMatrix) { + canvas.translate(-transX, -transY); + canvas.concat(getMatrix()); + canvas.translate(transX, transY); + } + } + if (alpha < 1.0f) { + parent.mGroupFlags |= parent.FLAG_CLEAR_TRANSFORMATION; + if (hasNoCache) { + final int multipliedAlpha = (int) (255 * alpha); + if (!onSetAlpha(multipliedAlpha)) { + int layerFlags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG; + if ((flags & parent.FLAG_CLIP_CHILDREN) == parent.FLAG_CLIP_CHILDREN || + layerType != LAYER_TYPE_NONE) { + layerFlags |= Canvas.CLIP_TO_LAYER_SAVE_FLAG; + } + if (layerType == LAYER_TYPE_NONE) { + final int scrollX = hasDisplayList ? 0 : sx; + final int scrollY = hasDisplayList ? 0 : sy; + canvas.saveLayerAlpha(scrollX, scrollY, scrollX + mRight - mLeft, + scrollY + mBottom - mTop, multipliedAlpha, layerFlags); + } + } else { + // Alpha is handled by the child directly, clobber the layer's alpha + mPrivateFlags |= ALPHA_SET; + } + } + } + } else if ((mPrivateFlags & ALPHA_SET) == ALPHA_SET) { + onSetAlpha(255); + mPrivateFlags &= ~ALPHA_SET; + } + if ((flags & parent.FLAG_CLIP_CHILDREN) == parent.FLAG_CLIP_CHILDREN) { + if (offsetForScroll) { + canvas.clipRect(sx, sy, sx + (mRight - mLeft), sy + (mBottom - mTop)); + } else { + if (!scalingRequired || cache == null) { + canvas.clipRect(0, 0, mRight - mLeft, mBottom - mTop); + } else { + canvas.clipRect(0, 0, cache.getWidth(), cache.getHeight()); + } + } + } + if (hasDisplayList) { + displayList = getDisplayList(); + if (!displayList.isValid()) { + // Uncommon, but possible. If a view is removed from the hierarchy during the call + // to getDisplayList(), the display list will be marked invalid and we should not + // try to use it again. + displayList = null; + hasDisplayList = false; + } + } + if (hasNoCache) { + boolean layerRendered = false; + if (layerType == LAYER_TYPE_HARDWARE) { + final HardwareLayer layer = getHardwareLayer(); + if (layer != null && layer.isValid()) { + mLayerPaint.setAlpha((int) (alpha * 255)); + ((HardwareCanvas) canvas).drawHardwareLayer(layer, 0, 0, mLayerPaint); + layerRendered = true; + } else { + final int scrollX = hasDisplayList ? 0 : sx; + final int scrollY = hasDisplayList ? 0 : sy; + canvas.saveLayer(scrollX, scrollY, + scrollX + mRight - mLeft, scrollY + mBottom - mTop, mLayerPaint, + Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG); + } + } + if (!layerRendered) { + if (!hasDisplayList) { + // Fast path for layouts with no backgrounds + if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) { + if (ViewDebug.TRACE_HIERARCHY) { + ViewDebug.trace(parent, ViewDebug.HierarchyTraceType.DRAW); + } + mPrivateFlags &= ~DIRTY_MASK; + dispatchDraw(canvas); + } else { + draw(canvas); + } + } else { + mPrivateFlags &= ~DIRTY_MASK; + ((HardwareCanvas) canvas).drawDisplayList(displayList, + mRight - mLeft, mBottom - mTop, null); + } + } + } else if (cache != null) { + mPrivateFlags &= ~DIRTY_MASK; + Paint cachePaint; + if (layerType == LAYER_TYPE_NONE) { + cachePaint = parent.mCachePaint; + if (cachePaint == null) { + cachePaint = new Paint(); + cachePaint.setDither(false); + parent.mCachePaint = cachePaint; + } + if (alpha < 1.0f) { + cachePaint.setAlpha((int) (alpha * 255)); + parent.mGroupFlags |= parent.FLAG_ALPHA_LOWER_THAN_ONE; + } else if ((flags & parent.FLAG_ALPHA_LOWER_THAN_ONE) == + parent.FLAG_ALPHA_LOWER_THAN_ONE) { + cachePaint.setAlpha(255); + parent.mGroupFlags &= ~parent.FLAG_ALPHA_LOWER_THAN_ONE; + } + } else { + cachePaint = mLayerPaint; + cachePaint.setAlpha((int) (alpha * 255)); + } + canvas.drawBitmap(cache, 0.0f, 0.0f, cachePaint); + } + canvas.restoreToCount(restoreTo); + if (a != null && !more) { + if (!hardwareAccelerated && !a.getFillAfter()) { + onSetAlpha(255); + } + parent.finishAnimatingView(this, a); + } + if (more && hardwareAccelerated) { + // invalidation is the trigger to recreate display lists, so if we're using + // display lists to render, force an invalidate to allow the animation to + // continue drawing another frame + parent.invalidate(true); + if (a.hasAlpha() && (mPrivateFlags & ALPHA_SET) == ALPHA_SET) { + // alpha animations should cause the child to recreate its display list + invalidate(true); + } + } + mRecreateDisplayList = false; + return more; + } + /** + * Manually render this view (and all of its children) to the given Canvas. + * The view must have already done a full layout before this function is + * called. When implementing a view, implement + * {@link #onDraw(android.graphics.Canvas)} instead of overriding this method. + * If you do need to override this method, call the superclass version. + * + * @param canvas The Canvas to which the View is rendered. + */ + public void draw(Canvas canvas) { + if (ViewDebug.TRACE_HIERARCHY) { + ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW); + } + final int privateFlags = mPrivateFlags; + final boolean dirtyOpaque = (privateFlags & DIRTY_MASK) == DIRTY_OPAQUE && + (mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState); + mPrivateFlags = (privateFlags & ~DIRTY_MASK) | DRAWN; + /* + * Draw traversal performs several drawing steps which must be executed + * in the appropriate order: + * + * 1. Draw the background + * 2. If necessary, save the canvas' layers to prepare for fading + * 3. Draw view's content + * 4. Draw children + * 5. If necessary, draw the fading edges and restore layers + * 6. Draw decorations (scrollbars for instance) + */ + // Step 1, draw the background, if needed + int saveCount; + if (!dirtyOpaque) { + final Drawable background = mBGDrawable; + if (background != null) { + final int scrollX = mScrollX; + final int scrollY = mScrollY; + if (mBackgroundSizeChanged) { + background.setBounds(0, 0, mRight - mLeft, mBottom - mTop); + mBackgroundSizeChanged = false; + } + if ((scrollX | scrollY) == 0) { + background.draw(canvas); + } else { + canvas.translate(scrollX, scrollY); + background.draw(canvas); + canvas.translate(-scrollX, -scrollY); + } + } + } + // skip step 2 & 5 if possible (common case) + final int viewFlags = mViewFlags; + boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0; + boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0; + if (!verticalEdges && !horizontalEdges) { + // Step 3, draw the content + if (!dirtyOpaque) onDraw(canvas); + // Step 4, draw the children + dispatchDraw(canvas); + // Step 6, draw decorations (scrollbars) + onDrawScrollBars(canvas); + // we're done... + return; + } + /* + * Here we do the full fledged routine... + * (this is an uncommon case where speed matters less, + * this is why we repeat some of the tests that have been + * done above) + */ + boolean drawTop = false; + boolean drawBottom = false; + boolean drawLeft = false; + boolean drawRight = false; + float topFadeStrength = 0.0f; + float bottomFadeStrength = 0.0f; + float leftFadeStrength = 0.0f; + float rightFadeStrength = 0.0f; + // Step 2, save the canvas' layers + int paddingLeft = mPaddingLeft; + final boolean offsetRequired = isPaddingOffsetRequired(); + if (offsetRequired) { + paddingLeft += getLeftPaddingOffset(); + } + int left = mScrollX + paddingLeft; + int right = left + mRight - mLeft - mPaddingRight - paddingLeft; + int top = mScrollY + getFadeTop(offsetRequired); + int bottom = top + getFadeHeight(offsetRequired); + if (offsetRequired) { + right += getRightPaddingOffset(); + bottom += getBottomPaddingOffset(); + } + final ScrollabilityCache scrollabilityCache = mScrollCache; + final float fadeHeight = scrollabilityCache.fadingEdgeLength; + int length = (int) fadeHeight; + // clip the fade length if top and bottom fades overlap + // overlapping fades produce odd-looking artifacts + if (verticalEdges && (top + length > bottom - length)) { + length = (bottom - top) / 2; + } + // also clip horizontal fades if necessary + if (horizontalEdges && (left + length > right - length)) { + length = (right - left) / 2; + } + if (verticalEdges) { + topFadeStrength = Math.max(0.0f, Math.min(1.0f, getTopFadingEdgeStrength())); + drawTop = topFadeStrength * fadeHeight > 1.0f; + bottomFadeStrength = Math.max(0.0f, Math.min(1.0f, getBottomFadingEdgeStrength())); + drawBottom = bottomFadeStrength * fadeHeight > 1.0f; + } + if (horizontalEdges) { + leftFadeStrength = Math.max(0.0f, Math.min(1.0f, getLeftFadingEdgeStrength())); + drawLeft = leftFadeStrength * fadeHeight > 1.0f; + rightFadeStrength = Math.max(0.0f, Math.min(1.0f, getRightFadingEdgeStrength())); + drawRight = rightFadeStrength * fadeHeight > 1.0f; + } + saveCount = canvas.getSaveCount(); + int solidColor = getSolidColor(); + if (solidColor == 0) { + final int flags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG; + if (drawTop) { + canvas.saveLayer(left, top, right, top + length, null, flags); + } + if (drawBottom) { + canvas.saveLayer(left, bottom - length, right, bottom, null, flags); + } + if (drawLeft) { + canvas.saveLayer(left, top, left + length, bottom, null, flags); + } + if (drawRight) { + canvas.saveLayer(right - length, top, right, bottom, null, flags); + } + } else { + scrollabilityCache.setFadeColor(solidColor); + } + // Step 3, draw the content + if (!dirtyOpaque) onDraw(canvas); + // Step 4, draw the children + dispatchDraw(canvas); + // Step 5, draw the fade effect and restore layers + final Paint p = scrollabilityCache.paint; + final Matrix matrix = scrollabilityCache.matrix; + final Shader fade = scrollabilityCache.shader; + if (drawTop) { + matrix.setScale(1, fadeHeight * topFadeStrength); + matrix.postTranslate(left, top); + fade.setLocalMatrix(matrix); + canvas.drawRect(left, top, right, top + length, p); + } + if (drawBottom) { + matrix.setScale(1, fadeHeight * bottomFadeStrength); + matrix.postRotate(180); + matrix.postTranslate(left, bottom); + fade.setLocalMatrix(matrix); + canvas.drawRect(left, bottom - length, right, bottom, p); + } + if (drawLeft) { + matrix.setScale(1, fadeHeight * leftFadeStrength); + matrix.postRotate(-90); + matrix.postTranslate(left, top); + fade.setLocalMatrix(matrix); + canvas.drawRect(left, top, left + length, bottom, p); + } + if (drawRight) { + matrix.setScale(1, fadeHeight * rightFadeStrength); + matrix.postRotate(90); + matrix.postTranslate(right, top); + fade.setLocalMatrix(matrix); + canvas.drawRect(right - length, top, right, bottom, p); + } + canvas.restoreToCount(saveCount); + // Step 6, draw decorations (scrollbars) + onDrawScrollBars(canvas); + } + /** + * Override this if your view is known to always be drawn on top of a solid color background, + * and needs to draw fading edges. Returning a non-zero color enables the view system to + * optimize the drawing of the fading edges. If you do return a non-zero color, the alpha + * should be set to 0xFF. + * + * @see #setVerticalFadingEdgeEnabled(boolean) + * @see #setHorizontalFadingEdgeEnabled(boolean) + * + * @return The known solid color background for this view, or 0 if the color may vary + */ + @ViewDebug.ExportedProperty(category = "drawing") + public int getSolidColor() { + return 0; + } + /** + * Build a human readable string representation of the specified view flags. + * + * @param flags the view flags to convert to a string + * @return a String representing the supplied flags + */ + private static String printFlags(int flags) { + String output = ""; + int numFlags = 0; + if ((flags & FOCUSABLE_MASK) == FOCUSABLE) { + output += "TAKES_FOCUS"; + numFlags++; + } + switch (flags & VISIBILITY_MASK) { + case INVISIBLE: + if (numFlags > 0) { + output += " "; + } + output += "INVISIBLE"; + // USELESS HERE numFlags++; + break; + case GONE: + if (numFlags > 0) { + output += " "; + } + output += "GONE"; + // USELESS HERE numFlags++; + break; + default: + break; + } + return output; + } + /** + * Build a human readable string representation of the specified private + * view flags. + * + * @param privateFlags the private view flags to convert to a string + * @return a String representing the supplied flags + */ + private static String printPrivateFlags(int privateFlags) { + String output = ""; + int numFlags = 0; + if ((privateFlags & WANTS_FOCUS) == WANTS_FOCUS) { + output += "WANTS_FOCUS"; + numFlags++; + } + if ((privateFlags & FOCUSED) == FOCUSED) { + if (numFlags > 0) { + output += " "; + } + output += "FOCUSED"; + numFlags++; + } + if ((privateFlags & SELECTED) == SELECTED) { + if (numFlags > 0) { + output += " "; + } + output += "SELECTED"; + numFlags++; + } + if ((privateFlags & IS_ROOT_NAMESPACE) == IS_ROOT_NAMESPACE) { + if (numFlags > 0) { + output += " "; + } + output += "IS_ROOT_NAMESPACE"; + numFlags++; + } + if ((privateFlags & HAS_BOUNDS) == HAS_BOUNDS) { + if (numFlags > 0) { + output += " "; + } + output += "HAS_BOUNDS"; + numFlags++; + } + if ((privateFlags & DRAWN) == DRAWN) { + if (numFlags > 0) { + output += " "; + } + output += "DRAWN"; + // USELESS HERE numFlags++; + } + return output; + } + /** + *

Indicates whether or not this view's layout will be requested during + * the next hierarchy layout pass.

+ * + * @return true if the layout will be forced during next layout pass + */ + public boolean isLayoutRequested() { + return (mPrivateFlags & FORCE_LAYOUT) == FORCE_LAYOUT; + } + /** + * Assign a size and position to a view and all of its + * descendants + * + *

This is the second phase of the layout mechanism. + * (The first is measuring). In this phase, each parent calls + * layout on all of its children to position them. + * This is typically done using the child measurements + * that were stored in the measure pass().

+ * + *

Derived classes should not override this method. + * Derived classes with children should override + * onLayout. In that method, they should + * call layout on each of their children.

+ * + * @param l Left position, relative to parent + * @param t Top position, relative to parent + * @param r Right position, relative to parent + * @param b Bottom position, relative to parent + */ + @SuppressWarnings({"unchecked"}) + public void layout(int l, int t, int r, int b) { + int oldL = mLeft; + int oldT = mTop; + int oldB = mBottom; + int oldR = mRight; + boolean changed = setFrame(l, t, r, b); + if (changed || (mPrivateFlags & LAYOUT_REQUIRED) == LAYOUT_REQUIRED) { + if (ViewDebug.TRACE_HIERARCHY) { + ViewDebug.trace(this, ViewDebug.HierarchyTraceType.ON_LAYOUT); + } + onLayout(changed, l, t, r, b); + mPrivateFlags &= ~LAYOUT_REQUIRED; + ListenerInfo li = mListenerInfo; + if (li != null && li.mOnLayoutChangeListeners != null) { + ArrayList listenersCopy = + (ArrayList)li.mOnLayoutChangeListeners.clone(); + int numListeners = listenersCopy.size(); + for (int i = 0; i < numListeners; ++i) { + listenersCopy.get(i).onLayoutChange(this, l, t, r, b, oldL, oldT, oldR, oldB); + } + } + } + mPrivateFlags &= ~FORCE_LAYOUT; + } + /** + * Called from layout when this view should + * assign a size and position to each of its children. + * + * Derived classes with children should override + * this method and call layout on each of + * their children. + * @param changed This is a new size or position for this view + * @param left Left position, relative to parent + * @param top Top position, relative to parent + * @param right Right position, relative to parent + * @param bottom Bottom position, relative to parent + */ + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + } + /** + * Assign a size and position to this view. + * + * This is called from layout. + * + * @param left Left position, relative to parent + * @param top Top position, relative to parent + * @param right Right position, relative to parent + * @param bottom Bottom position, relative to parent + * @return true if the new size and position are different than the + * previous ones + * {@hide} + */ + protected boolean setFrame(int left, int top, int right, int bottom) { + boolean changed = false; + if (DBG) { + Log.d("View", this + " View.setFrame(" + left + "," + top + "," + + right + "," + bottom + ")"); + } + if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) { + changed = true; + // Remember our drawn bit + int drawn = mPrivateFlags & DRAWN; + int oldWidth = mRight - mLeft; + int oldHeight = mBottom - mTop; + int newWidth = right - left; + int newHeight = bottom - top; + boolean sizeChanged = (newWidth != oldWidth) || (newHeight != oldHeight); + // Invalidate our old position + invalidate(sizeChanged); + mLeft = left; + mTop = top; + mRight = right; + mBottom = bottom; + mPrivateFlags |= HAS_BOUNDS; + if (sizeChanged) { + if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) { + // A change in dimension means an auto-centered pivot point changes, too + if (mTransformationInfo != null) { + mTransformationInfo.mMatrixDirty = true; + } + } + onSizeChanged(newWidth, newHeight, oldWidth, oldHeight); + } + if ((mViewFlags & VISIBILITY_MASK) == VISIBLE) { + // If we are visible, force the DRAWN bit to on so that + // this invalidate will go through (at least to our parent). + // This is because someone may have invalidated this view + // before this call to setFrame came in, thereby clearing + // the DRAWN bit. + mPrivateFlags |= DRAWN; + invalidate(sizeChanged); + // parent display list may need to be recreated based on a change in the bounds + // of any child + invalidateParentCaches(); + } + // Reset drawn bit to original value (invalidate turns it off) + mPrivateFlags |= drawn; + mBackgroundSizeChanged = true; + } + return changed; + } + /** + * Finalize inflating a view from XML. This is called as the last phase + * of inflation, after all child views have been added. + * + *

Even if the subclass overrides onFinishInflate, they should always be + * sure to call the super method, so that we get called. + */ + protected void onFinishInflate() { + } + /** + * Returns the resources associated with this view. + * + * @return Resources object. + */ + public Resources getResources() { + return mResources; + } + /** + * Invalidates the specified Drawable. + * + * @param drawable the drawable to invalidate + */ + public void invalidateDrawable(Drawable drawable) { + if (verifyDrawable(drawable)) { + final Rect dirty = drawable.getBounds(); + final int scrollX = mScrollX; + final int scrollY = mScrollY; + invalidate(dirty.left + scrollX, dirty.top + scrollY, + dirty.right + scrollX, dirty.bottom + scrollY); + } + } + /** + * Schedules an action on a drawable to occur at a specified time. + * + * @param who the recipient of the action + * @param what the action to run on the drawable + * @param when the time at which the action must occur. Uses the + * {@link SystemClock#uptimeMillis} timebase. + */ + public void scheduleDrawable(Drawable who, Runnable what, long when) { + if (verifyDrawable(who) && what != null) { + if (mAttachInfo != null) { + mAttachInfo.mHandler.postAtTime(what, who, when); + } else { + ViewRootImpl.getRunQueue().postDelayed(what, when - SystemClock.uptimeMillis()); + } + } + } + /** + * Cancels a scheduled action on a drawable. + * + * @param who the recipient of the action + * @param what the action to cancel + */ + public void unscheduleDrawable(Drawable who, Runnable what) { + if (verifyDrawable(who) && what != null) { + if (mAttachInfo != null) { + mAttachInfo.mHandler.removeCallbacks(what, who); + } else { + ViewRootImpl.getRunQueue().removeCallbacks(what); + } + } + } + /** + * Unschedule any events associated with the given Drawable. This can be + * used when selecting a new Drawable into a view, so that the previous + * one is completely unscheduled. + * + * @param who The Drawable to unschedule. + * + * @see #drawableStateChanged + */ + public void unscheduleDrawable(Drawable who) { + if (mAttachInfo != null) { + mAttachInfo.mHandler.removeCallbacksAndMessages(who); + } + } + /** + * Return the layout direction of a given Drawable. + * + * @param who the Drawable to query + * + * @hide + */ + public int getResolvedLayoutDirection(Drawable who) { + return (who == mBGDrawable) ? getResolvedLayoutDirection() : LAYOUT_DIRECTION_DEFAULT; + } + /** + * If your view subclass is displaying its own Drawable objects, it should + * override this function and return true for any Drawable it is + * displaying. This allows animations for those drawables to be + * scheduled. + * + *

Be sure to call through to the super class when overriding this + * function. + * + * @param who The Drawable to verify. Return true if it is one you are + * displaying, else return the result of calling through to the + * super class. + * + * @return boolean If true than the Drawable is being displayed in the + * view; else false and it is not allowed to animate. + * + * @see #unscheduleDrawable(android.graphics.drawable.Drawable) + * @see #drawableStateChanged() + */ + protected boolean verifyDrawable(Drawable who) { + return who == mBGDrawable; + } + /** + * This function is called whenever the state of the view changes in such + * a way that it impacts the state of drawables being shown. + * + *

Be sure to call through to the superclass when overriding this + * function. + * + * @see Drawable#setState(int[]) + */ + protected void drawableStateChanged() { + Drawable d = mBGDrawable; + if (d != null && d.isStateful()) { + d.setState(getDrawableState()); + } + } + /** + * Call this to force a view to update its drawable state. This will cause + * drawableStateChanged to be called on this view. Views that are interested + * in the new state should call getDrawableState. + * + * @see #drawableStateChanged + * @see #getDrawableState + */ + public void refreshDrawableState() { + mPrivateFlags |= DRAWABLE_STATE_DIRTY; + drawableStateChanged(); + ViewParent parent = mParent; + if (parent != null) { + parent.childDrawableStateChanged(this); + } + } + /** + * Return an array of resource IDs of the drawable states representing the + * current state of the view. + * + * @return The current drawable state + * + * @see Drawable#setState(int[]) + * @see #drawableStateChanged() + * @see #onCreateDrawableState(int) + */ + public final int[] getDrawableState() { + if ((mDrawableState != null) && ((mPrivateFlags & DRAWABLE_STATE_DIRTY) == 0)) { + return mDrawableState; + } else { + mDrawableState = onCreateDrawableState(0); + mPrivateFlags &= ~DRAWABLE_STATE_DIRTY; + return mDrawableState; + } + } + /** + * Generate the new {@link android.graphics.drawable.Drawable} state for + * this view. This is called by the view + * system when the cached Drawable state is determined to be invalid. To + * retrieve the current state, you should use {@link #getDrawableState}. + * + * @param extraSpace if non-zero, this is the number of extra entries you + * would like in the returned array in which you can place your own + * states. + * + * @return Returns an array holding the current {@link Drawable} state of + * the view. + * + * @see #mergeDrawableStates(int[], int[]) + */ + protected int[] onCreateDrawableState(int extraSpace) { + if ((mViewFlags & DUPLICATE_PARENT_STATE) == DUPLICATE_PARENT_STATE && + mParent instanceof View) { + return ((View) mParent).onCreateDrawableState(extraSpace); + } + int[] drawableState; + int privateFlags = mPrivateFlags; + int viewStateIndex = 0; + if ((privateFlags & PRESSED) != 0) viewStateIndex |= VIEW_STATE_PRESSED; + if ((mViewFlags & ENABLED_MASK) == ENABLED) viewStateIndex |= VIEW_STATE_ENABLED; + if (isFocused()) viewStateIndex |= VIEW_STATE_FOCUSED; + if ((privateFlags & SELECTED) != 0) viewStateIndex |= VIEW_STATE_SELECTED; + if (hasWindowFocus()) viewStateIndex |= VIEW_STATE_WINDOW_FOCUSED; + if ((privateFlags & ACTIVATED) != 0) viewStateIndex |= VIEW_STATE_ACTIVATED; + if (mAttachInfo != null && mAttachInfo.mHardwareAccelerationRequested && + HardwareRenderer.isAvailable()) { + // This is set if HW acceleration is requested, even if the current + // process doesn't allow it. This is just to allow app preview + // windows to better match their app. + viewStateIndex |= VIEW_STATE_ACCELERATED; + } + if ((privateFlags & HOVERED) != 0) viewStateIndex |= VIEW_STATE_HOVERED; + final int privateFlags2 = mPrivateFlags2; + if ((privateFlags2 & DRAG_CAN_ACCEPT) != 0) viewStateIndex |= VIEW_STATE_DRAG_CAN_ACCEPT; + if ((privateFlags2 & DRAG_HOVERED) != 0) viewStateIndex |= VIEW_STATE_DRAG_HOVERED; + drawableState = VIEW_STATE_SETS[viewStateIndex]; + //noinspection ConstantIfStatement + if (false) { + Log.i("View", "drawableStateIndex=" + viewStateIndex); + Log.i("View", toString() + + " pressed=" + ((privateFlags & PRESSED) != 0) + + " en=" + ((mViewFlags & ENABLED_MASK) == ENABLED) + + " fo=" + hasFocus() + + " sl=" + ((privateFlags & SELECTED) != 0) + + " wf=" + hasWindowFocus() + + ": " + Arrays.toString(drawableState)); + } + if (extraSpace == 0) { + return drawableState; + } + final int[] fullState; + if (drawableState != null) { + fullState = new int[drawableState.length + extraSpace]; + System.arraycopy(drawableState, 0, fullState, 0, drawableState.length); + } else { + fullState = new int[extraSpace]; + } + return fullState; + } + /** + * Merge your own state values in additionalState into the base + * state values baseState that were returned by + * {@link #onCreateDrawableState(int)}. + * + * @param baseState The base state values returned by + * {@link #onCreateDrawableState(int)}, which will be modified to also hold your + * own additional state values. + * + * @param additionalState The additional state values you would like + * added to baseState; this array is not modified. + * + * @return As a convenience, the baseState array you originally + * passed into the function is returned. + * + * @see #onCreateDrawableState(int) + */ + protected static int[] mergeDrawableStates(int[] baseState, int[] additionalState) { + final int N = baseState.length; + int i = N - 1; + while (i >= 0 && baseState[i] == 0) { + i--; + } + System.arraycopy(additionalState, 0, baseState, i + 1, additionalState.length); + return baseState; + } + /** + * Call {@link Drawable#jumpToCurrentState() Drawable.jumpToCurrentState()} + * on all Drawable objects associated with this view. + */ + public void jumpDrawablesToCurrentState() { + if (mBGDrawable != null) { + mBGDrawable.jumpToCurrentState(); + } + } + /** + * Sets the background color for this view. + * @param color the color of the background + */ + @RemotableViewMethod + public void setBackgroundColor(int color) { + if (mBGDrawable instanceof ColorDrawable) { + ((ColorDrawable) mBGDrawable).setColor(color); + } else { + setBackgroundDrawable(new ColorDrawable(color)); + } + } + /** + * Set the background to a given resource. The resource should refer to + * a Drawable object or 0 to remove the background. + * @param resid The identifier of the resource. + * @attr ref android.R.styleable#View_background + */ + @RemotableViewMethod + public void setBackgroundResource(int resid) { + if (resid != 0 && resid == mBackgroundResource) { + return; + } + Drawable d= null; + if (resid != 0) { + d = mResources.getDrawable(resid); + } + setBackgroundDrawable(d); + mBackgroundResource = resid; + } + /** + * Set the background to a given Drawable, or remove the background. If the + * background has padding, this View's padding is set to the background's + * padding. However, when a background is removed, this View's padding isn't + * touched. If setting the padding is desired, please use + * {@link #setPadding(int, int, int, int)}. + * + * @param d The Drawable to use as the background, or null to remove the + * background + */ + public void setBackgroundDrawable(Drawable d) { + if (d == mBGDrawable) { + return; + } + boolean requestLayout = false; + mBackgroundResource = 0; + /* + * Regardless of whether we're setting a new background or not, we want + * to clear the previous drawable. + */ + if (mBGDrawable != null) { + mBGDrawable.setCallback(null); + unscheduleDrawable(mBGDrawable); + } + if (d != null) { + Rect padding = sThreadLocal.get(); + if (padding == null) { + padding = new Rect(); + sThreadLocal.set(padding); + } + if (d.getPadding(padding)) { + switch (d.getResolvedLayoutDirectionSelf()) { + case LAYOUT_DIRECTION_RTL: + setPadding(padding.right, padding.top, padding.left, padding.bottom); + break; + case LAYOUT_DIRECTION_LTR: + default: + setPadding(padding.left, padding.top, padding.right, padding.bottom); + } + } + // Compare the minimum sizes of the old Drawable and the new. If there isn't an old or + // if it has a different minimum size, we should layout again + if (mBGDrawable == null || mBGDrawable.getMinimumHeight() != d.getMinimumHeight() || + mBGDrawable.getMinimumWidth() != d.getMinimumWidth()) { + requestLayout = true; + } + d.setCallback(this); + if (d.isStateful()) { + d.setState(getDrawableState()); + } + d.setVisible(getVisibility() == VISIBLE, false); + mBGDrawable = d; + if ((mPrivateFlags & SKIP_DRAW) != 0) { + mPrivateFlags &= ~SKIP_DRAW; + mPrivateFlags |= ONLY_DRAWS_BACKGROUND; + requestLayout = true; + } + } else { + /* Remove the background */ + mBGDrawable = null; + if ((mPrivateFlags & ONLY_DRAWS_BACKGROUND) != 0) { + /* + * This view ONLY drew the background before and we're removing + * the background, so now it won't draw anything + * (hence we SKIP_DRAW) + */ + mPrivateFlags &= ~ONLY_DRAWS_BACKGROUND; + mPrivateFlags |= SKIP_DRAW; + } + /* + * When the background is set, we try to apply its padding to this + * View. When the background is removed, we don't touch this View's + * padding. This is noted in the Javadocs. Hence, we don't need to + * requestLayout(), the invalidate() below is sufficient. + */ + // The old background's minimum size could have affected this + // View's layout, so let's requestLayout + requestLayout = true; + } + computeOpaqueFlags(); + if (requestLayout) { + requestLayout(); + } + mBackgroundSizeChanged = true; + invalidate(true); + } + /** + * Gets the background drawable + * @return The drawable used as the background for this view, if any. + */ + public Drawable getBackground() { + return mBGDrawable; + } + /** + * Sets the padding. The view may add on the space required to display + * the scrollbars, depending on the style and visibility of the scrollbars. + * So the values returned from {@link #getPaddingLeft}, {@link #getPaddingTop}, + * {@link #getPaddingRight} and {@link #getPaddingBottom} may be different + * from the values set in this call. + * + * @attr ref android.R.styleable#View_padding + * @attr ref android.R.styleable#View_paddingBottom + * @attr ref android.R.styleable#View_paddingLeft + * @attr ref android.R.styleable#View_paddingRight + * @attr ref android.R.styleable#View_paddingTop + * @param left the left padding in pixels + * @param top the top padding in pixels + * @param right the right padding in pixels + * @param bottom the bottom padding in pixels + */ + public void setPadding(int left, int top, int right, int bottom) { + boolean changed = false; + mUserPaddingRelative = false; + mUserPaddingLeft = left; + mUserPaddingRight = right; + mUserPaddingBottom = bottom; + final int viewFlags = mViewFlags; + // Common case is there are no scroll bars. + if ((viewFlags & (SCROLLBARS_VERTICAL|SCROLLBARS_HORIZONTAL)) != 0) { + if ((viewFlags & SCROLLBARS_VERTICAL) != 0) { + final int offset = (viewFlags & SCROLLBARS_INSET_MASK) == 0 + ? 0 : getVerticalScrollbarWidth(); + switch (mVerticalScrollbarPosition) { + case SCROLLBAR_POSITION_DEFAULT: + if (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) { + left += offset; + } else { + right += offset; + } + break; + case SCROLLBAR_POSITION_RIGHT: + right += offset; + break; + case SCROLLBAR_POSITION_LEFT: + left += offset; + break; + } + } + if ((viewFlags & SCROLLBARS_HORIZONTAL) != 0) { + bottom += (viewFlags & SCROLLBARS_INSET_MASK) == 0 + ? 0 : getHorizontalScrollbarHeight(); + } + } + if (mPaddingLeft != left) { + changed = true; + mPaddingLeft = left; + } + if (mPaddingTop != top) { + changed = true; + mPaddingTop = top; + } + if (mPaddingRight != right) { + changed = true; + mPaddingRight = right; + } + if (mPaddingBottom != bottom) { + changed = true; + mPaddingBottom = bottom; + } + if (changed) { + requestLayout(); + } + } + /** + * Sets the relative padding. The view may add on the space required to display + * the scrollbars, depending on the style and visibility of the scrollbars. + * So the values returned from {@link #getPaddingStart}, {@link #getPaddingTop}, + * {@link #getPaddingEnd} and {@link #getPaddingBottom} may be different + * from the values set in this call. + * + * @attr ref android.R.styleable#View_padding + * @attr ref android.R.styleable#View_paddingBottom + * @attr ref android.R.styleable#View_paddingStart + * @attr ref android.R.styleable#View_paddingEnd + * @attr ref android.R.styleable#View_paddingTop + * @param start the start padding in pixels + * @param top the top padding in pixels + * @param end the end padding in pixels + * @param bottom the bottom padding in pixels + * + * @hide + */ + public void setPaddingRelative(int start, int top, int end, int bottom) { + mUserPaddingRelative = true; + mUserPaddingStart = start; + mUserPaddingEnd = end; + switch(getResolvedLayoutDirection()) { + case LAYOUT_DIRECTION_RTL: + setPadding(end, top, start, bottom); + break; + case LAYOUT_DIRECTION_LTR: + default: + setPadding(start, top, end, bottom); + } + } + /** + * Returns the top padding of this view. + * + * @return the top padding in pixels + */ + public int getPaddingTop() { + return mPaddingTop; + } + /** + * Returns the bottom padding of this view. If there are inset and enabled + * scrollbars, this value may include the space required to display the + * scrollbars as well. + * + * @return the bottom padding in pixels + */ + public int getPaddingBottom() { + return mPaddingBottom; + } + /** + * Returns the left padding of this view. If there are inset and enabled + * scrollbars, this value may include the space required to display the + * scrollbars as well. + * + * @return the left padding in pixels + */ + public int getPaddingLeft() { + return mPaddingLeft; + } + /** + * Returns the start padding of this view. If there are inset and enabled + * scrollbars, this value may include the space required to display the + * scrollbars as well. + * + * @return the start padding in pixels + * + * @hide + */ + public int getPaddingStart() { + return (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) ? + mPaddingRight : mPaddingLeft; + } + /** + * Returns the right padding of this view. If there are inset and enabled + * scrollbars, this value may include the space required to display the + * scrollbars as well. + * + * @return the right padding in pixels + */ + public int getPaddingRight() { + return mPaddingRight; + } + /** + * Returns the end padding of this view. If there are inset and enabled + * scrollbars, this value may include the space required to display the + * scrollbars as well. + * + * @return the end padding in pixels + * + * @hide + */ + public int getPaddingEnd() { + return (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) ? + mPaddingLeft : mPaddingRight; + } + /** + * Return if the padding as been set thru relative values + * {@link #setPaddingRelative(int, int, int, int)} or thru + * @attr ref android.R.styleable#View_paddingStart or + * @attr ref android.R.styleable#View_paddingEnd + * + * @return true if the padding is relative or false if it is not. + * + * @hide + */ + public boolean isPaddingRelative() { + return mUserPaddingRelative; + } + /** + * Changes the selection state of this view. A view can be selected or not. + * Note that selection is not the same as focus. Views are typically + * selected in the context of an AdapterView like ListView or GridView; + * the selected view is the view that is highlighted. + * + * @param selected true if the view must be selected, false otherwise + */ + public void setSelected(boolean selected) { + if (((mPrivateFlags & SELECTED) != 0) != selected) { + mPrivateFlags = (mPrivateFlags & ~SELECTED) | (selected ? SELECTED : 0); + if (!selected) resetPressedState(); + invalidate(true); + refreshDrawableState(); + dispatchSetSelected(selected); + } + } + /** + * Dispatch setSelected to all of this View's children. + * + * @see #setSelected(boolean) + * + * @param selected The new selected state + */ + protected void dispatchSetSelected(boolean selected) { + } + /** + * Indicates the selection state of this view. + * + * @return true if the view is selected, false otherwise + */ + @ViewDebug.ExportedProperty + public boolean isSelected() { + return (mPrivateFlags & SELECTED) != 0; + } + /** + * Changes the activated state of this view. A view can be activated or not. + * Note that activation is not the same as selection. Selection is + * a transient property, representing the view (hierarchy) the user is + * currently interacting with. Activation is a longer-term state that the + * user can move views in and out of. For example, in a list view with + * single or multiple selection enabled, the views in the current selection + * set are activated. (Um, yeah, we are deeply sorry about the terminology + * here.) The activated state is propagated down to children of the view it + * is set on. + * + * @param activated true if the view must be activated, false otherwise + */ + public void setActivated(boolean activated) { + if (((mPrivateFlags & ACTIVATED) != 0) != activated) { + mPrivateFlags = (mPrivateFlags & ~ACTIVATED) | (activated ? ACTIVATED : 0); + invalidate(true); + refreshDrawableState(); + dispatchSetActivated(activated); + } + } + /** + * Dispatch setActivated to all of this View's children. + * + * @see #setActivated(boolean) + * + * @param activated The new activated state + */ + protected void dispatchSetActivated(boolean activated) { + } + /** + * Indicates the activation state of this view. + * + * @return true if the view is activated, false otherwise + */ + @ViewDebug.ExportedProperty + public boolean isActivated() { + return (mPrivateFlags & ACTIVATED) != 0; + } + /** + * Returns the ViewTreeObserver for this view's hierarchy. The view tree + * observer can be used to get notifications when global events, like + * layout, happen. + * + * The returned ViewTreeObserver observer is not guaranteed to remain + * valid for the lifetime of this View. If the caller of this method keeps + * a long-lived reference to ViewTreeObserver, it should always check for + * the return value of {@link ViewTreeObserver#isAlive()}. + * + * @return The ViewTreeObserver for this view's hierarchy. + */ + public ViewTreeObserver getViewTreeObserver() { + if (mAttachInfo != null) { + return mAttachInfo.mTreeObserver; + } + if (mFloatingTreeObserver == null) { + mFloatingTreeObserver = new ViewTreeObserver(); + } + return mFloatingTreeObserver; + } + /** + *

Finds the topmost view in the current view hierarchy.

+ * + * @return the topmost view containing this view + */ + public View getRootView() { + if (mAttachInfo != null) { + final View v = mAttachInfo.mRootView; + if (v != null) { + return v; + } + } + View parent = this; + while (parent.mParent != null && parent.mParent instanceof View) { + parent = (View) parent.mParent; + } + return parent; + } + /** + *

Computes the coordinates of this view on the screen. The argument + * must be an array of two integers. After the method returns, the array + * contains the x and y location in that order.

+ * + * @param location an array of two integers in which to hold the coordinates + */ + public void getLocationOnScreen(int[] location) { + getLocationInWindow(location); + final AttachInfo info = mAttachInfo; + if (info != null) { + location[0] += info.mWindowLeft; + location[1] += info.mWindowTop; + } + } + /** + *

Computes the coordinates of this view in its window. The argument + * must be an array of two integers. After the method returns, the array + * contains the x and y location in that order.

+ * + * @param location an array of two integers in which to hold the coordinates + */ + public void getLocationInWindow(int[] location) { + if (location == null || location.length < 2) { + throw new IllegalArgumentException("location must be an array of two integers"); + } + if (mAttachInfo == null) { + // When the view is not attached to a window, this method does not make sense + location[0] = location[1] = 0; + return; + } + float[] position = mAttachInfo.mTmpTransformLocation; + position[0] = position[1] = 0.0f; + if (!hasIdentityMatrix()) { + getMatrix().mapPoints(position); + } + position[0] += mLeft; + position[1] += mTop; + ViewParent viewParent = mParent; + while (viewParent instanceof View) { + final View view = (View) viewParent; + position[0] -= view.mScrollX; + position[1] -= view.mScrollY; + if (!view.hasIdentityMatrix()) { + view.getMatrix().mapPoints(position); + } + position[0] += view.mLeft; + position[1] += view.mTop; + viewParent = view.mParent; + } + if (viewParent instanceof ViewRootImpl) { + // *cough* + final ViewRootImpl vr = (ViewRootImpl) viewParent; + position[1] -= vr.mCurScrollY; + } + location[0] = (int) (position[0] + 0.5f); + location[1] = (int) (position[1] + 0.5f); + } + /** + * {@hide} + * @param id the id of the view to be found + * @return the view of the specified id, null if cannot be found + */ + protected View findViewTraversal(int id) { + if (id == mID) { + return this; + } + return null; + } + /** + * {@hide} + * @param tag the tag of the view to be found + * @return the view of specified tag, null if cannot be found + */ + protected View findViewWithTagTraversal(Object tag) { + if (tag != null && tag.equals(mTag)) { + return this; + } + return null; + } + /** + * {@hide} + * @param predicate The predicate to evaluate. + * @param childToSkip If not null, ignores this child during the recursive traversal. + * @return The first view that matches the predicate or null. + */ + protected View findViewByPredicateTraversal(Predicate predicate, View childToSkip) { + if (predicate.apply(this)) { + return this; + } + return null; + } + /** + * Look for a child view with the given id. If this view has the given + * id, return this view. + * + * @param id The id to search for. + * @return The view that has the given id in the hierarchy or null + */ + public final View findViewById(int id) { + if (id < 0) { + return null; + } + return findViewTraversal(id); + } + /** + * Finds a view by its unuque and stable accessibility id. + * + * @param accessibilityId The searched accessibility id. + * @return The found view. + */ + final View findViewByAccessibilityId(int accessibilityId) { + if (accessibilityId < 0) { + return null; + } + return findViewByAccessibilityIdTraversal(accessibilityId); + } + /** + * Performs the traversal to find a view by its unuque and stable accessibility id. + * + * Note:This method does not stop at the root namespace + * boundary since the user can touch the screen at an arbitrary location + * potentially crossing the root namespace bounday which will send an + * accessibility event to accessibility services and they should be able + * to obtain the event source. Also accessibility ids are guaranteed to be + * unique in the window. + * + * @param accessibilityId The accessibility id. + * @return The found view. + */ + View findViewByAccessibilityIdTraversal(int accessibilityId) { + if (getAccessibilityViewId() == accessibilityId) { + return this; + } + return null; + } + /** + * Look for a child view with the given tag. If this view has the given + * tag, return this view. + * + * @param tag The tag to search for, using "tag.equals(getTag())". + * @return The View that has the given tag in the hierarchy or null + */ + public final View findViewWithTag(Object tag) { + if (tag == null) { + return null; + } + return findViewWithTagTraversal(tag); + } + /** + * {@hide} + * Look for a child view that matches the specified predicate. + * If this view matches the predicate, return this view. + * + * @param predicate The predicate to evaluate. + * @return The first view that matches the predicate or null. + */ + public final View findViewByPredicate(Predicate predicate) { + return findViewByPredicateTraversal(predicate, null); + } + /** + * {@hide} + * Look for a child view that matches the specified predicate, + * starting with the specified view and its descendents and then + * recusively searching the ancestors and siblings of that view + * until this view is reached. + * + * This method is useful in cases where the predicate does not match + * a single unique view (perhaps multiple views use the same id) + * and we are trying to find the view that is "closest" in scope to the + * starting view. + * + * @param start The view to start from. + * @param predicate The predicate to evaluate. + * @return The first view that matches the predicate or null. + */ + public final View findViewByPredicateInsideOut(View start, Predicate predicate) { + View childToSkip = null; + for (;;) { + View view = start.findViewByPredicateTraversal(predicate, childToSkip); + if (view != null || start == this) { + return view; + } + ViewParent parent = start.getParent(); + if (parent == null || !(parent instanceof View)) { + return null; + } + childToSkip = start; + start = (View) parent; + } + } + /** + * Sets the identifier for this view. The identifier does not have to be + * unique in this view's hierarchy. The identifier should be a positive + * number. + * + * @see #NO_ID + * @see #getId() + * @see #findViewById(int) + * + * @param id a number used to identify the view + * + * @attr ref android.R.styleable#View_id + */ + public void setId(int id) { + mID = id; + } + /** + * {@hide} + * + * @param isRoot true if the view belongs to the root namespace, false + * otherwise + */ + public void setIsRootNamespace(boolean isRoot) { + if (isRoot) { + mPrivateFlags |= IS_ROOT_NAMESPACE; + } else { + mPrivateFlags &= ~IS_ROOT_NAMESPACE; + } + } + /** + * {@hide} + * + * @return true if the view belongs to the root namespace, false otherwise + */ + public boolean isRootNamespace() { + return (mPrivateFlags&IS_ROOT_NAMESPACE) != 0; + } + /** + * Returns this view's identifier. + * + * @return a positive integer used to identify the view or {@link #NO_ID} + * if the view has no ID + * + * @see #setId(int) + * @see #findViewById(int) + * @attr ref android.R.styleable#View_id + */ + @ViewDebug.CapturedViewProperty + public int getId() { + return mID; + } + /** + * Returns this view's tag. + * + * @return the Object stored in this view as a tag + * + * @see #setTag(Object) + * @see #getTag(int) + */ + @ViewDebug.ExportedProperty + public Object getTag() { + return mTag; + } + /** + * Sets the tag associated with this view. A tag can be used to mark + * a view in its hierarchy and does not have to be unique within the + * hierarchy. Tags can also be used to store data within a view without + * resorting to another data structure. + * + * @param tag an Object to tag the view with + * + * @see #getTag() + * @see #setTag(int, Object) + */ + public void setTag(final Object tag) { + mTag = tag; + } + /** + * Returns the tag associated with this view and the specified key. + * + * @param key The key identifying the tag + * + * @return the Object stored in this view as a tag + * + * @see #setTag(int, Object) + * @see #getTag() + */ + public Object getTag(int key) { + if (mKeyedTags != null) return mKeyedTags.get(key); + return null; + } + /** + * Sets a tag associated with this view and a key. A tag can be used + * to mark a view in its hierarchy and does not have to be unique within + * the hierarchy. Tags can also be used to store data within a view + * without resorting to another data structure. + * + * The specified key should be an id declared in the resources of the + * application to ensure it is unique (see the ID resource type). + * Keys identified as belonging to + * the Android framework or not associated with any package will cause + * an {@link IllegalArgumentException} to be thrown. + * + * @param key The key identifying the tag + * @param tag An Object to tag the view with + * + * @throws IllegalArgumentException If they specified key is not valid + * + * @see #setTag(Object) + * @see #getTag(int) + */ + public void setTag(int key, final Object tag) { + // If the package id is 0x00 or 0x01, it's either an undefined package + // or a framework id + if ((key >>> 24) < 2) { + throw new IllegalArgumentException("The key must be an application-specific " + + "resource id."); + } + setKeyedTag(key, tag); + } + /** + * Variation of {@link #setTag(int, Object)} that enforces the key to be a + * framework id. + * + * @hide + */ + public void setTagInternal(int key, Object tag) { + if ((key >>> 24) != 0x1) { + throw new IllegalArgumentException("The key must be a framework-specific " + + "resource id."); + } + setKeyedTag(key, tag); + } + private void setKeyedTag(int key, Object tag) { + if (mKeyedTags == null) { + mKeyedTags = new SparseArray(); + } + mKeyedTags.put(key, tag); + } + /** + * @param consistency The type of consistency. See ViewDebug for more information. + * + * @hide + */ + protected boolean dispatchConsistencyCheck(int consistency) { + return onConsistencyCheck(consistency); + } + /** + * Method that subclasses should implement to check their consistency. The type of + * consistency check is indicated by the bit field passed as a parameter. + * + * @param consistency The type of consistency. See ViewDebug for more information. + * + * @throws IllegalStateException if the view is in an inconsistent state. + * + * @hide + */ + protected boolean onConsistencyCheck(int consistency) { + boolean result = true; + final boolean checkLayout = (consistency & ViewDebug.CONSISTENCY_LAYOUT) != 0; + final boolean checkDrawing = (consistency & ViewDebug.CONSISTENCY_DRAWING) != 0; + if (checkLayout) { + if (getParent() == null) { + result = false; + android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG, + "View " + this + " does not have a parent."); + } + if (mAttachInfo == null) { + result = false; + android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG, + "View " + this + " is not attached to a window."); + } + } + if (checkDrawing) { + // Do not check the DIRTY/DRAWN flags because views can call invalidate() + // from their draw() method + if ((mPrivateFlags & DRAWN) != DRAWN && + (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID) { + result = false; + android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG, + "View " + this + " was invalidated but its drawing cache is valid."); + } + } + return result; + } + /** + * Prints information about this view in the log output, with the tag + * {@link #VIEW_LOG_TAG}. + * + * @hide + */ + public void debug() { + debug(0); + } + /** + * Prints information about this view in the log output, with the tag + * {@link #VIEW_LOG_TAG}. Each line in the output is preceded with an + * indentation defined by the depth. + * + * @param depth the indentation level + * + * @hide + */ + protected void debug(int depth) { + String output = debugIndent(depth - 1); + output += "+ " + this; + int id = getId(); + if (id != -1) { + output += " (id=" + id + ")"; + } + Object tag = getTag(); + if (tag != null) { + output += " (tag=" + tag + ")"; + } + Log.d(VIEW_LOG_TAG, output); + if ((mPrivateFlags & FOCUSED) != 0) { + output = debugIndent(depth) + " FOCUSED"; + Log.d(VIEW_LOG_TAG, output); + } + output = debugIndent(depth); + output += "frame={" + mLeft + ", " + mTop + ", " + mRight + + ", " + mBottom + "} scroll={" + mScrollX + ", " + mScrollY + + "} "; + Log.d(VIEW_LOG_TAG, output); + if (mPaddingLeft != 0 || mPaddingTop != 0 || mPaddingRight != 0 + || mPaddingBottom != 0) { + output = debugIndent(depth); + output += "padding={" + mPaddingLeft + ", " + mPaddingTop + + ", " + mPaddingRight + ", " + mPaddingBottom + "}"; + Log.d(VIEW_LOG_TAG, output); + } + output = debugIndent(depth); + output += "mMeasureWidth=" + mMeasuredWidth + + " mMeasureHeight=" + mMeasuredHeight; + Log.d(VIEW_LOG_TAG, output); + output = debugIndent(depth); + if (mLayoutParams == null) { + output += "BAD! no layout params"; + } else { + output = mLayoutParams.debug(output); + } + Log.d(VIEW_LOG_TAG, output); + output = debugIndent(depth); + output += "flags={"; + output += View.printFlags(mViewFlags); + output += "}"; + Log.d(VIEW_LOG_TAG, output); + output = debugIndent(depth); + output += "privateFlags={"; + output += View.printPrivateFlags(mPrivateFlags); + output += "}"; + Log.d(VIEW_LOG_TAG, output); + } + /** + * Creates an string of whitespaces used for indentation. + * + * @param depth the indentation level + * @return a String containing (depth * 2 + 3) * 2 white spaces + * + * @hide + */ + protected static String debugIndent(int depth) { + StringBuilder spaces = new StringBuilder((depth * 2 + 3) * 2); + for (int i = 0; i < (depth * 2) + 3; i++) { + spaces.append(' ').append(' '); + } + return spaces.toString(); + } + /** + *

Return the offset of the widget's text baseline from the widget's top + * boundary. If this widget does not support baseline alignment, this + * method returns -1.

+ * + * @return the offset of the baseline within the widget's bounds or -1 + * if baseline alignment is not supported + */ + @ViewDebug.ExportedProperty(category = "layout") + public int getBaseline() { + return -1; + } + /** + * Call this when something has changed which has invalidated the + * layout of this view. This will schedule a layout pass of the view + * tree. + */ + public void requestLayout() { + if (ViewDebug.TRACE_HIERARCHY) { + ViewDebug.trace(this, ViewDebug.HierarchyTraceType.REQUEST_LAYOUT); + } + if (getAccessibilityNodeProvider() != null) { + throw new IllegalStateException("Views with AccessibilityNodeProvider" + + " can't have children."); + } + mPrivateFlags |= FORCE_LAYOUT; + mPrivateFlags |= INVALIDATED; + if (mParent != null) { + if (mLayoutParams != null) { + mLayoutParams.resolveWithDirection(getResolvedLayoutDirection()); + } + if (!mParent.isLayoutRequested()) { + mParent.requestLayout(); + } + } + } + /** + * Forces this view to be laid out during the next layout pass. + * This method does not call requestLayout() or forceLayout() + * on the parent. + */ + public void forceLayout() { + mPrivateFlags |= FORCE_LAYOUT; + mPrivateFlags |= INVALIDATED; + } + /** + *

+ * This is called to find out how big a view should be. The parent + * supplies constraint information in the width and height parameters. + *

+ * + *

+ * The actual measurement work of a view is performed in + * {@link #onMeasure(int, int)}, called by this method. Therefore, only + * {@link #onMeasure(int, int)} can and must be overridden by subclasses. + *

+ * + * + * @param widthMeasureSpec Horizontal space requirements as imposed by the + * parent + * @param heightMeasureSpec Vertical space requirements as imposed by the + * parent + * + * @see #onMeasure(int, int) + */ + public final void measure(int widthMeasureSpec, int heightMeasureSpec) { + if ((mPrivateFlags & FORCE_LAYOUT) == FORCE_LAYOUT || + widthMeasureSpec != mOldWidthMeasureSpec || + heightMeasureSpec != mOldHeightMeasureSpec) { + // first clears the measured dimension flag + mPrivateFlags &= ~MEASURED_DIMENSION_SET; + if (ViewDebug.TRACE_HIERARCHY) { + ViewDebug.trace(this, ViewDebug.HierarchyTraceType.ON_MEASURE); + } + // measure ourselves, this should set the measured dimension flag back + onMeasure(widthMeasureSpec, heightMeasureSpec); + // flag not set, setMeasuredDimension() was not invoked, we raise + // an exception to warn the developer + if ((mPrivateFlags & MEASURED_DIMENSION_SET) != MEASURED_DIMENSION_SET) { + throw new IllegalStateException("onMeasure() did not set the" + + " measured dimension by calling" + + " setMeasuredDimension()"); + } + mPrivateFlags |= LAYOUT_REQUIRED; + } + mOldWidthMeasureSpec = widthMeasureSpec; + mOldHeightMeasureSpec = heightMeasureSpec; + } + /** + *

+ * Measure the view and its content to determine the measured width and the + * measured height. This method is invoked by {@link #measure(int, int)} and + * should be overriden by subclasses to provide accurate and efficient + * measurement of their contents. + *

+ * + *

+ * CONTRACT: When overriding this method, you + * must call {@link #setMeasuredDimension(int, int)} to store the + * measured width and height of this view. Failure to do so will trigger an + * IllegalStateException, thrown by + * {@link #measure(int, int)}. Calling the superclass' + * {@link #onMeasure(int, int)} is a valid use. + *

+ * + *

+ * The base class implementation of measure defaults to the background size, + * unless a larger size is allowed by the MeasureSpec. Subclasses should + * override {@link #onMeasure(int, int)} to provide better measurements of + * their content. + *

+ * + *

+ * If this method is overridden, it is the subclass's responsibility to make + * sure the measured height and width are at least the view's minimum height + * and width ({@link #getSuggestedMinimumHeight()} and + * {@link #getSuggestedMinimumWidth()}). + *

+ * + * @param widthMeasureSpec horizontal space requirements as imposed by the parent. + * The requirements are encoded with + * {@link android.view.View.MeasureSpec}. + * @param heightMeasureSpec vertical space requirements as imposed by the parent. + * The requirements are encoded with + * {@link android.view.View.MeasureSpec}. + * + * @see #getMeasuredWidth() + * @see #getMeasuredHeight() + * @see #setMeasuredDimension(int, int) + * @see #getSuggestedMinimumHeight() + * @see #getSuggestedMinimumWidth() + * @see android.view.View.MeasureSpec#getMode(int) + * @see android.view.View.MeasureSpec#getSize(int) + */ + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), + getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec)); + } + /** + *

This mehod must be called by {@link #onMeasure(int, int)} to store the + * measured width and measured height. Failing to do so will trigger an + * exception at measurement time.

+ * + * @param measuredWidth The measured width of this view. May be a complex + * bit mask as defined by {@link #MEASURED_SIZE_MASK} and + * {@link #MEASURED_STATE_TOO_SMALL}. + * @param measuredHeight The measured height of this view. May be a complex + * bit mask as defined by {@link #MEASURED_SIZE_MASK} and + * {@link #MEASURED_STATE_TOO_SMALL}. + */ + protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) { + mMeasuredWidth = measuredWidth; + mMeasuredHeight = measuredHeight; + mPrivateFlags |= MEASURED_DIMENSION_SET; + } + /** + * Merge two states as returned by {@link #getMeasuredState()}. + * @param curState The current state as returned from a view or the result + * of combining multiple views. + * @param newState The new view state to combine. + * @return Returns a new integer reflecting the combination of the two + * states. + */ + public static int combineMeasuredStates(int curState, int newState) { + return curState | newState; + } + /** + * Version of {@link #resolveSizeAndState(int, int, int)} + * returning only the {@link #MEASURED_SIZE_MASK} bits of the result. + */ + public static int resolveSize(int size, int measureSpec) { + return resolveSizeAndState(size, measureSpec, 0) & MEASURED_SIZE_MASK; + } + /** + * Utility to reconcile a desired size and state, with constraints imposed + * by a MeasureSpec. Will take the desired size, unless a different size + * is imposed by the constraints. The returned value is a compound integer, + * with the resolved size in the {@link #MEASURED_SIZE_MASK} bits and + * optionally the bit {@link #MEASURED_STATE_TOO_SMALL} set if the resulting + * size is smaller than the size the view wants to be. + * + * @param size How big the view wants to be + * @param measureSpec Constraints imposed by the parent + * @return Size information bit mask as defined by + * {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}. + */ + public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) { + int result = size; + int specMode = MeasureSpec.getMode(measureSpec); + int specSize = MeasureSpec.getSize(measureSpec); + switch (specMode) { + case MeasureSpec.UNSPECIFIED: + result = size; + break; + case MeasureSpec.AT_MOST: + if (specSize < size) { + result = specSize | MEASURED_STATE_TOO_SMALL; + } else { + result = size; + } + break; + case MeasureSpec.EXACTLY: + result = specSize; + break; + } + return result | (childMeasuredState&MEASURED_STATE_MASK); + } + /** + * Utility to return a default size. Uses the supplied size if the + * MeasureSpec imposed no constraints. Will get larger if allowed + * by the MeasureSpec. + * + * @param size Default size for this view + * @param measureSpec Constraints imposed by the parent + * @return The size this view should be. + */ + public static int getDefaultSize(int size, int measureSpec) { + int result = size; + int specMode = MeasureSpec.getMode(measureSpec); + int specSize = MeasureSpec.getSize(measureSpec); + switch (specMode) { + case MeasureSpec.UNSPECIFIED: + result = size; + break; + case MeasureSpec.AT_MOST: + case MeasureSpec.EXACTLY: + result = specSize; + break; + } + return result; + } + /** + * Returns the suggested minimum height that the view should use. This + * returns the maximum of the view's minimum height + * and the background's minimum height + * ({@link android.graphics.drawable.Drawable#getMinimumHeight()}). + *

+ * When being used in {@link #onMeasure(int, int)}, the caller should still + * ensure the returned height is within the requirements of the parent. + * + * @return The suggested minimum height of the view. + */ + protected int getSuggestedMinimumHeight() { + int suggestedMinHeight = mMinHeight; + if (mBGDrawable != null) { + final int bgMinHeight = mBGDrawable.getMinimumHeight(); + if (suggestedMinHeight < bgMinHeight) { + suggestedMinHeight = bgMinHeight; + } + } + return suggestedMinHeight; + } + /** + * Returns the suggested minimum width that the view should use. This + * returns the maximum of the view's minimum width) + * and the background's minimum width + * ({@link android.graphics.drawable.Drawable#getMinimumWidth()}). + *

+ * When being used in {@link #onMeasure(int, int)}, the caller should still + * ensure the returned width is within the requirements of the parent. + * + * @return The suggested minimum width of the view. + */ + protected int getSuggestedMinimumWidth() { + int suggestedMinWidth = mMinWidth; + if (mBGDrawable != null) { + final int bgMinWidth = mBGDrawable.getMinimumWidth(); + if (suggestedMinWidth < bgMinWidth) { + suggestedMinWidth = bgMinWidth; + } + } + return suggestedMinWidth; + } + /** + * Sets the minimum height of the view. It is not guaranteed the view will + * be able to achieve this minimum height (for example, if its parent layout + * constrains it with less available height). + * + * @param minHeight The minimum height the view will try to be. + */ + public void setMinimumHeight(int minHeight) { + mMinHeight = minHeight; + } + /** + * Sets the minimum width of the view. It is not guaranteed the view will + * be able to achieve this minimum width (for example, if its parent layout + * constrains it with less available width). + * + * @param minWidth The minimum width the view will try to be. + */ + public void setMinimumWidth(int minWidth) { + mMinWidth = minWidth; + } + /** + * Get the animation currently associated with this view. + * + * @return The animation that is currently playing or + * scheduled to play for this view. + */ + public Animation getAnimation() { + return mCurrentAnimation; + } + /** + * Start the specified animation now. + * + * @param animation the animation to start now + */ + public void startAnimation(Animation animation) { + animation.setStartTime(Animation.START_ON_FIRST_FRAME); + setAnimation(animation); + invalidateParentCaches(); + invalidate(true); + } + /** + * Cancels any animations for this view. + */ + public void clearAnimation() { + if (mCurrentAnimation != null) { + mCurrentAnimation.detach(); + } + mCurrentAnimation = null; + invalidateParentIfNeeded(); + } + /** + * Sets the next animation to play for this view. + * If you want the animation to play immediately, use + * startAnimation. This method provides allows fine-grained + * control over the start time and invalidation, but you + * must make sure that 1) the animation has a start time set, and + * 2) the view will be invalidated when the animation is supposed to + * start. + * + * @param animation The next animation, or null. + */ + public void setAnimation(Animation animation) { + mCurrentAnimation = animation; + if (animation != null) { + animation.reset(); + } + } + /** + * Invoked by a parent ViewGroup to notify the start of the animation + * currently associated with this view. If you override this method, + * always call super.onAnimationStart(); + * + * @see #setAnimation(android.view.animation.Animation) + * @see #getAnimation() + */ + protected void onAnimationStart() { + mPrivateFlags |= ANIMATION_STARTED; + } + /** + * Invoked by a parent ViewGroup to notify the end of the animation + * currently associated with this view. If you override this method, + * always call super.onAnimationEnd(); + * + * @see #setAnimation(android.view.animation.Animation) + * @see #getAnimation() + */ + protected void onAnimationEnd() { + mPrivateFlags &= ~ANIMATION_STARTED; + } + /** + * Invoked if there is a Transform that involves alpha. Subclass that can + * draw themselves with the specified alpha should return true, and then + * respect that alpha when their onDraw() is called. If this returns false + * then the view may be redirected to draw into an offscreen buffer to + * fulfill the request, which will look fine, but may be slower than if the + * subclass handles it internally. The default implementation returns false. + * + * @param alpha The alpha (0..255) to apply to the view's drawing + * @return true if the view can draw with the specified alpha. + */ + protected boolean onSetAlpha(int alpha) { + return false; + } + /** + * This is used by the RootView to perform an optimization when + * the view hierarchy contains one or several SurfaceView. + * SurfaceView is always considered transparent, but its children are not, + * therefore all View objects remove themselves from the global transparent + * region (passed as a parameter to this function). + * + * @param region The transparent region for this ViewAncestor (window). + * + * @return Returns true if the effective visibility of the view at this + * point is opaque, regardless of the transparent region; returns false + * if it is possible for underlying windows to be seen behind the view. + * + * {@hide} + */ + public boolean gatherTransparentRegion(Region region) { + final AttachInfo attachInfo = mAttachInfo; + if (region != null && attachInfo != null) { + final int pflags = mPrivateFlags; + if ((pflags & SKIP_DRAW) == 0) { + // The SKIP_DRAW flag IS NOT set, so this view draws. We need to + // remove it from the transparent region. + final int[] location = attachInfo.mTransparentLocation; + getLocationInWindow(location); + region.op(location[0], location[1], location[0] + mRight - mLeft, + location[1] + mBottom - mTop, Region.Op.DIFFERENCE); + } else if ((pflags & ONLY_DRAWS_BACKGROUND) != 0 && mBGDrawable != null) { + // The ONLY_DRAWS_BACKGROUND flag IS set and the background drawable + // exists, so we remove the background drawable's non-transparent + // parts from this transparent region. + applyDrawableToTransparentRegion(mBGDrawable, region); + } + } + return true; + } + /** + * Play a sound effect for this view. + * + *

The framework will play sound effects for some built in actions, such as + * clicking, but you may wish to play these effects in your widget, + * for instance, for internal navigation. + * + *

The sound effect will only be played if sound effects are enabled by the user, and + * {@link #isSoundEffectsEnabled()} is true. + * + * @param soundConstant One of the constants defined in {@link SoundEffectConstants} + */ + public void playSoundEffect(int soundConstant) { + if (mAttachInfo == null || mAttachInfo.mRootCallbacks == null || !isSoundEffectsEnabled()) { + return; + } + mAttachInfo.mRootCallbacks.playSoundEffect(soundConstant); + } + /** + * BZZZTT!!1! + * + *

Provide haptic feedback to the user for this view. + * + *

The framework will provide haptic feedback for some built in actions, + * such as long presses, but you may wish to provide feedback for your + * own widget. + * + *

The feedback will only be performed if + * {@link #isHapticFeedbackEnabled()} is true. + * + * @param feedbackConstant One of the constants defined in + * {@link HapticFeedbackConstants} + */ + public boolean performHapticFeedback(int feedbackConstant) { + return performHapticFeedback(feedbackConstant, 0); + } + /** + * BZZZTT!!1! + * + *

Like {@link #performHapticFeedback(int)}, with additional options. + * + * @param feedbackConstant One of the constants defined in + * {@link HapticFeedbackConstants} + * @param flags Additional flags as per {@link HapticFeedbackConstants}. + */ + public boolean performHapticFeedback(int feedbackConstant, int flags) { + if (mAttachInfo == null) { + return false; + } + //noinspection SimplifiableIfStatement + if ((flags & HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING) == 0 + && !isHapticFeedbackEnabled()) { + return false; + } + return mAttachInfo.mRootCallbacks.performHapticFeedback(feedbackConstant, + (flags & HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING) != 0); + } + /** + * Request that the visibility of the status bar be changed. + * @param visibility Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE} or + * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}. + */ + public void setSystemUiVisibility(int visibility) { + if (visibility != mSystemUiVisibility) { + mSystemUiVisibility = visibility; + if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) { + mParent.recomputeViewAttributes(this); + } + } + } + /** + * Returns the status bar visibility that this view has requested. + * @return Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE} or + * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}. + */ + public int getSystemUiVisibility() { + return mSystemUiVisibility; + } + /** + * Set a listener to receive callbacks when the visibility of the system bar changes. + * @param l The {@link OnSystemUiVisibilityChangeListener} to receive callbacks. + */ + public void setOnSystemUiVisibilityChangeListener(OnSystemUiVisibilityChangeListener l) { + getListenerInfo().mOnSystemUiVisibilityChangeListener = l; + if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) { + mParent.recomputeViewAttributes(this); + } + } + /** + * Dispatch callbacks to {@link #setOnSystemUiVisibilityChangeListener} down + * the view hierarchy. + */ + public void dispatchSystemUiVisibilityChanged(int visibility) { + ListenerInfo li = mListenerInfo; + if (li != null && li.mOnSystemUiVisibilityChangeListener != null) { + li.mOnSystemUiVisibilityChangeListener.onSystemUiVisibilityChange( + visibility & PUBLIC_STATUS_BAR_VISIBILITY_MASK); + } + } + void updateLocalSystemUiVisibility(int localValue, int localChanges) { + int val = (mSystemUiVisibility&~localChanges) | (localValue&localChanges); + if (val != mSystemUiVisibility) { + setSystemUiVisibility(val); + } + } + /** + * Creates an image that the system displays during the drag and drop + * operation. This is called a "drag shadow". The default implementation + * for a DragShadowBuilder based on a View returns an image that has exactly the same + * appearance as the given View. The default also positions the center of the drag shadow + * directly under the touch point. If no View is provided (the constructor with no parameters + * is used), and {@link #onProvideShadowMetrics(Point,Point) onProvideShadowMetrics()} and + * {@link #onDrawShadow(Canvas) onDrawShadow()} are not overriden, then the + * default is an invisible drag shadow. + *

+ * You are not required to use the View you provide to the constructor as the basis of the + * drag shadow. The {@link #onDrawShadow(Canvas) onDrawShadow()} method allows you to draw + * anything you want as the drag shadow. + *

+ *

+ * You pass a DragShadowBuilder object to the system when you start the drag. The system + * calls {@link #onProvideShadowMetrics(Point,Point) onProvideShadowMetrics()} to get the + * size and position of the drag shadow. It uses this data to construct a + * {@link android.graphics.Canvas} object, then it calls {@link #onDrawShadow(Canvas) onDrawShadow()} + * so that your application can draw the shadow image in the Canvas. + *

+ * + *
+ *

Developer Guides

+ *

For a guide to implementing drag and drop features, read the + * Drag and Drop developer guide.

+ *
+ */ + public static class DragShadowBuilder { + private final WeakReference mView; + /** + * Constructs a shadow image builder based on a View. By default, the resulting drag + * shadow will have the same appearance and dimensions as the View, with the touch point + * over the center of the View. + * @param view A View. Any View in scope can be used. + */ + public DragShadowBuilder(View view) { + mView = new WeakReference(view); + } + /** + * Construct a shadow builder object with no associated View. This + * constructor variant is only useful when the {@link #onProvideShadowMetrics(Point, Point)} + * and {@link #onDrawShadow(Canvas)} methods are also overridden in order + * to supply the drag shadow's dimensions and appearance without + * reference to any View object. If they are not overridden, then the result is an + * invisible drag shadow. + */ + public DragShadowBuilder() { + mView = new WeakReference(null); + } + /** + * Returns the View object that had been passed to the + * {@link #View.DragShadowBuilder(View)} + * constructor. If that View parameter was {@code null} or if the + * {@link #View.DragShadowBuilder()} + * constructor was used to instantiate the builder object, this method will return + * null. + * + * @return The View object associate with this builder object. + */ + @SuppressWarnings({"JavadocReference"}) + final public View getView() { + return mView.get(); + } + /** + * Provides the metrics for the shadow image. These include the dimensions of + * the shadow image, and the point within that shadow that should + * be centered under the touch location while dragging. + *

+ * The default implementation sets the dimensions of the shadow to be the + * same as the dimensions of the View itself and centers the shadow under + * the touch point. + *

+ * + * @param shadowSize A {@link android.graphics.Point} containing the width and height + * of the shadow image. Your application must set {@link android.graphics.Point#x} to the + * desired width and must set {@link android.graphics.Point#y} to the desired height of the + * image. + * + * @param shadowTouchPoint A {@link android.graphics.Point} for the position within the + * shadow image that should be underneath the touch point during the drag and drop + * operation. Your application must set {@link android.graphics.Point#x} to the + * X coordinate and {@link android.graphics.Point#y} to the Y coordinate of this position. + */ + public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) { + final View view = mView.get(); + if (view != null) { + shadowSize.set(view.getWidth(), view.getHeight()); + shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y / 2); + } else { + Log.e(View.VIEW_LOG_TAG, "Asked for drag thumb metrics but no view"); + } + } + /** + * Draws the shadow image. The system creates the {@link android.graphics.Canvas} object + * based on the dimensions it received from the + * {@link #onProvideShadowMetrics(Point, Point)} callback. + * + * @param canvas A {@link android.graphics.Canvas} object in which to draw the shadow image. + */ + public void onDrawShadow(Canvas canvas) { + final View view = mView.get(); + if (view != null) { + view.draw(canvas); + } else { + Log.e(View.VIEW_LOG_TAG, "Asked to draw drag shadow but no view"); + } + } + } + /** + * Starts a drag and drop operation. When your application calls this method, it passes a + * {@link android.view.View.DragShadowBuilder} object to the system. The + * system calls this object's {@link DragShadowBuilder#onProvideShadowMetrics(Point, Point)} + * to get metrics for the drag shadow, and then calls the object's + * {@link DragShadowBuilder#onDrawShadow(Canvas)} to draw the drag shadow itself. + *

+ * Once the system has the drag shadow, it begins the drag and drop operation by sending + * drag events to all the View objects in your application that are currently visible. It does + * this either by calling the View object's drag listener (an implementation of + * {@link android.view.View.OnDragListener#onDrag(View,DragEvent) onDrag()} or by calling the + * View object's {@link android.view.View#onDragEvent(DragEvent) onDragEvent()} method. + * Both are passed a {@link android.view.DragEvent} object that has a + * {@link android.view.DragEvent#getAction()} value of + * {@link android.view.DragEvent#ACTION_DRAG_STARTED}. + *

+ *

+ * Your application can invoke startDrag() on any attached View object. The View object does not + * need to be the one used in {@link android.view.View.DragShadowBuilder}, nor does it need to + * be related to the View the user selected for dragging. + *

+ * @param data A {@link android.content.ClipData} object pointing to the data to be + * transferred by the drag and drop operation. + * @param shadowBuilder A {@link android.view.View.DragShadowBuilder} object for building the + * drag shadow. + * @param myLocalState An {@link java.lang.Object} containing local data about the drag and + * drop operation. This Object is put into every DragEvent object sent by the system during the + * current drag. + *

+ * myLocalState is a lightweight mechanism for the sending information from the dragged View + * to the target Views. For example, it can contain flags that differentiate between a + * a copy operation and a move operation. + *

+ * @param flags Flags that control the drag and drop operation. No flags are currently defined, + * so the parameter should be set to 0. + * @return {@code true} if the method completes successfully, or + * {@code false} if it fails anywhere. Returning {@code false} means the system was unable to + * do a drag, and so no drag operation is in progress. + */ + public final boolean startDrag(ClipData data, DragShadowBuilder shadowBuilder, + Object myLocalState, int flags) { + if (ViewDebug.DEBUG_DRAG) { + Log.d(VIEW_LOG_TAG, "startDrag: data=" + data + " flags=" + flags); + } + boolean okay = false; + Point shadowSize = new Point(); + Point shadowTouchPoint = new Point(); + shadowBuilder.onProvideShadowMetrics(shadowSize, shadowTouchPoint); + if ((shadowSize.x < 0) || (shadowSize.y < 0) || + (shadowTouchPoint.x < 0) || (shadowTouchPoint.y < 0)) { + throw new IllegalStateException("Drag shadow dimensions must not be negative"); + } + if (ViewDebug.DEBUG_DRAG) { + Log.d(VIEW_LOG_TAG, "drag shadow: width=" + shadowSize.x + " height=" + shadowSize.y + + " shadowX=" + shadowTouchPoint.x + " shadowY=" + shadowTouchPoint.y); + } + Surface surface = new Surface(); + try { + IBinder token = mAttachInfo.mSession.prepareDrag(mAttachInfo.mWindow, + flags, shadowSize.x, shadowSize.y, surface); + if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "prepareDrag returned token=" + token + + " surface=" + surface); + if (token != null) { + Canvas canvas = surface.lockCanvas(null); + try { + canvas.drawColor(0, PorterDuff.Mode.CLEAR); + shadowBuilder.onDrawShadow(canvas); + } finally { + surface.unlockCanvasAndPost(canvas); + } + final ViewRootImpl root = getViewRootImpl(); + // Cache the local state object for delivery with DragEvents + root.setLocalDragState(myLocalState); + // repurpose 'shadowSize' for the last touch point + root.getLastTouchPoint(shadowSize); + okay = mAttachInfo.mSession.performDrag(mAttachInfo.mWindow, token, + shadowSize.x, shadowSize.y, + shadowTouchPoint.x, shadowTouchPoint.y, data); + if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "performDrag returned " + okay); + // Off and running! Release our local surface instance; the drag + // shadow surface is now managed by the system process. + surface.release(); + } + } catch (Exception e) { + Log.e(VIEW_LOG_TAG, "Unable to initiate drag", e); + surface.destroy(); + } + return okay; + } + /** + * Handles drag events sent by the system following a call to + * {@link android.view.View#startDrag(ClipData,DragShadowBuilder,Object,int) startDrag()}. + *

+ * When the system calls this method, it passes a + * {@link android.view.DragEvent} object. A call to + * {@link android.view.DragEvent#getAction()} returns one of the action type constants defined + * in DragEvent. The method uses these to determine what is happening in the drag and drop + * operation. + * @param event The {@link android.view.DragEvent} sent by the system. + * The {@link android.view.DragEvent#getAction()} method returns an action type constant defined + * in DragEvent, indicating the type of drag event represented by this object. + * @return {@code true} if the method was successful, otherwise {@code false}. + *

+ * The method should return {@code true} in response to an action type of + * {@link android.view.DragEvent#ACTION_DRAG_STARTED} to receive drag events for the current + * operation. + *

+ *

+ * The method should also return {@code true} in response to an action type of + * {@link android.view.DragEvent#ACTION_DROP} if it consumed the drop, or + * {@code false} if it didn't. + *

+ */ + public boolean onDragEvent(DragEvent event) { + return false; + } + /** + * Detects if this View is enabled and has a drag event listener. + * If both are true, then it calls the drag event listener with the + * {@link android.view.DragEvent} it received. If the drag event listener returns + * {@code true}, then dispatchDragEvent() returns {@code true}. + *

+ * For all other cases, the method calls the + * {@link android.view.View#onDragEvent(DragEvent) onDragEvent()} drag event handler + * method and returns its result. + *

+ *

+ * This ensures that a drag event is always consumed, even if the View does not have a drag + * event listener. However, if the View has a listener and the listener returns true, then + * onDragEvent() is not called. + *

+ */ + public boolean dispatchDragEvent(DragEvent event) { + //noinspection SimplifiableIfStatement + ListenerInfo li = mListenerInfo; + if (li != null && li.mOnDragListener != null && (mViewFlags & ENABLED_MASK) == ENABLED + && li.mOnDragListener.onDrag(this, event)) { + return true; + } + return onDragEvent(event); + } + boolean canAcceptDrag() { + return (mPrivateFlags2 & DRAG_CAN_ACCEPT) != 0; + } + /** + * This needs to be a better API (NOT ON VIEW) before it is exposed. If + * it is ever exposed at all. + * @hide + */ + public void onCloseSystemDialogs(String reason) { + } + /** + * Given a Drawable whose bounds have been set to draw into this view, + * update a Region being computed for + * {@link #gatherTransparentRegion(android.graphics.Region)} so + * that any non-transparent parts of the Drawable are removed from the + * given transparent region. + * + * @param dr The Drawable whose transparency is to be applied to the region. + * @param region A Region holding the current transparency information, + * where any parts of the region that are set are considered to be + * transparent. On return, this region will be modified to have the + * transparency information reduced by the corresponding parts of the + * Drawable that are not transparent. + * {@hide} + */ + public void applyDrawableToTransparentRegion(Drawable dr, Region region) { + if (DBG) { + Log.i("View", "Getting transparent region for: " + this); + } + final Region r = dr.getTransparentRegion(); + final Rect db = dr.getBounds(); + final AttachInfo attachInfo = mAttachInfo; + if (r != null && attachInfo != null) { + final int w = getRight()-getLeft(); + final int h = getBottom()-getTop(); + if (db.left > 0) { + //Log.i("VIEW", "Drawable left " + db.left + " > view 0"); + r.op(0, 0, db.left, h, Region.Op.UNION); + } + if (db.right < w) { + //Log.i("VIEW", "Drawable right " + db.right + " < view " + w); + r.op(db.right, 0, w, h, Region.Op.UNION); + } + if (db.top > 0) { + //Log.i("VIEW", "Drawable top " + db.top + " > view 0"); + r.op(0, 0, w, db.top, Region.Op.UNION); + } + if (db.bottom < h) { + //Log.i("VIEW", "Drawable bottom " + db.bottom + " < view " + h); + r.op(0, db.bottom, w, h, Region.Op.UNION); + } + final int[] location = attachInfo.mTransparentLocation; + getLocationInWindow(location); + r.translate(location[0], location[1]); + region.op(r, Region.Op.INTERSECT); + } else { + region.op(db, Region.Op.DIFFERENCE); + } + } + private void checkForLongClick(int delayOffset) { + if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) { + mHasPerformedLongPress = false; + if (mPendingCheckForLongPress == null) { + mPendingCheckForLongPress = new CheckForLongPress(); + } + mPendingCheckForLongPress.rememberWindowAttachCount(); + postDelayed(mPendingCheckForLongPress, + ViewConfiguration.getLongPressTimeout() - delayOffset); + } + } + /** + * Inflate a view from an XML resource. This convenience method wraps the {@link + * LayoutInflater} class, which provides a full range of options for view inflation. + * + * @param context The Context object for your activity or application. + * @param resource The resource ID to inflate + * @param root A view group that will be the parent. Used to properly inflate the + * layout_* parameters. + * @see LayoutInflater + */ + public static View inflate(Context context, int resource, ViewGroup root) { + LayoutInflater factory = LayoutInflater.from(context); + return factory.inflate(resource, root); + } + /** + * Scroll the view with standard behavior for scrolling beyond the normal + * content boundaries. Views that call this method should override + * {@link #onOverScrolled(int, int, boolean, boolean)} to respond to the + * results of an over-scroll operation. + * + * Views can use this method to handle any touch or fling-based scrolling. + * + * @param deltaX Change in X in pixels + * @param deltaY Change in Y in pixels + * @param scrollX Current X scroll value in pixels before applying deltaX + * @param scrollY Current Y scroll value in pixels before applying deltaY + * @param scrollRangeX Maximum content scroll range along the X axis + * @param scrollRangeY Maximum content scroll range along the Y axis + * @param maxOverScrollX Number of pixels to overscroll by in either direction + * along the X axis. + * @param maxOverScrollY Number of pixels to overscroll by in either direction + * along the Y axis. + * @param isTouchEvent true if this scroll operation is the result of a touch event. + * @return true if scrolling was clamped to an over-scroll boundary along either + * axis, false otherwise. + */ + @SuppressWarnings({"UnusedParameters"}) + protected boolean overScrollBy(int deltaX, int deltaY, + int scrollX, int scrollY, + int scrollRangeX, int scrollRangeY, + int maxOverScrollX, int maxOverScrollY, + boolean isTouchEvent) { + final int overScrollMode = mOverScrollMode; + final boolean canScrollHorizontal = + computeHorizontalScrollRange() > computeHorizontalScrollExtent(); + final boolean canScrollVertical = + computeVerticalScrollRange() > computeVerticalScrollExtent(); + final boolean overScrollHorizontal = overScrollMode == OVER_SCROLL_ALWAYS || + (overScrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && canScrollHorizontal); + final boolean overScrollVertical = overScrollMode == OVER_SCROLL_ALWAYS || + (overScrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && canScrollVertical); + int newScrollX = scrollX + deltaX; + if (!overScrollHorizontal) { + maxOverScrollX = 0; + } + int newScrollY = scrollY + deltaY; + if (!overScrollVertical) { + maxOverScrollY = 0; + } + // Clamp values if at the limits and record + final int left = -maxOverScrollX; + final int right = maxOverScrollX + scrollRangeX; + final int top = -maxOverScrollY; + final int bottom = maxOverScrollY + scrollRangeY; + boolean clampedX = false; + if (newScrollX > right) { + newScrollX = right; + clampedX = true; + } else if (newScrollX < left) { + newScrollX = left; + clampedX = true; + } + boolean clampedY = false; + if (newScrollY > bottom) { + newScrollY = bottom; + clampedY = true; + } else if (newScrollY < top) { + newScrollY = top; + clampedY = true; + } + onOverScrolled(newScrollX, newScrollY, clampedX, clampedY); + return clampedX || clampedY; + } + /** + * Called by {@link #overScrollBy(int, int, int, int, int, int, int, int, boolean)} to + * respond to the results of an over-scroll operation. + * + * @param scrollX New X scroll value in pixels + * @param scrollY New Y scroll value in pixels + * @param clampedX True if scrollX was clamped to an over-scroll boundary + * @param clampedY True if scrollY was clamped to an over-scroll boundary + */ + protected void onOverScrolled(int scrollX, int scrollY, + boolean clampedX, boolean clampedY) { + // Intentionally empty. + } + /** + * Returns the over-scroll mode for this view. The result will be + * one of {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS} + * (allow over-scrolling only if the view content is larger than the container), + * or {@link #OVER_SCROLL_NEVER}. + * + * @return This view's over-scroll mode. + */ + public int getOverScrollMode() { + return mOverScrollMode; + } + /** + * Set the over-scroll mode for this view. Valid over-scroll modes are + * {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS} + * (allow over-scrolling only if the view content is larger than the container), + * or {@link #OVER_SCROLL_NEVER}. + * + * Setting the over-scroll mode of a view will have an effect only if the + * view is capable of scrolling. + * + * @param overScrollMode The new over-scroll mode for this view. + */ + public void setOverScrollMode(int overScrollMode) { + if (overScrollMode != OVER_SCROLL_ALWAYS && + overScrollMode != OVER_SCROLL_IF_CONTENT_SCROLLS && + overScrollMode != OVER_SCROLL_NEVER) { + throw new IllegalArgumentException("Invalid overscroll mode " + overScrollMode); + } + mOverScrollMode = overScrollMode; + } + /** + * Gets a scale factor that determines the distance the view should scroll + * vertically in response to {@link MotionEvent#ACTION_SCROLL}. + * @return The vertical scroll scale factor. + * @hide + */ + protected float getVerticalScrollFactor() { + if (mVerticalScrollFactor == 0) { + TypedValue outValue = new TypedValue(); + if (!mContext.getTheme().resolveAttribute( + com.android.internal.R.attr.listPreferredItemHeight, outValue, true)) { + throw new IllegalStateException( + "Expected theme to define listPreferredItemHeight."); + } + mVerticalScrollFactor = outValue.getDimension( + mContext.getResources().getDisplayMetrics()); + } + return mVerticalScrollFactor; + } + /** + * Gets a scale factor that determines the distance the view should scroll + * horizontally in response to {@link MotionEvent#ACTION_SCROLL}. + * @return The horizontal scroll scale factor. + * @hide + */ + protected float getHorizontalScrollFactor() { + // TODO: Should use something else. + return getVerticalScrollFactor(); + } + /** + * Return the value specifying the text direction or policy that was set with + * {@link #setTextDirection(int)}. + * + * @return the defined text direction. It can be one of: + * + * {@link #TEXT_DIRECTION_INHERIT}, + * {@link #TEXT_DIRECTION_FIRST_STRONG} + * {@link #TEXT_DIRECTION_ANY_RTL}, + * {@link #TEXT_DIRECTION_LTR}, + * {@link #TEXT_DIRECTION_RTL}, + * {@link #TEXT_DIRECTION_LOCALE}, + * + */ + public int getTextDirection() { + return mTextDirection; + } + /** + * Set the text direction. + * + * @param textDirection the direction to set. Should be one of: + * + * {@link #TEXT_DIRECTION_INHERIT}, + * {@link #TEXT_DIRECTION_FIRST_STRONG} + * {@link #TEXT_DIRECTION_ANY_RTL}, + * {@link #TEXT_DIRECTION_LTR}, + * {@link #TEXT_DIRECTION_RTL}, + * {@link #TEXT_DIRECTION_LOCALE}, + * + */ + public void setTextDirection(int textDirection) { + if (textDirection != mTextDirection) { + mTextDirection = textDirection; + resetResolvedTextDirection(); + requestLayout(); + } + } + /** + * Return the resolved text direction. + * + * @return the resolved text direction. Return one of: + * + * {@link #TEXT_DIRECTION_FIRST_STRONG} + * {@link #TEXT_DIRECTION_ANY_RTL}, + * {@link #TEXT_DIRECTION_LTR}, + * {@link #TEXT_DIRECTION_RTL}, + * {@link #TEXT_DIRECTION_LOCALE}, + * + */ + public int getResolvedTextDirection() { + if (mResolvedTextDirection == TEXT_DIRECTION_INHERIT) { + resolveTextDirection(); + } + return mResolvedTextDirection; + } + /** + * Resolve the text direction. + * + */ + protected void resolveTextDirection() { + if (mTextDirection != TEXT_DIRECTION_INHERIT) { + mResolvedTextDirection = mTextDirection; + return; + } + if (mParent != null && mParent instanceof ViewGroup) { + mResolvedTextDirection = ((ViewGroup) mParent).getResolvedTextDirection(); + return; + } + mResolvedTextDirection = TEXT_DIRECTION_FIRST_STRONG; + } + /** + * Reset resolved text direction. Will be resolved during a call to getResolvedTextDirection(). + * + */ + protected void resetResolvedTextDirection() { + mResolvedTextDirection = TEXT_DIRECTION_INHERIT; + } + // + // Properties + // + /** + * A Property wrapper around the alpha functionality handled by the + * {@link View#setAlpha(float)} and {@link View#getAlpha()} methods. + */ + public static final Property ALPHA = new FloatProperty("alpha") { + @Override + public void setValue(View object, float value) { + object.setAlpha(value); + } + @Override + public Float get(View object) { + return object.getAlpha(); + } + }; + /** + * A Property wrapper around the translationX functionality handled by the + * {@link View#setTranslationX(float)} and {@link View#getTranslationX()} methods. + */ + public static final Property TRANSLATION_X = new FloatProperty("translationX") { + @Override + public void setValue(View object, float value) { + object.setTranslationX(value); + } + @Override + public Float get(View object) { + return object.getTranslationX(); + } + }; + /** + * A Property wrapper around the translationY functionality handled by the + * {@link View#setTranslationY(float)} and {@link View#getTranslationY()} methods. + */ + public static final Property TRANSLATION_Y = new FloatProperty("translationY") { + @Override + public void setValue(View object, float value) { + object.setTranslationY(value); + } + @Override + public Float get(View object) { + return object.getTranslationY(); + } + }; + /** + * A Property wrapper around the x functionality handled by the + * {@link View#setX(float)} and {@link View#getX()} methods. + */ + public static final Property X = new FloatProperty("x") { + @Override + public void setValue(View object, float value) { + object.setX(value); + } + @Override + public Float get(View object) { + return object.getX(); + } + }; + /** + * A Property wrapper around the y functionality handled by the + * {@link View#setY(float)} and {@link View#getY()} methods. + */ + public static final Property Y = new FloatProperty("y") { + @Override + public void setValue(View object, float value) { + object.setY(value); + } + @Override + public Float get(View object) { + return object.getY(); + } + }; + /** + * A Property wrapper around the rotation functionality handled by the + * {@link View#setRotation(float)} and {@link View#getRotation()} methods. + */ + public static final Property ROTATION = new FloatProperty("rotation") { + @Override + public void setValue(View object, float value) { + object.setRotation(value); + } + @Override + public Float get(View object) { + return object.getRotation(); + } + }; + /** + * A Property wrapper around the rotationX functionality handled by the + * {@link View#setRotationX(float)} and {@link View#getRotationX()} methods. + */ + public static final Property ROTATION_X = new FloatProperty("rotationX") { + @Override + public void setValue(View object, float value) { + object.setRotationX(value); + } + @Override + public Float get(View object) { + return object.getRotationX(); + } + }; + /** + * A Property wrapper around the rotationY functionality handled by the + * {@link View#setRotationY(float)} and {@link View#getRotationY()} methods. + */ + public static final Property ROTATION_Y = new FloatProperty("rotationY") { + @Override + public void setValue(View object, float value) { + object.setRotationY(value); + } + @Override + public Float get(View object) { + return object.getRotationY(); + } + }; + /** + * A Property wrapper around the scaleX functionality handled by the + * {@link View#setScaleX(float)} and {@link View#getScaleX()} methods. + */ + public static final Property SCALE_X = new FloatProperty("scaleX") { + @Override + public void setValue(View object, float value) { + object.setScaleX(value); + } + @Override + public Float get(View object) { + return object.getScaleX(); + } + }; + /** + * A Property wrapper around the scaleY functionality handled by the + * {@link View#setScaleY(float)} and {@link View#getScaleY()} methods. + */ + public static final Property SCALE_Y = new FloatProperty("scaleY") { + @Override + public void setValue(View object, float value) { + object.setScaleY(value); + } + @Override + public Float get(View object) { + return object.getScaleY(); + } + }; + /** + * A MeasureSpec encapsulates the layout requirements passed from parent to child. + * Each MeasureSpec represents a requirement for either the width or the height. + * A MeasureSpec is comprised of a size and a mode. There are three possible + * modes: + *
+ *
UNSPECIFIED
+ *
+ * The parent has not imposed any constraint on the child. It can be whatever size + * it wants. + *
+ * + *
EXACTLY
+ *
+ * The parent has determined an exact size for the child. The child is going to be + * given those bounds regardless of how big it wants to be. + *
+ * + *
AT_MOST
+ *
+ * The child can be as large as it wants up to the specified size. + *
+ *
+ * + * MeasureSpecs are implemented as ints to reduce object allocation. This class + * is provided to pack and unpack the <size, mode> tuple into the int. + */ + public static class MeasureSpec { + private static final int MODE_SHIFT = 30; + private static final int MODE_MASK = 0x3 << MODE_SHIFT; + /** + * Measure specification mode: The parent has not imposed any constraint + * on the child. It can be whatever size it wants. + */ + public static final int UNSPECIFIED = 0 << MODE_SHIFT; + /** + * Measure specification mode: The parent has determined an exact size + * for the child. The child is going to be given those bounds regardless + * of how big it wants to be. + */ + public static final int EXACTLY = 1 << MODE_SHIFT; + /** + * Measure specification mode: The child can be as large as it wants up + * to the specified size. + */ + public static final int AT_MOST = 2 << MODE_SHIFT; + /** + * Creates a measure specification based on the supplied size and mode. + * + * The mode must always be one of the following: + *
    + *
  • {@link android.view.View.MeasureSpec#UNSPECIFIED}
  • + *
  • {@link android.view.View.MeasureSpec#EXACTLY}
  • + *
  • {@link android.view.View.MeasureSpec#AT_MOST}
  • + *
+ * + * @param size the size of the measure specification + * @param mode the mode of the measure specification + * @return the measure specification based on size and mode + */ + public static int makeMeasureSpec(int size, int mode) { + return size + mode; + } + /** + * Extracts the mode from the supplied measure specification. + * + * @param measureSpec the measure specification to extract the mode from + * @return {@link android.view.View.MeasureSpec#UNSPECIFIED}, + * {@link android.view.View.MeasureSpec#AT_MOST} or + * {@link android.view.View.MeasureSpec#EXACTLY} + */ + public static int getMode(int measureSpec) { + return (measureSpec & MODE_MASK); + } + /** + * Extracts the size from the supplied measure specification. + * + * @param measureSpec the measure specification to extract the size from + * @return the size in pixels defined in the supplied measure specification + */ + public static int getSize(int measureSpec) { + return (measureSpec & ~MODE_MASK); + } + /** + * Returns a String representation of the specified measure + * specification. + * + * @param measureSpec the measure specification to convert to a String + * @return a String with the following format: "MeasureSpec: MODE SIZE" + */ + public static String toString(int measureSpec) { + int mode = getMode(measureSpec); + int size = getSize(measureSpec); + StringBuilder sb = new StringBuilder("MeasureSpec: "); + if (mode == UNSPECIFIED) + sb.append("UNSPECIFIED "); + else if (mode == EXACTLY) + sb.append("EXACTLY "); + else if (mode == AT_MOST) + sb.append("AT_MOST "); + else + sb.append(mode).append(" "); + sb.append(size); + return sb.toString(); + } + } + class CheckForLongPress implements Runnable { + private int mOriginalWindowAttachCount; + public void run() { + if (isPressed() && (mParent != null) + && mOriginalWindowAttachCount == mWindowAttachCount) { + if (performLongClick()) { + mHasPerformedLongPress = true; + } + } + } + public void rememberWindowAttachCount() { + mOriginalWindowAttachCount = mWindowAttachCount; + } + } + private final class CheckForTap implements Runnable { + public void run() { + mPrivateFlags &= ~PREPRESSED; + mPrivateFlags |= PRESSED; + refreshDrawableState(); + checkForLongClick(ViewConfiguration.getTapTimeout()); + } + } + private final class PerformClick implements Runnable { + public void run() { + performClick(); + } + } + /** @hide */ + public void hackTurnOffWindowResizeAnim(boolean off) { + mAttachInfo.mTurnOffWindowResizeAnim = off; + } + /** + * This method returns a ViewPropertyAnimator object, which can be used to animate + * specific properties on this View. + * + * @return ViewPropertyAnimator The ViewPropertyAnimator associated with this View. + */ + public ViewPropertyAnimator animate() { + if (mAnimator == null) { + mAnimator = new ViewPropertyAnimator(this); + } + return mAnimator; + } + /** + * Interface definition for a callback to be invoked when a key event is + * dispatched to this view. The callback will be invoked before the key + * event is given to the view. + */ + public interface OnKeyListener { + /** + * Called when a key is dispatched to a view. This allows listeners to + * get a chance to respond before the target view. + * + * @param v The view the key has been dispatched to. + * @param keyCode The code for the physical key that was pressed + * @param event The KeyEvent object containing full information about + * the event. + * @return True if the listener has consumed the event, false otherwise. + */ + boolean onKey(View v, int keyCode, KeyEvent event); + } + /** + * Interface definition for a callback to be invoked when a touch event is + * dispatched to this view. The callback will be invoked before the touch + * event is given to the view. + */ + public interface OnTouchListener { + /** + * Called when a touch event is dispatched to a view. This allows listeners to + * get a chance to respond before the target view. + * + * @param v The view the touch event has been dispatched to. + * @param event The MotionEvent object containing full information about + * the event. + * @return True if the listener has consumed the event, false otherwise. + */ + boolean onTouch(View v, MotionEvent event); + } + /** + * Interface definition for a callback to be invoked when a hover event is + * dispatched to this view. The callback will be invoked before the hover + * event is given to the view. + */ + public interface OnHoverListener { + /** + * Called when a hover event is dispatched to a view. This allows listeners to + * get a chance to respond before the target view. + * + * @param v The view the hover event has been dispatched to. + * @param event The MotionEvent object containing full information about + * the event. + * @return True if the listener has consumed the event, false otherwise. + */ + boolean onHover(View v, MotionEvent event); + } + /** + * Interface definition for a callback to be invoked when a generic motion event is + * dispatched to this view. The callback will be invoked before the generic motion + * event is given to the view. + */ + public interface OnGenericMotionListener { + /** + * Called when a generic motion event is dispatched to a view. This allows listeners to + * get a chance to respond before the target view. + * + * @param v The view the generic motion event has been dispatched to. + * @param event The MotionEvent object containing full information about + * the event. + * @return True if the listener has consumed the event, false otherwise. + */ + boolean onGenericMotion(View v, MotionEvent event); + } + /** + * Interface definition for a callback to be invoked when a view has been clicked and held. + */ + public interface OnLongClickListener { + /** + * Called when a view has been clicked and held. + * + * @param v The view that was clicked and held. + * + * @return true if the callback consumed the long click, false otherwise. + */ + boolean onLongClick(View v); + } + /** + * Interface definition for a callback to be invoked when a drag is being dispatched + * to this view. The callback will be invoked before the hosting view's own + * onDrag(event) method. If the listener wants to fall back to the hosting view's + * onDrag(event) behavior, it should return 'false' from this callback. + * + *
+ *

Developer Guides

+ *

For a guide to implementing drag and drop features, read the + * Drag and Drop developer guide.

+ *
+ */ + public interface OnDragListener { + /** + * Called when a drag event is dispatched to a view. This allows listeners + * to get a chance to override base View behavior. + * + * @param v The View that received the drag event. + * @param event The {@link android.view.DragEvent} object for the drag event. + * @return {@code true} if the drag event was handled successfully, or {@code false} + * if the drag event was not handled. Note that {@code false} will trigger the View + * to call its {@link #onDragEvent(DragEvent) onDragEvent()} handler. + */ + boolean onDrag(View v, DragEvent event); + } + /** + * Interface definition for a callback to be invoked when the focus state of + * a view changed. + */ + public interface OnFocusChangeListener { + /** + * Called when the focus state of a view has changed. + * + * @param v The view whose state has changed. + * @param hasFocus The new focus state of v. + */ + void onFocusChange(View v, boolean hasFocus); + } + /** + * Interface definition for a callback to be invoked when a view is clicked. + */ + public interface OnClickListener { + /** + * Called when a view has been clicked. + * + * @param v The view that was clicked. + */ + void onClick(View v); + } + /** + * Interface definition for a callback to be invoked when the context menu + * for this view is being built. + */ + public interface OnCreateContextMenuListener { + /** + * Called when the context menu for this view is being built. It is not + * safe to hold onto the menu after this method returns. + * + * @param menu The context menu that is being built + * @param v The view for which the context menu is being built + * @param menuInfo Extra information about the item for which the + * context menu should be shown. This information will vary + * depending on the class of v. + */ + void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo); + } + /** + * Interface definition for a callback to be invoked when the status bar changes + * visibility. This reports global changes to the system UI + * state, not just what the application is requesting. + * + * @see View#setOnSystemUiVisibilityChangeListener(android.view.View.OnSystemUiVisibilityChangeListener) + */ + public interface OnSystemUiVisibilityChangeListener { + /** + * Called when the status bar changes visibility because of a call to + * {@link View#setSystemUiVisibility(int)}. + * + * @param visibility Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE} or + * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}. This tells you the + * global state of the UI visibility flags, not what your + * app is currently applying. + */ + public void onSystemUiVisibilityChange(int visibility); + } + /** + * Interface definition for a callback to be invoked when this view is attached + * or detached from its window. + */ + public interface OnAttachStateChangeListener { + /** + * Called when the view is attached to a window. + * @param v The view that was attached + */ + public void onViewAttachedToWindow(View v); + /** + * Called when the view is detached from a window. + * @param v The view that was detached + */ + public void onViewDetachedFromWindow(View v); + } + private final class UnsetPressedState implements Runnable { + public void run() { + setPressed(false); + } + } + /** + * Base class for derived classes that want to save and restore their own + * state in {@link android.view.View#onSaveInstanceState()}. + */ + public static class BaseSavedState extends AbsSavedState { + /** + * Constructor used when reading from a parcel. Reads the state of the superclass. + * + * @param source + */ + public BaseSavedState(Parcel source) { + super(source); + } + /** + * Constructor called by derived classes when creating their SavedState objects + * + * @param superState The state of the superclass of this view + */ + public BaseSavedState(Parcelable superState) { + super(superState); + } + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + public BaseSavedState createFromParcel(Parcel in) { + return new BaseSavedState(in); + } + public BaseSavedState[] newArray(int size) { + return new BaseSavedState[size]; + } + }; + } + /** + * A set of information given to a view when it is attached to its parent + * window. + */ + static class AttachInfo { + interface Callbacks { + void playSoundEffect(int effectId); + boolean performHapticFeedback(int effectId, boolean always); + } + /** + * InvalidateInfo is used to post invalidate(int, int, int, int) messages + * to a Handler. This class contains the target (View) to invalidate and + * the coordinates of the dirty rectangle. + * + * For performance purposes, this class also implements a pool of up to + * POOL_LIMIT objects that get reused. This reduces memory allocations + * whenever possible. + */ + static class InvalidateInfo implements Poolable { + private static final int POOL_LIMIT = 10; + private static final Pool sPool = Pools.synchronizedPool( + Pools.finitePool(new PoolableManager() { + public InvalidateInfo newInstance() { + return new InvalidateInfo(); + } + public void onAcquired(InvalidateInfo element) { + } + public void onReleased(InvalidateInfo element) { + element.target = null; + } + }, POOL_LIMIT) + ); + private InvalidateInfo mNext; + private boolean mIsPooled; + View target; + int left; + int top; + int right; + int bottom; + public void setNextPoolable(InvalidateInfo element) { + mNext = element; + } + public InvalidateInfo getNextPoolable() { + return mNext; + } + static InvalidateInfo acquire() { + return sPool.acquire(); + } + void release() { + sPool.release(this); + } + public boolean isPooled() { + return mIsPooled; + } + public void setPooled(boolean isPooled) { + mIsPooled = isPooled; + } + } + final IWindowSession mSession; + final IWindow mWindow; + final IBinder mWindowToken; + final Callbacks mRootCallbacks; + HardwareCanvas mHardwareCanvas; + /** + * The top view of the hierarchy. + */ + View mRootView; + IBinder mPanelParentWindowToken; + Surface mSurface; + boolean mHardwareAccelerated; + boolean mHardwareAccelerationRequested; + HardwareRenderer mHardwareRenderer; + /** + * Scale factor used by the compatibility mode + */ + float mApplicationScale; + /** + * Indicates whether the application is in compatibility mode + */ + boolean mScalingRequired; + /** + * If set, ViewAncestor doesn't use its lame animation for when the window resizes. + */ + boolean mTurnOffWindowResizeAnim; + /** + * Left position of this view's window + */ + int mWindowLeft; + /** + * Top position of this view's window + */ + int mWindowTop; + /** + * Indicates whether views need to use 32-bit drawing caches + */ + boolean mUse32BitDrawingCache; + /** + * For windows that are full-screen but using insets to layout inside + * of the screen decorations, these are the current insets for the + * content of the window. + */ + final Rect mContentInsets = new Rect(); + /** + * For windows that are full-screen but using insets to layout inside + * of the screen decorations, these are the current insets for the + * actual visible parts of the window. + */ + final Rect mVisibleInsets = new Rect(); + /** + * The internal insets given by this window. This value is + * supplied by the client (through + * {@link ViewTreeObserver.OnComputeInternalInsetsListener}) and will + * be given to the window manager when changed to be used in laying + * out windows behind it. + */ + final ViewTreeObserver.InternalInsetsInfo mGivenInternalInsets + = new ViewTreeObserver.InternalInsetsInfo(); + /** + * All views in the window's hierarchy that serve as scroll containers, + * used to determine if the window can be resized or must be panned + * to adjust for a soft input area. + */ + final ArrayList mScrollContainers = new ArrayList(); + final KeyEvent.DispatcherState mKeyDispatchState + = new KeyEvent.DispatcherState(); + /** + * Indicates whether the view's window currently has the focus. + */ + boolean mHasWindowFocus; + /** + * The current visibility of the window. + */ + int mWindowVisibility; + /** + * Indicates the time at which drawing started to occur. + */ + long mDrawingTime; + /** + * Indicates whether or not ignoring the DIRTY_MASK flags. + */ + boolean mIgnoreDirtyState; + /** + * This flag tracks when the mIgnoreDirtyState flag is set during draw(), + * to avoid clearing that flag prematurely. + */ + boolean mSetIgnoreDirtyState = false; + /** + * Indicates whether the view's window is currently in touch mode. + */ + boolean mInTouchMode; + /** + * Indicates that ViewAncestor should trigger a global layout change + * the next time it performs a traversal + */ + boolean mRecomputeGlobalAttributes; + /** + * Always report new attributes at next traversal. + */ + boolean mForceReportNewAttributes; + /** + * Set during a traveral if any views want to keep the screen on. + */ + boolean mKeepScreenOn; + /** + * Bitwise-or of all of the values that views have passed to setSystemUiVisibility(). + */ + int mSystemUiVisibility; + /** + * True if a view in this hierarchy has an OnSystemUiVisibilityChangeListener + * attached. + */ + boolean mHasSystemUiListeners; + /** + * Set if the visibility of any views has changed. + */ + boolean mViewVisibilityChanged; + /** + * Set to true if a view has been scrolled. + */ + boolean mViewScrollChanged; + /** + * Global to the view hierarchy used as a temporary for dealing with + * x/y points in the transparent region computations. + */ + final int[] mTransparentLocation = new int[2]; + /** + * Global to the view hierarchy used as a temporary for dealing with + * x/y points in the ViewGroup.invalidateChild implementation. + */ + final int[] mInvalidateChildLocation = new int[2]; + /** + * Global to the view hierarchy used as a temporary for dealing with + * x/y location when view is transformed. + */ + final float[] mTmpTransformLocation = new float[2]; + /** + * The view tree observer used to dispatch global events like + * layout, pre-draw, touch mode change, etc. + */ + final ViewTreeObserver mTreeObserver = new ViewTreeObserver(); + /** + * A Canvas used by the view hierarchy to perform bitmap caching. + */ + Canvas mCanvas; + /** + * The view root impl. + */ + final ViewRootImpl mViewRootImpl; + /** + * A Handler supplied by a view's {@link android.view.ViewRootImpl}. This + * handler can be used to pump events in the UI events queue. + */ + final Handler mHandler; + /** + * Temporary for use in computing invalidate rectangles while + * calling up the hierarchy. + */ + final Rect mTmpInvalRect = new Rect(); + /** + * Temporary for use in computing hit areas with transformed views + */ + final RectF mTmpTransformRect = new RectF(); + /** + * Temporary list for use in collecting focusable descendents of a view. + */ + final ArrayList mFocusablesTempList = new ArrayList(24); + /** + * The id of the window for accessibility purposes. + */ + int mAccessibilityWindowId = View.NO_ID; + /** + * Creates a new set of attachment information with the specified + * events handler and thread. + * + * @param handler the events handler the view must use + */ + AttachInfo(IWindowSession session, IWindow window, + ViewRootImpl viewRootImpl, Handler handler, Callbacks effectPlayer) { + mSession = session; + mWindow = window; + mWindowToken = window.asBinder(); + mViewRootImpl = viewRootImpl; + mHandler = handler; + mRootCallbacks = effectPlayer; + } + } + /** + *

ScrollabilityCache holds various fields used by a View when scrolling + * is supported. This avoids keeping too many unused fields in most + * instances of View.

+ */ + private static class ScrollabilityCache implements Runnable { + /** + * Scrollbars are not visible + */ + public static final int OFF = 0; + /** + * Scrollbars are visible + */ + public static final int ON = 1; + /** + * Scrollbars are fading away + */ + public static final int FADING = 2; + public boolean fadeScrollBars; + public int fadingEdgeLength; + public int scrollBarDefaultDelayBeforeFade; + public int scrollBarFadeDuration; + public int scrollBarSize; + public ScrollBarDrawable scrollBar; + public float[] interpolatorValues; + public View host; + public final Paint paint; + public final Matrix matrix; + public Shader shader; + public final Interpolator scrollBarInterpolator = new Interpolator(1, 2); + private static final float[] OPAQUE = { 255 }; + private static final float[] TRANSPARENT = { 0.0f }; + /** + * When fading should start. This time moves into the future every time + * a new scroll happens. Measured based on SystemClock.uptimeMillis() + */ + public long fadeStartTime; + /** + * The current state of the scrollbars: ON, OFF, or FADING + */ + public int state = OFF; + private int mLastColor; + public ScrollabilityCache(ViewConfiguration configuration, View host) { + fadingEdgeLength = configuration.getScaledFadingEdgeLength(); + scrollBarSize = configuration.getScaledScrollBarSize(); + scrollBarDefaultDelayBeforeFade = ViewConfiguration.getScrollDefaultDelay(); + scrollBarFadeDuration = ViewConfiguration.getScrollBarFadeDuration(); + paint = new Paint(); + matrix = new Matrix(); + // use use a height of 1, and then wack the matrix each time we + // actually use it. + shader = new LinearGradient(0, 0, 0, 1, 0xFF000000, 0, Shader.TileMode.CLAMP); + paint.setShader(shader); + paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); + this.host = host; + } + public void setFadeColor(int color) { + if (color != 0 && color != mLastColor) { + mLastColor = color; + color |= 0xFF000000; + shader = new LinearGradient(0, 0, 0, 1, color | 0xFF000000, + color & 0x00FFFFFF, Shader.TileMode.CLAMP); + paint.setShader(shader); + // Restore the default transfer mode (src_over) + paint.setXfermode(null); + } + } + public void run() { + long now = AnimationUtils.currentAnimationTimeMillis(); + if (now >= fadeStartTime) { + // the animation fades the scrollbars out by changing + // the opacity (alpha) from fully opaque to fully + // transparent + int nextFrame = (int) now; + int framesCount = 0; + Interpolator interpolator = scrollBarInterpolator; + // Start opaque + interpolator.setKeyFrame(framesCount++, nextFrame, OPAQUE); + // End transparent + nextFrame += scrollBarFadeDuration; + interpolator.setKeyFrame(framesCount, nextFrame, TRANSPARENT); + state = FADING; + // Kick off the fade animation + host.invalidate(true); + } + } + } + /** + * Resuable callback for sending + * {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} accessibility event. + */ + private class SendViewScrolledAccessibilityEvent implements Runnable { + public volatile boolean mIsPending; + public void run() { + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SCROLLED); + mIsPending = false; + } + } + /** + *

+ * This class represents a delegate that can be registered in a {@link View} + * to enhance accessibility support via composition rather via inheritance. + * It is specifically targeted to widget developers that extend basic View + * classes i.e. classes in package android.view, that would like their + * applications to be backwards compatible. + *

+ *

+ * A scenario in which a developer would like to use an accessibility delegate + * is overriding a method introduced in a later API version then the minimal API + * version supported by the application. For example, the method + * {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} is not available + * in API version 4 when the accessibility APIs were first introduced. If a + * developer would like his application to run on API version 4 devices (assuming + * all other APIs used by the application are version 4 or lower) and take advantage + * of this method, instead of overriding the method which would break the application's + * backwards compatibility, he can override the corresponding method in this + * delegate and register the delegate in the target View if the API version of + * the system is high enough i.e. the API version is same or higher to the API + * version that introduced + * {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)}. + *

+ *

+ * Here is an example implementation: + *

+ *

+ * if (Build.VERSION.SDK_INT >= 14) { + * // If the API version is equal of higher than the version in + * // which onInitializeAccessibilityNodeInfo was introduced we + * // register a delegate with a customized implementation. + * View view = findViewById(R.id.view_id); + * view.setAccessibilityDelegate(new AccessibilityDelegate() { + * public void onInitializeAccessibilityNodeInfo(View host, + * AccessibilityNodeInfo info) { + * // Let the default implementation populate the info. + * super.onInitializeAccessibilityNodeInfo(host, info); + * // Set some other information. + * info.setEnabled(host.isEnabled()); + * } + * }); + * } + *

+ *

+ * This delegate contains methods that correspond to the accessibility methods + * in View. If a delegate has been specified the implementation in View hands + * off handling to the corresponding method in this delegate. The default + * implementation the delegate methods behaves exactly as the corresponding + * method in View for the case of no accessibility delegate been set. Hence, + * to customize the behavior of a View method, clients can override only the + * corresponding delegate method without altering the behavior of the rest + * accessibility related methods of the host view. + *

+ */ + public static class AccessibilityDelegate { + /** + * Sends an accessibility event of the given type. If accessibility is not + * enabled this method has no effect. + *

+ * The default implementation behaves as {@link View#sendAccessibilityEvent(int) + * View#sendAccessibilityEvent(int)} for the case of no accessibility delegate + * been set. + *

+ * + * @param host The View hosting the delegate. + * @param eventType The type of the event to send. + * + * @see View#sendAccessibilityEvent(int) View#sendAccessibilityEvent(int) + */ + public void sendAccessibilityEvent(View host, int eventType) { + host.sendAccessibilityEventInternal(eventType); + } + /** + * Sends an accessibility event. This method behaves exactly as + * {@link #sendAccessibilityEvent(View, int)} but takes as an argument an + * empty {@link AccessibilityEvent} and does not perform a check whether + * accessibility is enabled. + *

+ * The default implementation behaves as + * {@link View#sendAccessibilityEventUnchecked(AccessibilityEvent) + * View#sendAccessibilityEventUnchecked(AccessibilityEvent)} for + * the case of no accessibility delegate been set. + *

+ * + * @param host The View hosting the delegate. + * @param event The event to send. + * + * @see View#sendAccessibilityEventUnchecked(AccessibilityEvent) + * View#sendAccessibilityEventUnchecked(AccessibilityEvent) + */ + public void sendAccessibilityEventUnchecked(View host, AccessibilityEvent event) { + host.sendAccessibilityEventUncheckedInternal(event); + } + /** + * Dispatches an {@link AccessibilityEvent} to the host {@link View} first and then + * to its children for adding their text content to the event. + *

+ * The default implementation behaves as + * {@link View#dispatchPopulateAccessibilityEvent(AccessibilityEvent) + * View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)} for + * the case of no accessibility delegate been set. + *

+ * + * @param host The View hosting the delegate. + * @param event The event. + * @return True if the event population was completed. + * + * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent) + * View#dispatchPopulateAccessibilityEvent(AccessibilityEvent) + */ + public boolean dispatchPopulateAccessibilityEvent(View host, AccessibilityEvent event) { + return host.dispatchPopulateAccessibilityEventInternal(event); + } + /** + * Gives a chance to the host View to populate the accessibility event with its + * text content. + *

+ * The default implementation behaves as + * {@link View#onPopulateAccessibilityEvent(AccessibilityEvent) + * View#onPopulateAccessibilityEvent(AccessibilityEvent)} for + * the case of no accessibility delegate been set. + *

+ * + * @param host The View hosting the delegate. + * @param event The accessibility event which to populate. + * + * @see View#onPopulateAccessibilityEvent(AccessibilityEvent) + * View#onPopulateAccessibilityEvent(AccessibilityEvent) + */ + public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) { + host.onPopulateAccessibilityEventInternal(event); + } + /** + * Initializes an {@link AccessibilityEvent} with information about the + * the host View which is the event source. + *

+ * The default implementation behaves as + * {@link View#onInitializeAccessibilityEvent(AccessibilityEvent) + * View#onInitializeAccessibilityEvent(AccessibilityEvent)} for + * the case of no accessibility delegate been set. + *

+ * + * @param host The View hosting the delegate. + * @param event The event to initialize. + * + * @see View#onInitializeAccessibilityEvent(AccessibilityEvent) + * View#onInitializeAccessibilityEvent(AccessibilityEvent) + */ + public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) { + host.onInitializeAccessibilityEventInternal(event); + } + /** + * Initializes an {@link AccessibilityNodeInfo} with information about the host view. + *

+ * The default implementation behaves as + * {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo) + * View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} for + * the case of no accessibility delegate been set. + *

+ * + * @param host The View hosting the delegate. + * @param info The instance to initialize. + * + * @see View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo) + * View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo) + */ + public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { + host.onInitializeAccessibilityNodeInfoInternal(info); + } + /** + * Called when a child of the host View has requested sending an + * {@link AccessibilityEvent} and gives an opportunity to the parent (the host) + * to augment the event. + *

+ * The default implementation behaves as + * {@link ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent) + * ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)} for + * the case of no accessibility delegate been set. + *

+ * + * @param host The View hosting the delegate. + * @param child The child which requests sending the event. + * @param event The event to be sent. + * @return True if the event should be sent + * + * @see ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent) + * ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent) + */ + public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child, + AccessibilityEvent event) { + return host.onRequestSendAccessibilityEventInternal(child, event); + } + /** + * Gets the provider for managing a virtual view hierarchy rooted at this View + * and reported to {@link android.accessibilityservice.AccessibilityService}s + * that explore the window content. + *

+ * The default implementation behaves as + * {@link View#getAccessibilityNodeProvider() View#getAccessibilityNodeProvider()} for + * the case of no accessibility delegate been set. + *

+ * + * @return The provider. + * + * @see AccessibilityNodeProvider + */ + public AccessibilityNodeProvider getAccessibilityNodeProvider(View host) { + return null; + } + } +} diff --git a/src/test/TEST0.java b/src/test/TEST0.java index 1478984..f54e866 100644 --- a/src/test/TEST0.java +++ b/src/test/TEST0.java @@ -1,11 +1,13 @@ class Example { + private double x = 12.34; public int m1 = 5; public T m2; private static P1.P2.T m3; void message() { + double x = 12.34; а += 1; static int z; var f = 1;