All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.xtext.xbase.controlflow.DefaultEarlyExitComputer Maven / Gradle / Ivy

/**
 * Copyright (c) 2011 itemis AG (http://www.itemis.eu) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package org.eclipse.xtext.xbase.controlflow;

import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import org.eclipse.emf.common.util.EList;
import org.eclipse.xtext.xbase.XAbstractFeatureCall;
import org.eclipse.xtext.xbase.XBasicForLoopExpression;
import org.eclipse.xtext.xbase.XBlockExpression;
import org.eclipse.xtext.xbase.XCasePart;
import org.eclipse.xtext.xbase.XCatchClause;
import org.eclipse.xtext.xbase.XConstructorCall;
import org.eclipse.xtext.xbase.XDoWhileExpression;
import org.eclipse.xtext.xbase.XExpression;
import org.eclipse.xtext.xbase.XForLoopExpression;
import org.eclipse.xtext.xbase.XIfExpression;
import org.eclipse.xtext.xbase.XReturnExpression;
import org.eclipse.xtext.xbase.XSwitchExpression;
import org.eclipse.xtext.xbase.XSynchronizedExpression;
import org.eclipse.xtext.xbase.XThrowExpression;
import org.eclipse.xtext.xbase.XTryCatchFinallyExpression;
import org.eclipse.xtext.xbase.XVariableDeclaration;
import org.eclipse.xtext.xbase.XWhileExpression;
import org.eclipse.xtext.xbase.controlflow.EarlyExitInterpreter;
import org.eclipse.xtext.xbase.controlflow.IEarlyExitComputer;

/**
 * @author Sebastian Zarnekow - Initial contribution and API
 */
@Singleton
@SuppressWarnings("all")
public class DefaultEarlyExitComputer implements IEarlyExitComputer {
  @Inject
  private EarlyExitInterpreter earlyExitInterpreter;
  
  @Override
  public boolean isEarlyExit(final XExpression expression) {
    Collection exitPoints = this.getExitPoints(expression);
    boolean _isNotEmpty = this.isNotEmpty(exitPoints);
    if (_isNotEmpty) {
      return true;
    }
    return false;
  }
  
  protected boolean isNotEmpty(final Collection exitPoints) {
    return ((!Objects.equal(exitPoints, null)) && (!exitPoints.isEmpty()));
  }
  
  @Override
  public Collection getExitPoints(final XExpression expression) {
    boolean _equals = Objects.equal(expression, null);
    if (_equals) {
      return Collections.emptyList();
    }
    return this.exitPoints(expression);
  }
  
  /**
   * @param expression unused in this context but required in dispatch signature
   */
  protected Collection _exitPoints(final XExpression expression) {
    return Collections.emptyList();
  }
  
  protected Collection _exitPoints(final XReturnExpression expression) {
    IEarlyExitComputer.ExitPoint _exitPoint = new IEarlyExitComputer.ExitPoint(expression, false);
    return Collections.singletonList(_exitPoint);
  }
  
  protected Collection _exitPoints(final XThrowExpression expression) {
    IEarlyExitComputer.ExitPoint _exitPoint = new IEarlyExitComputer.ExitPoint(expression, true);
    return Collections.singletonList(_exitPoint);
  }
  
  protected Collection _exitPoints(final XBlockExpression expression) {
    EList _expressions = expression.getExpressions();
    for (final XExpression child : _expressions) {
      {
        Collection exitPoints = this.getExitPoints(child);
        boolean _isNotEmpty = this.isNotEmpty(exitPoints);
        if (_isNotEmpty) {
          return exitPoints;
        }
      }
    }
    return Collections.emptyList();
  }
  
  protected Collection _exitPoints(final XBasicForLoopExpression expression) {
    EList _initExpressions = expression.getInitExpressions();
    for (final XExpression initExpression : _initExpressions) {
      {
        Collection exitPoints = this.getExitPoints(initExpression);
        boolean _isNotEmpty = this.isNotEmpty(exitPoints);
        if (_isNotEmpty) {
          return exitPoints;
        }
      }
    }
    XExpression predicate = expression.getExpression();
    Collection exitPoints = this.getExitPoints(predicate);
    boolean _isNotEmpty = this.isNotEmpty(exitPoints);
    if (_isNotEmpty) {
      return exitPoints;
    }
    if ((Objects.equal(predicate, null) || this.isBooleanConstant(predicate, true))) {
      XExpression _eachExpression = expression.getEachExpression();
      Collection _exitPoints = this.getExitPoints(_eachExpression);
      exitPoints = _exitPoints;
      boolean _isNotEmpty_1 = this.isNotEmpty(exitPoints);
      if (_isNotEmpty_1) {
        return exitPoints;
      }
      EList _updateExpressions = expression.getUpdateExpressions();
      for (final XExpression child : _updateExpressions) {
        {
          Collection _exitPoints_1 = this.getExitPoints(child);
          exitPoints = _exitPoints_1;
          boolean _isNotEmpty_2 = this.isNotEmpty(exitPoints);
          if (_isNotEmpty_2) {
            return exitPoints;
          }
        }
      }
      IEarlyExitComputer.ExitPoint _exitPoint = new IEarlyExitComputer.ExitPoint(expression, false);
      return Collections.singletonList(_exitPoint);
    }
    return Collections.emptyList();
  }
  
  protected Collection _exitPoints(final XForLoopExpression expression) {
    XExpression _forExpression = expression.getForExpression();
    Collection exitPoints = this.getExitPoints(_forExpression);
    boolean _isNotEmpty = this.isNotEmpty(exitPoints);
    if (_isNotEmpty) {
      return exitPoints;
    }
    return Collections.emptyList();
  }
  
  protected Collection _exitPoints(final XWhileExpression expression) {
    XExpression _predicate = expression.getPredicate();
    Collection exitPoints = this.getExitPoints(_predicate);
    boolean _isNotEmpty = this.isNotEmpty(exitPoints);
    if (_isNotEmpty) {
      return exitPoints;
    }
    XExpression _predicate_1 = expression.getPredicate();
    boolean _isBooleanConstant = this.isBooleanConstant(_predicate_1, true);
    if (_isBooleanConstant) {
      XExpression _body = expression.getBody();
      Collection _exitPoints = this.getExitPoints(_body);
      exitPoints = _exitPoints;
      boolean _isNotEmpty_1 = this.isNotEmpty(exitPoints);
      if (_isNotEmpty_1) {
        return exitPoints;
      }
      IEarlyExitComputer.ExitPoint _exitPoint = new IEarlyExitComputer.ExitPoint(expression, false);
      return Collections.singletonList(_exitPoint);
    }
    return Collections.emptyList();
  }
  
  protected boolean isBooleanConstant(final XExpression expression, final boolean value) {
    return this.earlyExitInterpreter.isConstant(expression, Boolean.valueOf(value));
  }
  
  protected Collection _exitPoints(final XDoWhileExpression expression) {
    XExpression _body = expression.getBody();
    Collection exitPoints = this.getExitPoints(_body);
    boolean _isNotEmpty = this.isNotEmpty(exitPoints);
    if (_isNotEmpty) {
      return exitPoints;
    }
    XExpression _predicate = expression.getPredicate();
    Collection _exitPoints = this.getExitPoints(_predicate);
    exitPoints = _exitPoints;
    boolean _isNotEmpty_1 = this.isNotEmpty(exitPoints);
    if (_isNotEmpty_1) {
      return exitPoints;
    }
    XExpression _predicate_1 = expression.getPredicate();
    boolean _isBooleanConstant = this.isBooleanConstant(_predicate_1, true);
    if (_isBooleanConstant) {
      IEarlyExitComputer.ExitPoint _exitPoint = new IEarlyExitComputer.ExitPoint(expression, false);
      return Collections.singletonList(_exitPoint);
    }
    return Collections.emptyList();
  }
  
  protected Collection _exitPoints(final XVariableDeclaration expression) {
    XExpression _right = expression.getRight();
    return this.getExitPoints(_right);
  }
  
  protected Collection _exitPoints(final XIfExpression expression) {
    XExpression _if = expression.getIf();
    Collection ifExitPoints = this.getExitPoints(_if);
    boolean _isNotEmpty = this.isNotEmpty(ifExitPoints);
    if (_isNotEmpty) {
      return ifExitPoints;
    }
    XExpression _then = expression.getThen();
    Collection thenExitPoints = this.getExitPoints(_then);
    XExpression _else = expression.getElse();
    Collection elseExitPoints = this.getExitPoints(_else);
    if ((this.isNotEmpty(thenExitPoints) && this.isNotEmpty(elseExitPoints))) {
      Collection result = Lists.newArrayList(thenExitPoints);
      result.addAll(elseExitPoints);
      return result;
    }
    return Collections.emptyList();
  }
  
  protected Collection _exitPoints(final XSwitchExpression expression) {
    XExpression _switch = expression.getSwitch();
    Collection switchExitPoints = this.getExitPoints(_switch);
    boolean _isNotEmpty = this.isNotEmpty(switchExitPoints);
    if (_isNotEmpty) {
      return switchExitPoints;
    }
    Collection result = Lists.newArrayList();
    EList _cases = expression.getCases();
    for (final XCasePart casePart : _cases) {
      {
        XExpression then = casePart.getThen();
        boolean _notEquals = (!Objects.equal(then, null));
        if (_notEquals) {
          Collection caseExit = this.getExitPoints(then);
          boolean _isNotEmpty_1 = this.isNotEmpty(caseExit);
          boolean _not = (!_isNotEmpty_1);
          if (_not) {
            return Collections.emptyList();
          } else {
            result.addAll(caseExit);
          }
        }
      }
    }
    XExpression _default = expression.getDefault();
    Collection defaultExit = this.getExitPoints(_default);
    boolean _isNotEmpty_1 = this.isNotEmpty(defaultExit);
    boolean _not = (!_isNotEmpty_1);
    if (_not) {
      return Collections.emptyList();
    } else {
      result.addAll(defaultExit);
    }
    return result;
  }
  
  protected Collection _exitPoints(final XAbstractFeatureCall expression) {
    EList _actualArguments = expression.getActualArguments();
    for (final XExpression argument : _actualArguments) {
      {
        Collection argumentExitPoints = this.getExitPoints(argument);
        boolean _isNotEmpty = this.isNotEmpty(argumentExitPoints);
        if (_isNotEmpty) {
          return argumentExitPoints;
        }
      }
    }
    return Collections.emptyList();
  }
  
  protected Collection _exitPoints(final XConstructorCall expression) {
    EList _arguments = expression.getArguments();
    for (final XExpression argument : _arguments) {
      {
        Collection argumentExitPoints = this.getExitPoints(argument);
        boolean _isNotEmpty = this.isNotEmpty(argumentExitPoints);
        if (_isNotEmpty) {
          return argumentExitPoints;
        }
      }
    }
    return Collections.emptyList();
  }
  
  protected Collection _exitPoints(final XTryCatchFinallyExpression expression) {
    XExpression _expression = expression.getExpression();
    Collection tryExitPoints = this.getExitPoints(_expression);
    boolean _isNotEmpty = this.isNotEmpty(tryExitPoints);
    if (_isNotEmpty) {
      Collection result = Lists.newArrayList(tryExitPoints);
      EList _catchClauses = expression.getCatchClauses();
      for (final XCatchClause catchClause : _catchClauses) {
        {
          XExpression _expression_1 = catchClause.getExpression();
          Collection catchExitPoints = this.getExitPoints(_expression_1);
          boolean _isNotEmpty_1 = this.isNotEmpty(catchExitPoints);
          if (_isNotEmpty_1) {
            result.addAll(catchExitPoints);
          } else {
            XExpression _finallyExpression = expression.getFinallyExpression();
            return this.getExitPoints(_finallyExpression);
          }
        }
      }
      return result;
    }
    XExpression _finallyExpression = expression.getFinallyExpression();
    return this.getExitPoints(_finallyExpression);
  }
  
  protected Collection _exitPoints(final XSynchronizedExpression expression) {
    XExpression _param = expression.getParam();
    Collection paramExitPoints = this.getExitPoints(_param);
    boolean _isNotEmpty = this.isNotEmpty(paramExitPoints);
    if (_isNotEmpty) {
      return paramExitPoints;
    }
    XExpression _expression = expression.getExpression();
    return this.getExitPoints(_expression);
  }
  
  protected Collection exitPoints(final XExpression expression) {
    if (expression instanceof XDoWhileExpression) {
      return _exitPoints((XDoWhileExpression)expression);
    } else if (expression instanceof XWhileExpression) {
      return _exitPoints((XWhileExpression)expression);
    } else if (expression instanceof XAbstractFeatureCall) {
      return _exitPoints((XAbstractFeatureCall)expression);
    } else if (expression instanceof XBasicForLoopExpression) {
      return _exitPoints((XBasicForLoopExpression)expression);
    } else if (expression instanceof XBlockExpression) {
      return _exitPoints((XBlockExpression)expression);
    } else if (expression instanceof XConstructorCall) {
      return _exitPoints((XConstructorCall)expression);
    } else if (expression instanceof XForLoopExpression) {
      return _exitPoints((XForLoopExpression)expression);
    } else if (expression instanceof XIfExpression) {
      return _exitPoints((XIfExpression)expression);
    } else if (expression instanceof XReturnExpression) {
      return _exitPoints((XReturnExpression)expression);
    } else if (expression instanceof XSwitchExpression) {
      return _exitPoints((XSwitchExpression)expression);
    } else if (expression instanceof XSynchronizedExpression) {
      return _exitPoints((XSynchronizedExpression)expression);
    } else if (expression instanceof XThrowExpression) {
      return _exitPoints((XThrowExpression)expression);
    } else if (expression instanceof XTryCatchFinallyExpression) {
      return _exitPoints((XTryCatchFinallyExpression)expression);
    } else if (expression instanceof XVariableDeclaration) {
      return _exitPoints((XVariableDeclaration)expression);
    } else if (expression != null) {
      return _exitPoints(expression);
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.asList(expression).toString());
    }
  }
}