1671 |
1671 |
1672 enum ParensResult { |
1672 enum ParensResult { |
1673 CAST, |
1673 CAST, |
1674 EXPLICIT_LAMBDA, |
1674 EXPLICIT_LAMBDA, |
1675 IMPLICIT_LAMBDA, |
1675 IMPLICIT_LAMBDA, |
|
1676 IMPLICIT_LAMBDA_ALL_VAR, |
|
1677 BAD_LAMBDA, |
1676 PARENS |
1678 PARENS |
1677 } |
1679 } |
1678 |
1680 |
1679 JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) { |
1681 JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) { |
1680 List<JCVariableDecl> params = explicitParams ? |
1682 List<JCVariableDecl> params = explicitParams ? |
1681 formalParameters(true) : |
1683 formalParameters(true) : |
1682 implicitParameters(hasParens); |
1684 implicitParameters(hasParens); |
1683 |
1685 |
|
1686 if (explicitParams) { |
|
1687 LambdaClassfier lambdaClassfier = new LambdaClassfier(); |
|
1688 for (JCVariableDecl param: params) { |
|
1689 if (param.vartype != null && |
|
1690 isRestrictedLocalVarTypeName(param.vartype) && |
|
1691 param.vartype.hasTag(TYPEARRAY)) { |
|
1692 log.error(DiagnosticFlag.SYNTAX, param.pos, Errors.VarNotAllowedArray); |
|
1693 } |
|
1694 if (param.vartype != null && param.name != names.empty) { |
|
1695 if (isRestrictedLocalVarTypeName(param.vartype)) { |
|
1696 lambdaClassfier.addImplicitVarParameter(); |
|
1697 } else { |
|
1698 lambdaClassfier.addExplicitParameter(); |
|
1699 } |
|
1700 } |
|
1701 if (param.vartype == null && param.name != names.empty || |
|
1702 param.vartype != null && param.name == names.empty) { |
|
1703 lambdaClassfier.addImplicitParameter(); |
|
1704 } |
|
1705 if (lambdaClassfier.result() == ParensResult.BAD_LAMBDA) { |
|
1706 break; |
|
1707 } |
|
1708 } |
|
1709 if (lambdaClassfier.diagFragment != null) { |
|
1710 log.error(DiagnosticFlag.SYNTAX, pos, Errors.InvalidLambdaParameterDeclaration(lambdaClassfier.diagFragment)); |
|
1711 } |
|
1712 } |
1684 return lambdaExpressionOrStatementRest(params, pos); |
1713 return lambdaExpressionOrStatementRest(params, pos); |
|
1714 } |
|
1715 |
|
1716 class LambdaClassfier { |
|
1717 ParensResult kind; //ParensResult.EXPLICIT_LAMBDA; |
|
1718 Fragment diagFragment; |
|
1719 List<JCVariableDecl> params; |
|
1720 |
|
1721 void addExplicitParameter() { |
|
1722 reduce(ParensResult.EXPLICIT_LAMBDA); |
|
1723 } |
|
1724 |
|
1725 void addImplicitVarParameter() { |
|
1726 reduce(ParensResult.IMPLICIT_LAMBDA_ALL_VAR); |
|
1727 } |
|
1728 |
|
1729 void addImplicitParameter() { |
|
1730 reduce(ParensResult.IMPLICIT_LAMBDA); |
|
1731 } |
|
1732 |
|
1733 private void reduce(ParensResult newKind) { |
|
1734 if (kind == null) { |
|
1735 kind = newKind; |
|
1736 } else if (kind != newKind && kind != ParensResult.BAD_LAMBDA) { |
|
1737 ParensResult currentKind = kind; |
|
1738 kind = ParensResult.BAD_LAMBDA; |
|
1739 switch (currentKind) { |
|
1740 case EXPLICIT_LAMBDA: |
|
1741 if (newKind == ParensResult.IMPLICIT_LAMBDA) { |
|
1742 diagFragment = Fragments.ImplicitAndExplicitNotAllowed; |
|
1743 } else if (newKind == ParensResult.IMPLICIT_LAMBDA_ALL_VAR) { |
|
1744 diagFragment = Fragments.VarAndExplicitNotAllowed; |
|
1745 } |
|
1746 break; |
|
1747 case IMPLICIT_LAMBDA: |
|
1748 if (newKind == ParensResult.EXPLICIT_LAMBDA) { |
|
1749 diagFragment = Fragments.ImplicitAndExplicitNotAllowed; |
|
1750 } else if (newKind == ParensResult.IMPLICIT_LAMBDA_ALL_VAR) { |
|
1751 diagFragment = Fragments.VarAndImplicitNotAllowed; |
|
1752 } |
|
1753 break; |
|
1754 case IMPLICIT_LAMBDA_ALL_VAR: |
|
1755 if (newKind == ParensResult.EXPLICIT_LAMBDA) { |
|
1756 diagFragment = Fragments.VarAndExplicitNotAllowed; |
|
1757 } else if (newKind == ParensResult.IMPLICIT_LAMBDA) { |
|
1758 diagFragment = Fragments.VarAndImplicitNotAllowed; |
|
1759 } |
|
1760 break; |
|
1761 default: |
|
1762 throw new AssertionError("unexpected option for field kind"); |
|
1763 } |
|
1764 } |
|
1765 } |
|
1766 |
|
1767 ParensResult result() { |
|
1768 return kind; |
|
1769 } |
1685 } |
1770 } |
1686 |
1771 |
1687 JCExpression lambdaExpressionOrStatementRest(List<JCVariableDecl> args, int pos) { |
1772 JCExpression lambdaExpressionOrStatementRest(List<JCVariableDecl> args, int pos) { |
1688 checkSourceLevel(Feature.LAMBDA); |
1773 checkSourceLevel(Feature.LAMBDA); |
1689 accept(ARROW); |
1774 accept(ARROW); |
3042 log.error(token.pos, Errors.ArrayAndReceiver); |
3127 log.error(token.pos, Errors.ArrayAndReceiver); |
3043 } |
3128 } |
3044 return toP(F.at(pos).ReceiverVarDef(mods, pn, type)); |
3129 return toP(F.at(pos).ReceiverVarDef(mods, pn, type)); |
3045 } |
3130 } |
3046 } else { |
3131 } else { |
3047 name = ident(); |
3132 if (!lambdaParameter || |
|
3133 LAX_IDENTIFIER.accepts(token.kind) || |
|
3134 mods.flags != Flags.PARAMETER || |
|
3135 mods.annotations.nonEmpty()) { |
|
3136 name = ident(); |
|
3137 } else { |
|
3138 /** if it is a lambda parameter and the token kind is not an identifier, |
|
3139 * and there are no modifiers or annotations, then this means that the compiler |
|
3140 * supposed the lambda to be explicit but it can contain a mix of implicit, |
|
3141 * var or explicit parameters. So we assign the error name to the parameter name |
|
3142 * instead of issuing an error and analyze the lambda parameters as a whole at |
|
3143 * a higher level. |
|
3144 */ |
|
3145 name = names.empty; |
|
3146 } |
3048 } |
3147 } |
3049 } |
3148 } |
3050 if ((mods.flags & Flags.VARARGS) != 0 && |
3149 if ((mods.flags & Flags.VARARGS) != 0 && |
3051 token.kind == LBRACKET) { |
3150 token.kind == LBRACKET) { |
3052 log.error(token.pos, Errors.VarargsAndOldArraySyntax); |
3151 log.error(token.pos, Errors.VarargsAndOldArraySyntax); |
3945 protected JCVariableDecl formalParameter(boolean lambdaParameter) { |
4044 protected JCVariableDecl formalParameter(boolean lambdaParameter) { |
3946 JCModifiers mods = optFinal(Flags.PARAMETER); |
4045 JCModifiers mods = optFinal(Flags.PARAMETER); |
3947 // need to distinguish between vararg annos and array annos |
4046 // need to distinguish between vararg annos and array annos |
3948 // look at typeAnnotationsPushedBack comment |
4047 // look at typeAnnotationsPushedBack comment |
3949 this.permitTypeAnnotationsPushBack = true; |
4048 this.permitTypeAnnotationsPushBack = true; |
3950 JCExpression type = parseType(); |
4049 JCExpression type = parseType(lambdaParameter); |
3951 this.permitTypeAnnotationsPushBack = false; |
4050 this.permitTypeAnnotationsPushBack = false; |
3952 |
4051 |
3953 if (token.kind == ELLIPSIS) { |
4052 if (token.kind == ELLIPSIS) { |
3954 List<JCAnnotation> varargsAnnos = typeAnnotationsPushedBack; |
4053 List<JCAnnotation> varargsAnnos = typeAnnotationsPushedBack; |
3955 typeAnnotationsPushedBack = List.nil(); |
4054 typeAnnotationsPushedBack = List.nil(); |