001/* 002 * Copyright (c) 2012-2018 Institut National des Sciences Appliquées de Lyon (INSA Lyon) and others 003 * 004 * This program and the accompanying materials are made available under the 005 * terms of the Eclipse Public License 2.0 which is available at 006 * http://www.eclipse.org/legal/epl-2.0. 007 * 008 * SPDX-License-Identifier: EPL-2.0 009 */ 010 011package gololang.ir; 012 013import java.util.Objects; 014import java.util.Collections; 015import java.util.List; 016 017public final class ReturnStatement extends GoloStatement<ReturnStatement> { 018 019 private GoloStatement<?> expressionStatement; 020 private boolean returningVoid; 021 private boolean synthetic; 022 023 private ReturnStatement(ExpressionStatement<?> expression) { 024 super(); 025 setExpressionStatement(expression); 026 this.returningVoid = false; 027 this.synthetic = false; 028 } 029 030 /** 031 * Creates a {@code return} statement. 032 * 033 * @param value an object interpreted as an {@link ExpressionStatement} 034 * @see ExpressionStatement#of(Object) 035 */ 036 public static ReturnStatement of(Object value) { 037 return new ReturnStatement(ExpressionStatement.of(value)); 038 } 039 040 /** 041 * Creates a {@code void} return statement. 042 */ 043 public static ReturnStatement empty() { 044 return new ReturnStatement(null).returningVoid(); 045 } 046 047 protected ReturnStatement self() { return this; } 048 049 public GoloStatement<?> expression() { 050 return expressionStatement; 051 } 052 053 private void setExpressionStatement(GoloStatement<?> stat) { 054 if (stat != null) { 055 this.expressionStatement = makeParentOf(stat); 056 } else { 057 this.expressionStatement = null; 058 } 059 } 060 061 public boolean isReturningVoid() { 062 return returningVoid; 063 } 064 065 public ReturnStatement returningVoid() { 066 this.returningVoid = true; 067 return this; 068 } 069 070 public ReturnStatement synthetic() { 071 this.synthetic = true; 072 return this; 073 } 074 075 public boolean isSynthetic() { 076 return this.synthetic; 077 } 078 079 @Override 080 public String toString() { 081 return "return " + ( 082 returningVoid || expressionStatement == null 083 ? "" 084 : expressionStatement.toString()); 085 } 086 087 /** 088 * {@inheritDoc} 089 */ 090 @Override 091 public void accept(GoloIrVisitor visitor) { 092 visitor.visitReturnStatement(this); 093 } 094 095 /** 096 * {@inheritDoc} 097 */ 098 @Override 099 public List<GoloElement<?>> children() { 100 if (expressionStatement != null) { 101 return Collections.singletonList(expressionStatement); 102 } 103 return Collections.emptyList(); 104 } 105 106 /** 107 * {@inheritDoc} 108 */ 109 @Override 110 protected void replaceElement(GoloElement<?> original, GoloElement<?> newElement) { 111 if (Objects.equals(original, expressionStatement) && newElement instanceof ExpressionStatement) { 112 setExpressionStatement(ExpressionStatement.of(newElement)); 113 } else { 114 throw cantReplace(original, newElement); 115 } 116 } 117}