< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java

Print this page


   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) {


< prev index next >