< prev index next >

src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java

Print this page


   1 /*
   2  * Copyright (c) 2014, 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


  42 import static com.sun.tools.javac.parser.Tokens.TokenKind.INTERFACE;
  43 import static com.sun.tools.javac.parser.Tokens.TokenKind.LPAREN;
  44 import static com.sun.tools.javac.parser.Tokens.TokenKind.MONKEYS_AT;
  45 import static com.sun.tools.javac.parser.Tokens.TokenKind.SEMI;
  46 import static com.sun.tools.javac.parser.Tokens.TokenKind.VOID;
  47 import com.sun.tools.javac.tree.JCTree;
  48 import com.sun.tools.javac.tree.JCTree.JCAnnotation;
  49 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
  50 import com.sun.tools.javac.tree.JCTree.JCExpression;
  51 import com.sun.tools.javac.tree.JCTree.JCExpressionStatement;
  52 import com.sun.tools.javac.tree.JCTree.JCModifiers;
  53 import com.sun.tools.javac.tree.JCTree.JCStatement;
  54 import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
  55 import com.sun.tools.javac.tree.JCTree.Tag;
  56 import static com.sun.tools.javac.tree.JCTree.Tag.IDENT;
  57 import com.sun.tools.javac.util.List;
  58 import com.sun.tools.javac.util.ListBuffer;
  59 import com.sun.tools.javac.util.Name;
  60 import com.sun.tools.javac.util.Position;
  61 

  62 /**
  63  * This is a subclass of JavacParser which overrides one method with a modified
  64  * verson of that method designed to allow parsing of one "snippet" of Java
  65  * code without the surrounding context of class, method, etc.
  66  * Accepts an expression, a statement, an import, or the declaration of a
  67  * method, variable, or type (class, interface, ...).
  68  */
  69 class ReplParser extends JavacParser {
  70 
  71     // force starting in expression mode
  72     private final boolean forceExpression;
  73 
  74     public ReplParser(ParserFactory fac,
  75             com.sun.tools.javac.parser.Lexer S,
  76             boolean keepDocComments,
  77             boolean keepLineMap,
  78             boolean keepEndPositions,
  79             boolean forceExpression) {
  80         super(fac, S, keepDocComments, keepLineMap, keepEndPositions);
  81         this.forceExpression = forceExpression;


 161             case DO:
 162             case TRY:
 163             case RETURN:
 164             case THROW:
 165             case BREAK:
 166             case CONTINUE:
 167             case SEMI:
 168             case ELSE:
 169             case FINALLY:
 170             case CATCH:
 171             case ASSERT:
 172                 return List.<JCTree>of(parseStatement());
 173             case SYNCHRONIZED:
 174                 if (peekToken(LPAREN)) {
 175                     return List.<JCTree>of(parseStatement());
 176                 }
 177                 //fall-through
 178             default:
 179                 JCModifiers mods = modifiersOpt(pmods);
 180                 if (token.kind == CLASS

 181                         || token.kind == INTERFACE
 182                         || token.kind == ENUM) {
 183                     return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc));
 184                 } else {
 185                     int pos = token.pos;
 186                     List<JCTypeParameter> typarams = typeParametersOpt();
 187                     // if there are type parameters but no modifiers, save the start
 188                     // position of the method in the modifiers.
 189                     if (typarams.nonEmpty() && mods.pos == Position.NOPOS) {
 190                         mods.pos = pos;
 191                         storeEnd(mods, pos);
 192                     }
 193                     List<JCAnnotation> annosAfterParams = annotationsOpt(Tag.ANNOTATION);
 194 
 195                     if (annosAfterParams.nonEmpty()) {
 196                         checkSourceLevel(annosAfterParams.head.pos, Feature.ANNOTATIONS_AFTER_TYPE_PARAMS);
 197                         mods.annotations = mods.annotations.appendList(annosAfterParams);
 198                         if (mods.pos == Position.NOPOS) {
 199                             mods.pos = mods.annotations.head.pos;
 200                         }
 201                     }
 202 
 203                     Token prevToken = token;


 211                         // return type of method, declared type of variable, or an expression
 212                         // unless expression is being forced
 213                         t = term(forceExpression
 214                                 ? EXPR
 215                                 : EXPR | TYPE);
 216                     }
 217                     if (token.kind == COLON && t.hasTag(IDENT)) {
 218                         // labelled statement
 219                         nextToken();
 220                         JCStatement stat = parseStatement();
 221                         return List.<JCTree>of(F.at(pos).Labelled(prevToken.name(), stat));
 222                     } else if ((isVoid || (lastmode & TYPE) != 0) && LAX_IDENTIFIER.accepts(token.kind)) {
 223                         // we have "Type Ident", so we can assume it is variable or method declaration
 224                         pos = token.pos;
 225                         Name name = ident();
 226                         if (token.kind == LPAREN) {
 227                         // method declaration
 228                             //mods.flags |= Flags.STATIC;
 229                             return List.of(methodDeclaratorRest(
 230                                     pos, mods, t, name, typarams,
 231                                     false, isVoid, dc));
 232                         } else if (!isVoid && typarams.isEmpty()) {
 233                         // variable declaration
 234                             //mods.flags |= Flags.STATIC;
 235                             List<JCTree> defs
 236                                     = variableDeclaratorsRest(pos, mods, t, name, false, dc,
 237                                             new ListBuffer<JCTree>(), true).toList();
 238                             accept(SEMI);
 239                             storeEnd(defs.last(), S.prevToken().endPos);
 240                             return defs;
 241                         } else {
 242                             // malformed declaration, return error
 243                             pos = token.pos;
 244                             List<JCTree> err = isVoid
 245                                     ? List.of(toP(F.at(pos).MethodDef(mods, name, t, typarams,
 246                                                             List.nil(), List.nil(), null, null)))
 247                                     : null;
 248                             return List.<JCTree>of(syntaxError(token.pos, err, Errors.Expected(LPAREN)));
 249                         }
 250                     } else if (!typarams.isEmpty()) {
 251                         // type parameters on non-variable non-method -- error
   1 /*
   2  * Copyright (c) 2014, 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


  42 import static com.sun.tools.javac.parser.Tokens.TokenKind.INTERFACE;
  43 import static com.sun.tools.javac.parser.Tokens.TokenKind.LPAREN;
  44 import static com.sun.tools.javac.parser.Tokens.TokenKind.MONKEYS_AT;
  45 import static com.sun.tools.javac.parser.Tokens.TokenKind.SEMI;
  46 import static com.sun.tools.javac.parser.Tokens.TokenKind.VOID;
  47 import com.sun.tools.javac.tree.JCTree;
  48 import com.sun.tools.javac.tree.JCTree.JCAnnotation;
  49 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
  50 import com.sun.tools.javac.tree.JCTree.JCExpression;
  51 import com.sun.tools.javac.tree.JCTree.JCExpressionStatement;
  52 import com.sun.tools.javac.tree.JCTree.JCModifiers;
  53 import com.sun.tools.javac.tree.JCTree.JCStatement;
  54 import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
  55 import com.sun.tools.javac.tree.JCTree.Tag;
  56 import static com.sun.tools.javac.tree.JCTree.Tag.IDENT;
  57 import com.sun.tools.javac.util.List;
  58 import com.sun.tools.javac.util.ListBuffer;
  59 import com.sun.tools.javac.util.Name;
  60 import com.sun.tools.javac.util.Position;
  61 
  62 import static com.sun.tools.javac.parser.Tokens.TokenKind.IDENTIFIER;
  63 /**
  64  * This is a subclass of JavacParser which overrides one method with a modified
  65  * verson of that method designed to allow parsing of one "snippet" of Java
  66  * code without the surrounding context of class, method, etc.
  67  * Accepts an expression, a statement, an import, or the declaration of a
  68  * method, variable, or type (class, interface, ...).
  69  */
  70 class ReplParser extends JavacParser {
  71 
  72     // force starting in expression mode
  73     private final boolean forceExpression;
  74 
  75     public ReplParser(ParserFactory fac,
  76             com.sun.tools.javac.parser.Lexer S,
  77             boolean keepDocComments,
  78             boolean keepLineMap,
  79             boolean keepEndPositions,
  80             boolean forceExpression) {
  81         super(fac, S, keepDocComments, keepLineMap, keepEndPositions);
  82         this.forceExpression = forceExpression;


 162             case DO:
 163             case TRY:
 164             case RETURN:
 165             case THROW:
 166             case BREAK:
 167             case CONTINUE:
 168             case SEMI:
 169             case ELSE:
 170             case FINALLY:
 171             case CATCH:
 172             case ASSERT:
 173                 return List.<JCTree>of(parseStatement());
 174             case SYNCHRONIZED:
 175                 if (peekToken(LPAREN)) {
 176                     return List.<JCTree>of(parseStatement());
 177                 }
 178                 //fall-through
 179             default:
 180                 JCModifiers mods = modifiersOpt(pmods);
 181                 if (token.kind == CLASS
 182                         || token.kind == IDENTIFIER && token.name() == names.record
 183                         || token.kind == INTERFACE
 184                         || token.kind == ENUM) {
 185                     return List.<JCTree>of(classOrRecordOrInterfaceOrEnumDeclaration(mods, dc));
 186                 } else {
 187                     int pos = token.pos;
 188                     List<JCTypeParameter> typarams = typeParametersOpt();
 189                     // if there are type parameters but no modifiers, save the start
 190                     // position of the method in the modifiers.
 191                     if (typarams.nonEmpty() && mods.pos == Position.NOPOS) {
 192                         mods.pos = pos;
 193                         storeEnd(mods, pos);
 194                     }
 195                     List<JCAnnotation> annosAfterParams = annotationsOpt(Tag.ANNOTATION);
 196 
 197                     if (annosAfterParams.nonEmpty()) {
 198                         checkSourceLevel(annosAfterParams.head.pos, Feature.ANNOTATIONS_AFTER_TYPE_PARAMS);
 199                         mods.annotations = mods.annotations.appendList(annosAfterParams);
 200                         if (mods.pos == Position.NOPOS) {
 201                             mods.pos = mods.annotations.head.pos;
 202                         }
 203                     }
 204 
 205                     Token prevToken = token;


 213                         // return type of method, declared type of variable, or an expression
 214                         // unless expression is being forced
 215                         t = term(forceExpression
 216                                 ? EXPR
 217                                 : EXPR | TYPE);
 218                     }
 219                     if (token.kind == COLON && t.hasTag(IDENT)) {
 220                         // labelled statement
 221                         nextToken();
 222                         JCStatement stat = parseStatement();
 223                         return List.<JCTree>of(F.at(pos).Labelled(prevToken.name(), stat));
 224                     } else if ((isVoid || (lastmode & TYPE) != 0) && LAX_IDENTIFIER.accepts(token.kind)) {
 225                         // we have "Type Ident", so we can assume it is variable or method declaration
 226                         pos = token.pos;
 227                         Name name = ident();
 228                         if (token.kind == LPAREN) {
 229                         // method declaration
 230                             //mods.flags |= Flags.STATIC;
 231                             return List.of(methodDeclaratorRest(
 232                                     pos, mods, t, name, typarams,
 233                                     false, isVoid, false, dc));
 234                         } else if (!isVoid && typarams.isEmpty()) {
 235                         // variable declaration
 236                             //mods.flags |= Flags.STATIC;
 237                             List<JCTree> defs
 238                                     = variableDeclaratorsRest(pos, mods, t, name, false, dc,
 239                                             new ListBuffer<JCTree>(), true).toList();
 240                             accept(SEMI);
 241                             storeEnd(defs.last(), S.prevToken().endPos);
 242                             return defs;
 243                         } else {
 244                             // malformed declaration, return error
 245                             pos = token.pos;
 246                             List<JCTree> err = isVoid
 247                                     ? List.of(toP(F.at(pos).MethodDef(mods, name, t, typarams,
 248                                                             List.nil(), List.nil(), null, null)))
 249                                     : null;
 250                             return List.<JCTree>of(syntaxError(token.pos, err, Errors.Expected(LPAREN)));
 251                         }
 252                     } else if (!typarams.isEmpty()) {
 253                         // type parameters on non-variable non-method -- error
< prev index next >