1.1 --- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Fri Mar 25 15:17:52 2011 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Mar 29 16:40:07 2011 +0100 1.3 @@ -971,7 +971,7 @@ 1.4 if ((mode & EXPR) != 0) { 1.5 mode = EXPR; 1.6 S.nextToken(); 1.7 - if (S.token() == LT) typeArgs = typeArguments(); 1.8 + if (S.token() == LT) typeArgs = typeArguments(false); 1.9 t = creator(pos, typeArgs); 1.10 typeArgs = null; 1.11 } else return illegal(); 1.12 @@ -1036,7 +1036,7 @@ 1.13 mode = EXPR; 1.14 int pos1 = S.pos(); 1.15 S.nextToken(); 1.16 - if (S.token() == LT) typeArgs = typeArguments(); 1.17 + if (S.token() == LT) typeArgs = typeArguments(false); 1.18 t = innerCreator(pos1, typeArgs, t); 1.19 typeArgs = null; 1.20 break loop; 1.21 @@ -1116,7 +1116,7 @@ 1.22 mode = EXPR; 1.23 int pos2 = S.pos(); 1.24 S.nextToken(); 1.25 - if (S.token() == LT) typeArgs = typeArguments(); 1.26 + if (S.token() == LT) typeArgs = typeArguments(false); 1.27 t = innerCreator(pos2, typeArgs, t); 1.28 typeArgs = null; 1.29 } else { 1.30 @@ -1146,7 +1146,7 @@ 1.31 } else { 1.32 int pos = S.pos(); 1.33 accept(DOT); 1.34 - typeArgs = (S.token() == LT) ? typeArguments() : null; 1.35 + typeArgs = (S.token() == LT) ? typeArguments(false) : null; 1.36 t = toP(F.at(pos).Select(t, ident())); 1.37 t = argumentsOpt(typeArgs, t); 1.38 } 1.39 @@ -1206,7 +1206,7 @@ 1.40 (mode & NOPARAMS) == 0) { 1.41 mode = TYPE; 1.42 checkGenerics(); 1.43 - return typeArguments(t); 1.44 + return typeArguments(t, false); 1.45 } else { 1.46 return t; 1.47 } 1.48 @@ -1223,51 +1223,54 @@ 1.49 illegal(); 1.50 } 1.51 mode = useMode; 1.52 - return typeArguments(); 1.53 + return typeArguments(false); 1.54 } 1.55 return null; 1.56 } 1.57 1.58 /** TypeArguments = "<" TypeArgument {"," TypeArgument} ">" 1.59 */ 1.60 - List<JCExpression> typeArguments() { 1.61 - ListBuffer<JCExpression> args = lb(); 1.62 + List<JCExpression> typeArguments(boolean diamondAllowed) { 1.63 if (S.token() == LT) { 1.64 S.nextToken(); 1.65 - if (S.token() == GT && (mode & DIAMOND) != 0) { 1.66 + if (S.token() == GT && diamondAllowed) { 1.67 checkDiamond(); 1.68 + mode |= DIAMOND; 1.69 S.nextToken(); 1.70 return List.nil(); 1.71 - } 1.72 - args.append(((mode & EXPR) == 0) ? typeArgument() : parseType()); 1.73 - while (S.token() == COMMA) { 1.74 - S.nextToken(); 1.75 + } else { 1.76 + ListBuffer<JCExpression> args = ListBuffer.lb(); 1.77 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType()); 1.78 - } 1.79 - switch (S.token()) { 1.80 - case GTGTGTEQ: 1.81 - S.token(GTGTEQ); 1.82 - break; 1.83 - case GTGTEQ: 1.84 - S.token(GTEQ); 1.85 - break; 1.86 - case GTEQ: 1.87 - S.token(EQ); 1.88 - break; 1.89 - case GTGTGT: 1.90 - S.token(GTGT); 1.91 - break; 1.92 - case GTGT: 1.93 - S.token(GT); 1.94 - break; 1.95 - default: 1.96 - accept(GT); 1.97 - break; 1.98 + while (S.token() == COMMA) { 1.99 + S.nextToken(); 1.100 + args.append(((mode & EXPR) == 0) ? typeArgument() : parseType()); 1.101 + } 1.102 + switch (S.token()) { 1.103 + case GTGTGTEQ: 1.104 + S.token(GTGTEQ); 1.105 + break; 1.106 + case GTGTEQ: 1.107 + S.token(GTEQ); 1.108 + break; 1.109 + case GTEQ: 1.110 + S.token(EQ); 1.111 + break; 1.112 + case GTGTGT: 1.113 + S.token(GTGT); 1.114 + break; 1.115 + case GTGT: 1.116 + S.token(GT); 1.117 + break; 1.118 + default: 1.119 + accept(GT); 1.120 + break; 1.121 + } 1.122 + return args.toList(); 1.123 } 1.124 } else { 1.125 syntaxError(S.pos(), "expected", LT); 1.126 + return List.nil(); 1.127 } 1.128 - return args.toList(); 1.129 } 1.130 1.131 /** TypeArgument = Type 1.132 @@ -1303,9 +1306,9 @@ 1.133 } 1.134 } 1.135 1.136 - JCTypeApply typeArguments(JCExpression t) { 1.137 + JCTypeApply typeArguments(JCExpression t, boolean diamondAllowed) { 1.138 int pos = S.pos(); 1.139 - List<JCExpression> args = typeArguments(); 1.140 + List<JCExpression> args = typeArguments(diamondAllowed); 1.141 return toP(F.at(pos).TypeApply(t, args)); 1.142 } 1.143 1.144 @@ -1370,18 +1373,25 @@ 1.145 } 1.146 JCExpression t = qualident(); 1.147 int oldmode = mode; 1.148 - mode = TYPE | DIAMOND; 1.149 + mode = TYPE; 1.150 + boolean diamondFound = false; 1.151 if (S.token() == LT) { 1.152 checkGenerics(); 1.153 - t = typeArguments(t); 1.154 + t = typeArguments(t, true); 1.155 + diamondFound = (mode & DIAMOND) != 0; 1.156 } 1.157 while (S.token() == DOT) { 1.158 + if (diamondFound) { 1.159 + //cannot select after a diamond 1.160 + illegal(S.pos()); 1.161 + } 1.162 int pos = S.pos(); 1.163 S.nextToken(); 1.164 t = toP(F.at(pos).Select(t, ident())); 1.165 if (S.token() == LT) { 1.166 checkGenerics(); 1.167 - t = typeArguments(t); 1.168 + t = typeArguments(t, true); 1.169 + diamondFound = (mode & DIAMOND) != 0; 1.170 } 1.171 } 1.172 mode = oldmode; 1.173 @@ -1416,9 +1426,8 @@ 1.174 JCExpression t = toP(F.at(S.pos()).Ident(ident())); 1.175 if (S.token() == LT) { 1.176 int oldmode = mode; 1.177 - mode |= DIAMOND; 1.178 checkGenerics(); 1.179 - t = typeArguments(t); 1.180 + t = typeArguments(t, true); 1.181 mode = oldmode; 1.182 } 1.183 return classCreatorRest(newpos, encl, typeArgs, t);