001 /* Copyright (c) 2005-2008, Torbjorn Ekman 002 * All rights reserved. 003 * 004 * Redistribution and use in source and binary forms, with or without 005 * modification, are permitted provided that the following conditions are met: 006 * 007 * 1. Redistributions of source code must retain the above copyright notice, 008 * this list of conditions and the following disclaimer. 009 * 010 * 2. Redistributions in binary form must reproduce the above copyright notice, 011 * this list of conditions and the following disclaimer in the documentation 012 * and/or other materials provided with the distribution. 013 * 014 * 3. Neither the name of the copyright holder nor the names of its 015 * contributors may be used to endorse or promote products derived from this 016 * software without specific prior written permission. 017 * 018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 021 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 022 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 028 * POSSIBILITY OF SUCH DAMAGE. 029 */ 030 031 032 aspect TypeCheck { 033 public void ASTNode.typeCheck() { 034 } 035 036 syn boolean Expr.isVariable() = false; 037 eq AbstractDot.isVariable() = lastAccess().isVariable(); 038 eq VarAccess.isVariable() = true; 039 eq ArrayAccess.isVariable() = true; 040 eq ParExpr.isVariable() = getExpr().isVariable(); 041 042 // 5.2 043 public void VariableDeclaration.typeCheck() { 044 if (hasInit()) { 045 TypeDecl source = getInit().type(); 046 TypeDecl dest = type(); 047 if (!source.assignConversionTo(dest, getInit())) { 048 errorf("can not assign variable %s of type %s a value of type %s", 049 name(), dest.typeName(), source.typeName()); 050 } 051 } 052 } 053 054 // 5.2 055 public void FieldDeclaration.typeCheck() { 056 if (hasInit()) { 057 TypeDecl source = getInit().type(); 058 TypeDecl dest = type(); 059 if (!source.assignConversionTo(dest, getInit())) { 060 errorf("can not assign field %s of type %s a value of type %s", 061 name(), dest.typeName(), source.typeName()); 062 } 063 } 064 } 065 066 // 5.2 Assignment Conversion 067 public void AssignSimpleExpr.typeCheck() { 068 if (!getDest().isVariable()) { 069 error("left hand side is not a variable"); 070 } else if (!getSource().type().assignConversionTo(getDest().type(), getSource()) 071 && !getSource().type().isUnknown()) { 072 errorf("can not assign %s of type %s a value of type %s", 073 getDest().prettyPrint(), getDest().type().typeName(), getSource().type().typeName()); 074 } 075 } 076 077 public void AssignExpr.typeCheck() { 078 if (!getDest().isVariable()) { 079 error("left hand side is not a variable"); 080 } else { 081 TypeDecl source = getSource().type(); 082 TypeDecl dest = getDest().type(); 083 if (getSource().type().isPrimitive() && getDest().type().isPrimitive()) { 084 return; 085 } 086 errorf("can not assign %s of type %s a value of type %s", 087 getDest().prettyPrint(), getDest().type().typeName(), getSource().type().typeName()); 088 } 089 } 090 091 public void AssignMultiplicativeExpr.typeCheck() { 092 if (getSource().type().isBoolean() || getDest().type().isBoolean()) { 093 error("Multiplicative operators do not operate on boolean types"); 094 } 095 super.typeCheck(); 096 } 097 098 public void AssignPlusExpr.typeCheck() { 099 if (!getDest().isVariable()) { 100 error("left hand side is not a variable"); 101 } else if (getSource().type().isUnknown() || getDest().type().isUnknown()) { 102 return; 103 } else if (getDest().type().isString() && !(getSource().type().isVoid())) { 104 return; 105 } else if (getSource().type().isBoolean() || getDest().type().isBoolean()) { 106 error("Operator + does not operate on boolean types"); 107 } else if (getSource().type().isPrimitive() && getDest().type().isPrimitive()) { 108 return; 109 } else 110 errorf("can not assign %s of type %s a value of type %s", 111 getDest().prettyPrint(), getDest().type().typeName(), getSource().type().typeName()); 112 } 113 public void AssignMinusExpr.typeCheck() { 114 if (getSource().type().isBoolean() || getDest().type().isBoolean()) { 115 error("Operator - does not operate on boolean types"); 116 } 117 super.typeCheck(); 118 } 119 120 public void AssignShiftExpr.typeCheck() { 121 if (!getSource().type().isIntegralType() || !getDest().type().isIntegralType()) { 122 error("Shift operators only operate on integral types"); 123 } 124 super.typeCheck(); 125 } 126 127 public void AssignBitwiseExpr.typeCheck() { 128 TypeDecl source = getSource().type(); 129 TypeDecl dest = getDest().type(); 130 if (source.isIntegralType() && dest.isIntegralType()) { 131 super.typeCheck(); 132 } else if (source.isBoolean() && dest.isBoolean()) { 133 super.typeCheck(); 134 } else { 135 error("Operator only operates on integral and boolean types"); 136 } 137 } 138 139 // 5.3 Method Invocation Conversion 140 public void MethodAccess.typeCheck() { 141 for (int i = 0; i < getNumArg(); ++i) { 142 if (getArg(i).type().isVoid()) { 143 errorf("expression '%s' has type void and is not a valid method argument", 144 getArg(i).prettyPrint()); 145 } 146 } 147 for (int i = 0; i < decl().getNumParameter(); i++) { 148 TypeDecl exprType = getArg(i).type(); 149 TypeDecl parmType = decl().getParameter(i).type(); 150 if (!exprType.methodInvocationConversionTo(parmType) 151 && !exprType.isUnknown() && !parmType.isUnknown()) { 152 errorf("argument '%s' of type %s is not compatible with the method parameter type %s", 153 getArg(i).prettyPrint(), exprType.typeName(), parmType.typeName()); 154 } 155 } 156 } 157 158 // 15.13 159 public void ArrayAccess.typeCheck() { 160 if (isQualified() && !qualifier().type().isArrayDecl() && !qualifier().type().isUnknown()) { 161 errorf("the type %s of the indexed element is not an array", qualifier().type().name()); 162 } 163 if (!getExpr().type().unaryNumericPromotion().isInt() || !getExpr().type().isIntegralType()) { 164 errorf("array index must be int after unary numeric promotion which %s is not", 165 getExpr().type().typeName()); 166 } 167 } 168 169 public void ArrayInit.typeCheck() { 170 TypeDecl initializerType = declType().componentType(); 171 if (initializerType.isUnknown()) { 172 error("the dimension of the initializer is larger than the expected dimension"); 173 } 174 for (int i = 0; i < getNumInit(); i++) { 175 Expr e = getInit(i); 176 if (!e.type().assignConversionTo(initializerType, e)) { 177 errorf("the type %s of the initializer is not compatible with %s", 178 e.type().name(), initializerType.name()); 179 } 180 } 181 } 182 183 // 15.17 184 public void MultiplicativeExpr.typeCheck() { 185 if (!getLeftOperand().type().isNumericType()) { 186 errorf("%s is not numeric", getLeftOperand().type().typeName()); 187 } 188 if (!getRightOperand().type().isNumericType()) { 189 errorf("%s is not numeric", getRightOperand().type().typeName()); 190 } 191 } 192 193 // 15.18 194 public void AdditiveExpr.typeCheck() { 195 if (!getLeftOperand().type().isNumericType()) { 196 errorf("%s is not numeric", getLeftOperand().type().typeName()); 197 } 198 if (!getRightOperand().type().isNumericType()) { 199 errorf("%s is not numeric", getRightOperand().type().typeName()); 200 } 201 } 202 203 // 15.18 204 public void AddExpr.typeCheck() { 205 TypeDecl left = getLeftOperand().type(); 206 TypeDecl right = getRightOperand().type(); 207 if (!left.isString() && !right.isString()) { 208 super.typeCheck(); 209 } else if (left.isVoid()) { 210 error("The type void of the left hand side is not numeric"); 211 } else if (right.isVoid()) { 212 error("The type void of the right hand side is not numeric"); 213 } 214 } 215 216 // 15.19 217 public void ShiftExpr.typeCheck() { 218 if (!getLeftOperand().type().isIntegralType()) { 219 errorf("%s is not integral", getLeftOperand().type().typeName()); 220 } 221 if (!getRightOperand().type().isIntegralType()) { 222 errorf("%s is not integral", getRightOperand().type().typeName()); 223 } 224 } 225 226 // 15.22 227 public void BitwiseExpr.typeCheck() { 228 TypeDecl left = getLeftOperand().type(); 229 TypeDecl right = getRightOperand().type(); 230 if (left.isIntegralType() && right.isIntegralType()) { 231 return; 232 } else if (left.isBoolean() && right.isBoolean()) { 233 return; 234 } else { 235 errorf("%s is not compatible with %s", left.typeName(), right.typeName()); 236 } 237 } 238 239 // 15.20 240 public void RelationalExpr.typeCheck() { 241 if (!getLeftOperand().type().isNumericType()) { 242 errorf("%s is not numeric", getLeftOperand().type().typeName()); 243 } 244 if (!getRightOperand().type().isNumericType()) { 245 errorf("%s is not numeric", getRightOperand().type().typeName()); 246 } 247 } 248 249 // 15.23, 15.24 250 public void LogicalExpr.typeCheck() { 251 if (!getLeftOperand().type().isBoolean()) { 252 errorf("%s is not boolean", getLeftOperand().type().typeName()); 253 } 254 if (!getRightOperand().type().isBoolean()) { 255 errorf("%s is not boolean", getRightOperand().type().typeName()); 256 } 257 } 258 259 // 15.21 260 public void EqualityExpr.typeCheck() { 261 TypeDecl left = getLeftOperand().type(); 262 TypeDecl right = getRightOperand().type(); 263 if (left.isNumericType() && right.isNumericType()) { 264 return; 265 } else if (left.isBoolean() && right.isBoolean()) { 266 return; 267 } else if ((left.isReferenceType() || left.isNull()) && (right.isReferenceType() || right.isNull())) { 268 if (left.castingConversionTo(right) || right.castingConversionTo(left)) { 269 return; 270 } 271 } 272 errorf("%s can not be compared to %s", left.typeName(), right.typeName()); 273 } 274 275 // 15.20.2 276 public void InstanceOfExpr.typeCheck() { 277 TypeDecl relationalExpr = getExpr().type(); 278 TypeDecl referenceType = getTypeAccess().type(); 279 if (!relationalExpr.isUnknown()) { 280 if (!relationalExpr.isReferenceType() && !relationalExpr.isNull()) { 281 error("The relational expression in instance of must be reference or null type"); 282 } 283 if (!referenceType.isReferenceType()) { 284 error("The reference expression in instance of must be reference type"); 285 } 286 if (!relationalExpr.castingConversionTo(referenceType)) { 287 errorf("The type %s of the relational expression %s can not be cast into the type %s", 288 relationalExpr.typeName(), getExpr().prettyPrint(), referenceType.typeName()); 289 } 290 if (getExpr().isTypeAccess()) { 291 errorf("The relational expression %s must not be a type name", getExpr().prettyPrint()); 292 } 293 } 294 } 295 296 // 15.16 297 public void CastExpr.typeCheck() { 298 TypeDecl expr = getExpr().type(); 299 TypeDecl type = getTypeAccess().type(); 300 if (!expr.isUnknown()) { 301 if (!expr.castingConversionTo(type)) { 302 errorf("%s can not be cast into %s", expr.typeName(), type.typeName()); 303 } 304 if (!getTypeAccess().isTypeAccess()) { 305 errorf("%s is not a type access in cast expression", getTypeAccess().prettyPrint()); 306 } 307 } 308 } 309 310 public void ParExpr.typeCheck() { 311 if (getExpr().isTypeAccess()) { 312 errorf("%s is a type and may not be used in parenthesized expression", getExpr().prettyPrint()); 313 } 314 } 315 316 // 15.15.3 317 public void PlusExpr.typeCheck() { 318 if (!getOperand().type().isNumericType()) { 319 error("unary plus only operates on numeric types"); 320 } 321 } 322 323 // 15.15.4 324 public void MinusExpr.typeCheck() { 325 if (!getOperand().type().isNumericType()) { 326 error("unary minus only operates on numeric types"); 327 } 328 } 329 330 // 15.15.5 331 public void BitNotExpr.typeCheck() { 332 if (!getOperand().type().isIntegralType()) { 333 error("unary ~ only operates on integral types"); 334 } 335 } 336 337 // 15.15.6 338 public void LogNotExpr.typeCheck() { 339 if (!getOperand().type().isBoolean()) { 340 error("unary ! only operates on boolean types"); 341 } 342 } 343 344 // 15.14 345 public void PostfixExpr.typeCheck() { 346 if (!getOperand().isVariable()) { 347 error("postfix expressions only work on variables"); 348 } else if (!getOperand().type().isNumericType()) { 349 error("postfix expressions only operates on numeric types"); 350 } 351 } 352 353 // 15.15.1 354 public void PreIncExpr.typeCheck() { 355 if (!getOperand().isVariable()) { 356 error("prefix increment expression only work on variables"); 357 } else if (!getOperand().type().isNumericType()) { 358 error("unary increment only operates on numeric types"); 359 } 360 } 361 362 // 15.15.2 363 public void PreDecExpr.typeCheck() { 364 if (!getOperand().isVariable()) { 365 error("prefix decrement expression only work on variables"); 366 } else if (!getOperand().type().isNumericType()) { 367 error("unary decrement only operates on numeric types"); 368 } 369 } 370 371 public void IfStmt.typeCheck() { 372 TypeDecl cond = getCondition().type(); 373 if (!cond.isBoolean()) { 374 errorf("the type of \"%s\" is %s which is not boolean", 375 getCondition().prettyPrint(), cond.name()); 376 } 377 } 378 public void WhileStmt.typeCheck() { 379 TypeDecl cond = getCondition().type(); 380 if (!cond.isBoolean()) { 381 errorf("the type of \"%s\" is %s which is not boolean", 382 getCondition().prettyPrint(), cond.name()); 383 } 384 } 385 public void DoStmt.typeCheck() { 386 TypeDecl cond = getCondition().type(); 387 if (!cond.isBoolean()) { 388 errorf("the type of \"%s\" is %s which is not boolean", 389 getCondition().prettyPrint(), cond.name()); 390 } 391 } 392 public void ForStmt.typeCheck() { 393 if (hasCondition()) { 394 TypeDecl cond = getCondition().type(); 395 if (!cond.isBoolean()) { 396 errorf("the type of \"%s\" is %s which is not boolean", 397 getCondition().prettyPrint(), cond.name()); 398 } 399 } 400 } 401 402 public void SwitchStmt.typeCheck() { 403 TypeDecl type = getExpr().type(); 404 if (!type.isIntegralType() || type.isLong()) { 405 error("Switch expression must be of char, byte, short, or int"); 406 } 407 } 408 409 public void ConstCase.typeCheck() { 410 TypeDecl switchType = switchType(); 411 TypeDecl type = getValue().type(); 412 if (!type.assignConversionTo(switchType, getValue())) { 413 error("Constant expression must be assignable to Expression"); 414 } 415 if (!getValue().isConstant() && !getValue().type().isUnknown()) { 416 error("Switch expression must be constant"); 417 } 418 } 419 420 inh TypeDecl Case.switchType(); 421 eq SwitchStmt.getBlock().switchType() = getExpr().type(); 422 eq Program.getChild().switchType() = unknownType(); 423 424 public void SynchronizedStmt.typeCheck() { 425 TypeDecl type = getExpr().type(); 426 if (!type.isReferenceType() || type.isNull()) { 427 error("*** The type of the expression must be a reference"); 428 } 429 } 430 431 public void BasicCatch.typeCheck() { 432 if (!getParameter().type().instanceOf(typeThrowable())) { 433 error("*** The catch variable must extend Throwable"); 434 } 435 } 436 437 public void ThrowStmt.typeCheck() { 438 if (!getExpr().type().instanceOf(typeThrowable())) { 439 error("*** The thrown expression must extend Throwable"); 440 } 441 } 442 443 public void AssertStmt.typeCheck() { 444 // 14.10 445 if (!getCondition().type().isBoolean()) { 446 error("Assert requires boolean condition"); 447 } 448 if (hasMessage() && getMessage().type().isVoid()) { 449 error("The detail message of an assert statement may not be void"); 450 } 451 } 452 453 public void MethodDecl.typeCheck() { 454 // Thrown vs super class method see MethodDecl.nameCheck 455 // 8.4.4 456 TypeDecl exceptionType = typeThrowable(); 457 for (int i = 0; i < getNumException(); i++) { 458 TypeDecl typeDecl = getException(i).type(); 459 if (!typeDecl.instanceOf(exceptionType)) { 460 errorf("%s throws non throwable type %s", signature(), typeDecl.fullName()); 461 } 462 } 463 464 // check returns 465 if (!isVoid() && hasBlock() && getBlock().canCompleteNormally()) { 466 error("the body of a non void method may not complete normally"); 467 } 468 469 } 470 // 14.16 471 inh TypeDecl TypeDecl.typeVoid(); 472 inh TypeDecl ReturnStmt.returnType(); 473 eq TypeDecl.getBodyDecl().returnType() = typeVoid(); 474 eq MethodDecl.getBlock().returnType() = type(); 475 eq Program.getChild().returnType() = typeVoid(); 476 477 public void ReturnStmt.typeCheck() { 478 if (hasResult() && !returnType().isVoid()) { 479 if (!getResult().type().assignConversionTo(returnType(), getResult())) { 480 errorf("return value must be an instance of %s which %s is not", 481 returnType().typeName(), getResult().type().typeName()); 482 } 483 } 484 // 8.4.5 8.8.5 485 if (returnType().isVoid() && hasResult()) { 486 error("return stmt may not have an expression in void methods"); 487 } 488 // 8.4.5 489 if (!returnType().isVoid() && !hasResult()) { 490 error("return stmt must have an expression in non void methods"); 491 } 492 if (enclosingBodyDecl() instanceof InstanceInitializer || enclosingBodyDecl() instanceof StaticInitializer) { 493 error("Initializers may not return"); 494 } 495 496 } 497 498 public void ConstructorDecl.typeCheck() { 499 // 8.8.4 (8.4.4) 500 TypeDecl exceptionType = typeThrowable(); 501 for (int i = 0; i < getNumException(); i++) { 502 TypeDecl typeDecl = getException(i).type(); 503 if (!typeDecl.instanceOf(exceptionType)) { 504 errorf("%s throws non throwable type %s", signature(), typeDecl.fullName()); 505 } 506 } 507 } 508 509 public void ClassInstanceExpr.typeCheck() { 510 if (isQualified() && qualifier().isTypeAccess() && !qualifier().type().isUnknown()) { 511 error("*** The expression in a qualified class instance expr must not be a type name"); 512 } 513 // 15.9 514 if (isQualified() && !type().isInnerClass() && !((ClassDecl) type()).superclass().isInnerClass() && !type().isUnknown()) { 515 error("*** Qualified class instance creation can only instantiate inner classes and their anonymous subclasses"); 516 } 517 if (!type().isClassDecl()) { 518 errorf("*** Can only instantiate classes, which %s is not", type().typeName()); 519 } 520 typeCheckEnclosingInstance(); 521 typeCheckAnonymousSuperclassEnclosingInstance(); 522 } 523 524 public void ClassInstanceExpr.typeCheckEnclosingInstance() { 525 TypeDecl C = type(); 526 if (!C.isInnerClass()) { 527 return; 528 } 529 530 TypeDecl enclosing = null; 531 if (C.isAnonymous()) { 532 if (noEnclosingInstance()) { 533 enclosing = null; 534 } else { 535 enclosing = hostType(); 536 } 537 } else if (C.isLocalClass()) { 538 if (C.inStaticContext()) { 539 enclosing = null; 540 } else if (noEnclosingInstance()) { 541 enclosing = unknownType(); 542 } else { 543 TypeDecl nest = hostType(); 544 while (nest != null && !nest.instanceOf(C.enclosingType())) { 545 nest = nest.enclosingType(); 546 } 547 enclosing = nest; 548 } 549 } else if (C.isMemberType()) { 550 if (!isQualified()) { 551 if (noEnclosingInstance()) { 552 errorf("No enclosing instance to initialize %s with", C.typeName()); 553 //System.err.println("ClassInstanceExpr: Non qualified MemberType " + C.typeName() + " is in a static context when instantiated in " + this); 554 enclosing = unknownType(); 555 } else { 556 TypeDecl nest = hostType(); 557 while (nest != null && !nest.instanceOf(C.enclosingType())) { 558 if (nest.isStatic()) { 559 errorf("No enclosing instance to initialize %s with", C.typeName()); 560 nest = unknownType(); 561 break; 562 } 563 nest = nest.enclosingType(); 564 } 565 enclosing = nest == null ? unknownType() : nest; 566 } 567 } else { 568 enclosing = enclosingInstance(); 569 } 570 } 571 if (enclosing != null) { 572 if (enclosing.isUnknown()) { 573 errorf("No enclosing instance to initialize %s with", C.typeName()); 574 } else if (!enclosing.instanceOf(C.enclosingType())) { 575 errorf("*** Can not instantiate %s with the enclosing instance %s due to incorrect enclosing instance", 576 C.typeName(), enclosing.typeName()); 577 } else if (!isQualified() && C.isMemberType() && inExplicitConstructorInvocation() && enclosing == hostType()) { 578 errorf("*** The innermost enclosing instance of type %s is this which is not yet initialized here.", 579 enclosing.typeName()); 580 } 581 } 582 } 583 584 inh TypeDecl SuperConstructorAccess.enclosingInstance(); 585 inh TypeDecl ClassInstanceExpr.enclosingInstance(); 586 inh TypeDecl TypeDecl.enclosingInstance(); 587 eq Program.getChild().enclosingInstance() = null; 588 eq StaticInitializer.getBlock().enclosingInstance() = null; 589 //eq InstanceInitializer.getBlock().enclosingInstance() = null; 590 eq TypeDecl.getBodyDecl(int index).enclosingInstance() { 591 if (getBodyDecl(index) instanceof MemberTypeDecl && !((MemberTypeDecl) getBodyDecl(index)).typeDecl().isInnerType()) { 592 return null; 593 } 594 if (getBodyDecl(index) instanceof ConstructorDecl) { 595 return enclosingInstance(); 596 } 597 return this; 598 } 599 eq AbstractDot.getRight().enclosingInstance() = getLeft().type(); 600 eq ConstructorDecl.getParsedConstructorInvocation().enclosingInstance() = unknownType(); 601 eq ConstructorDecl.getImplicitConstructorInvocation().enclosingInstance() = unknownType(); 602 603 syn boolean ClassInstanceExpr.noEnclosingInstance() = 604 isQualified() ? qualifier().staticContextQualifier() : inStaticContext(); 605 606 public void ClassInstanceExpr.typeCheckAnonymousSuperclassEnclosingInstance() { 607 if (type().isAnonymous() && ((ClassDecl) type()).superclass().isInnerType()) { 608 TypeDecl S = ((ClassDecl) type()).superclass(); 609 if (S.isLocalClass()) { 610 if (S.inStaticContext()) { 611 } else if (noEnclosingInstance()) { 612 errorf("*** No enclosing instance to class %s due to static context", type().typeName()); 613 } else if (inExplicitConstructorInvocation()) { 614 errorf("*** No enclosing instance to superclass %s of %s since this is not initialized yet", 615 S.typeName(), type().typeName()); 616 } 617 } else if (S.isMemberType()) { 618 if (!isQualified()) { 619 // 15.9.2 2nd paragraph 620 if (noEnclosingInstance()) { 621 errorf("*** No enclosing instance to class %s due to static context", type().typeName()); 622 } else { 623 TypeDecl nest = hostType(); 624 while (nest != null && !nest.instanceOf(S.enclosingType())) { 625 nest = nest.enclosingType(); 626 } 627 if (nest == null) { 628 errorf("*** No enclosing instance to superclass %s of %s", 629 S.typeName(), type().typeName()); 630 } else if (inExplicitConstructorInvocation()) { 631 errorf("*** No enclosing instance to superclass %s of %s since this is not initialized yet", 632 S.typeName(), type().typeName()); 633 } 634 } 635 } 636 } 637 } 638 } 639 640 public void ArrayTypeWithSizeAccess.typeCheck() { 641 super.typeCheck(); 642 if (!getExpr().type().unaryNumericPromotion().isInt()) { 643 errorf("%s is not int after unary numeric promotion", getExpr().type().typeName()); 644 } 645 } 646 647 // 15.25 648 public void ConditionalExpr.typeCheck() { 649 if (!getCondition().type().isBoolean()) { 650 error("The first operand of a conditional expression must be a boolean"); 651 } 652 if (type().isUnknown() && !getTrueExpr().type().isUnknown() && !getFalseExpr().type().isUnknown()) { 653 error("The types of the second and third operand in this conditional expression do not match"); 654 } 655 } 656 657 public void IntegerLiteral.typeCheck() { 658 if (constant().error) { 659 error("The value of an int literal must be a decimal value in the range -2147483648..2147483647 or a hexadecimal or octal literal that fits in 32 bits."); 660 } 661 } 662 663 public void LongLiteral.typeCheck() { 664 if (constant().error) { 665 errorf("The value of the long literal %s is not legal", getLITERAL()); 666 } 667 } 668 669 public void FloatingPointLiteral.typeCheck() { 670 if (!isZero() && constant().floatValue() == 0.0f) { 671 errorf("It is an error for nonzero floating-point %s to round to zero", getLITERAL()); 672 } 673 if (constant().floatValue() == Float.NEGATIVE_INFINITY || constant().floatValue() == Float.POSITIVE_INFINITY) { 674 errorf("the floating-point literal \"%s\" is too large", getLITERAL()); 675 } 676 } 677 678 public void DoubleLiteral.typeCheck() { 679 if (!isZero() && constant().doubleValue() == 0.0f) { 680 errorf("It is an error for nonzero floating-point %s to round to zero", getLITERAL()); 681 } 682 if (constant().doubleValue() == Double.NEGATIVE_INFINITY || constant().doubleValue() == Double.POSITIVE_INFINITY) { 683 errorf("the floating-point literal \"%s\" is too large", getLITERAL()); 684 } 685 } 686 }