Commit fd8054a2 authored by Daniel Ratiu's avatar Daniel Ratiu
Browse files

fixing the typechecker for accesses to arrays

refs 1324
parent 6bc65c48
......@@ -18,6 +18,11 @@ $Id$
package org.fortiss.af3.component.constraint;
import static org.fortiss.af3.expression.model.terms.impl.DefinedConstStaticImpl.NoVal;
import static org.fortiss.af3.expression.utils.ExpressionUtils.getAccessedArrayVar;
import static org.fortiss.af3.expression.utils.ExpressionUtils.getStructureMember;
import static org.fortiss.af3.expression.utils.ExpressionUtils.getTypeDefinition;
import static org.fortiss.af3.expression.utils.ExpressionUtils.isArrayAccess;
import static org.fortiss.af3.expression.utils.ExpressionUtils.isStructureAccess;
import static org.fortiss.af3.expression.utils.NoValSpecialTreatmentUtils.getVariableAccessedInEqualityOrInequalityWithNoVal;
import static org.fortiss.af3.expression.utils.NoValSpecialTreatmentUtils.isEqualityOrInequalityWithNoVal;
import static org.fortiss.af3.project.utils.TypeScopeUtils.getTypeDefinition;
......@@ -33,12 +38,12 @@ import org.fortiss.af3.component.model.OutputPort;
import org.fortiss.af3.component.model.Port;
import org.fortiss.af3.expression.language.TypeSystemHandler;
import org.fortiss.af3.expression.model.definitions.Structure;
import org.fortiss.af3.expression.model.terms.ComplexVar;
import org.fortiss.af3.expression.model.terms.FunctionCall;
import org.fortiss.af3.expression.model.terms.PredefinedFunction;
import org.fortiss.af3.expression.model.terms.Var;
import org.fortiss.af3.expression.model.terms.imperative.Assignment;
import org.fortiss.af3.expression.model.types.TDefinedType;
import org.fortiss.af3.expression.utils.ExpressionUtils;
import org.fortiss.af3.project.model.typesystem.IFunction;
import org.fortiss.af3.project.model.typesystem.ITerm;
import org.fortiss.af3.project.model.typesystem.IType;
......@@ -112,15 +117,21 @@ abstract class TypeCheckConstraintCheckerBase<T extends EObject, V extends EObje
private void doIdentifierCheck(Var var, T modelElement, List<IConstraintViolation<V>> results) {
IVariableDefinition def = getVarDefinition(var);
if(def == null) {
if(isArrayAccess(var)) {
Var arrayVar = getAccessedArrayVar((ComplexVar)var);
IVariableDefinition arrayVarDef = getVarDefinition(arrayVar);
if(arrayVarDef != null) {
return;
}
}
if(var.eContainer() instanceof FunctionCall) {
FunctionCall fc = (FunctionCall)var.eContainer();
if(ExpressionUtils.isStructureAccess(fc)) {
ITypeDefinition typedef =
ExpressionUtils.getTypeDefinition(fc.getArguments(0), modelElement);
if(isStructureAccess(fc)) {
ITypeDefinition typedef = getTypeDefinition(fc.getArguments(0), modelElement);
if(typedef instanceof Structure) {
if(ExpressionUtils.getStructureMember((Structure)typedef,
var.getIdentifier()) != null)
if(getStructureMember((Structure)typedef, var.getIdentifier()) != null) {
return;
}
}
}
}
......
......@@ -41,6 +41,7 @@ import org.fortiss.af3.expression.model.definitions.StructureMember;
import org.fortiss.af3.expression.model.definitions.TypeDefinition;
import org.fortiss.af3.expression.model.terms.ArrayConst;
import org.fortiss.af3.expression.model.terms.BoolConst;
import org.fortiss.af3.expression.model.terms.ComplexVar;
import org.fortiss.af3.expression.model.terms.Const;
import org.fortiss.af3.expression.model.terms.DoubleConst;
import org.fortiss.af3.expression.model.terms.EOperator;
......@@ -119,7 +120,11 @@ public class TypeChecker implements ITypeChecker {
return typecheckConst((Const)term, expected, context);
}
if(term instanceof Var) {
// Use scoping to find variable type.
if(term instanceof ComplexVar) {
ComplexVar cv = (ComplexVar)term;
return typecheckArrayAccess((FunctionCall)cv.getTerm(), expected, context);
}
return expected.equals(getVarType((Var)term, context));
}
if(term instanceof FunctionCall) {
......
......@@ -37,6 +37,7 @@ import org.fortiss.af3.expression.model.definitions.EnumerationMember;
import org.fortiss.af3.expression.model.definitions.Structure;
import org.fortiss.af3.expression.model.definitions.StructureMember;
import org.fortiss.af3.expression.model.definitions.TypeDefinition;
import org.fortiss.af3.expression.model.terms.ComplexVar;
import org.fortiss.af3.expression.model.terms.Const;
import org.fortiss.af3.expression.model.terms.EOperator;
import org.fortiss.af3.expression.model.terms.FunctionCall;
......@@ -172,13 +173,58 @@ public class ExpressionUtils {
* @param term
* the term to be checked
* @return true, if the term is a member access term. false, otherwise
* */
*/
public static boolean isStructureAccess(ITerm term) {
return term instanceof FunctionCall &&
((FunctionCall)term).getFunction() instanceof PredefinedFunction &&
((PredefinedFunction)((FunctionCall)term).getFunction()).getOperator() == EOperator.MEMBER;
}
/**
* Check whether a given {@link ITerm} is an array access
*
* @param var
* the variable to be checked
* @return true, if the variable is an array access term. false, otherwise
*/
public static boolean isArrayAccess(Var var) {
if(!(var instanceof ComplexVar)) {
return false;
}
ComplexVar cVar = (ComplexVar)var;
if(!(cVar.getTerm() instanceof FunctionCall)) {
return false;
}
FunctionCall fc = (FunctionCall)cVar.getTerm();
return fc.getFunction() instanceof PredefinedFunction &&
((PredefinedFunction)fc.getFunction()).getOperator() == EOperator.INDEX;
}
/**
* Returns the accessed array variable
*
* @param var
* the array variable to be checked
* @return the variable with type array that is accessed
*/
public static Var getAccessedArrayVar(ComplexVar var) {
if(!(var.getTerm() instanceof FunctionCall)) {
return null;
}
FunctionCall fc = (FunctionCall)var.getTerm();
ITerm arg0 = fc.getArguments(0);
if(arg0 instanceof ComplexVar) {
return getAccessedArrayVar((ComplexVar)arg0);
}
return (Var)arg0;
}
/**
* Check whether a given {@link Var} is a reference to a member of a certain structure
*
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment