⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 typecheck.jrag

📁 JDK1.4编译器前端
💻 JRAG
📖 第 1 页 / 共 2 页
字号:
/* * The JastAdd Extensible Java Compiler (http://jastadd.org) is covered * by the modified BSD License. You should have received a copy of the * modified BSD license with this compiler. *  * Copyright (c) 2005-2008, Torbjorn Ekman * All rights reserved. */aspect TypeCheck {  public void ASTNode.typeCheck() {  }    syn boolean Expr.isVariable() = false;  eq AbstractDot.isVariable() = lastAccess().isVariable();  eq VarAccess.isVariable() = true;  eq ArrayAccess.isVariable() = true;  eq ParExpr.isVariable() = getExpr().isVariable();   // 5.2  public void VariableDeclaration.typeCheck() {    if(hasInit()) {      TypeDecl source = getInit().type();      TypeDecl dest = type();      if(!source.assignConversionTo(dest, getInit()))        error("can not assign " + name() + " of type " + dest.typeName() +              " a value of type " + source.typeName());    }  }  // 5.2  public void FieldDeclaration.typeCheck() {    if(hasInit()) {      TypeDecl source = getInit().type();      TypeDecl dest = type();      if(!source.assignConversionTo(dest, getInit()))        error("can not assign " + name() + " of type " + dest.typeName() +              " a value of type " + source.typeName());    }  }  // 5.2 Assignment Conversion  public void AssignSimpleExpr.typeCheck() {    if(!getDest().isVariable())      error("left hand side is not a variable");    else if(!sourceType().assignConversionTo(getDest().type(), getSource()) && !sourceType().isUnknown())      error("can not assign " + getDest() + " of type " + getDest().type().typeName() +            " a value of type " + sourceType().typeName());  }    public void AssignExpr.typeCheck() {    if(!getDest().isVariable())      error("left hand side is not a variable");    else {      TypeDecl source = sourceType();      TypeDecl dest = getDest().type();      if(getSource().type().isPrimitive() && getDest().type().isPrimitive())        return;      error("can not assign " + getDest() + " of type " + getDest().type().typeName() +            " a value of type " + sourceType().typeName());    }  }  public void AssignMultiplicativeExpr.typeCheck() {    if(sourceType().isBoolean() || getDest().type().isBoolean())      error("Multiplicative operators do not operate on boolean types");    super.typeCheck();  }    public void AssignPlusExpr.typeCheck() {    if(!getDest().isVariable())      error("left hand side is not a variable");    else if(getSource().type().isUnknown() || getDest().type().isUnknown())      return;    else if(getDest().type().isString() && !(getSource().type().isVoid()))      return;    else if(getSource().type().isBoolean() || getDest().type().isBoolean())      error("Operator + does not operate on boolean types");    else if(getSource().type().isPrimitive() && getDest().type().isPrimitive())      return;    else      error("can not assign " + getDest() + " of type " + getDest().type().typeName() +            " a value of type " + sourceType().typeName());  }  public void AssignMinusExpr.typeCheck() {    if(sourceType().isBoolean() || getDest().type().isBoolean())      error("Operator - does not operate on boolean types");    super.typeCheck();  }    public void AssignShiftExpr.typeCheck() {    if(!sourceType().isIntegralType() || !getDest().type().isIntegralType())      error("Shift operators only operate on integral types");    super.typeCheck();  }    public void AssignBitwiseExpr.typeCheck() {    TypeDecl source = sourceType();    TypeDecl dest = getDest().type();    if(source.isIntegralType() && dest.isIntegralType())      super.typeCheck();    else if(source.isBoolean() && dest.isBoolean())      super.typeCheck();    else      error("Operator only operates on integral and boolean types");  }  syn TypeDecl AssignExpr.sourceType() = getSource().type().isPrimitive() ? getSource().type() : unknownType();    eq AssignPlusExpr.sourceType() {    TypeDecl left = getDest().type();    TypeDecl right = getSource().type();    if(!left.isString() && !right.isString())      return super.sourceType();    if(left.isVoid() || right.isVoid())      return unknownType();    return left.isString() ? left : right;  }    syn TypeDecl AssignSimpleExpr.sourceType() = getSource().type();  // 5.3 Method Invocation Conversion  public void MethodAccess.typeCheck() {    for(int i = 0; i < decl().getNumParameter(); i++) {      TypeDecl exprType = getArg(i).type();      TypeDecl parmType = decl().getParameter(i).type();      if(!exprType.methodInvocationConversionTo(parmType) && !exprType.isUnknown() && !parmType.isUnknown()) {        error("The type " + exprType.typeName() + " of expr " +            getArg(i) + " is not compatible with the method parameter " +            decl().getParameter(i));      }    }  }            // 15.13  public void ArrayAccess.typeCheck() {    if(isQualified() && !qualifier().type().isArrayDecl() && !qualifier().type().isUnknown())      error("the type " + qualifier().type().name() + " of the indexed element is not an array");    if(!getExpr().type().unaryNumericPromotion().isInt() || !getExpr().type().isIntegralType())      error("array index must be int after unary numeric promotion which " + getExpr().type().typeName() + " is not");  }  public void ArrayInit.typeCheck() {    TypeDecl initializerType = declType().componentType();    if(initializerType.isUnknown())      error("the dimension of the initializer is larger than the expected dimension");    for(int i = 0; i < getNumInit(); i++) {      Expr e = getInit(i);      if(!e.type().assignConversionTo(initializerType, e))        error("the type " + e.type().name() + " of the initializer is not compatible with " + initializerType.name());     }  }  // 15.17  public void MultiplicativeExpr.typeCheck() {    if(!getLeftOperand().type().isNumericType())      error(getLeftOperand().type().typeName() + " is not numeric");    if(!getRightOperand().type().isNumericType())      error(getRightOperand().type().typeName() + " is not numeric");  }  // 15.18  public void AdditiveExpr.typeCheck() {    if(!getLeftOperand().type().isNumericType())      error(getLeftOperand().type().typeName() + " is not numeric");    if(!getRightOperand().type().isNumericType())      error(getRightOperand().type().typeName() + " is not numeric");  }    // 15.18  public void AddExpr.typeCheck() {    TypeDecl left = getLeftOperand().type();    TypeDecl right = getRightOperand().type();    if(!left.isString() && !right.isString())      super.typeCheck();    else if(left.isVoid())      error("The type void of the left hand side is not numeric");    else if(right.isVoid())      error("The type void of the right hand side is not numeric");  }       // 15.19  public void ShiftExpr.typeCheck() {    if(!getLeftOperand().type().isIntegralType())      error(getLeftOperand().type().typeName() + " is not integral");    if(!getRightOperand().type().isIntegralType())      error(getRightOperand().type().typeName() + " is not integral");  }    // 15.22  public void BitwiseExpr.typeCheck() {    TypeDecl left = getLeftOperand().type();    TypeDecl right = getRightOperand().type();    if(left.isIntegralType() && right.isIntegralType())      return;    else if(left.isBoolean() && right.isBoolean())      return;    else      error(left.typeName() + " is not compatible with " + right.typeName());  }  // 15.20  public void RelationalExpr.typeCheck() {    if(!getLeftOperand().type().isNumericType())      error(getLeftOperand().type().typeName() + " is not numeric");    if(!getRightOperand().type().isNumericType())      error(getRightOperand().type().typeName() + " is not numeric");  }  // 15.23, 15.24  public void LogicalExpr.typeCheck() {    if(!getLeftOperand().type().isBoolean())      error(getLeftOperand().type().typeName() + " is not boolean");    if(!getRightOperand().type().isBoolean())      error(getRightOperand().type().typeName() + " is not boolean");  }  // 15.21  public void EqualityExpr.typeCheck() {    TypeDecl left = getLeftOperand().type();    TypeDecl right = getRightOperand().type();    if(left.isNumericType() && right.isNumericType())      return;    else if(left.isBoolean() && right.isBoolean())      return;    else if((left.isReferenceType() || left.isNull()) && (right.isReferenceType() || right.isNull())) {      if(left.castingConversionTo(right) || right.castingConversionTo(left))        return;    }    error(left.typeName() + " can not be compared to " + right.typeName());  }  // 15.20.2  public void InstanceOfExpr.typeCheck() {    TypeDecl relationalExpr = getExpr().type();    TypeDecl referenceType = getTypeAccess().type();    if(!relationalExpr.isUnknown()) {      if(!relationalExpr.isReferenceType() && !relationalExpr.isNull())        error("The relational expression in instance of must be reference or null type");      if(!referenceType.isReferenceType())        error("The reference expression in instance of must be reference type");      if(!relationalExpr.castingConversionTo(referenceType))        error("The type " + relationalExpr.typeName() + " of the relational expression " +           getExpr() +  " can not be cast into the type " + referenceType.typeName());      if(getExpr().isTypeAccess())        error("The relational expression " + getExpr() + " must not be a type name");    }  }    // 15.16  public void CastExpr.typeCheck() {    TypeDecl expr = getExpr().type();    TypeDecl type = getTypeAccess().type();    if(!expr.isUnknown()) {      if(!expr.castingConversionTo(type))        error(expr.typeName() + " can not be cast into " + type.typeName());      if(!getTypeAccess().isTypeAccess())        error("" + getTypeAccess() + " is not a type access in cast expression");    }  }  public void ParExpr.typeCheck() {    if(getExpr().isTypeAccess())      error("" + getExpr() + " is a type and may not be used in parenthesized expression");  }    // 15.15.3  public void PlusExpr.typeCheck() {    if(!getOperand().type().isNumericType())      error("unary plus only operates on numeric types");  }    // 15.15.4  public void MinusExpr.typeCheck() {    if(!getOperand().type().isNumericType())      error("unary minus only operates on numeric types");  }  // 15.15.5  public void BitNotExpr.typeCheck() {    if(!getOperand().type().isIntegralType())      error("unary ~ only operates on integral types");  }  // 15.15.6  public void LogNotExpr.typeCheck() {    if(!getOperand().type().isBoolean())      error("unary ! only operates on boolean types");  }  // 15.14  public void PostfixExpr.typeCheck() {    if(!getOperand().isVariable())      error("postfix expressions only work on variables");    else if(!getOperand().type().isNumericType())      error("postfix expressions only operates on numeric types");  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -