1 package polyglot.ext.jl.ast; 2 3 import polyglot.ast.*; 4 import polyglot.types.*; 5 import polyglot.visit.*; 6 import polyglot.util.*; 7 import java.util.*; 8 9 14 public class Return_c extends Stmt_c implements Return 15 { 16 protected Expr expr; 17 18 public Return_c(Position pos, Expr expr) { 19 super(pos); 20 this.expr = expr; 21 } 22 23 24 public Expr expr() { 25 return this.expr; 26 } 27 28 29 public Return expr(Expr expr) { 30 Return_c n = (Return_c) copy(); 31 n.expr = expr; 32 return n; 33 } 34 35 36 protected Return_c reconstruct(Expr expr) { 37 if (expr != this.expr) { 38 Return_c n = (Return_c) copy(); 39 n.expr = expr; 40 return n; 41 } 42 43 return this; 44 } 45 46 47 public Node visitChildren(NodeVisitor v) { 48 Expr expr = (Expr) visitChild(this.expr, v); 49 return reconstruct(expr); 50 } 51 52 53 public Node typeCheck(TypeChecker tc) throws SemanticException { 54 TypeSystem ts = tc.typeSystem(); 55 Context c = tc.context(); 56 57 CodeInstance ci = c.currentCode(); 58 59 if (ci instanceof InitializerInstance) { 60 throw new SemanticException( 61 "Cannot return from an initializer block.", position()); 62 } 63 64 if (ci instanceof ConstructorInstance) { 65 if (expr != null) { 66 throw new SemanticException( 67 "Cannot return a value from " + ci + ".", 68 position()); 69 } 70 71 return this; 72 } 73 74 if (ci instanceof MethodInstance) { 75 MethodInstance mi = (MethodInstance) ci; 76 77 if (mi.returnType().isVoid()) { 78 if (expr != null) { 79 throw new SemanticException("Cannot return a value from " + 80 mi + ".", position()); 81 } 82 else { 83 return this; 84 } 85 } 86 else if (expr == null) { 87 throw new SemanticException("Must return a value from " + 88 mi + ".", position()); 89 } 90 91 if (ts.isImplicitCastValid(expr.type(), mi.returnType())) { 92 return this; 93 } 94 95 if (ts.numericConversionValid(mi.returnType(), 96 expr.constantValue())) { 97 return this; 98 } 99 100 throw new SemanticException("Cannot return expression of type " + 101 expr.type() + " from " + mi + ".", expr.position()); 102 } 103 104 throw new InternalCompilerError("Unrecognized code type."); 105 } 106 107 public Type childExpectedType(Expr child, AscriptionVisitor av) { 108 if (child == expr) { 109 Context c = av.context(); 110 CodeInstance ci = c.currentCode(); 111 112 if (ci instanceof MethodInstance) { 113 MethodInstance mi = (MethodInstance) ci; 114 115 TypeSystem ts = av.typeSystem(); 116 117 if (ts.numericConversionValid(mi.returnType(), 120 child.constantValue())) { 121 return child.type(); 122 } 123 else { 124 return mi.returnType(); 125 } 126 } 127 } 128 129 return child.type(); 130 } 131 132 public String toString() { 133 return "return" + (expr != null ? " " + expr : "") + ";"; 134 } 135 136 137 public void prettyPrint(CodeWriter w, PrettyPrinter tr) { 138 w.write("return") ; 139 if (expr != null) { 140 w.write(" "); 141 print(expr, w, tr); 142 } 143 w.write(";"); 144 } 145 146 public Term entry() { 147 if (expr != null) return expr.entry(); 148 return this; 149 } 150 151 public List acceptCFG(CFGBuilder v, List succs) { 152 if (expr != null) { 153 v.visitCFG(expr, this); 154 } 155 156 v.visitReturn(this); 157 return Collections.EMPTY_LIST; 158 } 159 } 160 | Popular Tags |