1 /*
2 * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
744 }
745
746 public JCExpression parseType(boolean allowVar) {
747 List<JCAnnotation> annotations = typeAnnotationsOpt();
748 return parseType(allowVar, annotations);
749 }
750
751 public JCExpression parseType(boolean allowVar, List<JCAnnotation> annotations) {
752 JCExpression result = unannotatedType(allowVar);
753
754 if (annotations.nonEmpty()) {
755 result = insertAnnotationsToMostInner(result, annotations, false);
756 }
757
758 return result;
759 }
760
761 public JCExpression unannotatedType(boolean allowVar) {
762 JCExpression result = term(TYPE);
763
764 if (!allowVar && isRestrictedLocalVarTypeName(result)) {
765 syntaxError(result.pos, "var.not.allowed.here");
766 }
767
768 return result;
769 }
770
771
772
773 protected JCExpression term(int newmode) {
774 int prevmode = mode;
775 mode = newmode;
776 JCExpression t = term();
777 lastmode = mode;
778 mode = prevmode;
779 return t;
780 }
781
782 /**
783 * {@literal
784 * Expression = Expression1 [ExpressionRest]
2938 boolean localDecl)
2939 {
2940 return variableDeclaratorsRest(token.pos, mods, type, ident(), false, null, vdefs, localDecl);
2941 }
2942
2943 /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
2944 * ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
2945 *
2946 * @param reqInit Is an initializer always required?
2947 * @param dc The documentation comment for the variable declarations, or null.
2948 */
2949 protected <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos,
2950 JCModifiers mods,
2951 JCExpression type,
2952 Name name,
2953 boolean reqInit,
2954 Comment dc,
2955 T vdefs,
2956 boolean localDecl)
2957 {
2958 JCVariableDecl head = variableDeclaratorRest(pos, mods, type, name, reqInit, dc, localDecl);
2959 boolean implicit = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && head.vartype == null;
2960 vdefs.append(head);
2961 while (token.kind == COMMA) {
2962 if (implicit) {
2963 reportSyntaxError(pos, "var.not.allowed.compound");
2964 }
2965 // All but last of multiple declarators subsume a comma
2966 storeEnd((JCTree)vdefs.last(), token.endPos);
2967 nextToken();
2968 vdefs.append(variableDeclarator(mods, type, reqInit, dc, localDecl));
2969 }
2970 return vdefs;
2971 }
2972
2973 /** VariableDeclarator = Ident VariableDeclaratorRest
2974 * ConstantDeclarator = Ident ConstantDeclaratorRest
2975 */
2976 JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, Comment dc, boolean localDecl) {
2977 return variableDeclaratorRest(token.pos, mods, type, ident(), reqInit, dc, localDecl);
2979
2980 /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
2981 * ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
2982 *
2983 * @param reqInit Is an initializer always required?
2984 * @param dc The documentation comment for the variable declarations, or null.
2985 */
2986 JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
2987 boolean reqInit, Comment dc, boolean localDecl) {
2988 type = bracketsOpt(type);
2989 JCExpression init = null;
2990 if (token.kind == EQ) {
2991 nextToken();
2992 init = variableInitializer();
2993 }
2994 else if (reqInit) syntaxError(token.pos, "expected", EQ);
2995 JCTree elemType = TreeInfo.innermostType(type, true);
2996 int startPos = Position.NOPOS;
2997 if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && elemType.hasTag(IDENT)) {
2998 Name typeName = ((JCIdent)elemType).name;
2999 if (isRestrictedLocalVarTypeName(typeName)) {
3000 if (type.hasTag(TYPEARRAY)) {
3001 //error - 'var' and arrays
3002 reportSyntaxError(pos, "var.not.allowed.array");
3003 } else {
3004 startPos = TreeInfo.getStartPos(mods);
3005 if (startPos == Position.NOPOS)
3006 startPos = TreeInfo.getStartPos(type);
3007 //implicit type
3008 type = null;
3009 }
3010 }
3011 }
3012 JCVariableDecl result =
3013 toP(F.at(pos).VarDef(mods, name, type, init));
3014 attach(result, dc);
3015 result.startPos = startPos;
3016 return result;
3017 }
3018
3019 boolean isRestrictedLocalVarTypeName(JCExpression e) {
3020 switch (e.getTag()) {
3021 case IDENT:
3022 return isRestrictedLocalVarTypeName(((JCIdent)e).name);
3023 case TYPEARRAY:
3024 return isRestrictedLocalVarTypeName(((JCArrayTypeTree)e).elemtype);
3025 default:
3026 return false;
3027 }
3028 }
3029
3030 boolean isRestrictedLocalVarTypeName(Name name) {
3031 return Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && name == names.var;
3032 }
3033
3034 /** VariableDeclaratorId = Ident BracketsOpt
3035 */
3036 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
3037 return variableDeclaratorId(mods, type, false);
3038 }
3039 //where
3040 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean lambdaParameter) {
3041 int pos = token.pos;
3042 Name name;
3043 if (lambdaParameter && token.kind == UNDERSCORE) {
3044 log.error(pos, Errors.UnderscoreAsIdentifierInLambda);
3045 name = token.name();
3046 nextToken();
3047 } else {
3048 if (allowThisIdent && !lambdaParameter) {
3049 JCExpression pn = qualident(false);
3050 if (pn.hasTag(Tag.IDENT) && ((JCIdent)pn).name != names._this) {
3051 name = ((JCIdent)pn).name;
3386 JCExpression extending = null;
3387 if (token.kind == EXTENDS) {
3388 nextToken();
3389 extending = parseType();
3390 }
3391 List<JCExpression> implementing = List.nil();
3392 if (token.kind == IMPLEMENTS) {
3393 nextToken();
3394 implementing = typeList();
3395 }
3396 List<JCTree> defs = classOrInterfaceBody(name, false);
3397 JCClassDecl result = toP(F.at(pos).ClassDef(
3398 mods, name, typarams, extending, implementing, defs));
3399 attach(result, dc);
3400 return result;
3401 }
3402
3403 Name typeName() {
3404 int pos = token.pos;
3405 Name name = ident();
3406 if (isRestrictedLocalVarTypeName(name)) {
3407 reportSyntaxError(pos, "var.not.allowed", name);
3408 }
3409 return name;
3410 }
3411
3412 /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
3413 * [EXTENDS TypeList] InterfaceBody
3414 * @param mods The modifiers starting the interface declaration
3415 * @param dc The documentation comment for the interface, or null.
3416 */
3417 protected JCClassDecl interfaceDeclaration(JCModifiers mods, Comment dc) {
3418 int pos = token.pos;
3419 accept(INTERFACE);
3420
3421 Name name = typeName();
3422
3423 List<JCTypeParameter> typarams = typeParametersOpt();
3424
3425 List<JCExpression> extending = List.nil();
3426 if (token.kind == EXTENDS) {
|
1 /*
2 * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
744 }
745
746 public JCExpression parseType(boolean allowVar) {
747 List<JCAnnotation> annotations = typeAnnotationsOpt();
748 return parseType(allowVar, annotations);
749 }
750
751 public JCExpression parseType(boolean allowVar, List<JCAnnotation> annotations) {
752 JCExpression result = unannotatedType(allowVar);
753
754 if (annotations.nonEmpty()) {
755 result = insertAnnotationsToMostInner(result, annotations, false);
756 }
757
758 return result;
759 }
760
761 public JCExpression unannotatedType(boolean allowVar) {
762 JCExpression result = term(TYPE);
763
764 if (isRestrictedLocalVarTypeName(result) && !allowVar) {
765 syntaxError(result.pos, "var.not.allowed.here");
766 }
767
768 return result;
769 }
770
771
772
773 protected JCExpression term(int newmode) {
774 int prevmode = mode;
775 mode = newmode;
776 JCExpression t = term();
777 lastmode = mode;
778 mode = prevmode;
779 return t;
780 }
781
782 /**
783 * {@literal
784 * Expression = Expression1 [ExpressionRest]
2938 boolean localDecl)
2939 {
2940 return variableDeclaratorsRest(token.pos, mods, type, ident(), false, null, vdefs, localDecl);
2941 }
2942
2943 /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
2944 * ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
2945 *
2946 * @param reqInit Is an initializer always required?
2947 * @param dc The documentation comment for the variable declarations, or null.
2948 */
2949 protected <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos,
2950 JCModifiers mods,
2951 JCExpression type,
2952 Name name,
2953 boolean reqInit,
2954 Comment dc,
2955 T vdefs,
2956 boolean localDecl)
2957 {
2958 JCTree elemType = TreeInfo.innermostType(type, true); // bracketsOpt needed?
2959 if (elemType.hasTag(IDENT)) {
2960 Name typeName = ((JCIdent)elemType).name;
2961 boolean typeNameVarCheck = isRestrictedLocalVarTypeName(typeName, elemType.pos);
2962 }
2963
2964 JCVariableDecl head = variableDeclaratorRest(pos, mods, type, name, reqInit, dc, localDecl);
2965 boolean implicit = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && head.vartype == null;
2966 vdefs.append(head);
2967 while (token.kind == COMMA) {
2968 if (implicit) {
2969 reportSyntaxError(pos, "var.not.allowed.compound");
2970 }
2971 // All but last of multiple declarators subsume a comma
2972 storeEnd((JCTree)vdefs.last(), token.endPos);
2973 nextToken();
2974 vdefs.append(variableDeclarator(mods, type, reqInit, dc, localDecl));
2975 }
2976 return vdefs;
2977 }
2978
2979 /** VariableDeclarator = Ident VariableDeclaratorRest
2980 * ConstantDeclarator = Ident ConstantDeclaratorRest
2981 */
2982 JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, Comment dc, boolean localDecl) {
2983 return variableDeclaratorRest(token.pos, mods, type, ident(), reqInit, dc, localDecl);
2985
2986 /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
2987 * ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
2988 *
2989 * @param reqInit Is an initializer always required?
2990 * @param dc The documentation comment for the variable declarations, or null.
2991 */
2992 JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
2993 boolean reqInit, Comment dc, boolean localDecl) {
2994 type = bracketsOpt(type);
2995 JCExpression init = null;
2996 if (token.kind == EQ) {
2997 nextToken();
2998 init = variableInitializer();
2999 }
3000 else if (reqInit) syntaxError(token.pos, "expected", EQ);
3001 JCTree elemType = TreeInfo.innermostType(type, true);
3002 int startPos = Position.NOPOS;
3003 if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && elemType.hasTag(IDENT)) {
3004 Name typeName = ((JCIdent)elemType).name;
3005 if (isRestrictedLocalVarTypeName(typeName, elemType.pos)) {
3006 if (type.hasTag(TYPEARRAY)) {
3007 //error - 'var' and arrays
3008 reportSyntaxError(pos, "var.not.allowed.array");
3009 } else {
3010 startPos = TreeInfo.getStartPos(mods);
3011 if (startPos == Position.NOPOS)
3012 startPos = TreeInfo.getStartPos(type);
3013 //implicit type
3014 type = null;
3015 }
3016 }
3017 }
3018 JCVariableDecl result =
3019 toP(F.at(pos).VarDef(mods, name, type, init));
3020 attach(result, dc);
3021 result.startPos = startPos;
3022 return result;
3023 }
3024
3025 boolean isRestrictedLocalVarTypeName(JCExpression e) {
3026 switch (e.getTag()) {
3027 case IDENT:
3028 return isRestrictedLocalVarTypeName(((JCIdent)e).name, e.pos);
3029 case TYPEARRAY:
3030 return isRestrictedLocalVarTypeName(((JCArrayTypeTree)e).elemtype);
3031 default:
3032 return false;
3033 }
3034 }
3035
3036 boolean isRestrictedLocalVarTypeName(Name name, int pos) {
3037 if (name == names.var) {
3038 if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3039 return true;
3040 } else {
3041 warning(pos, "var.not.allowed", name);
3042 }
3043 }
3044 return false;
3045 }
3046
3047 /** VariableDeclaratorId = Ident BracketsOpt
3048 */
3049 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
3050 return variableDeclaratorId(mods, type, false);
3051 }
3052 //where
3053 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean lambdaParameter) {
3054 int pos = token.pos;
3055 Name name;
3056 if (lambdaParameter && token.kind == UNDERSCORE) {
3057 log.error(pos, Errors.UnderscoreAsIdentifierInLambda);
3058 name = token.name();
3059 nextToken();
3060 } else {
3061 if (allowThisIdent && !lambdaParameter) {
3062 JCExpression pn = qualident(false);
3063 if (pn.hasTag(Tag.IDENT) && ((JCIdent)pn).name != names._this) {
3064 name = ((JCIdent)pn).name;
3399 JCExpression extending = null;
3400 if (token.kind == EXTENDS) {
3401 nextToken();
3402 extending = parseType();
3403 }
3404 List<JCExpression> implementing = List.nil();
3405 if (token.kind == IMPLEMENTS) {
3406 nextToken();
3407 implementing = typeList();
3408 }
3409 List<JCTree> defs = classOrInterfaceBody(name, false);
3410 JCClassDecl result = toP(F.at(pos).ClassDef(
3411 mods, name, typarams, extending, implementing, defs));
3412 attach(result, dc);
3413 return result;
3414 }
3415
3416 Name typeName() {
3417 int pos = token.pos;
3418 Name name = ident();
3419 if (isRestrictedLocalVarTypeName(name, pos)) {
3420 reportSyntaxError(pos, "var.not.allowed", name);
3421 }
3422 return name;
3423 }
3424
3425 /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
3426 * [EXTENDS TypeList] InterfaceBody
3427 * @param mods The modifiers starting the interface declaration
3428 * @param dc The documentation comment for the interface, or null.
3429 */
3430 protected JCClassDecl interfaceDeclaration(JCModifiers mods, Comment dc) {
3431 int pos = token.pos;
3432 accept(INTERFACE);
3433
3434 Name name = typeName();
3435
3436 List<JCTypeParameter> typarams = typeParametersOpt();
3437
3438 List<JCExpression> extending = List.nil();
3439 if (token.kind == EXTENDS) {
|