/******************************************************************************* | |
* Copyright (c) 2004-2011 Akos Horvath and Daniel Varro | |
* 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 | |
* | |
* Contributors: | |
* Akos Horvath - initial API and implementation | |
*******************************************************************************/ | |
package org.eclipse.viatra2.gtasm.interpreter.impl.rules; | |
import java.util.ArrayList; | |
import java.util.Collection; | |
import java.util.Collections; | |
import java.util.Comparator; | |
import java.util.HashMap; | |
import java.util.Hashtable; | |
import java.util.Map; | |
import org.eclipse.emf.common.util.EList; | |
import org.eclipse.viatra2.core.IEntity; | |
import org.eclipse.viatra2.core.IModelElement; | |
import org.eclipse.viatra2.gtasm.interpreter.exception.ASMInterpreterErrorStrings; | |
import org.eclipse.viatra2.gtasm.interpreter.exception.ViatraTransformationException; | |
import org.eclipse.viatra2.gtasm.interpreter.executionEnvironment.IExecutionEnvironment; | |
import org.eclipse.viatra2.gtasm.interpreter.impl.executionEnvironment.BlockRuleExecutionEnvironment; | |
import org.eclipse.viatra2.gtasm.interpreter.impl.machine.ASMInterpreterException; | |
import org.eclipse.viatra2.gtasm.interpreter.term.rules.TermEvaluator; | |
import org.eclipse.viatra2.gtasm.patternmatcher.ExecutionMode; | |
import org.eclipse.viatra2.gtasm.patternmatcher.IMatching; | |
import org.eclipse.viatra2.gtasm.patternmatcher.ParameterMode; | |
import org.eclipse.viatra2.gtasm.patternmatcher.PatternCallSignature; | |
import org.eclipse.viatra2.gtasm.patternmatcher.PatternMatcherParameters; | |
import org.eclipse.viatra2.gtasm.patternmatcher.Scope; | |
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.compoundRules.BlockRule; | |
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.compoundRules.CollectionIteratorRule; | |
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.compoundRules.ForallRule; | |
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.core.RuntimeAnnotation; | |
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.core.RuntimeAnnotationElement; | |
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.SymbolicRuleParameter; | |
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.Variable; | |
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.enums.DirectionKind; | |
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.enums.ValueKind; | |
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.simpleRules.GTRuleInvocation; | |
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.GTPatternCall; | |
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.Term; | |
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.VariableReference; | |
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.gt.ContainmentConstraint; | |
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.gt.GTPattern; | |
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.gt.GTRule; | |
import org.eclipse.viatra2.interpreters.IProgressReport; | |
/** Contains all the helper methods for the Block rule interpretation | |
* @author Akos Horvath | |
* | |
*/ | |
public abstract class BlockRuleInterpreterHelper { | |
/** Returns the transformed scope constraints of a GT pattern or GT rule invocation | |
* @param executionEnvironment The execution environment on which the elements are evaluated | |
* @param containmentConstraints The constraints of the invocations | |
* @return The variable and the corresponding Scope in a HashMap | |
* @throws ViatraTransformationException | |
*/ | |
static HashMap<Variable,Scope> getScopesFromContainmentConstraints(IExecutionEnvironment executionEnvironment | |
,CollectionIteratorRule rule) throws ViatraTransformationException | |
{ | |
EList<ContainmentConstraint> containmentConstraints = rule.getContainmentConstraints(); | |
HashMap<Variable,Scope> parameterScopes = new HashMap<Variable,Scope>(); | |
for (Object cC: containmentConstraints) { | |
ContainmentConstraint containmentConstraint = (ContainmentConstraint) cC; | |
if(containmentConstraint.getParent()!=null) | |
{ | |
Object constraintParent = TermEvaluator.getInstance().evaluate(executionEnvironment, containmentConstraint.getParent()); | |
if(constraintParent instanceof IEntity) | |
{ | |
parameterScopes .put((containmentConstraint).getVariable(), | |
new Scope( containmentConstraint.getMode().getValue(), | |
(IModelElement)(TermEvaluator.getInstance().evaluate(executionEnvironment, containmentConstraint.getParent() )))); | |
} | |
else | |
{ | |
// Scope parent!= ENTITY, the element the scope references does not exist | |
String[] context = {containmentConstraint.getVariable().getName()}; | |
ViatraTransformationException e = new ASMInterpreterException(ASMInterpreterErrorStrings.SCOPE_NOT_AN_ENTITY | |
,context | |
,containmentConstraint.getVariable()); | |
throw e.addNewStackElement(rule); | |
} | |
} | |
else | |
parameterScopes .put(containmentConstraint.getVariable(), new Scope()); | |
} | |
return parameterScopes; | |
} | |
/** Evaluates the do part of the GT Rule if it exists | |
* @param gtRule The GTRule invoked | |
* @param match The matching produced by the application of the GT rule | |
* @param blockRule the block rule representing the DO part | |
* @param blockRuleExecutionEnvironment the corresponding execution environment on which we the TERMS evaluated | |
* @param ruleInvocation the actual gtRule invocation | |
* @return true if it is successfully evaluated (or no DO part) else false | |
* @throws ViatraTransformationException | |
*/ | |
static boolean evaulateDoPartofGTRuleInvocation(GTRule gtRule | |
, Object[] match | |
, BlockRule blockRule | |
, IExecutionEnvironment blockRuleExecutionEnvironment | |
, GTRuleInvocation ruleInvocation | |
, IProgressReport pr) | |
throws ViatraTransformationException | |
{ | |
// the block rule does not have a do part | |
if(blockRule.getBody() == null) | |
return Boolean.TRUE; | |
GTRuleInvocation gtRuleInvocation = ((CollectionIteratorRule) blockRule).getGtrule(); | |
for (int i=0;i<gtRule.getSymParameters().size();i++) { | |
//Only OUT and INOUT parameters have to be updated | |
if(!(gtRule.getSymParameters().get(i)).getDirection().equals(DirectionKind.IN_LITERAL) ) | |
{ | |
if(match[i].equals(ValueKind.UNDEF_LITERAL)) | |
//have to check that it is not a quantified variable | |
{ | |
Object ActualTerm = ruleInvocation.getActualParameters().get(i); | |
if(!(ActualTerm instanceof VariableReference | |
// the CollectionIterator rule's actual parameter | |
&& ((CollectionIteratorRule)blockRule).getLocalVariables().contains(((VariableReference)ActualTerm).getVariable()))) | |
{ | |
String[] context = {(gtRule.getSymParameters().get(i)).getName(), gtRule.getName()}; | |
throw new ASMInterpreterException(ASMInterpreterErrorStrings.GTOUTPUT_IN_INOUT_NOT_BOUND | |
,context | |
,blockRule); | |
} | |
} | |
// else | |
// throw new ASMInterpreterException(((SymbolicRuleParameter)gtRule.getSymParameters().get(i)).getName()+ASMInterpreterErrorStrings.GTOUTPUT_IN_INOUT_NOT_BOUND+gtRule.getName(),blockRule); | |
// //have to check that an input parameter is not changed during the execution of the GTRule | |
// if(!match[i] | |
// .equals( | |
// blockRuleExecutionEnvironment.getTermEvaluator().evaluate(blockRuleExecutionEnvironment | |
// ,(Term)((CollectionIteratorRule)blockRule).getGtrule().getActualParameters().get(i))) ) | |
// { | |
// ViatraTransformationException e = new ASMInterpreterException(ASMInterpreterErrorStrings.GTIN_OUTDIFFERENCE,(GTASMElement)chooseBlockRule.getGtrule().getActualParameters().get(i)); | |
// e.addNewStackElement(blockRule); | |
// throw e; | |
// } | |
} | |
// else | |
//INOUT or OUT parameter has to be changed | |
// if(!((SymbolicRuleParameter)gtRule.getSymParameters().get(i)).getDirection().equals(DirectionKind.IN_LITERAL)) | |
// { | |
try { | |
if(gtRuleInvocation.getActualParameters().get(i) instanceof VariableReference) | |
{ | |
Variable variable = ((VariableReference)(gtRuleInvocation).getActualParameters().get(i)).getVariable(); | |
blockRuleExecutionEnvironment. | |
setVariableValue( | |
variable, | |
match[i]); | |
} | |
} catch (ViatraTransformationException e) { | |
String n = ""; | |
if(gtRuleInvocation.getActualParameters().get(i) instanceof VariableReference) | |
n = ((VariableReference)(gtRuleInvocation).getActualParameters().get(i)).getVariable().getName(); | |
String[] context = {n,e.getMessage()}; | |
throw new ASMInterpreterException( | |
blockRule instanceof ForallRule?ASMInterpreterErrorStrings.RULE_INIT_VAR_FORALL:ASMInterpreterErrorStrings.RULE_INIT_VAR_CHOOSE | |
,context | |
,blockRule); | |
} | |
// } | |
} | |
return RuleInterpreter.getInstance().interpretRule(blockRuleExecutionEnvironment,blockRule.getBody(),pr); | |
} | |
/** Returns the appropriate parameters for the GTRUleMatcher invocation. | |
* @param executionEnvironment The environment in which the terms will be evaluated | |
* @param ruleToBeInterpreted the Block rule containing the GT rule invocation | |
* @param parameterScopes Scope parameters for the quantified variables | |
* @param gtRule the invoked GT rule | |
* @param invocation the GT rule invocation rule | |
* @return | |
* @throws ViatraTransformationException | |
*/ | |
static PatternMatcherParameters getGTRuleMatchParameters(IExecutionEnvironment executionEnvironment | |
, CollectionIteratorRule ruleToBeInterpreted | |
, Map<Variable,Scope> parameterScopes | |
, GTRule gtRule | |
, GTRuleInvocation invocation) | |
throws ViatraTransformationException | |
{ | |
Object[] patternParams = new Object[invocation.getActualParameters().size()]; | |
Integer[] quantificationOrder=new Integer[invocation.getActualParameters().size()]; | |
PatternCallSignature[] patternCallSignatures=new PatternCallSignature[invocation.getActualParameters().size()]; | |
// quantification order in case of forall rule | |
int outerVariableCounterForQuantificationOrder=(ruleToBeInterpreted).getLocalVariables().size(); | |
int localVariableCounterForQuantificationOrder=0; | |
for (int i = 0 ; i< invocation.getActualParameters().size(); i++) { | |
Object ActualTerm = invocation.getActualParameters().get(i); | |
SymbolicRuleParameter symParam = gtRule.getSymParameters().get(i); | |
PatternCallSignature pcs=new PatternCallSignature(); | |
// the value of the actual parameter | |
patternParams[i] = TermEvaluator.getInstance().evaluate(executionEnvironment , (Term)ActualTerm); | |
/************* Execution mode handling*********************/ | |
if( ActualTerm instanceof VariableReference | |
// the CollectionIterator rule's actual parameter | |
&& (ruleToBeInterpreted).getLocalVariables().contains(((VariableReference)ActualTerm).getVariable())) | |
{ | |
if( ruleToBeInterpreted instanceof ForallRule) | |
pcs.setExecutionMode(ExecutionMode.MULTIPLE_RESULTS); | |
else | |
pcs.setExecutionMode(ExecutionMode.SINGLE_RESULT); | |
// pcs.setParameterMode(ParameterMode.OUTPUT); //the variable is quantified by the BlockRule | |
// checks that the quantified variable is a parameter of the LHS, if not exception | |
boolean isQuantifiedVariableinLHS = false; | |
for(int j = 0; j< gtRule.getPrecondition().getActualParameters().size(); j++){ | |
if(((VariableReference)gtRule.getPrecondition().getActualParameters().get(j)).getVariable().equals(symParam.getVariable())) | |
isQuantifiedVariableinLHS = true; | |
} | |
if(!isQuantifiedVariableinLHS) | |
{ | |
String[] context = {((VariableReference)ActualTerm).getVariable().getName(),gtRule.getName()}; | |
ViatraTransformationException e = new ASMInterpreterException( | |
ASMInterpreterErrorStrings.GTINPUT_QUANTIFIED_NOTIN_LHS | |
,context | |
,gtRule); | |
throw e.addNewStackElement(ruleToBeInterpreted); | |
} | |
} | |
else | |
{ | |
pcs.setExecutionMode(ExecutionMode.SINGLE_RESULT); | |
} | |
/************* Input / Output parameter handling*********************/ | |
if(symParam.getDirection().equals(DirectionKind.IN_LITERAL)) //INPUT | |
{ if((patternParams[i]==null | |
|| ValueKind.UNDEF_LITERAL.equals(patternParams[i]))) | |
{ | |
String[] context = {symParam.getVariable().getName(),gtRule.getName()}; | |
ViatraTransformationException e = new ASMInterpreterException(ASMInterpreterErrorStrings.GTINPUT_IN | |
,context | |
,gtRule); | |
throw e.addNewStackElement(ruleToBeInterpreted); | |
} | |
else | |
pcs.setParameterMode(ParameterMode.INPUT); | |
} | |
else | |
if(symParam.getDirection().equals(DirectionKind.OUT_LITERAL)) //OUTPUT | |
{ | |
if(ActualTerm instanceof VariableReference) | |
{ pcs.setParameterMode(ParameterMode.OUTPUT); | |
patternParams[i] = ValueKind.UNDEF_LITERAL; | |
} | |
else // an OUT parameter is not a Vairable -> throws exception as it is not allowed | |
{ | |
String[] context = {symParam.getVariable().getName(),gtRule.getName()}; | |
ViatraTransformationException e = new ASMInterpreterException(ASMInterpreterErrorStrings.GTINPUT_OUT | |
,context | |
,gtRule); | |
throw e.addNewStackElement(ruleToBeInterpreted); | |
} | |
//if((patternParams[i]==null | |
// || ValueKind.UNDEF_LITERAL.equals(patternParams[i]))) | |
//else | |
// { | |
//if(pcs.getParameterMode() == null) // Its is a quantificated variable if paramterMode != null | |
// { | |
//log.warning(symParam.getName()+" is an OUTPUT parameter but has a value at the invocation of the "); | |
//GTASMException e = new ASMInterpreterException(symParam.getVariable().getName()+ASMInterpreterErrorStrings.GTINPUT_OUT+gtRule.getName()+" gt rule.",gtRule); | |
//throw e.addNewStackElement(ruleToBeInterpreted); | |
// } | |
// } | |
} | |
else | |
//if(symParam.getDirection().equals(DirectionKind.INOUT_LITERAL)) //INOUT | |
{ | |
// in and inout parameter has to have an input value! | |
if((patternParams[i]==null | |
|| ValueKind.UNDEF_LITERAL.equals(patternParams[i]))) | |
{ | |
String[] context = {symParam.getVariable().getName(),gtRule.getName()}; | |
ViatraTransformationException e = new ASMInterpreterException(ASMInterpreterErrorStrings.GTINPUT_IN | |
,context | |
,gtRule); | |
throw e.addNewStackElement(ruleToBeInterpreted); | |
} | |
else | |
pcs.setParameterMode(ParameterMode.INPUT); | |
} | |
/************* Scope of the parameters handling*********************/ | |
if(ActualTerm instanceof VariableReference) // variable type element can be in the scope order | |
{ | |
if(parameterScopes.containsKey(((VariableReference)ActualTerm).getVariable())) | |
pcs.setParameterScope(parameterScopes.get(((VariableReference)ActualTerm).getVariable())); | |
else | |
pcs.setParameterScope(new Scope()); | |
} | |
else //node varibaleReference type input parameter | |
{ | |
pcs.setParameterScope(new Scope()); | |
} | |
/************* Quantification order in case of forall rule*********************/ | |
if(ruleToBeInterpreted instanceof ForallRule) | |
if(ActualTerm instanceof VariableReference) | |
{ | |
if(((ruleToBeInterpreted).getLocalVariables().indexOf(((VariableReference)ActualTerm).getVariable()))==-1) | |
{ | |
// an error occured, there is a variable which is quanitified by the BlockRule but not used in the GT rule | |
if(invocation.getActualParameters().size() == outerVariableCounterForQuantificationOrder) | |
getNoneUsedVariable(ruleToBeInterpreted); | |
quantificationOrder[outerVariableCounterForQuantificationOrder]=i; | |
outerVariableCounterForQuantificationOrder++; | |
} | |
else | |
{ | |
quantificationOrder[((ruleToBeInterpreted).getLocalVariables().indexOf(((VariableReference)ActualTerm).getVariable()))]= i; | |
localVariableCounterForQuantificationOrder++; | |
} | |
} | |
else | |
{ | |
//error a variable is not quantified varibale | |
if(invocation.getActualParameters().size() == outerVariableCounterForQuantificationOrder) | |
getNoneUsedVariable(ruleToBeInterpreted); | |
quantificationOrder[outerVariableCounterForQuantificationOrder]=i; | |
outerVariableCounterForQuantificationOrder++; | |
} | |
// the signature is assigned to the array | |
patternCallSignatures[i]=pcs; | |
} | |
return new PatternMatcherParameters(patternCallSignatures,patternParams,quantificationOrder); | |
} | |
/** Evaluates which parameter is quantified but not used in the (GT rule or pattern) invocation | |
* @param ruleToBeInterpreted the Block rule which invokes the Pattern or GT rule | |
* @throws ViatraTransformationException | |
*/ | |
static void getNoneUsedVariable(CollectionIteratorRule ruleToBeInterpreted) | |
throws ViatraTransformationException{ | |
//Called from a gtPattern or a gtRule | |
String name = (ruleToBeInterpreted).getCondition() instanceof GTPatternCall? | |
((GTPatternCall)(ruleToBeInterpreted).getCondition()).getCalledPattern().getName()+ " pattern" | |
:(ruleToBeInterpreted).getGtrule().getRule().getName() + " GT Rule"; | |
EList<Term> actualParamater = (ruleToBeInterpreted).getCondition() instanceof GTPatternCall? | |
((GTPatternCall)(ruleToBeInterpreted).getCondition()).getActualParameters() | |
:(ruleToBeInterpreted).getGtrule().getActualParameters(); | |
for(int j=0; j< ruleToBeInterpreted.getLocalVariables().size(); j++) | |
{// search for the errorfull variable | |
Variable locVar = ruleToBeInterpreted.getLocalVariables().get(j); | |
boolean usedInRule = false; | |
for(int k = 0; k < actualParamater.size(); k++) | |
{//if it is used in the gtRule then the usedInRule is set to true | |
if(actualParamater.get(k) instanceof VariableReference | |
&& ((VariableReference)actualParamater.get(k)).getVariable().equals(locVar)) | |
usedInRule = true; | |
} | |
if(!usedInRule) //we have the errorful variable | |
{ | |
String[] context = {locVar.getName(),name }; | |
throw new ASMInterpreterException(ASMInterpreterErrorStrings.BLOCKRULE_PARAMS_NOT_USED | |
,context | |
,ruleToBeInterpreted); | |
} | |
} | |
String[] context = {name}; | |
throw new ASMInterpreterException(ASMInterpreterErrorStrings.FATAL_ERROR | |
,context | |
,ruleToBeInterpreted); | |
} | |
/** Returns the appropriate parameters for the PatternMatcher invocation | |
* @param executionEnvironment the execution environment of the invocation context | |
* @param ruleToBeInterpreted the choose/forall rule that is invoked | |
* @param parameterScopes the scope of the parameters | |
* @return the parameters of the rule | |
* @throws ViatraTransformationException | |
*/ | |
static PatternMatcherParameters getMatchParameters(IExecutionEnvironment executionEnvironment | |
, CollectionIteratorRule ruleToBeInterpreted | |
, Map<Variable,Scope> parameterScopes) | |
throws ViatraTransformationException | |
{ | |
CollectionIteratorRule iteratorBlockRule = (ruleToBeInterpreted); | |
int paramSize = ((GTPatternCall)iteratorBlockRule.getCondition()).getActualParameters().size(); | |
//a quantified variable is not used | |
if(paramSize < iteratorBlockRule.getLocalVariables().size()) | |
getNoneUsedVariable(ruleToBeInterpreted); | |
Object[] patternParams = new Object[paramSize]; | |
Integer[] quantificationOrder=new Integer[paramSize]; | |
PatternCallSignature[] patternCallSignatures=new PatternCallSignature[paramSize]; | |
int outerVariableCounterForQuantificationOrder=iteratorBlockRule.getLocalVariables().size(); | |
int localVariableCounterForQuantificationOrder=0; | |
//for (Object term : ((GTPatternCall)((CollectionIteratorRule)ruleToBeInterpreted).getCondition()).getActualParameters()) { | |
for (int i = 0 ; i< paramSize; i++) { | |
Object ActualTerm = ((GTPatternCall)iteratorBlockRule.getCondition()).getActualParameters().get(i); | |
PatternCallSignature pcs=new PatternCallSignature(); | |
patternParams[i] = TermEvaluator.getInstance().evaluate(executionEnvironment , (Term)ActualTerm); | |
/************* Execution mode handling*********************/ | |
if((Term)ActualTerm instanceof VariableReference | |
&& ruleToBeInterpreted instanceof ForallRule | |
&& iteratorBlockRule.getLocalVariables().contains(((VariableReference)ActualTerm).getVariable())) | |
pcs.setExecutionMode(ExecutionMode.MULTIPLE_RESULTS); | |
else | |
pcs.setExecutionMode(ExecutionMode.SINGLE_RESULT); | |
/************* Input / Output parameter handling*********************/ | |
if(patternParams[i]==null||ValueKind.UNDEF_LITERAL.equals(patternParams[i])) | |
{ | |
if((Term)ActualTerm instanceof VariableReference | |
&& iteratorBlockRule.getLocalVariables().contains(((VariableReference)ActualTerm).getVariable())) | |
pcs.setParameterMode(ParameterMode.OUTPUT); | |
else | |
{ | |
String[] context = {""+i}; | |
throw new ASMInterpreterException(ASMInterpreterErrorStrings.BLOCKRULE_PARAM_NOT_QUANTIFIED | |
,context | |
,iteratorBlockRule); | |
} | |
} | |
else | |
pcs.setParameterMode(ParameterMode.INPUT); | |
/************* Scope of the parameters handling*********************/ | |
if(ActualTerm instanceof VariableReference) | |
{ Variable variable = ((VariableReference)ActualTerm).getVariable(); | |
if(parameterScopes.containsKey(variable)) | |
pcs.setParameterScope(parameterScopes.get(variable)); | |
else | |
pcs.setParameterScope(new Scope()); | |
} | |
else | |
{ | |
pcs.setParameterScope(new Scope()); | |
} | |
patternCallSignatures[i]=pcs; | |
/************* Quantification order in case of forall rule*********************/ | |
if(ruleToBeInterpreted instanceof ForallRule) | |
if(ActualTerm instanceof VariableReference) | |
{ Variable variable = ((VariableReference)ActualTerm).getVariable(); | |
//is it a variable which is quantified | |
if(iteratorBlockRule.getLocalVariables().indexOf(variable)==-1) | |
{ | |
//an error occured, there is a variable which is quanitificated by the BlockRule but not used in the GT pattern. Throws ViatraTransformationException | |
if(paramSize == outerVariableCounterForQuantificationOrder) | |
getNoneUsedVariable(ruleToBeInterpreted); | |
quantificationOrder[outerVariableCounterForQuantificationOrder]=i; | |
outerVariableCounterForQuantificationOrder++; | |
} | |
else | |
{ | |
quantificationOrder[iteratorBlockRule .getLocalVariables().indexOf(variable)]= i; | |
localVariableCounterForQuantificationOrder++; | |
} | |
} | |
else | |
{ | |
quantificationOrder[outerVariableCounterForQuantificationOrder]=i; | |
outerVariableCounterForQuantificationOrder++; | |
} | |
}// end of for cycle | |
return new PatternMatcherParameters(patternCallSignatures,patternParams,quantificationOrder); | |
} | |
/** Creates a new execution environment for a CollectionIterator rule | |
* @param executionEnvironment the parent execution environment | |
* @param ruleToBeInterpreted the CollectionIterator rule | |
* @return new execution environment, where parent = executionEnviroment | |
*/ | |
static BlockRuleExecutionEnvironment getNewExecutionEnvironment(IExecutionEnvironment executionEnvironment,CollectionIteratorRule ruleToBeInterpreted) | |
{ | |
// Needs a new Exec.env. for the new Variables. | |
BlockRuleExecutionEnvironment forallRuleExecutionEnvironment = | |
new BlockRuleExecutionEnvironment(executionEnvironment.getFramework(),ruleToBeInterpreted.getBody()); | |
Map<Variable, Object> variables = new Hashtable<Variable, Object>(executionEnvironment.getVariableValues()); | |
for (Object variable : ruleToBeInterpreted.getLocalVariables()) { | |
variables.put((Variable)variable, ValueKind.UNDEF_LITERAL); | |
} | |
forallRuleExecutionEnvironment.onBegin(variables); | |
return forallRuleExecutionEnvironment; | |
} | |
/** | |
* Reorders the matches of the pattern according to the ordering settings, if specified. | |
* | |
* @param gtPattern the pattern that was matched | |
* @param matches the already retrieved matches of the pattern | |
* @return the reordered matches, or the original collection if no ordering was specified | |
*/ | |
@SuppressWarnings("unchecked") | |
static Collection<IMatching> reorder(GTPattern gtPattern, Collection<IMatching> matches) { | |
// is ordering required? | |
Integer orderColoumn = null; | |
boolean orderDesc = false; | |
String orderType = "string"; | |
for (Object annot : gtPattern.getRuntimeAnnotations()) { | |
RuntimeAnnotation annot2 = (RuntimeAnnotation) annot; | |
if ("@orderby".equals(annot2.getAnnotationName().toLowerCase())) { | |
for (Object oRel: annot2.getElements()) { | |
RuntimeAnnotationElement rel = (RuntimeAnnotationElement)oRel; | |
if ("col".equals(rel.getKey().toLowerCase())) { | |
try { | |
orderColoumn = Integer.parseInt(rel.getValue()); | |
} catch (NumberFormatException ex) { | |
//throw new ASMInterpreterException("", , forallGTPatternCall); | |
} | |
} | |
else if ("order".equals(rel.getKey().toLowerCase()) && "desc".equals(rel.getValue().toLowerCase())) | |
orderDesc = true; | |
else if ("type".equals(rel.getKey().toLowerCase())) | |
orderType = rel.getValue().toLowerCase(); | |
} | |
break; | |
} | |
} | |
// if yes, do the ordering | |
if (orderColoumn !=null) | |
{ | |
final boolean desc = orderDesc; | |
final Map<IMatching, Comparable> keys = new HashMap<IMatching, Comparable>(); | |
for (IMatching match : matches) { | |
Object col = match.lookup(orderColoumn); | |
Comparable key = null; | |
if (col!=null) { | |
if (col instanceof IEntity) { | |
if ("name".equals(orderType)) key = ((IModelElement)col).getName(); | |
else if ("name-nocase".equals(orderType)) key = ((IModelElement)col).getName().toLowerCase(); | |
else if ("fqn".equals(orderType)) key = ((IModelElement)col).getFullyQualifiedName(); | |
else if ("fqn-nocase".equals(orderType)) key = ((IModelElement)col).getFullyQualifiedName().toLowerCase(); | |
else { | |
String value = ((IEntity)col).getValue(); | |
if ("double".equals(orderType)) key = Double.parseDouble(value); | |
else if ("integer".equals(orderType)) key = Integer.parseInt(value); | |
else if ("nocase".equals(orderType)) key = value.toLowerCase(); | |
else if ("value-nocase".equals(orderType)) key = value.toLowerCase(); | |
else key = value; | |
} | |
} else if (col instanceof Comparable) | |
key = (Comparable) col; | |
else key = col.toString(); | |
} | |
keys.put(match, key); | |
} | |
ArrayList<IMatching> matchList = new ArrayList<IMatching>(matches); | |
Collections.sort(matchList, new Comparator<IMatching>() { | |
@Override | |
public int compare(IMatching o1, IMatching o2) { | |
int compareResult = keys.get(o1).compareTo(keys.get(o2)); | |
return desc ? -compareResult : compareResult; | |
} | |
}); | |
matches = matchList; | |
} | |
return matches; | |
} | |
} |