Commit 1d0f15ed authored by Philip Makedonski's avatar Philip Makedonski
Browse files

+ refined handling of out parameters in function calls, including predefined...

+ refined handling of out parameters in function calls, including predefined functions and user-defined functions in assignments and conditional expressions
parent 8a789f32
Loading
Loading
Loading
Loading
+67 −3
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ import de.ugoe.cs.swe.tTCN3.ComponentElementDef
import de.ugoe.cs.swe.tTCN3.ConditionalConstruct
import de.ugoe.cs.swe.tTCN3.ControlStatement
import de.ugoe.cs.swe.tTCN3.ExtFunctionDef
import de.ugoe.cs.swe.tTCN3.Fdecvalue
import de.ugoe.cs.swe.tTCN3.FunctionDef
import de.ugoe.cs.swe.tTCN3.FunctionDefList
import de.ugoe.cs.swe.tTCN3.FunctionFormalPar
@@ -53,6 +54,11 @@ import org.eclipse.xtext.validation.EValidatorRegistrar

import static extension de.ugoe.cs.swe.common.TTCN3ScopeHelper.*
import static extension org.eclipse.xtext.EcoreUtil2.*
import de.ugoe.cs.swe.tTCN3.Fint2enum
import de.ugoe.cs.swe.tTCN3.FdecvalueUnichar
import de.ugoe.cs.swe.tTCN3.OpCall
import de.ugoe.cs.swe.tTCN3.Expression
import de.ugoe.cs.swe.tTCN3.BooleanExpression

class DataFlowValidator extends AbstractDeclarativeValidator {
    val ConfigTools configTools = ConfigTools.getInstance;
@@ -567,11 +573,60 @@ class DataFlowValidator extends AbstractDeclarativeValidator {
        }
    }

    protected def void processOpCall(OpCall opCall, DataFlowHelper dfh) {
        if (opCall.preFunction !== null) {
            val pf = opCall.preFunction
            if (pf instanceof Fdecvalue) {
                dfh.checkVariableStatus(pf.e1.eAllOfType(ReferencedValue))
                val outPar = pf.e2.eContents.get(0)
                if (outPar instanceof ReferencedValue) {
                    dfh.updateVariableStatus(outPar)
                }
            } else if (pf instanceof Fint2enum) {
                dfh.checkVariableStatus(pf.e1.eAllOfType(ReferencedValue))
                val outPar = pf.e2.eContents.get(0)
                if (outPar instanceof ReferencedValue) {
                    dfh.updateVariableStatus(outPar)
                }
            } else if (pf instanceof FdecvalueUnichar) {
                dfh.checkVariableStatus(pf.e1.eAllOfType(ReferencedValue))
                val outPar = pf.e2.eContents.get(0)
                if (outPar instanceof ReferencedValue) {
                    dfh.updateVariableStatus(outPar)
                }
            } else {
                //default handling
                dfh.checkVariableStatus(pf.eAllOfType(ReferencedValue))
            }
        } else if (opCall.function !== null) {
            opCall.function.processFunctionInstance(dfh)
        } else {
            dfh.checkVariableStatus(opCall.eAllOfType(ReferencedValue))
        }
    }
    
    protected def void processExpression(Expression expression, DataFlowHelper dfh) {
        if (expression instanceof OpCall) {
            expression.processOpCall(dfh)
        } else {
            dfh.checkVariableStatus(expression.eAllOfType(ReferencedValue))
        }
    }
    
    protected def void processBasicStatement(BasicStatements basic, DataFlowHelper dfh) {
        if (basic.assign !== null) {
        
            //only for assignments or other statements that are not within nested blocks
            dfh.checkVariableStatus(basic.assign.eAllOfType(ReferencedValue))
            if (basic.assign.expression !== null) {
                basic.assign.expression.processExpression(dfh)
            } else if (basic.assign.body !== null) {
                dfh.checkVariableStatus(basic.assign.body.eAllOfType(ReferencedValue))
            }            
            
            if (basic.assign.extra !== null) {
                dfh.checkVariableStatus(basic.assign.extra.eAllOfType(ReferencedValue))
            }
            
            dfh.updateVariableStatus(basic.assign.ref.ref)
        
        } else if (basic.block !== null) {
@@ -608,9 +663,18 @@ class DataFlowValidator extends AbstractDeclarativeValidator {
        }
    }

    protected def void processConditionalStatementExpression(BooleanExpression expression, DataFlowHelper dfh) {
        dfh.checkVariableStatus(expression.eAllOfType(ReferencedValue).filter[getContainerOfType(OpCall) === null])
        
        for (e : expression.eAllOfType(OpCall)) {
            e.processOpCall(dfh)
        }
    }

    
    protected def void processConditionalStatement(ConditionalConstruct conditional, DataFlowHelper dfh) {
        //condition
        dfh.checkVariableStatus(conditional.expression.eAllOfType(ReferencedValue))
        conditional.expression.processConditionalStatementExpression(dfh)
        
        //block
        var sdfh = new DataFlowHelper(dfh)
@@ -755,7 +819,7 @@ class DataFlowValidator extends AbstractDeclarativeValidator {
    protected def void checkVariableStatus(DataFlowHelper dfh, Iterable<ReferencedValue> values) {
        for (value : values.filter[eContainer instanceof Value
            || (eContainer instanceof VariableRef //what was this for again?
                && !(eContainer.eContainer instanceof Assignment)
                && !(eContainer.eContainer instanceof Assignment) //this shall be superfluous as well
            )
        ]) {
            //check states