|
22 | 22 | import org.codehaus.groovy.GroovyBugError; |
23 | 23 | import org.codehaus.groovy.ast.ClassHelper; |
24 | 24 | import org.codehaus.groovy.ast.ClassNode; |
25 | | -import org.codehaus.groovy.ast.ConstructorNode; |
26 | | -import org.codehaus.groovy.ast.MethodNode; |
27 | 25 | import org.codehaus.groovy.ast.Variable; |
28 | 26 | import org.codehaus.groovy.ast.expr.CastExpression; |
29 | 27 | import org.codehaus.groovy.ast.expr.ConstantExpression; |
@@ -313,36 +311,40 @@ public void doAsType(final ClassNode targetType) { |
313 | 311 | doConvertAndCast(targetType,true); |
314 | 312 | } |
315 | 313 |
|
316 | | - private void throwExceptionForNoStackElement(final int size, final ClassNode targetType, final boolean coerce) { |
317 | | - if (size > 0) return; |
318 | | - StringBuilder sb = new StringBuilder(); |
319 | | - sb.append("Internal compiler error while compiling ").append(controller.getSourceUnit().getName()).append("\n"); |
320 | | - MethodNode methodNode = controller.getMethodNode(); |
321 | | - if (methodNode!=null) { |
322 | | - sb.append("Method: "); |
323 | | - sb.append(methodNode); |
324 | | - sb.append("\n"); |
325 | | - } |
326 | | - ConstructorNode constructorNode = controller.getConstructorNode(); |
327 | | - if (constructorNode!=null) { |
| 314 | + private String missingOperand(final ClassNode targetType, final boolean coerce) { |
| 315 | + var sb = new StringBuilder("Internal compiler error while compiling "); |
| 316 | + sb.append(controller.getSourceUnit().getName()); |
| 317 | + sb.append("\n"); |
| 318 | + var constructorNode = controller.getConstructorNode(); |
| 319 | + if (constructorNode != null) { |
328 | 320 | sb.append("Constructor: "); |
329 | | - sb.append(methodNode); |
| 321 | + sb.append(constructorNode); |
330 | 322 | sb.append("\n"); |
| 323 | + } else { |
| 324 | + var methodNode = controller.getMethodNode(); |
| 325 | + if (methodNode != null) { |
| 326 | + sb.append("Method: "); |
| 327 | + sb.append(methodNode); |
| 328 | + sb.append("\n"); |
| 329 | + } |
331 | 330 | } |
332 | | - sb.append("Line ").append(controller.getLineNumber()).append(","); |
333 | | - sb.append(" expecting ").append(coerce ? "coercion" : "casting").append(" to ").append(targetType.toString(false)); |
| 331 | + sb.append("Line ").append(controller.getLineNumber()).append(", expecting ").append(coerce ? "coercion" : "casting"); |
| 332 | + sb.append(" to ").append(ClassNodeUtils.formatTypeName(targetType)); |
334 | 333 | sb.append(" but operand stack is empty"); |
335 | | - throw new ArrayIndexOutOfBoundsException(sb.toString()); |
| 334 | + return sb.toString(); |
336 | 335 | } |
337 | 336 |
|
338 | 337 | private void doConvertAndCast(ClassNode targetType, final boolean coerce) { |
339 | 338 | int size = stack.size(); |
340 | | - throwExceptionForNoStackElement(size, targetType, coerce); |
| 339 | + if (size == 0) { |
| 340 | + throw new ArrayIndexOutOfBoundsException(missingOperand(targetType, coerce)); |
| 341 | + } |
341 | 342 |
|
342 | 343 | ClassNode top = stack.get(size - 1); |
343 | | - targetType = targetType.redirect(); |
344 | | - if (top == targetType /* for better performance */ |
345 | | - || ClassNodeUtils.isCompatibleWith(top, targetType)) return; |
| 344 | + if (top == (targetType = targetType.redirect()) // quick check |
| 345 | + || ClassNodeUtils.isCompatibleWith(top, targetType)) { |
| 346 | + return; |
| 347 | + } |
346 | 348 |
|
347 | 349 | if (coerce) { |
348 | 350 | controller.getInvocationWriter().coerce(top, targetType); |
|
0 commit comments