terfloth@itemis.de před 13 roky
rodič
revize
54ecf7045d

+ 8 - 0
plugins/org.yakindu.sct.model.stext/.settings/org.eclipse.xtend.core.Xtend.prefs

@@ -0,0 +1,8 @@
+autobuilding=true
+eclipse.preferences.version=1
+is_project_specific=true
+outlet.DEFAULT_OUTPUT.cleanDirectory=false
+outlet.DEFAULT_OUTPUT.cleanupDerived=true
+outlet.DEFAULT_OUTPUT.createDirectory=true
+outlet.DEFAULT_OUTPUT.derived=false
+outlet.DEFAULT_OUTPUT.override=true

+ 553 - 0
plugins/org.yakindu.sct.model.stext/xtend-gen/org/yakindu/sct/model/stext/validation/TypeInferrer.java

@@ -0,0 +1,553 @@
+package org.yakindu.sct.model.stext.validation;
+
+import com.google.common.base.Objects;
+import com.google.inject.Inject;
+import java.util.Arrays;
+import org.eclipse.emf.ecore.EObject;
+import org.yakindu.base.types.Feature;
+import org.yakindu.base.types.ITypeSystemAccess;
+import org.yakindu.base.types.Type;
+import org.yakindu.sct.model.sgraph.Statement;
+import org.yakindu.sct.model.stext.stext.ActiveStateReferenceExpression;
+import org.yakindu.sct.model.stext.stext.AdditiveOperator;
+import org.yakindu.sct.model.stext.stext.AssignmentExpression;
+import org.yakindu.sct.model.stext.stext.BitwiseAndExpression;
+import org.yakindu.sct.model.stext.stext.BitwiseOrExpression;
+import org.yakindu.sct.model.stext.stext.BitwiseXorExpression;
+import org.yakindu.sct.model.stext.stext.BoolLiteral;
+import org.yakindu.sct.model.stext.stext.ConditionalExpression;
+import org.yakindu.sct.model.stext.stext.ElementReferenceExpression;
+import org.yakindu.sct.model.stext.stext.EventDefinition;
+import org.yakindu.sct.model.stext.stext.EventRaisingExpression;
+import org.yakindu.sct.model.stext.stext.EventValueReferenceExpression;
+import org.yakindu.sct.model.stext.stext.Expression;
+import org.yakindu.sct.model.stext.stext.FeatureCall;
+import org.yakindu.sct.model.stext.stext.HexLiteral;
+import org.yakindu.sct.model.stext.stext.IntLiteral;
+import org.yakindu.sct.model.stext.stext.Literal;
+import org.yakindu.sct.model.stext.stext.LogicalAndExpression;
+import org.yakindu.sct.model.stext.stext.LogicalNotExpression;
+import org.yakindu.sct.model.stext.stext.LogicalOrExpression;
+import org.yakindu.sct.model.stext.stext.LogicalRelationExpression;
+import org.yakindu.sct.model.stext.stext.MultiplicativeOperator;
+import org.yakindu.sct.model.stext.stext.NumericalAddSubtractExpression;
+import org.yakindu.sct.model.stext.stext.NumericalMultiplyDivideExpression;
+import org.yakindu.sct.model.stext.stext.NumericalUnaryExpression;
+import org.yakindu.sct.model.stext.stext.OperationDefinition;
+import org.yakindu.sct.model.stext.stext.PrimitiveValueExpression;
+import org.yakindu.sct.model.stext.stext.RealLiteral;
+import org.yakindu.sct.model.stext.stext.RelationalOperator;
+import org.yakindu.sct.model.stext.stext.ShiftExpression;
+import org.yakindu.sct.model.stext.stext.ShiftOperator;
+import org.yakindu.sct.model.stext.stext.StringLiteral;
+import org.yakindu.sct.model.stext.stext.UnaryOperator;
+import org.yakindu.sct.model.stext.stext.VariableDefinition;
+import org.yakindu.sct.model.stext.validation.ITypeInferrer;
+import org.yakindu.sct.model.stext.validation.TypeCheckException;
+import org.yakindu.sct.model.stext.validation.TypeInferrerCache;
+import org.yakindu.sct.model.stext.validation.TypeInferrerCache.ICacheableTypeAnalyzer;
+
+/**
+ * The TypeInferrer checks an expression AST for type conformance
+ * 
+ * @author andreas muelder - Initial contribution and API
+ */
+@SuppressWarnings("all")
+public class TypeInferrer implements ITypeInferrer, ICacheableTypeAnalyzer {
+  @Inject
+  private ITypeSystemAccess ts;
+  
+  @Inject
+  private TypeInferrerCache cache;
+  
+  public Type getType(final Statement stmt) {
+    Type _xblockexpression = null;
+    {
+      boolean _equals = Objects.equal(stmt, null);
+      if (_equals) {
+        return null;
+      }
+      Type _get = this.cache.get(stmt, this);
+      _xblockexpression = (_get);
+    }
+    return _xblockexpression;
+  }
+  
+  protected Type _inferType(final Statement statement) {
+    return null;
+  }
+  
+  public Type check(final Statement stmt) {
+    Type _type = this.getType(stmt);
+    return _type;
+  }
+  
+  /**
+   * Check Variable assignments
+   */
+  protected Type _inferType(final AssignmentExpression assignment) {
+    Expression _expression = assignment.getExpression();
+    Type valueType = this.getType(_expression);
+    Expression _varRef = assignment.getVarRef();
+    Type type = this.getType(_varRef);
+    boolean _isAssignable = this.ts.isAssignable(type, valueType);
+    boolean _not = (!_isAssignable);
+    if (_not) {
+      String _name = valueType==null?(String)null:valueType.getName();
+      String _plus = ("Can not assign a value of type " + _name);
+      String _plus_1 = (_plus + " to a variable of type ");
+      String _name_1 = type==null?(String)null:type.getName();
+      String _plus_2 = (_plus_1 + _name_1);
+      this.error(_plus_2);
+      return null;
+    }
+    return type;
+  }
+  
+  /**
+   * Check Event value assignments
+   */
+  protected Type _inferType(final EventRaisingExpression eventRaising) {
+    Expression _value = eventRaising.getValue();
+    Type valueType = this.getType(_value);
+    Expression _event = eventRaising.getEvent();
+    Type type = this.getType(_event);
+    boolean _isAssignable = this.ts.isAssignable(type, valueType);
+    boolean _not = (!_isAssignable);
+    if (_not) {
+      String _name = valueType==null?(String)null:valueType.getName();
+      String _plus = ("Can not assign a value of type " + _name);
+      String _plus_1 = (_plus + " to a variable of type ");
+      String _name_1 = type==null?(String)null:type.getName();
+      String _plus_2 = (_plus_1 + _name_1);
+      this.error(_plus_2);
+      return null;
+    }
+    return type;
+  }
+  
+  protected Type _inferType(final LogicalAndExpression expression) {
+    Expression _leftOperand = expression.getLeftOperand();
+    Type _type = this.getType(_leftOperand);
+    Expression _rightOperand = expression.getRightOperand();
+    Type _type_1 = this.getType(_rightOperand);
+    return this.assertBooleanTypes(_type, _type_1, "&&");
+  }
+  
+  protected Type _inferType(final LogicalOrExpression expression) {
+    Expression _leftOperand = expression.getLeftOperand();
+    Type _type = this.getType(_leftOperand);
+    Expression _rightOperand = expression.getRightOperand();
+    Type _type_1 = this.getType(_rightOperand);
+    return this.assertBooleanTypes(_type, _type_1, "||");
+  }
+  
+  public Type assertBooleanTypes(final Type left, final Type right, final String literal) {
+    boolean _and = false;
+    Type _assertIsBoolean = this.assertIsBoolean(left, literal);
+    boolean _notEquals = (!Objects.equal(_assertIsBoolean, null));
+    if (!_notEquals) {
+      _and = false;
+    } else {
+      Type _assertIsBoolean_1 = this.assertIsBoolean(right, literal);
+      boolean _notEquals_1 = (!Objects.equal(_assertIsBoolean_1, null));
+      _and = (_notEquals && _notEquals_1);
+    }
+    if (_and) {
+      return this.ts.combine(left, right);
+    }
+    return null;
+  }
+  
+  protected Type _inferType(final LogicalNotExpression expression) {
+    Expression _operand = expression.getOperand();
+    final Type type = this.getType(_operand);
+    return this.assertIsBoolean(type, "!");
+  }
+  
+  protected Type _inferType(final BitwiseAndExpression expression) {
+    Expression _leftOperand = expression.getLeftOperand();
+    Type _type = this.getType(_leftOperand);
+    this.assertIsInteger(_type, "&");
+    Expression _rightOperand = expression.getRightOperand();
+    Type _type_1 = this.getType(_rightOperand);
+    this.assertIsInteger(_type_1, "&");
+    return this.ts.getInteger();
+  }
+  
+  protected Type _inferType(final BitwiseOrExpression expression) {
+    Expression _leftOperand = expression.getLeftOperand();
+    Type _type = this.getType(_leftOperand);
+    this.assertIsInteger(_type, "|");
+    Expression _rightOperand = expression.getRightOperand();
+    Type _type_1 = this.getType(_rightOperand);
+    this.assertIsInteger(_type_1, "|");
+    return this.ts.getInteger();
+  }
+  
+  protected Type _inferType(final BitwiseXorExpression expression) {
+    Expression _leftOperand = expression.getLeftOperand();
+    Type _type = this.getType(_leftOperand);
+    this.assertIsInteger(_type, "^");
+    Expression _rightOperand = expression.getRightOperand();
+    Type _type_1 = this.getType(_rightOperand);
+    this.assertIsInteger(_type_1, "^");
+    return this.ts.getInteger();
+  }
+  
+  protected Type _inferType(final LogicalRelationExpression expression) {
+    Expression _leftOperand = expression.getLeftOperand();
+    final Type leftType = this.getType(_leftOperand);
+    Expression _rightOperand = expression.getRightOperand();
+    final Type rightType = this.getType(_rightOperand);
+    boolean _and = false;
+    boolean _isBoolean = this.ts.isBoolean(leftType);
+    if (!_isBoolean) {
+      _and = false;
+    } else {
+      boolean _isBoolean_1 = this.ts.isBoolean(rightType);
+      _and = (_isBoolean && _isBoolean_1);
+    }
+    if (_and) {
+      boolean _and_1 = false;
+      RelationalOperator _operator = expression.getOperator();
+      boolean _notEquals = (!Objects.equal(_operator, RelationalOperator.EQUALS));
+      if (!_notEquals) {
+        _and_1 = false;
+      } else {
+        RelationalOperator _operator_1 = expression.getOperator();
+        boolean _notEquals_1 = (!Objects.equal(_operator_1, RelationalOperator.NOT_EQUALS));
+        _and_1 = (_notEquals && _notEquals_1);
+      }
+      if (_and_1) {
+        RelationalOperator _operator_2 = expression.getOperator();
+        String _literal = _operator_2==null?(String)null:_operator_2.getLiteral();
+        String _plus = ("operator \'" + _literal);
+        String _plus_1 = (_plus + "\' can not be applied to boolean values!");
+        this.error(_plus_1);
+        return null;
+      }
+    } else {
+      final Type combined = this.ts.combine(leftType, rightType);
+      boolean _equals = Objects.equal(combined, null);
+      if (_equals) {
+        String _name = leftType==null?(String)null:leftType.getName();
+        String _plus_2 = ("Incompatible operands " + _name);
+        String _plus_3 = (_plus_2 + " and ");
+        String _name_1 = rightType==null?(String)null:rightType.getName();
+        String _plus_4 = (_plus_3 + _name_1);
+        String _plus_5 = (_plus_4 + " for operator \'");
+        RelationalOperator _operator_3 = expression.getOperator();
+        String _literal_1 = _operator_3.getLiteral();
+        String _plus_6 = (_plus_5 + _literal_1);
+        String _plus_7 = (_plus_6 + "\'");
+        this.error(_plus_7);
+      }
+    }
+    return this.ts.getBoolean();
+  }
+  
+  public Type assertNumericalTypes(final Type left, final Type right, final String operator) {
+    boolean _and = false;
+    Type _assertIsNumber = this.assertIsNumber(left, operator);
+    boolean _notEquals = (!Objects.equal(_assertIsNumber, null));
+    if (!_notEquals) {
+      _and = false;
+    } else {
+      Type _assertIsNumber_1 = this.assertIsNumber(right, operator);
+      boolean _notEquals_1 = (!Objects.equal(_assertIsNumber_1, null));
+      _and = (_notEquals && _notEquals_1);
+    }
+    if (_and) {
+      return this.ts.combine(left, right);
+    }
+    return null;
+  }
+  
+  protected Type _inferType(final NumericalAddSubtractExpression expression) {
+    Expression _leftOperand = expression.getLeftOperand();
+    Type _type = this.getType(_leftOperand);
+    Expression _rightOperand = expression.getRightOperand();
+    Type _type_1 = this.getType(_rightOperand);
+    AdditiveOperator _operator = expression.getOperator();
+    String _literal = _operator.getLiteral();
+    return this.assertNumericalTypes(_type, _type_1, _literal);
+  }
+  
+  protected Type _inferType(final NumericalMultiplyDivideExpression expression) {
+    Expression _leftOperand = expression.getLeftOperand();
+    Type _type = this.getType(_leftOperand);
+    Expression _rightOperand = expression.getRightOperand();
+    Type _type_1 = this.getType(_rightOperand);
+    MultiplicativeOperator _operator = expression.getOperator();
+    String _literal = _operator.getLiteral();
+    return this.assertNumericalTypes(_type, _type_1, _literal);
+  }
+  
+  protected Type _inferType(final NumericalUnaryExpression expression) {
+    Expression _operand = expression.getOperand();
+    final Type type = this.getType(_operand);
+    UnaryOperator _operator = expression.getOperator();
+    boolean _equals = Objects.equal(_operator, UnaryOperator.COMPLEMENT);
+    if (_equals) {
+      UnaryOperator _operator_1 = expression.getOperator();
+      String _literal = _operator_1.getLiteral();
+      return this.assertIsInteger(type, _literal);
+    }
+    UnaryOperator _operator_2 = expression.getOperator();
+    String _literal_1 = _operator_2.getLiteral();
+    return this.assertIsNumber(type, _literal_1);
+  }
+  
+  protected Type _inferType(final PrimitiveValueExpression expression) {
+    Literal _value = expression.getValue();
+    final Type t = this.getLiteralType(_value);
+    return t;
+  }
+  
+  protected Type _inferType(final ActiveStateReferenceExpression expression) {
+    return this.ts.getBoolean();
+  }
+  
+  protected Type _inferType(final ShiftExpression expression) {
+    Type _xblockexpression = null;
+    {
+      Expression _leftOperand = expression.getLeftOperand();
+      Type _type = this.getType(_leftOperand);
+      ShiftOperator _operator = expression.getOperator();
+      String _literal = _operator.getLiteral();
+      this.assertIsInteger(_type, _literal);
+      Expression _rightOperand = expression.getRightOperand();
+      Type _type_1 = this.getType(_rightOperand);
+      ShiftOperator _operator_1 = expression.getOperator();
+      String _literal_1 = _operator_1.getLiteral();
+      Type _assertIsInteger = this.assertIsInteger(_type_1, _literal_1);
+      _xblockexpression = (_assertIsInteger);
+    }
+    return _xblockexpression;
+  }
+  
+  protected Type _inferType(final ConditionalExpression expression) {
+    Expression _condition = expression.getCondition();
+    final Type condType = this.getType(_condition);
+    boolean _isBoolean = this.ts.isBoolean(condType);
+    boolean _not = (!_isBoolean);
+    if (_not) {
+      this.error("Condition type have to be boolean");
+      return null;
+    }
+    Expression _trueCase = expression.getTrueCase();
+    final Type trueType = this.getType(_trueCase);
+    Expression _falseCase = expression.getFalseCase();
+    final Type falseType = this.getType(_falseCase);
+    return this.ts.combine(trueType, falseType);
+  }
+  
+  protected Type _inferType(final FeatureCall featureCall) {
+    EObject _feature = featureCall.getFeature();
+    if ((_feature instanceof Feature)) {
+      EObject _feature_1 = featureCall.getFeature();
+      return ((Feature) _feature_1)==null?(Type)null:((Feature) _feature_1).getType();
+    } else {
+      EObject _feature_2 = featureCall.getFeature();
+      boolean _notEquals = (!Objects.equal(_feature_2, null));
+      if (_notEquals) {
+        String _plus = ("Type of FeatureCall is unknown: " + featureCall);
+        this.error(_plus);
+        return null;
+      } else {
+        return null;
+      }
+    }
+  }
+  
+  protected Type _inferType(final ElementReferenceExpression expression) {
+    EObject _reference = expression.getReference();
+    return this.inferType(_reference, expression);
+  }
+  
+  protected Type _inferType(final EObject object, final ElementReferenceExpression expression) {
+    return null;
+  }
+  
+  protected Type _inferType(final VariableDefinition definition, final ElementReferenceExpression expression) {
+    return definition.getType();
+  }
+  
+  protected Type _inferType(final EventDefinition definition, final ElementReferenceExpression expression) {
+    boolean _or = false;
+    EObject _eContainer = expression.eContainer();
+    if ((_eContainer instanceof EventRaisingExpression)) {
+      _or = true;
+    } else {
+      EObject _eContainer_1 = expression.eContainer();
+      _or = ((_eContainer instanceof EventRaisingExpression) || (_eContainer_1 instanceof EventValueReferenceExpression));
+    }
+    if (_or) {
+      return definition.getType();
+    }
+    return this.ts.getBoolean();
+  }
+  
+  protected Type _inferType(final OperationDefinition definition, final ElementReferenceExpression expression) {
+    return definition.getType();
+  }
+  
+  protected Type _inferType(final EventValueReferenceExpression expression) {
+    Expression _value = expression.getValue();
+    return this.getType(_value);
+  }
+  
+  protected Type _getLiteralType(final HexLiteral literal) {
+    return this.ts.getInteger();
+  }
+  
+  protected Type _getLiteralType(final IntLiteral literal) {
+    return this.ts.getInteger();
+  }
+  
+  protected Type _getLiteralType(final BoolLiteral bool) {
+    return this.ts.getBoolean();
+  }
+  
+  protected Type _getLiteralType(final RealLiteral literal) {
+    return this.ts.getReal();
+  }
+  
+  protected Type _getLiteralType(final StringLiteral literal) {
+    return this.ts.getString();
+  }
+  
+  public Type assertIsInteger(final Type object, final String operator) {
+    boolean _isInteger = this.ts.isInteger(object);
+    boolean _not = (!_isInteger);
+    if (_not) {
+      String _plus = ("operator \'" + operator);
+      String _plus_1 = (_plus + "\' can only be applied to integers!");
+      this.error(_plus_1);
+      return null;
+    }
+    return object;
+  }
+  
+  public Type assertIsNumber(final Type object, final String operator) {
+    boolean _and = false;
+    boolean _isReal = this.ts.isReal(object);
+    boolean _not = (!_isReal);
+    if (!_not) {
+      _and = false;
+    } else {
+      boolean _isInteger = this.ts.isInteger(object);
+      boolean _not_1 = (!_isInteger);
+      _and = (_not && _not_1);
+    }
+    if (_and) {
+      String _plus = ("operator \'" + operator);
+      String _plus_1 = (_plus + "\' can only be applied to numbers!");
+      this.error(_plus_1);
+      return null;
+    }
+    return object;
+  }
+  
+  public Type assertIsBoolean(final Type object, final String operator) {
+    boolean _isBoolean = this.ts.isBoolean(object);
+    boolean _not = (!_isBoolean);
+    if (_not) {
+      String _plus = ("operator \'" + operator);
+      String _plus_1 = (_plus + "\' can only be applied to boolean values!");
+      this.error(_plus_1);
+    }
+    return object;
+  }
+  
+  public void error(final String msg) {
+    TypeCheckException _typeCheckException = new TypeCheckException(msg);
+    throw _typeCheckException;
+  }
+  
+  protected Type _inferType(final Expression expr) {
+    return null;
+  }
+  
+  public Type inferType(final Statement expression) {
+    if (expression instanceof ActiveStateReferenceExpression) {
+      return _inferType((ActiveStateReferenceExpression)expression);
+    } else if (expression instanceof AssignmentExpression) {
+      return _inferType((AssignmentExpression)expression);
+    } else if (expression instanceof BitwiseAndExpression) {
+      return _inferType((BitwiseAndExpression)expression);
+    } else if (expression instanceof BitwiseOrExpression) {
+      return _inferType((BitwiseOrExpression)expression);
+    } else if (expression instanceof BitwiseXorExpression) {
+      return _inferType((BitwiseXorExpression)expression);
+    } else if (expression instanceof ConditionalExpression) {
+      return _inferType((ConditionalExpression)expression);
+    } else if (expression instanceof ElementReferenceExpression) {
+      return _inferType((ElementReferenceExpression)expression);
+    } else if (expression instanceof EventRaisingExpression) {
+      return _inferType((EventRaisingExpression)expression);
+    } else if (expression instanceof EventValueReferenceExpression) {
+      return _inferType((EventValueReferenceExpression)expression);
+    } else if (expression instanceof FeatureCall) {
+      return _inferType((FeatureCall)expression);
+    } else if (expression instanceof LogicalAndExpression) {
+      return _inferType((LogicalAndExpression)expression);
+    } else if (expression instanceof LogicalNotExpression) {
+      return _inferType((LogicalNotExpression)expression);
+    } else if (expression instanceof LogicalOrExpression) {
+      return _inferType((LogicalOrExpression)expression);
+    } else if (expression instanceof LogicalRelationExpression) {
+      return _inferType((LogicalRelationExpression)expression);
+    } else if (expression instanceof NumericalAddSubtractExpression) {
+      return _inferType((NumericalAddSubtractExpression)expression);
+    } else if (expression instanceof NumericalMultiplyDivideExpression) {
+      return _inferType((NumericalMultiplyDivideExpression)expression);
+    } else if (expression instanceof NumericalUnaryExpression) {
+      return _inferType((NumericalUnaryExpression)expression);
+    } else if (expression instanceof PrimitiveValueExpression) {
+      return _inferType((PrimitiveValueExpression)expression);
+    } else if (expression instanceof ShiftExpression) {
+      return _inferType((ShiftExpression)expression);
+    } else if (expression instanceof Expression) {
+      return _inferType((Expression)expression);
+    } else if (expression != null) {
+      return _inferType(expression);
+    } else {
+      throw new IllegalArgumentException("Unhandled parameter types: " +
+        Arrays.<Object>asList(expression).toString());
+    }
+  }
+  
+  public Type inferType(final EObject definition, final ElementReferenceExpression expression) {
+    if (definition instanceof EventDefinition) {
+      return _inferType((EventDefinition)definition, expression);
+    } else if (definition instanceof OperationDefinition) {
+      return _inferType((OperationDefinition)definition, expression);
+    } else if (definition instanceof VariableDefinition) {
+      return _inferType((VariableDefinition)definition, expression);
+    } else if (definition != null) {
+      return _inferType(definition, expression);
+    } else {
+      throw new IllegalArgumentException("Unhandled parameter types: " +
+        Arrays.<Object>asList(definition, expression).toString());
+    }
+  }
+  
+  public Type getLiteralType(final Literal bool) {
+    if (bool instanceof BoolLiteral) {
+      return _getLiteralType((BoolLiteral)bool);
+    } else if (bool instanceof HexLiteral) {
+      return _getLiteralType((HexLiteral)bool);
+    } else if (bool instanceof IntLiteral) {
+      return _getLiteralType((IntLiteral)bool);
+    } else if (bool instanceof RealLiteral) {
+      return _getLiteralType((RealLiteral)bool);
+    } else if (bool instanceof StringLiteral) {
+      return _getLiteralType((StringLiteral)bool);
+    } else {
+      throw new IllegalArgumentException("Unhandled parameter types: " +
+        Arrays.<Object>asList(bool).toString());
+    }
+  }
+}