blob: 603ee6960133732d38a0bf9c72b90893854ed58f [file] [log] [blame]
/**
* Copyright (c) 2007 - 2009 OptXware Research and Development LLC.
* 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:
* Daniel Varro - Initial API and implementation
*/
package org.eclipse.viatra2.lpgparser.modelbuilder;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import lpg.lpgjavaruntime.DiagnoseParser;
import lpg.lpgjavaruntime.IToken;
import org.apache.commons.lang.StringEscapeUtils;
import org.eclipse.viatra2.core.IModelSpace;
import org.eclipse.viatra2.errors.info.Location;
import org.eclipse.viatra2.gtasm.support.helper.GTASMHelper;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.compoundRules.ChooseRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.compoundRules.CollectionIteratorRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.compoundRules.CompoundRulesFactory;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.compoundRules.ForallRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.compoundRules.IterateRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.compoundRules.LetRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.compoundRules.NestedRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.compoundRules.ParallelRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.compoundRules.RandomRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.compoundRules.SequentialRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.compoundRules.WhenRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.core.AnnotatedElement;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.core.Annotation;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.core.CoreFactory;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.core.GTASMElement;
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.core.impl.CoreFactoryImpl;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.ASMFunction;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.ChangeEvent;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.DefinitionsFactory;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.ImportDeclaration;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.InitialValue;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.Machine;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.Module;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.NamespaceDefinition;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.Rule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.SymbolicRuleParameter;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.TypeConstant;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.Variable;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.VariableDefinition;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.enums.ChangeKind;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.enums.ContainmentMode;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.enums.CopySemantics;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.enums.DeleteSemantics;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.enums.DirectionKind;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.enums.LogLevel;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.enums.MultiplicityKind;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.enums.ValueKind;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.simpleRules.ASMRuleInvocation;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.simpleRules.CallRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.simpleRules.ConditionalRuleIf;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.simpleRules.ConditionalRuleTry;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.simpleRules.FailRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.simpleRules.GTRuleInvocation;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.simpleRules.LogRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.simpleRules.PrintLnRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.simpleRules.PrintRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.simpleRules.RuleUpdateASMFunction;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.simpleRules.RuleUpdateVariable;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.simpleRules.SimpleRulesFactory;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.simpleRules.SkipRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.simpleRules.impl.SimpleRulesFactoryImpl;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.ASMFunctionInvocation;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.Constant;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.FunctionInvocation;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.GTPatternCall;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.ModelElementQuery;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.NativeFunctionInvocation;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.Term;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.TermsFactory;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.VariableReference;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.builtInFunctions.And;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.builtInFunctions.BuiltInFunctionsFactory;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.builtInFunctions.ConversionOperation;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.builtInFunctions.Division;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.builtInFunctions.Equals;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.builtInFunctions.Minus;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.builtInFunctions.Multiply;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.builtInFunctions.Not;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.builtInFunctions.NotEquals;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.builtInFunctions.Or;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.builtInFunctions.Plus;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.builtInFunctions.RelationalOperation;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.builtInFunctions.Remainder;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.builtInFunctions.XOr;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.gt.ContainmentConstraint;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.gt.GTMatchCounter;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.gt.GTPattern;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.gt.GTPatternBody;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.gt.GTRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.gt.GtFactory;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.gt.NonInjectivityConstraint;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.gt.PatternVariable;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.gt.PatternVariableAssignment;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.gt.PatternVariableConstraint;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.manipulationRules.copymove.CopymoveFactory;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.manipulationRules.copymove.ModelCopyRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.manipulationRules.copymove.MoveRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.manipulationRules.creation.CreateInstanceOf;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.manipulationRules.creation.CreateSupertypeOf;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.manipulationRules.creation.CreationFactory;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.manipulationRules.creation.ElementCreateRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.manipulationRules.creation.EntityCreateRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.manipulationRules.creation.RelationCreateRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.manipulationRules.creation.RelationshipCreateRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.manipulationRules.deletion.DeleteInstanceOf;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.manipulationRules.deletion.DeleteSupertypeOf;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.manipulationRules.deletion.DeletionFactory;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.manipulationRules.deletion.ElementDeleteRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.manipulationRules.deletion.RelationshipDeleteRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.manipulationRules.update.SetRule;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.manipulationRules.update.UpdateFactory;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.queryFunctions.ElementReference;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.queryFunctions.QueryFunctionsFactory;
import org.eclipse.viatra2.gtasmmodel.vpm.editmodel.EditmodelFactory;
import org.eclipse.viatra2.gtasmmodel.vpm.editmodel.Entity;
import org.eclipse.viatra2.gtasmmodel.vpm.editmodel.ModelElement;
import org.eclipse.viatra2.gtasmmodel.vpm.editmodel.Relation;
import org.eclipse.viatra2.gtasmmodel.vpm.editmodel.SupertypeOf;
import org.eclipse.viatra2.gtasmmodel.vpm.editmodel.TypeOf;
import org.eclipse.viatra2.lpgparser.ast.*;
import org.eclipse.viatra2.lpgparser.typechecker.VTCLTypeChecker;
import org.eclipse.viatra2.natives.ASMNativeFunction;
/**
* This class implements a recursive traversal of the VTCL AST in order to build
* an EMF representation of the VTCL program.
*
* @author Daniel Varro
*
*/
public class VTCLModelBuilder extends AbstractResultVisitor {
private VTCLModelResolver modelResolver = null;
private VTCLTypeChecker typeChecker = null;
public VTCLModelBuilder(IModelSpace modelSpace, ASMNativeFunction[] asmNativeFunctions) {
modelResolver = new VTCLModelResolver( modelSpace, asmNativeFunctions);
typeChecker = new VTCLTypeChecker(modelSpace);
//modelResolver.setTypeAssignments(typeChecker.getTypeAssignments());
}
public VTCLTypeChecker getTypeChecker() {
return typeChecker;
}
public VTCLModelResolver getModelResolver() {
return modelResolver;
}
private String fileName = "";
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
private DiagnoseParser diagnoseParser = null;
public DiagnoseParser getDiagnoseParser() {
return diagnoseParser;
}
public void setDiagnoseParser(DiagnoseParser diagnoseParser) {
this.diagnoseParser = diagnoseParser;
}
// private Object diagnoseOnce(VTCLParser parser) {
// if (getDiagnoseParser() == null) {
// ParseTable prsTable = new VTCLParserprs();
// DiagnoseParser diagnoseParser = new DiagnoseParser(parser, prsTable );
// setDiagnoseParser(diagnoseParser);
//// diagnoseParser.diagnose(n.getEnvironment().badToken());
// diagnoseParser.diagnose();
// }
// return null;
//
// }
/**
* Removes the "s surrounding a quoted string, if any.
*
* @param quoted a possibly quoted string
* @return <code>quoted</code> without the surrounding quotes, or just
* <code>quoted</code> verbatim if there were none
*/
private String unquote(String quoted) {
String result = quoted;
if ((result != null) && (result.length() > 1)) {
int max = result.length() - 1;
if ((result.charAt(0) == '"') && (quoted.charAt(max) == '"')) {
result = result.substring(1, max);
// this is a regexp, so the backslash needs to be
// re-escaped, thus "\\" is rendered in a Java
// string literal as "\\\\"
result = result.replaceAll("\\\\\"", "\""); //$NON-NLS-2$//$NON-NLS-1$
}
else if ((result.charAt(0) == '\'') && (quoted.charAt(max) == '\'')) {
result = result.substring(1, max);
// Maybe, the following line should be \\\\\" instead of \\\\\'
result = result.replaceAll("\\\\\'", "\'"); //$NON-NLS-2$//$NON-NLS-1$
}
}
return result;
}
// /**
// * Creates an annotation to store the fully qualified name of
// * referenced elements for the second run (to resolve references)
// *
// * @param element : a GTASMElement (from the model)
// * @param kind : AnnotationKey
// * @param value : the String to be stored
// */
// @SuppressWarnings("unchecked")
// private void annotateElement(GTASMElement element, String kind, String value) {
// Annotation info = CoreFactoryImpl.eINSTANCE.createAnnotation();
// info.setKey(kind);
// info.setValue(value);
// element.getAnnotations().add(info);
// }
/**
* Copies line and column information as annotation to the model element
* This node is called whenever a new GTASM model element is created
*
* @param node : an ASTNode node (from the AST)
* @param element : a GTASMElement (from the model)
*/
private void createNodeInfoFor(ASTNode node, AnnotatedElement element)
{
element.getAnnotations().add( createNodeInfoFrom(node));
element.getAnnotations().add( createNodeOffsetFrom(node));
}
private Annotation createNodeInfoFrom(ASTNode node)
{
Annotation nodeInfo = CoreFactoryImpl.eINSTANCE.createAnnotation();
nodeInfo.setKey(GTASMHelper.NODE_INFORMATION);
int bl = node.getLeftIToken().getLine();
int bc = node.getLeftIToken().getColumn();
int el = node.getRightIToken().getEndLine();
int ec = node.getRightIToken().getEndColumn();
if (bl == el && bc == ec) {
ec = ec + 1;
}
Location location = new Location(bl, bc, el, ec);
String value = location.toString();
nodeInfo.setValue(value);
return nodeInfo;
}
private Annotation createNodeOffsetFrom(ASTNode node) {
Annotation nodeOffset = CoreFactoryImpl.eINSTANCE.createAnnotation();
nodeOffset.setKey(GTASMHelper.NODE_OFFSET);
int start = node.getLeftIToken().getStartOffset();
int end = node.getRightIToken().getEndOffset();
String value = String.format("%d:%d", start, end);
nodeOffset.setValue(value);
return nodeOffset;
}
/**
* Copies line annotation from one GTASMElement to the other
* @param fromElem
* @param toElem
*/
private void copyNodeInfoFrom(GTASMElement fromElem, GTASMElement toElem) {
String locStr = GTASMHelper.extractAnnotation(fromElem, GTASMHelper.NODE_INFORMATION);
if (locStr != "") {
Annotation nodeInfo = CoreFactoryImpl.eINSTANCE.createAnnotation();
nodeInfo.setKey(GTASMHelper.NODE_INFORMATION);
nodeInfo.setValue(locStr);
toElem.getAnnotations().add( nodeInfo);
}
String offsetStr = GTASMHelper.extractAnnotation(toElem, GTASMHelper.NODE_OFFSET);
if (offsetStr != "") {
Annotation nodeOffset = CoreFactoryImpl.eINSTANCE.createAnnotation();
nodeOffset.setKey(GTASMHelper.NODE_OFFSET);
nodeOffset.setValue(offsetStr);
toElem.getAnnotations().add( nodeOffset);
}
}
@Override
public Object unimplementedVisitor(String s) {
System.out.println(s);
return String.valueOf("UnimplementedVisitor");
}
@Override
public Object visit(VTCLFile n) {
Module emfModule = DefinitionsFactory.eINSTANCE.createModule();
if (n.getNamespaceDefAST() != null) {
n.getNamespaceDefAST().accept(this, emfModule);
}
if (n.getNamespaceImportsAST() != null) {
n.getNamespaceImportsAST().accept(this, emfModule);
}
n.getGTASMDefAST().accept(this, emfModule);
// Set File Name of Module
emfModule.setFileName(fileName);
// Set Name of Module to be short file name -- Istvan
File f = new File(fileName);
emfModule.setName(f.getName());
return emfModule;
}
/**
* Visiting a {@link NamespaceDefAST} AST node and
* creating a {@link NamespaceDefinition} model element
* @param n : {@link NamespaceDefAST}
* @param o : {@link Module}
*/
@Override
public Object visit(NamespaceDefAST n, Object o) {
Module emfModule = (Module) o;
String namespaceFqn = (String) n.getQualifiedTypeNameAST().accept(this);
NamespaceDefinition namespace = DefinitionsFactory.eINSTANCE.createNamespaceDefinition();
namespace.setNamespaceValue(namespaceFqn);
namespace.setName(namespace.getNamespaceValue());
emfModule.setNamespace(namespace);
createNodeInfoFor(n,namespace);
return namespace;
}
// /**
// * Visiting a {@link NamespaceDefAST1} (ERROR_TOKEN)
// * @param n : {@link NamespaceDefAST1}
// */
// @Override
// public Object visit(NamespaceDefAST1 n, Object o) {
// ParseTable prsTable = new VTCLParserprs();
// DiagnoseParser diagnoseParser = new DiagnoseParser(n.getEnvironment(), prsTable );
// diagnoseParser.diagnose(n.getEnvironment().badToken());
// return null;
// }
/**
* Visiting a {@link NamespaceImportsAST} AST node to process
* all Namespace imports one by one
* @param n : {@link NamespaceImportAST0}
*/
@Override
public Object visit(NamespaceImportsAST n, Object o) {
Module emfModule = (Module) o;
// First add the left-most declarations
if (n.getNamespaceImportsAST() != null) {
n.getNamespaceImportsAST().accept(this, emfModule);
}
// Then add the right-most (unprocessed) declaration
ImportDeclaration importDecl = (ImportDeclaration) n.getNamespaceImportAST().accept(this);
if (importDecl != null) {
emfModule.getImport().add(importDecl);
importDecl.setName(importDecl.getImportValue());
}
return emfModule;
}
/**
* Visiting a {@link NamespaceImportAST0}, and
* creating an {@link ImportDeclaration}
* @param n : {@link NamespaceImportAST0}
*/
@Override
public Object visit(NamespaceImportAST0 n) {
// Import declaration is valid
String importStr = (String) n.getQualifiedTypeNameAST().accept(this);
ImportDeclaration importDecl = DefinitionsFactory.eINSTANCE.createImportDeclaration();
importDecl.setImportValue(importStr);
createNodeInfoFor(n,importDecl);
modelResolver.resolveNamespaceImport(importDecl);
return importDecl;
}
/**
* Visiting a {@link NamespaceImportAST1} (ERROR_TOKEN)
* @param n : {@link NamespaceImportAST1}
*/
@Override
public Object visit(NamespaceImportAST1 n) {
return null;
//return diagnoseOnce(n.getEnvironment());
}
/**
* Visiting a GTASMDefAST node
* and creating a Machine model element
* @param n : Current AST node of type GTASMDefAST
* @param o : a VTCL Module
*/
@Override
public Object visit(GTASMDefAST n, Object o) {
Module emfModule = (Module) o;
// Creating a new Machine
Machine emfMachine = DefinitionsFactory.eINSTANCE.createMachine();
// Initializing buffers for unresolved elements
modelResolver.setMachine(emfMachine);
modelResolver.clearBuffers();
// Setting its name and namespace
String localName = (String) n.getTypeNameAST().accept(this);
NamespaceDefinition namespace = emfModule.getNamespace();
emfMachine.setName(localName);
emfMachine.setFqn(((namespace != null) ? namespace.getNamespaceValue() + "." + localName : localName ) );
// Adding the Machine to the Module
emfModule.getMachine().add(emfMachine);
// Processing the contents
n.getMachineContentsAST().accept(this, emfMachine);
createNodeInfoFor(n, emfMachine);
// Processing runtime annotations
if (n.getOptAnnotationsAST() != null) {
n.getOptAnnotationsAST().accept(this, emfMachine.getRuntimeAnnotations());
}
//Loading documentation
loadDocumentationComments(n, emfMachine);
modelResolver.resolveModel();
return emfModule;
}
/**
* Visiting a MachineContentsAST node
* @param n : Current AST node of type MachineContentsAST
* @param o : a Machine
*/
@Override
public Object visit(MachineContentsAST n, Object o) {
Machine asmMachine = (Machine) o;
n.getMachineContentsAST().accept(this, asmMachine);
n.getMachineContentAST().accept(this, asmMachine);
return asmMachine;
}
@Override
public Object visit(MachineContentAST n) {
return null;
//return diagnoseOnce(n.getEnvironment());
}
@Override
public Object visit(MachineContentAST n, Object o) {
return visit(n);
}
/**
* Visiting an AsmRuleDefAST node and
* creating an (ASM) Rule
* @param n : Current AST node of type AsmRuleDefAST
* @param o : a Machine
*/
@Override
public Object visit(AsmRuleDefAST n, Object o) {
Machine asmMachine = (Machine) o;
Rule asmRule = DefinitionsFactory.eINSTANCE.createRule();
// Setting the name of the ASM Rule
String ruleStr = (String) n.getTypeNameAST().accept(this);
asmRule.setName(ruleStr);
asmRule.setFqn( asmMachine.getFqn() + "." + ruleStr);
if (ruleStr.equals( "main")) {
asmMachine.setMainRule(asmRule);
}
asmRule.setNamespace(asmMachine);
asmMachine.getAsmRuleDefinitions().add(asmRule);
// Process formal parameters
n.getDirectedFormalParameterDefAST().accept(this, asmRule.getSymParameters());
for (Iterator<SymbolicRuleParameter> iter = asmRule.getSymParameters().iterator(); iter.hasNext();) {
SymbolicRuleParameter param = iter.next();
asmRule.getLocalVariables().add(param.getVariable());
}
// Processing the body of the rule
// ASMRuleInvocation body = (ASMRuleInvocation)
n.getAsmRuleAST().accept(this, asmRule);
// asmRule.setBody(body);
createNodeInfoFor(n, asmRule);
// Processing runtime annotations
if (n.getOptAnnotationsAST() != null) {
n.getOptAnnotationsAST().accept(this, asmRule.getRuntimeAnnotations());
}
//Loading documentation
loadDocumentationComments(n, asmRule);
return asmMachine;
}
/**
* Visiting an AsmRuleAST (ERROR_TOKEN)
* @param n : AsmRuleAST
* @param o :
*/
@Override
public Object visit(AsmRuleAST n, Object o) {
return null;
//return diagnoseOnce(n.getEnvironment());
}
// ************** Sec. 5.2.1 Pattern definition ************************** //
/**
* Visiting a GraphPatternDefAST node and creating a GTPattern
* (should be called from a machine)
*
* @param n : GraphPatternDefAST
* @param o : Machine
* @return machine: Machine
*/
@Override
public Object visit(GraphPatternDefAST n, Object o) {
Machine machine = (Machine) o;
// Create a new GTPattern
GTPattern pattern = GtFactory.eINSTANCE.createGTPattern();
pattern.setNamespace(machine);
pattern.setContainer(machine);
// Set non-injective matching strategy if pattern is defined as sharable
if (n.getOptShareableDefAST() != null) {
pattern.setDistinctMatching(false);
}
// Default matching strategy is distinct matching
else {
pattern.setDistinctMatching(true);
}
// Setting the name of the pattern
String patternName = (String) n.getTypeNameAST().accept(this);
pattern.setName(patternName);
pattern.setFqn(machine.getFqn() + "." + patternName);
// Processing symbolic parameters
n.getFormalParameterDefAST().accept(this, pattern.getSymParameters());
// Processing pattern bodies
n.getPatternBodiesAST().accept(this, pattern.getPatternBodies());
// Creating node information
createNodeInfoFor(n, pattern);
// Processing runtime annotations
if (n.getOptAnnotationsAST() != null) {
n.getOptAnnotationsAST().accept(this, pattern.getRuntimeAnnotations());
}
//Loading documentation
loadDocumentationComments(n, pattern);
// Type checking
typeChecker.getPatternDefToCheck().add(pattern);
return machine;
}
/**
* Visiting a GraphPatternDefAST node and creating a GTPattern
* (should be called from negative patterns or GT Rules)
*
* @param n : {@link GraphPatternDefAST}
* @return pattern : {@link GTPattern}, which is created
*/
@Override
public Object visit(GraphPatternDefAST n) {
// Create a new GTPattern
GTPattern pattern = GtFactory.eINSTANCE.createGTPattern();
// Set non-injective matching strategy if pattern is defined as sharable
if (n.getOptShareableDefAST() != null) {
pattern.setDistinctMatching(false);
}
// Default matching strategy is distinct matching
else {
pattern.setDistinctMatching(true);
}
// Setting the name of the pattern
pattern.setName((String) n.getTypeNameAST().accept(this));
// Processing symbolic parameters
n.getFormalParameterDefAST().accept(this, pattern.getSymParameters());
// Processing pattern bodies
n.getPatternBodiesAST().accept(this, pattern.getPatternBodies());
// Creating node information
createNodeInfoFor(n, pattern);
// Processing runtime annotations
if (n.getOptAnnotationsAST() != null) {
n.getOptAnnotationsAST().accept(this, pattern.getRuntimeAnnotations());
}
//Loading documentation
loadDocumentationComments(n, pattern);
// Type checking
typeChecker.getPatternDefToCheck().add(pattern);
return pattern;
}
// /**
// * Visiting a GraphPatternDefAST1 node (ERROR_TOKEN)
// *
// * @param n : GraphPatternDefAST1
// */
// @Override
// public Object visit(GraphPatternDefAST1 n) {
// if (getDiagnoseParser() == null) {
// ParseTable prsTable = new VTCLParserprs();
// DiagnoseParser diagnoseParser = new DiagnoseParser(n.getEnvironment(), prsTable );
// setDiagnoseParser(diagnoseParser);
//// diagnoseParser.diagnose(n.getEnvironment().badToken());
// diagnoseParser.diagnose();
// }
// return null;
// }
// @Override
// public Object visit(GraphPatternDefAST1 n, Object o) {
// return visit(n);
// }
/**
* Visiting a PatternBodiesAST node and adding a new GTPatternBody
* to the list of GTPatternBodies of the current GTPattern
*
* @param n : PatternBodiesAST
* @param o : list of {@link GTPatternBody}
* @return pattern : GTPattern
*/
@Override
public Object visit(PatternBodiesAST n, Object o) {
@SuppressWarnings("unchecked")
List<GTPatternBody> patternList = (List<GTPatternBody>) o;
n.getPatternBodiesAST().accept(this, patternList);
n.getPatternBodyAST().accept(this, patternList);
return patternList;
}
/**
* Visiting a PatternBodyAST0 node and creating a GTPatternBody
* A new Entity is also created as the top-level container of the pattern graph
*
* @param n : PatternBodyAST0
* @param o : List (of GTPatternBody)
* @return patternList : of GTPatternBody containing the current body
*/
@Override
public Object visit(PatternBodyAST n, Object o) {
@SuppressWarnings("unchecked")
List<GTPatternBody> patternList = (List<GTPatternBody>) o;
GTPatternBody body = GtFactory.eINSTANCE.createGTPatternBody();
// Clearing helper collections
modelResolver.getOrphanBodyElements(body).clear();
modelResolver.getUnresolvedPatternVariableRefs(body).clear();
modelResolver.getBodyMapElement4Var(body).clear();
modelResolver.getBodyMapVar4Element(body).clear();
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
// Create a new container entity for local pattern elements
Entity topElement = EditmodelFactory.eINSTANCE.createEntity();
topElement.setName("top");
body.setPatternGraph(topElement);
// Add the new body to the GTPattern
patternList.add(body);
// Process the contents of the pattern body
if (n.getPatternBodyContentsAST() != null) {
n.getPatternBodyContentsAST().accept(this, body);
}
createNodeInfoFor(n, topElement);
// Resolve model element references
modelResolver.resolveModelElementReferences(body);
modelResolver.resolvePatternVariableRefs(body);
modelResolver.resolveVariableRefsInRule(body);
// Type checking for the check condition is carried out as for regular terms
modelResolver.getUnresolvedVariableRefsStack().pop();
// Resolving type strings
modelResolver.resolveEntityTypesInBody(body);
modelResolver.resolveRelationTypesInBody(body);
// Report if a pattern parameter is not used in the body
modelResolver.reportUnusedPatternParameter(body);
return patternList;
}
// /**
// * Visiting a PatternBodyAST1 node (ERROR_TOKEN)
// *
// * @param n : PatternBodyAST1
// * @param o : GTPattern
// */
// @Override
// public Object visit(PatternBodyAST1 n, Object o) {
// ParseTable prsTable = new VTCLParserprs();
// DiagnoseParser diagnoseParser = new DiagnoseParser(n.getEnvironment(), prsTable );
// diagnoseParser.diagnose(n.getEnvironment().badToken());
// return o;
// }
/**
* Visiting a PatternBodyContentAST node (ERROR_TOKEN)
*
* @param n : PatternBodyContentAST
* @param o : GTPatternBody
*/
@Override
public Object visit(PatternBodyContentAST n, Object o) {
return null;
//return diagnoseOnce(n.getEnvironment());
}
/**
* Visiting a PatternBodyContentsAST node and processing the next BodyContent
* (Entity, Relation, Relationship, PatternComposition, NegativePattern,
* PatternVariableAssignment, CheckCondition)
*
* @param n : PatternBodyContentAST
* @param o : GTPatternBody
*/
@Override
public Object visit(PatternBodyContentsAST n, Object o) {
GTPatternBody body = (GTPatternBody) o;
if (n.getPatternBodyContentsAST() != null) {
// Clearing the helper attribute storing orphan pattern elements
// Processing pattern body content
n.getPatternBodyContentsAST().accept(this, body);
// Resolving model element references for relations and relationships within pattern
}
n.getPatternBodyContentDefAST().accept(this, body);
return body;
}
/**
* Visiting a PatternCompositionAST node and creating a GTPatternCall
* (should be called from as part of a normal pattern body)
*
* @param n : PatternCompositionAST
* @param o : GTPatternBody
* @return body : GTPatternBody
*/
@Override
public Object visit(PatternCompositionAST n, Object o) {
GTPatternBody body = (GTPatternBody) o;
// Create a new GTPatternCall
GTPatternCall patternCall = TermsFactory.eINSTANCE.createGTPatternCall();
createNodeInfoFor(n, patternCall);
// Store the name of the called pattern as the FQN of the patternCall
String patternName = (String) n.getQualifiedTypeNameAST().accept(this);
patternCall.setFqn(patternName);
patternCall.setName(patternName);
// Adding the new pattern call to the body
body.getCalledPatterns().add(patternCall);
// Process the actual parameters of the called pattern
n.getActualPatternParameterDefAST().accept(this, patternCall.getActualParameters());
for (Term param : patternCall.getActualParameters()) {
// Create a PatternVariable definition if varRef cannot be resolved
// Return the corresponding PatternVariable, if already defined
VariableReference varRef = (VariableReference) param;
modelResolver.resolveLocalVariableInPattern(varRef, body);
// Type checking
typeChecker.getTermsToCheck().add(varRef);
}
// Type check compatibility of actual parameters
typeChecker.getPatternCallToCheck().add(patternCall);
if (n.getOptMatchCountAST() != null) {
VariableReference varRef = (VariableReference) n.getOptMatchCountAST().accept(this);
// Always create a new PatternVariable definition
PatternVariable varDef = modelResolver.createPatternVariableFromReference(varRef);
body.getLocalVariables().add(varDef);
// Create node information for the new variable definition
createNodeInfoFor(/*(ASTNode)*/ n.getOptMatchCountAST().getCounterVariableAST(), varDef);
// Add variable definition to the local variables of the pattern body
body.getLocalVariables().add(varDef);
// Create a match counter
GTMatchCounter matchCounter = GtFactory.eINSTANCE.createGTMatchCounter();
matchCounter.setPatternCall(patternCall);
matchCounter.setVariableReference(varRef);
// Create node information for the match counter
createNodeInfoFor(/*(ASTNode)*/ n.getOptMatchCountAST(), matchCounter);
}
// Resolve the reference to the called pattern in a later stage
modelResolver.getUnresolvedPatternCalls().add(patternCall);
return patternCall;
}
/**
* Visiting a PatternCompositionAST node and creating a GTPatternCall
* (should be called from as part of a negative pattern composition)
*
* @param n : PatternCompositionAST
* @return body : GTPatternBody
*/
@Override
public Object visit(PatternCompositionAST n) {
// Create a new GTPatternCall
GTPatternCall patternCall = TermsFactory.eINSTANCE.createGTPatternCall();
// Store the name of the called pattern as the FQN of the patternCall
String patternName = (String) n.getQualifiedTypeNameAST().accept(this);
patternCall.setFqn(patternName);
patternCall.setName(patternName);
createNodeInfoFor(n, patternCall);
// Process the actual parameters of the called pattern
n.getActualPatternParameterDefAST().accept(this, patternCall.getActualParameters());
// Type checking the actual parameters?
for (Term param : patternCall.getActualParameters()) {
VariableReference varRef = (VariableReference) param;
// We do not need to call resolveLocalVariableInPattern as negative patterns do not create variables in caller
// Type checking for variable references
typeChecker.getTermsToCheck().add(varRef);
}
// Type check compatibility of actual parameters
typeChecker.getPatternCallToCheck().add(patternCall);
// Initiate to resolve variable references in the caller, NOT here
// Resolve the reference to the called pattern in a later stage
modelResolver.getUnresolvedPatternCalls().add(patternCall);
return patternCall;
}
/**
* Visiting a NegativePatternAST0 node (Negative pattern call)
* and creating a negative GTPatternCall
*
* @param n : NegativePatternAST0
* @param o : GTPatternBody
* @return body : GTPatternBody
*/
@Override
public Object visit(NegativePatternAST n, Object o) {
GTPatternBody body = (GTPatternBody) o;
GTPatternCall patternCall = (GTPatternCall) n.getPatternCompositionAST().accept(this);
if (patternCall != null) {
body.getNegativePatterns().add(patternCall);
// Resolve variable references in a later stage
for (Term param : patternCall.getActualParameters()) {
VariableReference varRef = (VariableReference) param;
modelResolver.resolveLocalVariableInPattern(varRef, body);
// Type checking for variable references
typeChecker.getTermsToCheck().add(varRef);
}
}
// Type check compatibility of actual parameters
typeChecker.getPatternCallToCheck().add(patternCall);
// Match counters are not allowed in negative pattern calls
if (n.getPatternCompositionAST().getOptMatchCountAST() != null) {
modelResolver.reportInvalidMatchCounter(patternCall, "negative pattern calls");
}
// // Resolve the reference to the called pattern in a later stage
// unresolvedPatternCalls.add(patternCall);
return body;
}
/**
* Visiting a {@link PatternBodyContentDefAST0} node (Body content with SEMICOLON)
* and creating a negative GTPatternCall and a GTPattern
*
* @param n : NegativePatternAST1
* @param o : GTPatternBody
* @return body : GTPatternBody
*/
@Override
public Object visit(PatternBodyContentDefAST0 n, Object o) {
return n.getPatternBodyContentAST().accept(this, o);
}
/**
* Visiting a {@link PatternBodyContentDefAST1} node (Negative pattern definition)
* and creating a negative GTPatternCall and a GTPattern
*
* @param n : {@link PatternBodyContentDefAST1}
* @param o : {@link GTPatternBody}
* @return body : {@link GTPatternBody}
*/
@Override
public Object visit(PatternBodyContentDefAST1 n, Object o) {
GTPatternBody body = (GTPatternBody) o;
// Create a local GT pattern definition
GTPattern pattern = (GTPattern) n.getGraphPatternDefAST().accept(this);
body.getGtPatternDefinitions().add(pattern);
pattern.setNamespace(body.getHeader().getNamespace());
// Set FQN of the negative pattern
String fqn = body.getHeader().getFqn();
pattern.setFqn((fqn != null)? fqn + "." + pattern.getName() : pattern.getName());
// Create a negative GT pattern call
GTPatternCall patternCall = TermsFactory.eINSTANCE.createGTPatternCall();
body.getNegativePatterns().add(patternCall);
// Set the reference to the locally defined pattern
patternCall.setCalledPattern(pattern);
// Create actual parameters of the called pattern from the symbolic parameters
for (Object symParam: pattern.getSymParameters()) {
PatternVariable patternVar = (PatternVariable) symParam;
// Create a VariableReference
VariableReference varRef = TermsFactory.eINSTANCE.createVariableReference();
varRef.setName(patternVar.getName());
patternCall.getActualParameters().add(varRef);
// Resolve the reference to the variable of the CALLER pattern in a later stage
modelResolver.resolveLocalVariableInPattern(varRef, body);
// Type checking
typeChecker.getTermsToCheck().add(varRef);
}
copyNodeInfoFrom( pattern, patternCall);
return patternCall;
}
/**
* Visiting a CheckConditionAST node and
* returning a Term model element
* @param n : Current AST node of type CheckConditionAST
* @param o : GTPatternBody
* @return checkCond : Term
*/
@Override
public Object visit(CheckConditionAST n, Object o) {
GTPatternBody body = (GTPatternBody) o;
Term checkCond = (Term) n.getLogicalTermAST().accept(this);
body.getCheckExpressions().add(checkCond);
// Type checking for check condition
typeChecker.getTermsToCheck().add(checkCond);
return checkCond;
}
/**
* Visiting a PatternVariableAssignmentAST node and
* returning a PatternVariableAssignment model element
* @param n : Current AST node of type PatternVariableAssignmentAST
* @param o : GTPatternBody
* @return the created PatternVariableAssignment
*/
@Override
public Object visit(PatternVariableAssignmentAST n, Object o) {
GTPatternBody body = (GTPatternBody) o;
// Process left and right values
VariableReference left = (VariableReference) n.getPatternVariableRefAST().accept(this);
VariableReference right = (VariableReference) n.getPatternVariableRefAST3().accept(this);
// Create new PatternVariableAssignment
PatternVariableAssignment varAssign = GtFactory.eINSTANCE.createPatternVariableAssignment();
varAssign.setName(n.getPatternVariableRefAST().toString());
// varAssign.setLeftValue(left);
// varAssign.setRightValue(right);
body.getVariableAssignments().add(varAssign);
// Create node information
createNodeInfoFor(n, varAssign);
// // Check that left and right values are different
// modelResolver.validatePatternVariableConstraint(varAssign);
// // Resolve VariableReferences in a later stage
// modelResolver.getUnresolvedPatternVariableRefs(body).add(left);
// modelResolver.getUnresolvedPatternVariableRefs(body).add(right);
createPatternVariableConstraint(varAssign, left, right, body);
return varAssign;
}
/**
* Visiting a {@link NonInjectivityConstraintAST} node and
* returning a {@link NonInjectivityConstraint} model element
* @param n : Current AST node of type {@link NonInjectivityConstraintAST}
* @param o : GTPatternBody
* @return the created {@link NonInjectivityConstraint}
*/
@Override
public Object visit(NonInjectivityConstraintAST n, Object o) {
GTPatternBody body = (GTPatternBody) o;
// Process left and right values
VariableReference left = (VariableReference) n.getPatternVariableRefAST().accept(this);
VariableReference right = (VariableReference) n.getPatternVariableRefAST3().accept(this);
// Create new PatternVariableAssignment
NonInjectivityConstraint noninjConstraint = GtFactory.eINSTANCE.createNonInjectivityConstraint();
body.getNonInjectivityConstraints().add(noninjConstraint);
// Create node information
createNodeInfoFor(n, noninjConstraint);
createPatternVariableConstraint(noninjConstraint, left, right, body);
return noninjConstraint;
}
/**
* Provides uniform handling for pattern variable assignments and non-injectivity constraints
* @param constraint : {@link PatternVariableConstraint}
* @param left : {@link VariableReference}
* @param right : {@link VariableReference}
* @param body : {@link GTPatternBody}
*/
protected void createPatternVariableConstraint(PatternVariableConstraint constraint,
VariableReference left,
VariableReference right,
GTPatternBody body) {
constraint.setLeftValue(left);
constraint.setRightValue(right);
// Check that left and right values are different
modelResolver.validatePatternVariableConstraint(constraint);
// Resolve VariableReferences in a later stage
modelResolver.getUnresolvedPatternVariableRefs(body).add(left);
modelResolver.getUnresolvedPatternVariableRefs(body).add(right);
}
/**
* Visiting a PatternVariableDefAST node (definition) and
* returning a PatternVariable
* @param n : Current AST node of type PatternVariableDefAST
* @return var : PatternVariable
*/
@Override
public Object visit(PatternVariableDefAST n) {
PatternVariable var = GtFactory.eINSTANCE.createPatternVariable();
var.setName(n.toString());
createNodeInfoFor(n, var);
return var;
}
/**
* Visiting a PatternVariableDefAST node as part of FormalParamsAST
* returning the parameter list with a VariableReference
* @param n : Current AST node of type PatternVariableRefAST
* @param o : List (of PatternVariable)
* @return parameterList: List (of PatternVariable)
*/
@Override
public Object visit(PatternVariableDefAST n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a PatternVariableRefAST node (variable reference) and
* returning a VariableReference
* @param n : Current AST node of type PatternVariableRefAST
* @return varRef : VariableReference
*/
@Override
public Object visit(PatternVariableRefAST n) {
VariableReference varRef = TermsFactory.eINSTANCE.createVariableReference();
varRef.setName(n.toString());
createNodeInfoFor(n, varRef);
return varRef;
}
/**
* Visiting a PatternVariableRefAST node as part of a ActualParamsPatternVariablesAST
* returning the parameter list with a VariableReference
* @param n : Current AST node of type PatternVariableRefAST
* @param o : List (of VariableReference)
* @return parameterList: List (of VariableReference)
*/
@Override
public Object visit(PatternVariableRefAST n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a {@link PatternVariableDefRefAST0} node
* (variable definition and reference used in entity and relation definitions)
* and returning a VariableReference
* @param n : Current AST node of type {@link PatternVariableDefRefAST0}
* @return varRef : VariableReference
*/
@Override
public Object visit(PatternVariableDefRefAST0 n) {
VariableReference varRef = TermsFactory.eINSTANCE.createVariableReference();
varRef.setName(n.toString());
createNodeInfoFor(n, varRef);
return varRef;
}
/**
* Visiting a {@link PatternVariableDefRefAST1} node
* (variable definition and reference used in entity and relation defs)
* and returning a VariableReference
* @param n : Current AST node of type {@link PatternVariableDefRefAST1}
* @return varRef : VariableReference
*/
@Override
public Object visit(PatternVariableDefRefAST1 n) {
VariableReference varRef = TermsFactory.eINSTANCE.createVariableReference();
varRef.setName(n.toString());
createNodeInfoFor(n, varRef);
return varRef;
}
/**
* Visiting a {@link CounterVariableAST} node (variable defined for match counters)
* and returning a VariableReference
* @param n : Current AST node of type {@link CounterVariableAST}
* @return varRef : VariableReference
*/
@Override
public Object visit(CounterVariableAST n) {
VariableReference varRef = TermsFactory.eINSTANCE.createVariableReference();
varRef.setName(n.toString());
// Counter variables are always integers
varRef.setKind(ValueKind.INTEGER_LITERAL);
varRef.setType("datatypes.Integer");
createNodeInfoFor(n, varRef);
return varRef;
}
@Override
public Object visit(CounterVariableAST n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a GraphPatternCallAST node (from an ASM rule or condition)
* and creating a GTPatternCall model element
* @param n : Current AST node of type GraphPatternCallAST
* @return patternCall : GTPatternCall
*/
@Override
public Object visit(GraphPatternCallAST n) {
// Creating a GTPatternCall
GTPatternCall patternCall = TermsFactory.eINSTANCE.createGTPatternCall();
// Processing actual parameters
n.getActualParameterDefAST().accept(this, patternCall.getActualParameters());
// Type check compatibility of actual parameters
typeChecker.getPatternCallToCheck().add(patternCall);
// Store the name of the called pattern as the FQN of the patternCall
String patternName = (String) n.getQualifiedTypeNameAST().accept(this);
patternCall.setFqn(patternName);
if (n.getOptMatchCountAST() != null) {
VariableReference varRef = (VariableReference) n.getOptMatchCountAST().accept(this);
modelResolver.addVariableReferenceToStack(varRef);
// Type check compatibility for variable reference
typeChecker.getTermsToCheck().add(varRef);
// Create a match counter
GTMatchCounter matchCounter = GtFactory.eINSTANCE.createGTMatchCounter();
matchCounter.setPatternCall(patternCall);
matchCounter.setVariableReference(varRef);
// Create node information for the match counter
createNodeInfoFor(/*(ASTNode)*/ n.getOptMatchCountAST(), matchCounter);
}
// Resolve the reference to the called pattern in a later stage
modelResolver.getUnresolvedPatternCalls().add(patternCall);
// Creating node information
createNodeInfoFor(n, patternCall);
return patternCall;
}
/**
* Visiting an {@link OptMatchCountAST} node and returning a {@link VariableReference}
* @param n : Current AST node of type {@link OptMatchCountAST}
* @return variableRef: {@link VariableReference}
*/
@Override
public Object visit(OptMatchCountAST n) {
return n.getCounterVariableAST().accept(this);
}
// *********** Sec. 5.2.2 - 5.2.4 Entity, Relation, Relationship description //
/**
* Visiting an EntityAST node and
* returning an Entity model element
* @param n : Current AST node of type EntityAST
* @param o : GTPatternBody
* @return entity : Entity
*/
@Override
public Object visit(EntityAST n, Object o) {
GTPatternBody body = (GTPatternBody) o;
// Process the body of the entity
ModelElement entity = (ModelElement) n.getEntityBody().accept(this, body);
PatternVariable varDef = modelResolver.getBodyMapVar4Element(body).get(entity);
// Process type name and create an element wrapper
String typeName = (String) n.getQualifiedTypeNameAST().accept(this);
entity.setTypeStr(typeName);
// Process containment constraint (if any)
if (n.getContainmentConstraintOptAST() != null) {
ContainmentConstraint contConstr = (ContainmentConstraint) n.getContainmentConstraintOptAST().accept(this);
if (contConstr != null) {
contConstr.setVariable(varDef);
body.getContainmentConstraints().add(contConstr);
}
}
// if (n.getEntityValueOptAST() != null) {
// Term value = (Term) n.getEntityValueOptAST().accept(this);
// // Check if this is correct: only a String is allowed as a value of an Entity
// // This could be a real Term, since this can only be used in the as a postcondition
// // Maybe, values should be forbidden by the parser
// entity.setValue(value.toString());
// }
// Create annotation
createNodeInfoFor(n, entity);
return entity;
}
/**
* Visiting an EntityBodyAST node and
* creating an PatternVariable referring to the Entity
* @param n : Current AST node of type EntityBodyAST
* @param o : {@link GTPatternBody}
* @return entity : {@link Entity}
*/
@Override
public Object visit(EntityBody n, Object o) {
GTPatternBody body = (GTPatternBody) o;
IPatternVariableDefRefAST patternVariableDefRefAST = n.getPatternVariableDefRefAST();
VariableReference varRef = (VariableReference) patternVariableDefRefAST.accept(this);
// Create a PatternVariable definition if varRef is not yet defined
// Return the corresponding PatternVariable, if already defined
PatternVariable varDef = modelResolver.lookupVariableDefByName(varRef.getName(), body);
if (varDef == null) {
varDef = modelResolver.createPatternVariableFromReference(varRef);
body.getLocalVariables().add(varDef);
createNodeInfoFor((ASTNode) patternVariableDefRefAST, varDef);
}
else {
varRef.setVariable(varDef);
}
// PatternVariable varDef = modelResolver.resolveLocalVariable(varRef, body);
// Create an entity model element
Entity entity = EditmodelFactory.eINSTANCE.createEntity();
entity.setName(varRef.getName());
// Adding the VariableReference
entity.getVariableReferences().add(varRef);
// Adding entity as a usage of the PatternVariable
// The same PatternVariable may be used in different bodies!
varDef.getElementInPattern().add(entity);
// Recording the new pair of VariableDefinition-Entity to the helper BodyMap
modelResolver.storeVarDefForModelElement(body, varDef, entity);
// Setting the parent (container) of the entity
entity.setParent(body.getPatternGraph());
if (patternVariableDefRefAST instanceof PatternVariableDefRefAST0) {
createNodeInfoFor((PatternVariableDefRefAST0)patternVariableDefRefAST, entity);
} else if (patternVariableDefRefAST instanceof PatternVariableDefRefAST1) {
createNodeInfoFor((PatternVariableDefRefAST1)patternVariableDefRefAST, entity);
}
return entity;
}
// /**
// * Visiting an EntityValueOptAST node and
// * returning a Term (an Entity value)
// * @param n : Current AST node of type EntityBodyAST
// * @return term : Term
// */
// @Override
// public Object visit(EntityValueOptAST n) {
// return n.getArithmeticTermAST().accept(this);
// }
/**
* Visiting a RelationAST node and
* returning a Relation model element
* @param n : Current AST node of type RelationAST
* @param o : GTPatternBody
* @return relation : Relation
*/
@Override
public Object visit(RelationAST n, Object o) {
GTPatternBody body = (GTPatternBody) o;
// Process the body of the relation
Relation relation = (Relation) n.getRelationBodyAST().accept(this, body);
// Process type name and create an element wrapper
String typeName = (String) n.getQualifiedTypeNameAST().accept(this);
relation.setTypeStr(typeName);
// Add relation temporarily to the list of orphan elements
modelResolver.getOrphanBodyElements(body).add(relation);
return relation;
}
/**
* Visiting a RelationBodyAST node and
* returning a PatternVariable referring to the Relation model element
* @param n : Current AST node of type RelationBodyAST
* @param o : GTPatternBody
* @return relation : Relation
*/
@Override
public Object visit(RelationBodyAST n, Object o) {
GTPatternBody body = (GTPatternBody) o;
IPatternVariableDefRefAST varDefAST = n.getPatternVariableDefRefAST();
VariableReference varRef = (VariableReference) varDefAST.accept(this);
// Return the corresponding PatternVariable, if already defined
PatternVariable varDef = modelResolver.lookupVariableDefByName(varRef.getName(), body);
if (varDef == null) {
varDef = modelResolver.createPatternVariableFromReference(varRef);
body.getLocalVariables().add(varDef);
createNodeInfoFor((ASTNode) varDefAST, varDef);
}
else {
varRef.setVariable(varDef);
}
// Create a relation model element
Relation relation = EditmodelFactory.eINSTANCE.createRelation();
relation.setName(varRef.getName());
// Adding the VariableReference for the name
relation.getVariableReferences().add(varRef);
// Adding relation as a usage of the PatternVariable
// The same PatternVariable may be used in different bodies!
varDef.getElementInPattern().add(relation);
// Processing the source model element
VariableReference srcVar = (VariableReference) n.getPatternVariableRefAST().accept(this);
relation.getVariableReferences().add(srcVar);
relation.setFromStr(srcVar.getName());
// The source variable reference should be resolved
modelResolver.getUnresolvedPatternVariableRefs(body).add(srcVar);
// Processing the target model element
VariableReference trgVar = (VariableReference) n.getPatternVariableRefAST6().accept(this);
relation.getVariableReferences().add(trgVar);
relation.setToStr(trgVar.getName());
// The target variable reference should be resolved
modelResolver.getUnresolvedPatternVariableRefs(body).add(trgVar);
// Recording the new pair to the helper BodyMap
modelResolver.storeVarDefForModelElement(body, varDef, relation);
if (varDefAST instanceof PatternVariableDefRefAST0) {
createNodeInfoFor((PatternVariableDefRefAST0)varDefAST, relation);
} else if (varDefAST instanceof PatternVariableDefRefAST1) {
createNodeInfoFor((PatternVariableDefRefAST1)varDefAST, relation);
}
return relation;
}
/**
* Visiting an {@link InheritanceAST0} node (supertypeOf) and
* returning a SupertypeOf relationship
* @param n : Current AST node of type InheritanceAST0
* @param o : {@link GTPatternBody}
* @return the created {@link SupertypeOf} relationship
*/
@Override
public Object visit(InheritanceAST0 n, Object o) {
GTPatternBody body = (GTPatternBody) o;
// Creating a SupertypeOf relationship
SupertypeOf relship = EditmodelFactory.eINSTANCE.createSupertypeOf();
List<VariableReference> parameters = new ArrayList<VariableReference>();
n.getRelationshipBodyAST().accept(this, parameters);
// Setting the supertype
VariableReference supplierVar = parameters.get(0);
modelResolver.getUnresolvedPatternVariableRefs(body).add(supplierVar);
relship.setSupplierStr(supplierVar.getName());
// Setting the subtype
VariableReference clientVar = parameters.get(1);
modelResolver.getUnresolvedPatternVariableRefs(body).add(clientVar);
relship.setClientStr(clientVar.getName());
// Adding temporarily to the list of orphan pattern elements
modelResolver.getOrphanBodyElements(body).add(relship);
// Adding VariableReferences to the Relationship
relship.getVariableReferences().add(supplierVar);
relship.getVariableReferences().add(clientVar);
// Creating location information
createNodeInfoFor(n, relship);
return relship;
}
/**
* Visiting an {@link InheritanceAST1} node (subtypeOf) and
* returning a SupertypeOf relationship
* @param n : Current AST node of type InheritanceAST1
* @param o : {@link GTPatternBody}
* @return the created {@link SupertypeOf} relationship
*/
@Override
public Object visit(InheritanceAST1 n, Object o) {
GTPatternBody body = (GTPatternBody) o;
// Creating a SupertypeOf relationship
SupertypeOf relship = EditmodelFactory.eINSTANCE.createSupertypeOf();
List<VariableReference> parameters = new ArrayList<VariableReference>();
n.getRelationshipBodyAST().accept(this, parameters);
// Setting the supertype
VariableReference supplierVar = parameters.get(1);
modelResolver.getUnresolvedPatternVariableRefs(body).add(supplierVar);
relship.setSupplierStr(supplierVar.getName());
// Setting the subtype
VariableReference clientVar = parameters.get(0);
modelResolver.getUnresolvedPatternVariableRefs(body).add(clientVar);
relship.setClientStr(clientVar.getName());
// Adding temporarily to the list of orphan pattern elements
modelResolver.getOrphanBodyElements(body).add(relship);
// Adding VariableReferences to the Relationship
relship.getVariableReferences().add(supplierVar);
relship.getVariableReferences().add(clientVar);
// Creating location information
createNodeInfoFor(n, relship);
return relship;
}
/**
* Visiting an {@link InstantiationAST0} node (typeOf) and
* returning a TypeOf relationship
* @param n : Current AST node of type InstantiationAST0
* @param o : {@link GTPatternBody}
* @return the created {@link TypeOf} relationship
*/
@Override
public Object visit(InstantiationAST0 n, Object o) {
GTPatternBody body = (GTPatternBody) o;
// Creating a TypeOf relationship
TypeOf relship = EditmodelFactory.eINSTANCE.createTypeOf();
// Process the body of the relationship
List<VariableReference> parameters = new ArrayList<VariableReference>();
n.getRelationshipBodyAST().accept(this, parameters);
// Setting the type
VariableReference supplierVar = parameters.get(0);
modelResolver.getUnresolvedPatternVariableRefs(body).add(supplierVar);
relship.setSupplierStr(supplierVar.getName());
// Setting the instance
VariableReference clientVar = parameters.get(1);
modelResolver.getUnresolvedPatternVariableRefs(body).add(clientVar);
relship.setClientStr(clientVar.getName());
// Adding temporarily to the list of orphan pattern elements
modelResolver.getOrphanBodyElements(body).add(relship);
// Adding VariableReferences to the Relationship
relship.getVariableReferences().add(supplierVar);
relship.getVariableReferences().add(clientVar);
// Creating location information
createNodeInfoFor(n, relship);
return relship;
}
/**
* Visiting an {@link InstantiationAST1} node (instanceOf) and
* returning a TypeOf relationship
* @param n : Current AST node of type InstantiationAST1
* @param o : {@link GTPatternBody}
* @return the created {@link TypeOf} relationship
*/
@Override
public Object visit(InstantiationAST1 n, Object o) {
GTPatternBody body = (GTPatternBody) o;
List<VariableReference> parameters = new ArrayList<VariableReference>();
n.getRelationshipBodyAST().accept(this, parameters);
// Creating a TypeOf relationship
TypeOf relship = EditmodelFactory.eINSTANCE.createTypeOf();
// Setting the type
VariableReference supplierVar = parameters.get(1);
modelResolver.getUnresolvedPatternVariableRefs(body).add(supplierVar);
relship.setSupplierStr(supplierVar.getName());
// Setting the instance
VariableReference clientVar = parameters.get(0);
modelResolver.getUnresolvedPatternVariableRefs(body).add(clientVar);
relship.setClientStr(clientVar.getName());
// Adding temporarily to the list of orphan pattern elements
modelResolver.getOrphanBodyElements(body).add(relship);
// Adding VariableReferences to the Relationship
relship.getVariableReferences().add(supplierVar);
relship.getVariableReferences().add(clientVar);
// Creating location information
createNodeInfoFor(n, relship);
return relship;
}
/**
* Visiting an {@link RelationshipBodyAST} node and
* returning a List of VariableReferences
* @param n : Current AST node of type RelationshipBodyAST
* @param o : {@link List} (of VariableReferences)
* @return parameteters: {@link List} (of VariableReferences)
*/
@Override
public Object visit(RelationshipBodyAST n, Object o) {
@SuppressWarnings("unchecked")
List<VariableReference> parameters = (List<VariableReference>) o;
VariableReference first = (VariableReference) n.getPatternVariableRefAST().accept(this);
parameters.add(first);
VariableReference second = (VariableReference) n.getPatternVariableRefAST4().accept(this);
parameters.add(second);
return parameters;
}
// ************** Sec. 5.3 Graph transformation rules ********************** //
/**
* Visiting a {@link GTRuleDefAST} AST node and
* creating a {@link GTRule}
*
* @param n : {@link GTRuleDefAST}
* @param o : is expected to be {@link Machine}
* @return machine : {@link Machine}
*/
@Override
public Object visit(GTRuleDefAST n, Object o) {
Machine machine = (Machine) o;
// Creating a new GTRule
GTRule rule = GtFactory.eINSTANCE.createGTRule();
rule.setNamespace(machine);
// Setting the name of the GT rule
String ruleName = (String) n.getTypeNameAST().accept(this);
rule.setName(ruleName);
rule.setFqn(machine.getFqn() + "." + ruleName);
// Processing symbolic parameters
n.getDirectedFormalParameterDefAST().accept(this, rule.getSymParameters());
for (Iterator<SymbolicRuleParameter> iter = rule.getSymParameters().iterator(); iter.hasNext();) {
SymbolicRuleParameter param = iter.next();
rule.getLocalVariables().add(param.getVariable());
}
// Processing GTRule body
n.getGTRuleBodyAST().accept(this, rule);
// Creating node information
createNodeInfoFor(n, rule);
// Processing runtime annotations
if (n.getOptAnnotationsAST() != null) {
n.getOptAnnotationsAST().accept(this, rule.getRuntimeAnnotations());
}
//Loading documentation
loadDocumentationComments(n, rule);
return machine;
}
/**
* Visiting a {@link GTRuleBodyAST0} node
* and processing precondition, postcondition and action parts
*
* @param n : {@link GTRuleBodyAST0}
* @param o : expected to be GTRule
* @return rule : {@link GTRule}
*/
@Override
public Object visit(GTRuleBodyAST0 n, Object o) {
GTRule rule = (GTRule) o;
n.getPreconditionDefAST().accept(this, rule);
if (n.getPostconditionOptAST() != null) {
n.getPostconditionOptAST().accept(this, rule);
}
if (n.getActionOptAST() != null) {
n.getActionOptAST().accept(this, rule);
}
return rule;
}
/**
* Visiting a {@link GTRuleBodyAST1} node (ERROR_TOKEN)
*
* @param n : {@link GTRuleBodyAST1}
* @param o : expected to be GTRule
*/
@Override
public Object visit(GTRuleBodyAST1 n, Object o) {
return null;
//return diagnoseOnce(n.getEnvironment());
}
/**
* Visiting a {@link PreconditionDefAST0} node
* for a locally defined pattern
*
* @param n : {@link PreconditionDefAST0}
* @param o : expected to be a {@link GTRule}
* @return rule : {@link GTRule}
*/
@Override
public Object visit(PreconditionDefAST0 n, Object o) {
GTRule rule = (GTRule) o;
// Creating a new GTPattern definition
GTPattern lhs = (GTPattern) n.getGraphPatternDefAST().accept(this);
rule.getGtPatternDefinitions().add(lhs);
// Create a GT pattern call
GTPatternCall patternCall = TermsFactory.eINSTANCE.createGTPatternCall();
rule.setPrecondition(patternCall);
// Set the reference to the locally defined pattern
patternCall.setCalledPattern(lhs);
// Create actual parameters of the called pattern from the symbolic parameters
for (Object symParam: lhs.getSymParameters()) {
PatternVariable patternVar = (PatternVariable) symParam;
// Create a VariableReference
VariableReference varRef = TermsFactory.eINSTANCE.createVariableReference();
varRef.setName(patternVar.getName());
patternCall.getActualParameters().add(varRef);
modelResolver.resolveLocalVariableInGTRule(varRef, rule);
// Type checking for parameters
typeChecker.getTermsToCheck().add(varRef);
}
return rule;
}
/**
* Visiting a {@link PreconditionDefAST1} node
* for a predefined pattern
*
* @param n : {@link PreconditionDefAST1}
* @param o : expected to be a {@link GTRule}
* @return rule : {@link GTRule}
*/
@Override
public Object visit(PreconditionDefAST1 n, Object o) {
GTRule rule = (GTRule) o;
GTPatternCall patternCall = (GTPatternCall) n.getPatternCompositionAST().accept(this);
rule.setPrecondition(patternCall);
// Resolve variable references
for (Object param : patternCall.getActualParameters()) {
VariableReference varRef = (VariableReference) param;
modelResolver.resolveLocalVariableInGTRule(varRef, rule);
// Type checking for parameters
typeChecker.getTermsToCheck().add(varRef);
}
// Type check compatibility of actual parameters
typeChecker.getPatternCallToCheck().add(patternCall);
return rule;
}
/**
* Visiting a {@link PostconditionOptAST0} node
* for a locally defined pattern
*
* @param n : {@link PostconditionOptAST0}
* @param o : expected to be a {@link GTRule}
* @return rule : {@link GTRule}
*/
@Override
public Object visit(PostconditionOptAST0 n, Object o) {
GTRule rule = (GTRule) o;
// Creating a new GTPattern definition
GTPattern rhs = (GTPattern) n.getGraphPatternDefAST().accept(this);
rule.getGtPatternDefinitions().add(rhs);
// Create a GT pattern call
GTPatternCall patternCall = TermsFactory.eINSTANCE.createGTPatternCall();
rule.setPostcondition(patternCall);
// Set the reference to the locally defined pattern
patternCall.setCalledPattern(rhs);
// Create actual parameters of the called pattern from the symbolic parameters
for (Object symParam: rhs.getSymParameters()) {
PatternVariable patternVar = (PatternVariable) symParam;
// Create a VariableReference
VariableReference varRef = TermsFactory.eINSTANCE.createVariableReference();
varRef.setName(patternVar.getName());
patternCall.getActualParameters().add(varRef);
modelResolver.resolveLocalVariableInGTRule(varRef, rule);
// Type checking for parameters
typeChecker.getTermsToCheck().add(varRef);
}
return rule;
}
/**
* Visiting a {@link PostconditionOptAST1} node
* for a predefined pattern
*
* @param n : {@link PostconditionOptAST1}
* @param o : expected to be a {@link GTRule}
* @return rule : {@link GTRule}
*/
@Override
public Object visit(PostconditionOptAST1 n, Object o) {
GTRule rule = (GTRule) o;
GTPatternCall patternCall = (GTPatternCall) n.getPatternCompositionAST().accept(this);
rule.setPostcondition(patternCall);
// Resolve variable references
for (Object param : patternCall.getActualParameters()) {
VariableReference varRef = (VariableReference) param;
modelResolver.resolveLocalVariableInGTRule(varRef, rule);
// Type checking for parameters
typeChecker.getTermsToCheck().add(varRef);
}
// Type check compatibility of actual parameters
typeChecker.getPatternCallToCheck().add(patternCall);
// Match counters are not allowed in postconditions
if (n.getPatternCompositionAST().getOptMatchCountAST() != null) {
modelResolver.reportInvalidMatchCounter(patternCall, "postconditions");
}
return rule;
}
/**
* Visiting an {@link ActionOptAST} node
*
* @param n : {@link ActionOptAST}
* @param o : expected to be a {@link GTRule}
* @return rule : {@link GTRule}
*/
@Override
public Object visit(ActionOptAST n, Object o) {
GTRule gtRule = (GTRule) o;
// Creating a SeqRule
SequentialRule seqRule = CompoundRulesFactory.eINSTANCE.createSequentialRule();
gtRule.setAction(seqRule);
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
// Recording the action-gtRule pair (used when resolving variable refs)
modelResolver.getActionRuleMap().put(seqRule, gtRule);
// Processing the action body
n.getAsmRulesAST().accept(this, seqRule);
modelResolver.getUnresolvedVariableRefsStack().pop();
createNodeInfoFor(n, seqRule);
return gtRule;
}
/**
* Visiting a {@link GTRuleCallAST} node
* and creating a {@link GTRuleInvocation}
*
* @param n : {@link GTRuleCallAST}
* @return gtRuleInvoc : {@link GTRuleInvocation}
*/
@Override
public Object visit(GTRuleCallAST n) {
// Creating a GTRuleC invocation
GTRuleInvocation gtRuleInvoc = SimpleRulesFactory.eINSTANCE.createGTRuleInvocation();
// Processing actual parameters
n.getActualParameterDefAST().accept(this, gtRuleInvoc.getActualParameters());
// Store the name of the called pattern as the FQN of the patternCall
String patternName = (String) n.getQualifiedTypeNameAST().accept(this);
gtRuleInvoc.setFqn(patternName);
gtRuleInvoc.setName(patternName);
// Type check compatibility of actual parameters of GT rule invocation
typeChecker.getGtRuleInvocsToCheck().add(gtRuleInvoc);
// Type checking for actual parameters
for (Object param : gtRuleInvoc.getActualParameters()) {
Term term = (Term) param;
typeChecker.getTermsToCheck().add(term);
}
// Resolve the reference to the called pattern in a later stage
modelResolver.getUnresolvedGTRuleInvoc().add(gtRuleInvoc);
// Creating node information
createNodeInfoFor(n, gtRuleInvoc);
return gtRuleInvoc;
}
// ************** Sec. 5.4 ASM Terms and Formulas ************************** //
// ************** Sec. 5.4.1 Logical Terms *************************
/**
* Visiting a LogicalTermAST0 node (OR) and
* returning an Or RelationalOperation
* @param n : Current AST node of type LogicalTermAST0
*/
@Override
public Object visit(LogicalTermAST0 n) {
Term leftOperand = (Term) n.getLogicalTermAST().accept(this);
Term rightOperand = (Term) n.getLogicalAndTermAST().accept(this);
Or logicalTerm = BuiltInFunctionsFactory.eINSTANCE.createOr();
// Adding term parameters
logicalTerm.getActualParameters().add(leftOperand);
logicalTerm.getActualParameters().add(rightOperand);
createNodeInfoFor(n, logicalTerm);
// No type checking here
// typeChecker.typeCheckTerm(logicalTerm, leftOperand, rightOperand);
return logicalTerm;
}
@Override
public Object visit(LogicalTermAST0 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a LogicalTermAST1 node (XOR) and
* returning an Xor RelationalOperation
* @param n : Current AST node of type LogicalTermAST1
*/
@Override
public Object visit(LogicalTermAST1 n) {
Term leftOperand = (Term) n.getLogicalTermAST().accept(this);
Term rightOperand = (Term) n.getLogicalAndTermAST().accept(this);
XOr logicalTerm = BuiltInFunctionsFactory.eINSTANCE.createXOr();
logicalTerm.getActualParameters().add(leftOperand);
logicalTerm.getActualParameters().add(rightOperand);
createNodeInfoFor(n, logicalTerm);
// No type checking
//typeChecker.typeCheckTerm(logicalTerm, leftOperand, rightOperand);
return logicalTerm;
}
@Override
public Object visit(LogicalTermAST1 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a LogicalAndTermAST node (AND) and
* returning an And RelationalOperation
* @param n : Current AST node of type LogicalAndTermAST
*/
@Override
public Object visit(LogicalAndTermAST n) {
Term leftOperand = (Term) n.getLogicalAndTermAST().accept(this);
Term rightOperand = (Term) n.getEqualityTermAST().accept(this);
And logicalTerm = BuiltInFunctionsFactory.eINSTANCE.createAnd();
logicalTerm.getActualParameters().add(leftOperand);
logicalTerm.getActualParameters().add(rightOperand);
createNodeInfoFor(n, logicalTerm);
// No type checking
//typeChecker.typeCheckTerm(logicalTerm, leftOperand, rightOperand);
return logicalTerm;
}
@Override
public Object visit(LogicalAndTermAST n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting an {@link EqualityTermAST0} node (==) and
* returning an {@link Equals} RelationalOperation
* @param n : Current AST node of type {@link EqualityTermAST0}
*/
@Override
public Object visit(EqualityTermAST0 n) {
Term leftOperand = (Term) n.getEqualityTermAST().accept(this);
Term rightOperand = (Term) n.getRelationalTermAST().accept(this);
RelationalOperation equalTerm = BuiltInFunctionsFactory.eINSTANCE.createEquals();
equalTerm.getActualParameters().add(leftOperand);
equalTerm.getActualParameters().add(rightOperand);
createNodeInfoFor(n, equalTerm);
// No type checking
//typeChecker.typeCheckTerm(equalTerm, leftOperand, rightOperand);
return equalTerm;
}
@Override
public Object visit(EqualityTermAST0 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting an {@link EqualityTermAST1} node (!=) and
* returning an {@link NotEquals} RelationalOperation
* @param n : Current AST node of type {@link EqualityTermAST1}
*/
@Override
public Object visit(EqualityTermAST1 n) {
Term leftOperand = (Term) n.getEqualityTermAST().accept(this);
Term rightOperand = (Term) n.getRelationalTermAST().accept(this);
RelationalOperation equalTerm = BuiltInFunctionsFactory.eINSTANCE.createNotEquals();
equalTerm.getActualParameters().add(leftOperand);
equalTerm.getActualParameters().add(rightOperand);
createNodeInfoFor(n, equalTerm);
// No type checking
// typeChecker.typeCheckTerm(equalTerm, leftOperand, rightOperand);
return equalTerm;
}
@Override
public Object visit(EqualityTermAST1 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting an {@link RelationalTermAST} node (<,>,<=,>=) and
* returning the corresponding {@link RelationalOperation}
* @param n : Current AST node of type {@link RelationalTermAST}
*/
@Override
public Object visit(RelationalTermAST n) {
Term leftOperand = (Term) n.getRelationalTermAST().accept(this);
Term rightOperand = (Term) n.getArithmeticTermAST().accept(this);
RelationalOperation relTerm = (RelationalOperation) n.getRelationalOpAST().accept(this);
relTerm.getActualParameters().add(leftOperand);
relTerm.getActualParameters().add(rightOperand);
createNodeInfoFor(n, relTerm);
// No type checking
// typeChecker.typeCheckTerm(relTerm, leftOperand, rightOperand);
return relTerm;
}
@Override
public Object visit(RelationalTermAST n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
// /**
// * Visiting a BaseLogicalTermAST0 node (NOT) and
// * returning an NOT RelationalOperation
// * @param n : Current AST node of type BaseLogicalTermAST0
// */
// @SuppressWarnings("unchecked")
// @Override
// public Object visit(BaseLogicalTermAST0 n) {
// Term leftOperand = (Term) n.getBaseLogicalTermAST().accept(this);
// Not logicalTerm = BuiltInFunctionsFactory.eINSTANCE.createNot();
// logicalTerm.getActualParameters().add(leftOperand);
// createNodeInfoFor(n, logicalTerm);
// return logicalTerm;
// }
// @Override
// public Object visit(BaseLogicalTermAST0 n, Object o) {
// return defaultListVisit(n, (List<?>) o);
// }
//
// /**
// * Visiting a BaseLogicalTermAST1 node ( expr ) and
// * returning its content as a LogicalTerm (without parenthesis)
// * @param n : Current AST node of type BaseLogicalTermAST0
// */
// @Override
// public Object visit(BaseLogicalTermAST1 n) {
// return (Term) n.getLogicalTermAST().accept(this);
// }
// @Override
// public Object visit(BaseLogicalTermAST1 n, Object o) {
// return defaultListVisit(n, (List<?>) o);
// }
//
// /**
// * Visiting a BaseLogicalTermAST2 node (RelationalOperation) and
// * returning a RelationalOperation with ArithmeticTerms as parameters
// * @param n : Current AST node of type BaseLogicalTermAST2
// */
// @SuppressWarnings("unchecked")
// @Override
// public Object visit(BaseLogicalTermAST2 n) {
// RelationalOperation relOp = (RelationalOperation) n.getRelationalOpAST().accept(this);
// Term leftOperand = (Term) n.getArithmeticTermAST().accept(this);
// Term rightOperand = (Term) n.getArithmeticTermAST3().accept(this);
// relOp.getActualParameters().add(leftOperand);
// relOp.getActualParameters().add(rightOperand);
// createNodeInfoFor(n, relOp);
// return relOp;
// }
// @Override
// public Object visit(BaseLogicalTermAST2 n, Object o) {
// return defaultListVisit(n, (List<?>) o);
// }
/**
* Visiting a {@link RelationalOpAST} node (<,>,<=,>=) and
* returning a {@link RelationalOperation}
* @param n : Current AST node of type {@link RelationalOpAST}
*/
@Override
public Object visit(RelationalOpAST n) {
RelationalOperation op = null;
String opStr = n.toString();
if (opStr.equals("<")) {
op = BuiltInFunctionsFactory.eINSTANCE.createLessThan();
op.setName("<");
}
else if (opStr.equals(">")) {
op = BuiltInFunctionsFactory.eINSTANCE.createGreaterThan();
op.setName(">");
}
else if (opStr.equals("<=")) {
op = BuiltInFunctionsFactory.eINSTANCE.createLessThanOrEqualTo();
op.setName("<=");
}
else if (opStr.equals(">=")) {
op = BuiltInFunctionsFactory.eINSTANCE.createGreaterThanOrEqualTo();
op.setName(">=");
}
return op;
}
@Override
public Object visit(RelationalOpAST n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
// ************** Sec. 5.4 ASM Terms and Formulas ************************** //
/**
* Visiting a ArithmeticTermAST0 node (PLUS) and
* returning a Plus ArithmeticOperation
* @param n : Current AST node of type ArithmeticTermAST0
*/
@Override
public Object visit(ArithmeticTermAST0 n) {
Term leftOperand = (Term) n.getArithmeticTermAST().accept(this);
Term rightOperand = (Term) n.getMultArithmeticTermAST().accept(this);
Plus arithmeticTerm = BuiltInFunctionsFactory.eINSTANCE.createPlus();
arithmeticTerm.getActualParameters().add(leftOperand);
arithmeticTerm.getActualParameters().add(rightOperand);
createNodeInfoFor(n, arithmeticTerm);
arithmeticTerm.setName("PLUS");
// No type checking
// typeChecker.typeCheckTerm(arithmeticTerm, leftOperand, rightOperand);
return arithmeticTerm;
}
/**
* Visiting a ArithmeticTermAST0 node (PLUS) and adding it to the list
* represented by o
* @param n : Current AST node of type ArithmeticTermAST0
* @param o : List
* @return list : List
*/
@SuppressWarnings("rawtypes")
@Override
public Object visit(ArithmeticTermAST0 n, Object o) {
return defaultListVisit(n, (List) o);
}
/**
* Visiting a ArithmeticTermAST1 node (MINUS) and
* returning a Minus ArithmeticOperation
* @param n : Current AST node of type ArithmeticTermAST1
*/
@Override
public Object visit(ArithmeticTermAST1 n) {
Term leftOperand = (Term) n.getArithmeticTermAST().accept(this);
Term rightOperand = (Term) n.getMultArithmeticTermAST().accept(this);
Minus arithmeticTerm = BuiltInFunctionsFactory.eINSTANCE.createMinus();
arithmeticTerm.getActualParameters().add(leftOperand);
arithmeticTerm.getActualParameters().add(rightOperand);
createNodeInfoFor(n, arithmeticTerm);
arithmeticTerm.setName("MINUS");
// No type checking
// typeChecker.typeCheckTerm(arithmeticTerm, leftOperand, rightOperand);
return arithmeticTerm;
}
/**
* Visiting a ArithmeticTermAST1 node (MINUS) and adding it to the list
* represented by o
* @param n : Current AST node of type ArithmeticTermAST1
* @param o : List
* @return list : List
*/
@SuppressWarnings("rawtypes")
@Override
public Object visit(ArithmeticTermAST1 n, Object o) {
return defaultListVisit(n, (List) o);
}
/**
* Visiting a MultArithmeticTermAST0 node (MULTIPLY) and
* returning a Multiply ArithmeticOperation
* @param n : Current AST node of type MultArithmeticTermAST0
*/
@Override
public Object visit(MultArithmeticTermAST0 n) {
Term leftOperand = (Term) n.getMultArithmeticTermAST().accept(this);
Term rightOperand = (Term) n.getUnaryArithmeticTermAST().accept(this);
Multiply arithmeticTerm = BuiltInFunctionsFactory.eINSTANCE.createMultiply();
arithmeticTerm.getActualParameters().add(leftOperand);
arithmeticTerm.getActualParameters().add(rightOperand);
createNodeInfoFor(n, arithmeticTerm);
arithmeticTerm.setName("MULTIPLY");
// No type checking
// typeChecker.typeCheckTerm(arithmeticTerm, leftOperand, rightOperand);
return arithmeticTerm;
}
/**
* Visiting a MultArithmeticTermAST0 node (MINUS) and adding it to the list
* represented by o
* @param n : Current AST node of type ArithmeticTermAST1
* @param o : List
* @return list : List
*/
@SuppressWarnings("rawtypes")
@Override
public Object visit(MultArithmeticTermAST0 n, Object o) {
return defaultListVisit(n, (List) o);
}
/**
* Visiting a MultArithmeticTermAST1 node (DIVIDE) and
* returning a Division ArithmeticOperation
* @param n : Current AST node of type MultArithmeticTermAST1
*/
@Override
public Object visit(MultArithmeticTermAST1 n) {
Term leftOperand = (Term) n.getMultArithmeticTermAST().accept(this);
Term rightOperand = (Term) n.getUnaryArithmeticTermAST().accept(this);
Division arithmeticTerm = BuiltInFunctionsFactory.eINSTANCE.createDivision();
arithmeticTerm.getActualParameters().add(leftOperand);
arithmeticTerm.getActualParameters().add(rightOperand);
createNodeInfoFor(n, arithmeticTerm);
arithmeticTerm.setName("DIVIDE");
// No type checking
// typeChecker.typeCheckTerm(arithmeticTerm, leftOperand, rightOperand);
return arithmeticTerm;
}
@Override
public Object visit(MultArithmeticTermAST1 n, Object o) {
return visit(n);
}
/**
* Visiting a MultArithmeticTermAST2 node (REMAINDER) and
* returning a Remainder ArithmeticOperation
* @param n : Current AST node of type MultArithmeticTermAST2
*/
@Override
public Object visit(MultArithmeticTermAST2 n) {
Term leftOperand = (Term) n.getMultArithmeticTermAST().accept(this);
Term rightOperand = (Term) n.getUnaryArithmeticTermAST().accept(this);
Remainder arithmeticTerm = BuiltInFunctionsFactory.eINSTANCE.createRemainder();
arithmeticTerm.getActualParameters().add(leftOperand);
arithmeticTerm.getActualParameters().add(rightOperand);
createNodeInfoFor(n, arithmeticTerm);
arithmeticTerm.setName("REMAINDER");
// No type checking
// typeChecker.typeCheckTerm(arithmeticTerm, leftOperand, rightOperand);
return arithmeticTerm;
}
@Override
public Object visit(MultArithmeticTermAST2 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a {@link UnaryArithmeticTermAST0} (MINUS) and
* returning a {@link Minus} BuiltInFunction (with a single parameter)
* @param n : Current AST node of type {@link UnaryArithmeticTermAST0}
*/
@Override
public Object visit(UnaryArithmeticTermAST0 n) {
// Term leftOperand = (Term) n.getNavigationTermAST().accept(this);
Term leftOperand = (Term) n.getBaseArithmeticTermAST().accept(this);
Minus unaryTerm = BuiltInFunctionsFactory.eINSTANCE.createMinus();
unaryTerm.getActualParameters().add(leftOperand);
createNodeInfoFor(n, unaryTerm);
unaryTerm.setName("MINUS");
// No type checking
// typeChecker.typeCheckTerm(unaryTerm, leftOperand);
return unaryTerm;
}
@Override
public Object visit(UnaryArithmeticTermAST0 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a {@link UnaryArithmeticTermAST1} (NOT) and
* returning a {@link Not} BuiltInFunction (with a single parameter)
* @param n : Current AST node of type {@link UnaryArithmeticTermAST1}
*/
@Override
public Object visit(UnaryArithmeticTermAST1 n) {
// Term leftOperand = (Term) n.getNavigationTermAST().accept(this);
Term leftOperand = (Term) n.getBaseArithmeticTermAST().accept(this);
Not unaryTerm = BuiltInFunctionsFactory.eINSTANCE.createNot();
unaryTerm.getActualParameters().add(leftOperand);
createNodeInfoFor(n, unaryTerm);
unaryTerm.setName("NOT");
// No type checking
// typeChecker.typeCheckTerm(unaryTerm, leftOperand);
return unaryTerm;
}
@Override
public Object visit(UnaryArithmeticTermAST1 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
// /**
// * Visiting a {@link NavigationTermAST} (->) and
// * returning a {@link NavigationExpression} term
// * @param n : Current AST node of type {@link NavigationTermAST}
// */
// @Override
// public Object visit(NavigationTermAST n) {
// Term baseTerm = (Term) n.getBaseArithmeticTermAST().accept(this);
// String roleStr = (String) n.getTypeNameAST().accept(this);
// Navigation navigationExpr = QueryFunctionsFactory.eINSTANCE.createNavigation();
// navigationExpr.setArgument(baseTerm);
// navigationExpr.setNavigationRole(roleStr);
// createNodeInfoFor(n, navigationExpr);
// // Type checking
// navigationExpr.setKind(modelResolver.typeCheckTerm(navigationExpr, baseTerm));
// // Validating navigation
// // Navigation checking at compile time
// return navigationExpr;
// }
// @Override
// public Object visit(NavigationTermAST n, Object o) {
// return defaultListVisit(n, (List<?>) o);
// }
// /**
// * Visiting a BaseArithmeticTermAST0 node (MINUS) and
// * returning a Minus ArithmeticOperation (with a single parameter)
// * @param n : Current AST node of type BaseArithmeticTermAST0
// */
// @SuppressWarnings("unchecked")
// @Override
// public Object visit(BaseArithmeticTermAST0 n) {
// Term leftOperand = (Term) n.getValueAST().accept(this);
// Minus arithmeticTerm = BuiltInFunctionsFactory.eINSTANCE.createMinus();
// arithmeticTerm.getActualParameters().add(leftOperand);
// createNodeInfoFor(n, arithmeticTerm);
// return arithmeticTerm;
// }
// @Override
// public Object visit(BaseArithmeticTermAST0 n, Object o) {
// return defaultListVisit(n, (List<?>) o);
// }
/**
* Visiting a {@link BaseArithmeticTermAST} node ( expr ) and
* returning the internal ArithmeticTerm (without the parentheses)
* @param n : Current AST node of type {@link BaseArithmeticTermAST}
*/
@Override
public Object visit(BaseArithmeticTermAST n) {
return /*(Term)*/ n.getLogicalTermAST().accept(this);
}
@Override
public Object visit(BaseArithmeticTermAST n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
// ***************** Sec. 5.4.3. ASM Functions ********************
/**
* Visiting an {@link AsmFunctionDefAST} node and
* returning an ASM function
* @param n : Current AST node of type {@link AsmFunctionDefAST}
* @param o : The container machine of the ASM function
* @return asmFun : {@link ASMFunction}
*/
@Override
public Object visit(AsmFunctionDefAST n, Object o) {
Machine machine = (Machine) o;
ASMFunction asmFun = DefinitionsFactory.eINSTANCE.createASMFunction();
// Setting the name
String asmFunStr = (String) n.getTypeNameAST().accept(this);
asmFun.setFqn(machine.getFqn() + "." + asmFunStr);
asmFun.setName(asmFunStr);
asmFun.setNamespace(machine);
// Setting the arity / types of arities
n.getArityOrTypeDeclAST().accept(this, asmFun);
// Resolving return type specification
if (n.getReturnTypeOptAST() != null) {
n.getReturnTypeOptAST().accept(this, asmFun);
}
// Setting initial values
n.getInitialValuesOptAST().accept(this, asmFun.getInitialValues());
// Processing runtime annotations
if (n.getOptAnnotationsAST() != null) {
n.getOptAnnotationsAST().accept(this, asmFun.getRuntimeAnnotations());
}
//Loading documentation
loadDocumentationComments(n, asmFun);
// Validate that initial value definitions correspond to arity
modelResolver.validateAsmFunctionInitialValues(asmFun);
createNodeInfoFor(n, asmFun);
return asmFun;
}
/**
* Visiting an {@link ArityOrTypeDeclAST0} node (arity definition) and
* returning an ASM function
* @param n : Current AST node of type {@link ArityOrTypeDeclAST0}
* @param o : The ASM function for which we define arity
* @return asmFun : {@link ASMFunction}
*/
@Override
public Object visit(ArityOrTypeDeclAST0 n, Object o) {
ASMFunction asmFun = (ASMFunction) o;
// Setting the arity
Integer arity = (Integer) n.getArityAST().accept(this);
asmFun.setArity(arity.intValue());
return asmFun;
}
/**
* Visiting an {@link ArityOrTypeDeclAST1} node (type definition) and
* returning an ASM function
* @param n : Current AST node of type {@link ArityOrTypeDeclAST1}
* @param o : The ASM function for which we define types
* @return asmFun : {@link ASMFunction}
*/
@Override
public Object visit(ArityOrTypeDeclAST1 n, Object o) {
ASMFunction asmFun = (ASMFunction) o;
n.getTypeConstantsAST().accept(this, asmFun);
// Set the arity
asmFun.setArity(asmFun.getArgumentTypes().size());
return asmFun;
}
/**
* Visiting an ArityAST node (DecimalIntegerLiteral) and
* returning an Integer value
* @param n : Current AST node of type RelationalOpAST5
*/
@Override
public Object visit(ArityAST n) {
return Integer.parseInt(n.toString());
}
/**
* Visiting an InitialValueAST node and adding it to the list of InitialValues
* returning the List of InitialValues
* @param n : Current AST node of type InitialValueAST
* @param o : List of InitialValues
*/
@Override
public Object visit(InitialValueAST n, Object o) {
@SuppressWarnings("unchecked")
List<InitialValue> initValueList = (List<InitialValue>) o;
// Creating a new InitialValue
InitialValue initValue = DefinitionsFactory.eINSTANCE.createInitialValue();
initValueList.add(initValue);
// Processing the location
n.getActualParameterDefAST().accept(this, initValue.getLocations());
for (Object object : initValue.getLocations()) {
Term location = (Term) object;
// Type check compatibility of the location
typeChecker.getTermsToCheck().add(location);
}
// Processing the value
Term value = (Term) n.getArithmeticTermAST().accept(this);
initValue.setValue(value);
// Type check term
typeChecker.getTermsToCheck().add(value);
// Type check compatibility of initial value vs. type
typeChecker.getInitValuesToCheck().add(initValue);
createNodeInfoFor(n, initValue);
return initValueList;
}
/**
* Visiting an InitialValuesAST node and adding it to the list of InitialValues
* returning the List of InitialValues
* @param n : Current AST node of type InitialValuesAST
* @param o : List of InitialValues
*/
@Override
public Object visit(InitialValuesAST n, Object o) {
@SuppressWarnings("unchecked")
List<InitialValue> initValueList = (List<InitialValue>) o;
n.getInitialValuesAST().accept(this, initValueList);
n.getInitialValueAST().accept(this, initValueList);
return initValueList;
}
/**
* Visiting an InitialValuesOptAST0 node (empty definition)
* returning the empty List of InitialValue
* @param n : Current AST node of type InitialValuesOptAST0
* @param o : List of InitialValues
*/
@Override
public Object visit(InitialValuesOptAST0 n, Object o) {
return o;
}
/**
* Visiting an InitialValuesOptAST1 node (with InitialValue definitions)
* returning the List of InitialValues
* @param n : Current AST node of type InitialValuesOptAST1
* @param o : List of InitialValues
*/
@Override
public Object visit(InitialValuesOptAST1 n, Object o) {
return n.getInitialValuesAST().accept(this, o);
}
/**
* Visiting an AsmFunctionLocationAST node (as part of an Update rule)
* returning a RuleUpdateASMFunction
* This code is called as a left value in an UpdateRule
* @param n : Current AST node of type AsmFunctionLocationAST
* @param o : RuleUpdateASMFunction
* @return updateRule
*/
@Override
public Object visit(AsmFunctionUpdateLocationAST n, Object o) {
RuleUpdateASMFunction updateRule = (RuleUpdateASMFunction) o;
// Store the name of the ASM Function as the FQN of the rule
Constant asmFunConst = (Constant) n.getASMFunctionNameAST().accept(this);
updateRule.setFqn(asmFunConst.getValue());
// Processing actual parameters
n.getActualParameterDefAST().accept(this, updateRule.getLocations());
// Type checking the location
for (Object object : updateRule.getLocations()) {
Term location = (Term) object;
typeChecker.getTermsToCheck().add(location);
}
// Resolve the called ASM Function in a later stage
modelResolver.getUnresolvedAsmFunctionUpdates().add(updateRule);
return updateRule;
}
/**
* Visiting an AsmFunctionLocationAST node (as part of a Term)
* returning an ASMFunctionInvocation
* This code is called as a right value (Term)
* @param n : Current AST node of type AsmFunctionLocationAST
*/
@Override
public Object visit(AsmFunctionLocationAST n) {
FunctionInvocation funInvoc = null;
Constant asmFunConst= (Constant) n.getASMFunctionNameAST().accept(this);
String funInvocStr = asmFunConst.getValue();
// In case of native functions
if (modelResolver.lookupNativeAsmFunction(funInvocStr)) {
NativeFunctionInvocation nativeFunInvoc = TermsFactory.eINSTANCE.createNativeFunctionInvocation();
// Store the name of the called native ASM Function
nativeFunInvoc.setFunctionName(funInvocStr);
funInvoc = nativeFunInvoc;
// Type check compatibility of actual parameters
typeChecker.getNativeFunInvocsToCheck().add(nativeFunInvoc);
}
// In case of regular ASM functions
else {
ASMFunctionInvocation asmFunInvoc = TermsFactory.eINSTANCE.createASMFunctionInvocation();
// Store the name of the called ASM Function as the FQN
asmFunInvoc.setFqn(asmFunConst.getValue());
// Resolve the called ASM Function in the validation phase
modelResolver.getUnresolvedAsmFunctionInvocations().add(asmFunInvoc);
funInvoc = asmFunInvoc;
// Type check compatibility of actual parameters
typeChecker.getAsmFunInvocsToCheck().add(asmFunInvoc);
}
// Processing actual parameters
n.getActualParameterDefAST().accept(this, funInvoc.getActualParameters());
createNodeInfoFor(n, funInvoc);
funInvoc.setName(n.getASMFunctionNameAST().toString());
return funInvoc;
}
@Override
public Object visit(AsmFunctionLocationAST n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
// ***************** Sec. 5.4.4. Built-in Functions ********************
/**
* Visiting a BuiltInFunctionNameAST node and
* returning the appropriate ModelElementQuery
* @param n : Current AST node of type BuiltInFunctionNameAST
*/
@Override
public Object visit(BuiltInFunctionNameAST n) {
ModelElementQuery fun = null;
String funStr = n.toString();
if (funStr.equals("ref")) {
fun = QueryFunctionsFactory.eINSTANCE.createElementReference();
}
else if (funStr.equals("fqn")) {
fun = QueryFunctionsFactory.eINSTANCE.createFullyQualifiedName();
}
else if (funStr.equals("name")) {
fun = QueryFunctionsFactory.eINSTANCE.createName();
}
else if (funStr.equals("value")) {
fun = QueryFunctionsFactory.eINSTANCE.createValue();
}
else if (funStr.equals("source")) {
fun = QueryFunctionsFactory.eINSTANCE.createSource();
}
else if (funStr.equals("target")) {
fun = QueryFunctionsFactory.eINSTANCE.createTarget();
}
else if (funStr.equals("multiplicity")) {
fun = QueryFunctionsFactory.eINSTANCE.createMultiplicity();
}
else if (funStr.equals("aggregation")) {
fun = QueryFunctionsFactory.eINSTANCE.createAggregate();
}
else if (funStr.equals("inverse")) {
fun = QueryFunctionsFactory.eINSTANCE.createInverse();
} else {
//TODO Invalid built-in function - error/exception handling
return null;
}
fun.setName(funStr);
return fun;
}
@Override
public Object visit(BuiltInFunctionNameAST n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a ConversionFunctionNameAST node and
* returning the appropriate ConversionOperation
* @param n : Current AST node of type ConversionFunctionNameAST
*/
@Override
public Object visit(ConversionFunctionNameAST n) {
ConversionOperation fun = null;
String funStr = n.toString();
if (funStr.equals("toBoolean")) {
fun = BuiltInFunctionsFactory.eINSTANCE.createToBoolean();
}
else if (funStr.equals("toString")) {
fun = BuiltInFunctionsFactory.eINSTANCE.createToString();
}
else if (funStr.equals("toInteger")) {
fun = BuiltInFunctionsFactory.eINSTANCE.createToInt();
}
else if (funStr.equals("toDouble")) {
fun = BuiltInFunctionsFactory.eINSTANCE.createToDouble();
}
else if (funStr.equals("toMultiplicity")) {
fun = BuiltInFunctionsFactory.eINSTANCE.createToMultiplicity();
} else {
//TODO Invalid conversion function - error/exception handling
return null;
}
fun.setName(funStr);
return fun;
}
@Override
public Object visit(ConversionFunctionNameAST n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a PredefinedFunctionCallAST0 node (Model query function) and
* returning a ModelElementQuery
* @param n : Current AST node of type PredefinedFunctionCallAST0
*/
@Override
public Object visit(PredefinedFunctionCallAST0 n) {
ModelElementQuery modelQuery = (ModelElementQuery) n.getBuiltInFunctionNameAST().accept(this);
Term argument = (Term) n.getArithmeticTermAST().accept(this);
modelQuery.setArgument(argument);
createNodeInfoFor(n, modelQuery);
// No type checking
// typeChecker.typeCheckTerm(modelQuery, argument);
return modelQuery;
}
@Override
public Object visit(PredefinedFunctionCallAST0 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a PredefinedFunctionCallAST1 node (Conversion function) and
* returning a ConversionOperation
* @param n : Current AST node of type PredefinedFunctionCallAST1
*/
@Override
public Object visit(PredefinedFunctionCallAST1 n) {
ConversionOperation convOp = (ConversionOperation) n.getConversionFunctionNameAST().accept(this);
Term argument = (Term) n.getArithmeticTermAST().accept(this);
convOp.getActualParameters().add(argument);
createNodeInfoFor(n, convOp);
// No type checking
// typeChecker.typeCheckTerm(convOp, argument);
return convOp;
}
@Override
public Object visit(PredefinedFunctionCallAST1 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
// *************** Sec. 5.5.1 Simple ASM Rules ******************
protected void assignCaller(ASMRuleInvocation ruleInvoc, Object caller) {
if (caller instanceof ASMRuleInvocation) {
ASMRuleInvocation callerInvoc = (ASMRuleInvocation) caller;
ruleInvoc.setCaller(callerInvoc);
}
else if (caller instanceof Rule) {
Rule callerRule = (Rule) caller;
callerRule.setBody(ruleInvoc);
}
}
/**
* Visiting a FailRuleAST node, and creating a FailRule model element
* @param n : Current AST node of type FailRuleAST
* @param o : is expected to be a ASMRuleInvocation or Rule
* @return rule : FailRule
*/
@Override
public Object visit(FailRuleAST n, Object o) {
FailRule rule = SimpleRulesFactory.eINSTANCE.createFailRule();
assignCaller(rule, o);
createNodeInfoFor(n, rule);
rule.setName("FailRule");
return rule;
}
/**
* Visiting a IfRuleAST node without an "else" branch
* and creating a ConditionalRuleIf model element
* @param n : Current AST node of type IfRuleAST0
* @param o : is expected to be a ASMRuleInvocation or Rule
*/
@Override
public Object visit(IfRuleAST0 n, Object o) {
// Creating an IfRule
ConditionalRuleIf ifRule = SimpleRulesFactory.eINSTANCE.createConditionalRuleIf();
// Assigning the caller (ASM Rule definition or invocation)
assignCaller(ifRule, o);
// Reset buffer for unresolved variables
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
// Visiting the condition
Term condition = (Term) n.getLogicalTermAST().accept(this);
ifRule.setExpressionToTest(condition);
// Type checking condition
typeChecker.getTermsToCheck().add(condition);
modelResolver.resolveVariableRefsInRule(ifRule);
modelResolver.getUnresolvedVariableRefsStack().pop();
// Visiting the if branch
ASMRuleInvocation ifBranch = (ASMRuleInvocation) n.getAsmRuleAST().accept(this, ifRule);
ifRule.setRuleTrue(ifBranch);
createNodeInfoFor(n, ifRule);
ifRule.setName("IfRule");
return ifRule;
}
/**
* Visiting a IfRuleAST node WITH an "else" branch
* and creating a ConditionalRuleIf model element
* @param n : Current AST node of type IfRuleAST0
* @param o : is expected to be a ASMRuleInvocation or Rule
*/
@Override
public Object visit(IfRuleAST1 n, Object o) {
// Creating an IfRule
ConditionalRuleIf ifRule = SimpleRulesFactory.eINSTANCE.createConditionalRuleIf();
assignCaller(ifRule, o);
// Reset buffer for unresolved variables
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
// modelResolver.getUnresolvedVariableRefs().clear();
// Processing the condition
Term condition = (Term) n.getLogicalTermAST().accept(this);
ifRule.setExpressionToTest(condition);
// Type checking condition
typeChecker.getTermsToCheck().add(condition);
// Resolving variable references in Condition
modelResolver.resolveVariableRefsInRule(ifRule);
modelResolver.getUnresolvedVariableRefsStack().pop();
// Processing the if branch
ASMRuleInvocation ifBranch = (ASMRuleInvocation) n.getAsmRuleAST().accept(this, ifRule);
ifRule.setRuleTrue(ifBranch);
// Processing the else branch
ASMRuleInvocation elseBranch = (ASMRuleInvocation) n.getAsmRuleAST7().accept(this, ifRule);
ifRule.setRuleFalse(elseBranch);
createNodeInfoFor(n, ifRule);
ifRule.setName("IfRule");
return ifRule;
}
/**
* Visiting a TryRuleAST node without an "else" branch
* and creating a ConditionalRuleTry model element
* @param n : Current AST node of type TryRuleAST0
* @param o : is expected to be a ASMRuleInvocation or Rule
*/
@Override
public Object visit(TryRuleAST0 n, Object o) {
// Create new TryRule
ConditionalRuleTry tryRule = SimpleRulesFactory.eINSTANCE.createConditionalRuleTry();
assignCaller(tryRule, o);
// Visiting the try branch
ASMRuleInvocation tryBranch = (ASMRuleInvocation) n.getAsmRuleAST().accept(this, tryRule);
tryRule.setRuleToTry(tryBranch);
createNodeInfoFor(n, tryRule);
tryRule.setName("TryRule");
return tryRule;
}
/**
* Visiting a TryRuleAST node WITH an "else" branch
* and creating a ConditionalRuleTry model element
* @param n : Current AST node of type TryRuleAST0
* @param o : is expected to be a ASMRuleInvocation
*/
@Override
public Object visit(TryRuleAST1 n, Object o) {
// Create new TryRule
ConditionalRuleTry tryRule = SimpleRulesFactory.eINSTANCE.createConditionalRuleTry();
assignCaller(tryRule, o);
// Processing the try branch
ASMRuleInvocation tryBranch = (ASMRuleInvocation) n.getAsmRuleAST().accept(this, tryRule);
tryRule.setRuleToTry(tryBranch);
// Processing the else branch
ASMRuleInvocation elseBranch = (ASMRuleInvocation) n.getAsmRuleAST4().accept(this, tryRule);
tryRule.setRuleElse(elseBranch);
createNodeInfoFor(n, tryRule);
tryRule.setName("TryRule");
return tryRule;
}
/**
* Visiting a SkipRuleAST node, and creating an EMF model element SkipRule
* @param n : Current AST node of type SkipRuleAST
* @param o : is expected to be a ASMRuleInvocation or ASM Rule
*/
@Override
public Object visit(SkipRuleAST n, Object o) {
SkipRule rule = SimpleRulesFactory.eINSTANCE.createSkipRule();
assignCaller(rule, o);
createNodeInfoFor(n, rule);
rule.setName("SkipRule");
return rule;
}
/**
* Visiting a CallRuleAST node, and creating a CallRule model element
* @param n : Current AST node of type CallRuleAST
* @param o : is expected to be a ASMRuleInvocation
*/
@Override
public Object visit(CallRuleAST n, Object o) {
// Create new CallRule
CallRule callRule = SimpleRulesFactory.eINSTANCE.createCallRule();
assignCaller(callRule, o);
// Reset buffer for unresolved variables
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
// Setting the name of the called ASMRule
String ruleName = (String) n.getQualifiedTypeNameAST().accept(this);
callRule.setFqn(ruleName);
callRule.setName(ruleName);
// Setting the actual parameters
n.getActualParameterDefAST().accept(this, callRule.getActualParameters());
// Type checking actual parameters
for (Object param : callRule.getActualParameters()) {
Term term = (Term) param;
typeChecker.getTermsToCheck().add(term);
}
// Type check compatibility of actual parameters
typeChecker.getAsmCallRuleToCheck().add(callRule);
// Resolving variable references
modelResolver.resolveVariableRefsInRule(callRule);
modelResolver.getUnresolvedVariableRefsStack().pop();
// Creating node information
createNodeInfoFor(n, callRule);
// Resolve the reference to the called rule in a later stage
modelResolver.getUnresolvedAsmRuleCalls().add(callRule);
callRule.setName("CallRule");
return callRule;
}
/**
* Visiting a LogRuleAST node, and creating a LogRule model element
* @param n : Current AST node of type LogRuleAST
* @param o : is expected to be a ASMRuleInvocation
*/
@Override
public Object visit(LogRuleAST n, Object o) {
// Then create LogRule model element
LogRule logRule = SimpleRulesFactory.eINSTANCE.createLogRule();
assignCaller(logRule, o);
// Reset buffer for unresolved variables
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
// Process Log level
LogLevel logLevel = (LogLevel) n.getLogLevelAST().accept(this);
logRule.setLevel(logLevel);
// Process the term to log
Term logTerm = (Term) n.getArithmeticTermAST().accept(this);
logRule.setOut(logTerm);
// Type checking term
typeChecker.getTermsToCheck().add(logTerm);
// Resolve variable references in the out term
modelResolver.resolveVariableRefsInRule(logRule);
modelResolver.getUnresolvedVariableRefsStack().pop();
createNodeInfoFor(n, logRule);
logRule.setName("LogRule");
return logRule;
}
/**
* Visiting the LogLevelAST node, and returning its LogLevel
* @param n : Current AST node
*/
@Override
public Object visit(LogLevelAST n) {
String logStr = n.toString();
if (logStr.equals("debug")) {
return LogLevel.DEBUG_LITERAL;
}
else if (logStr.equals("info")) {
return LogLevel.INFO_LITERAL;
}
else if (logStr.equals("warning")) {
return LogLevel.WARNING_LITERAL;
}
else if (logStr.equals("error")) {
return LogLevel.ERROR_LITERAL;
}
else if (logStr.equals("fatal")) {
return LogLevel.FATAL_LITERAL;
}
return null;
}
/**
* Visiting a {@link PrintRuleAST0} node (print), and creating a PrintRule model element
* @param n : Current AST node of type PrintRuleAST0
* @param o : Object o is expected to be a ASMRuleInvocation
* @return printRule: {@link PrintRule}
*/
@Override
public Object visit(PrintRuleAST0 n, Object o) {
// Create a PrintRule
PrintRule printRule = SimpleRulesFactoryImpl.eINSTANCE.createPrintRule();
assignCaller(printRule, o);
// Reset buffer for unresolved variables
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
// Visit the term to print
Term printTerm = (Term) n.getLogicalTermAST().accept(this);
printRule.setOut(printTerm);
// Type checking term
typeChecker.getTermsToCheck().add(printTerm);
// Resolve variable references in the out term
modelResolver.resolveVariableRefsInRule(printRule);
modelResolver.getUnresolvedVariableRefsStack().pop();
createNodeInfoFor(n, printRule);
printRule.setName("PrintRule");
return printRule;
}
/**
* Visiting a {@link PrintRuleAST1} node (print with buffer), and
* creating a PrintLnRule model element
* @param n : Current AST node of type PrintRuleAST1
* @param o : Object o is expected to be a ASMRuleInvocation
* @return printRule : the new {@link PrintRule}
*/
@Override
public Object visit(PrintRuleAST1 n, Object o) {
// Create a PrintRule
PrintRule printRule = SimpleRulesFactoryImpl.eINSTANCE.createPrintRule();
assignCaller(printRule, o);
// Reset buffer for unresolved variables
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
// Visit the buffer to print to
Term buffer = (Term) n.getArithmeticTermAST().accept(this);
printRule.setBuffer(buffer);
// Process the term to print
Term printTerm = (Term) n.getLogicalTermAST().accept(this);
printRule.setOut(printTerm);
// Type checking term
typeChecker.getTermsToCheck().add(printTerm);
// Resolve variable references in the out term
modelResolver.resolveVariableRefsInRule(printRule);
modelResolver.getUnresolvedVariableRefsStack().pop();
createNodeInfoFor(n, printRule);
printRule.setName("PrintRule");
return printRule;
}
/**
* Visiting a {@link PrintRuleAST2} node (println), and creating a PrintRule model element
* @param n : Current AST node of type PrintRuleAST0
* @param o : Object o is expected to be a ASMRuleInvocation
* @return printRule: {@link PrintLnRule}
*/
@Override
public Object visit(PrintRuleAST2 n, Object o) {
// Create a PrintRule
PrintLnRule printRule = SimpleRulesFactoryImpl.eINSTANCE.createPrintLnRule();
assignCaller(printRule, o);
// Reset buffer for unresolved variables
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
// Visit the term to print
Term printTerm = (Term) n.getLogicalTermAST().accept(this);
printRule.setOut(printTerm);
// Type checking term
typeChecker.getTermsToCheck().add(printTerm);
// Resolve variable references in the out term
modelResolver.resolveVariableRefsInRule(printRule);
modelResolver.getUnresolvedVariableRefsStack().pop();
createNodeInfoFor(n, printRule);
printRule.setName("PrintLNRule");
return printRule;
}
/**
* Visiting a {@link PrintRuleAST3} node (println with buffer), and
* creating a PrintLnRule model element
* @param n : Current AST node of type PrintRuleAST1
* @param o : Object o is expected to be a ASMRuleInvocation
* @return printRule : the new {@link PrintLnRule}
*/
@Override
public Object visit(PrintRuleAST3 n, Object o) {
// Create a PrintRule
PrintLnRule printRule = SimpleRulesFactoryImpl.eINSTANCE.createPrintLnRule();
assignCaller(printRule, o);
// Reset buffer for unresolved variables
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
// Visit the buffer to print to
Term buffer = (Term) n.getArithmeticTermAST().accept(this);
printRule.setBuffer(buffer);
// Process the term to print
Term printTerm = (Term) n.getLogicalTermAST().accept(this);
printRule.setOut(printTerm);
// Type checking term
typeChecker.getTermsToCheck().add(printTerm);
// Resolve variable references in the out term
modelResolver.resolveVariableRefsInRule(printRule);
modelResolver.getUnresolvedVariableRefsStack().pop();
createNodeInfoFor(n, printRule);
printRule.setName("PrintLnRule");
return printRule;
}
/**
* Visiting an UpdateRuleAST0 node (for variable updates), and
* creating a RuleUpdateVariable model element.
* The references to the predefined variable used here are not resolved
* @param n : Current AST node of type UpdateRuleAST0
* @param o : Object o is expected to be a ASMRuleInvocation
*/
@Override
public Object visit(UpdateRuleAST0 n, Object o) {
// Create new Variable Update Rule
RuleUpdateVariable updateRule = SimpleRulesFactory.eINSTANCE.createRuleUpdateVariable();
assignCaller(updateRule, o);
// Reset buffer for unresolved variables
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
// Process the variable to be updated
VariableReference variableRef = (VariableReference) n.getVariableRefAST().accept(this);
updateRule.setVariable(variableRef);
// Type checking for variable reference
typeChecker.getTermsToCheck().add(variableRef);
// Process the term as the right value
Term term = (Term) n.getArithmeticTermAST().accept(this);
updateRule.setValue(term);
// Type checking for term
typeChecker.getTermsToCheck().add(term);
// Schedule type compatibility checking for Left and Right values
typeChecker.getUpdateRulesToCheck().add(updateRule);
// Resolve variable references in the term
modelResolver.resolveVariableRefsInRule(updateRule);
modelResolver.getUnresolvedVariableRefsStack().pop();
createNodeInfoFor(n, updateRule);
updateRule.setName("UpdateRule");
return updateRule;
}
/**
* Visiting an UpdateRuleAST1 node (for ASM function updates), and
* creating a RuleUpdateASMFunction model element.
* The references to the predefined variable used here are not resolved
* @param n : Current AST node of type UpdateRuleAST1
* @param o : Object o is expected to be a ASMRuleInvocation
*/
@Override
public Object visit(UpdateRuleAST1 n, Object o) {
RuleUpdateASMFunction updateRule = SimpleRulesFactory.eINSTANCE.createRuleUpdateASMFunction();
assignCaller(updateRule, o);
// Reset buffer for unresolved variables
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
// Process the ASM function to be updated
n.getAsmFunctionUpdateLocationAST().accept(this, updateRule);
// Process the term as the right value
Term term = (Term) n.getArithmeticTermAST().accept(this);
updateRule.setValue(term);
// Type checking for term
typeChecker.getTermsToCheck().add(term);
// Resolve variable references in the term
modelResolver.resolveVariableRefsInRule(updateRule);
modelResolver.getUnresolvedVariableRefsStack().pop();
// Schedule type compatibility checking for Left and Right values
typeChecker.getUpdateRulesToCheck().add(updateRule);
createNodeInfoFor(n, updateRule);
updateRule.setName("UpdateRule");
return updateRule;
}
// *************** Sec. 5.5.2. Compound ASM Rules ******************
/**
* Visiting a ChooseRuleAST node and
* creating a ChooseRule model element.
* @param n : Current AST node of type ChooseRuleAST
* @param o : Object o is expected to be a ASMRuleInvocation
*/
@Override
public Object visit(ChooseRuleAST n, Object o) {
// Create a choose rule
ChooseRule chooseRule = CompoundRulesFactory.eINSTANCE.createChooseRule();
assignCaller(chooseRule, o);
// Reset buffer for unresolved variables
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
// Process variable definitions (if any)
if (n.getConstrainedVariablesOptAST() != null) {
n.getConstrainedVariablesOptAST().accept(this, chooseRule);
}
// Process condition
Object cond = n.getConditionAST().accept(this);
// Check if the condition is a term (including ASMFunctionInvocation)
if (cond instanceof Term) {
Term term = (Term) cond;
chooseRule.setCondition(term);
chooseRule.setGtrule(null);
// Type checking for term
typeChecker.getTermsToCheck().add(term);
chooseRule.setName("ChooseRuleWithTerm");
}
// or a GTRuleInvocation
else if (cond instanceof GTRuleInvocation) {
GTRuleInvocation gtrule = (GTRuleInvocation) cond;
chooseRule.setGtrule(gtrule);
chooseRule.setCondition(null);
// Type check actual parameters of GTRuleInvocation is already scheduled
chooseRule.setName("ChooseRuleWithGTRule");
}
// Resolve variable references in the condition
modelResolver.resolveVariableRefsInRule(chooseRule);
modelResolver.getUnresolvedVariableRefsStack().pop();
// Process the body of the rule
n.getDoActionOptAST().accept(this, chooseRule);
createNodeInfoFor(n, chooseRule);
return chooseRule;
}
/**
* Visiting a ForallRuleAST node and
* creating a ForallRule model element.
* @param n : Current AST node of type ForallRuleAST
* @param o : Object o is expected to be a ASMRuleInvocation
*/
@Override
public Object visit(ForallRuleAST n, Object o) {
// Create a ForallRule
ForallRule forallRule = CompoundRulesFactory.eINSTANCE.createForallRule();
assignCaller(forallRule, o);
// Reset buffer for unresolved variables
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
// Process variable definitions (if any)
if (n.getConstrainedVariablesOptAST() != null) {
n.getConstrainedVariablesOptAST().accept(this, forallRule);
}
// Process condition
Object cond = n.getConditionAST().accept(this);
// Check if the condition is a term
if (cond instanceof Term) {
Term term = (Term) cond;
forallRule.setCondition(term);
forallRule.setGtrule(null);
// Type checking for term
typeChecker.getTermsToCheck().add(term);
forallRule.setName("ForallRuleWithTerm");
}
// or a GTRuleInvocation
else if (cond instanceof GTRuleInvocation) {
GTRuleInvocation gtrule = (GTRuleInvocation) cond;
forallRule.setGtrule(gtrule);
forallRule.setCondition(null);
// Type check actual parameters of GTRuleInvocation is already scheduled
forallRule.setName("ForallRuleWithGTRule");
}
// Resolve variable references in the condition
modelResolver.resolveVariableRefsInRule(forallRule);
modelResolver.getUnresolvedVariableRefsStack().pop();
// Process the body of the rule
n.getDoActionOptAST().accept(this, forallRule);
createNodeInfoFor(n, forallRule);
return forallRule;
}
/**
* Visiting a {@link DoActionOptAST0} node and
* creating a default {@link SkipRule} model element as body
* @param n : Current AST node of type {@link DoActionOptAST0}
* @param o : Object o is expected to be a {@link CollectionIteratorRule}
*/
@Override
public Object visit(DoActionOptAST0 n, Object o) {
CollectionIteratorRule callerRule = (CollectionIteratorRule) o;
SkipRule skipRule = SimpleRulesFactory.eINSTANCE.createSkipRule();
skipRule.setCaller(callerRule);
callerRule.setBody(skipRule);
// Node info is not created here
skipRule.setName("SkipRule");
return skipRule;
}
/**
* Visiting a {@link DoActionOptAST1} node
* @param n : Current AST node of type {@link DoActionOptAST1}
* @param o : Object o is expected to be a {@link CollectionIteratorRule}
*/
@Override
public Object visit(DoActionOptAST1 n, Object o) {
CollectionIteratorRule callerRule = (CollectionIteratorRule) o;
ASMRuleInvocation asmRule = (ASMRuleInvocation) n.getAsmRuleAST().accept(this, callerRule);
callerRule.setBody(asmRule);
return asmRule;
}
/**
* Visiting an IterateRuleAST node and
* creating an IterateRule model element.
* @param n : Current AST node of type IterateRuleAST
* @param o : Object o is expected to be an ASMRuleInvocation
*/
@Override
public Object visit(IterateRuleAST n, Object o) {
// Create an IterateRule
IterateRule iterateRule = CompoundRulesFactory.eINSTANCE.createIterateRule();
assignCaller(iterateRule, o);
// Processing the body
ASMRuleInvocation bodyRule = (ASMRuleInvocation) n.getAsmRuleAST().accept(this, iterateRule);
iterateRule.setBody(bodyRule);
createNodeInfoFor(n, iterateRule);
return iterateRule;
}
/**
* Visiting a {@link WhenRuleAST} and creating a {@link WhenRule} element
* @param n : Current AST node of type {@link WhenRuleAST}
* @param o : Object o is expected to be an ASMRuleInvocation
*/
@Override
public Object visit(WhenRuleAST n, Object o) {
WhenRule whenRule = CompoundRulesFactory.eINSTANCE.createWhenRule();
assignCaller(whenRule, o);
// Process condition
n.getWhenConditionAST().accept(this, whenRule.getConditions());
// Processing the body
ASMRuleInvocation bodyRule = (ASMRuleInvocation) n.getAsmRuleAST().accept(this, whenRule);
whenRule.setBody(bodyRule);
// Create node info
createNodeInfoFor(n, whenRule);
whenRule.setName("WhenCondition");
return whenRule;
}
/**
* Visiting a {@link WhenChangeAST0} (new clause)
* @param n : Current AST node of type {@link WhenChangeAST0}
* @param o : List of {@link ChangeEvent} as when conditions
*/
@Override
public Object visit(WhenChangeAST0 n, Object o) {
@SuppressWarnings("unchecked")
List<ChangeEvent> conditionList = (List<ChangeEvent>) o;
VariableReference varRef = (VariableReference) n.getVariableRefAST().accept(this);
ChangeEvent changeEvent = createChangeEvent(/*(ASTNode)*/ n, ChangeKind.NEW, varRef);
conditionList.add(changeEvent);
return conditionList;
}
/**
* Visiting a {@link WhenChangeAST1} (delete clause)
* @param n : Current AST node of type {@link WhenChangeAST1}
* @param o : List of {@link ChangeEvent} as when conditions
*/
@Override
public Object visit(WhenChangeAST1 n, Object o) {
@SuppressWarnings("unchecked")
List<ChangeEvent> conditionList = (List<ChangeEvent>) o;
VariableReference varRef = (VariableReference) n.getVariableRefAST().accept(this);
ChangeEvent changeEvent = createChangeEvent(/*(ASTNode)*/ n, ChangeKind.DELETE, varRef);
conditionList.add(changeEvent);
return conditionList;
}
/**
* Visiting a {@link WhenChangeAST2} (changed clause)
* @param n : Current AST node of type {@link WhenChangeAST2}
* @param o : List of {@link ChangeEvent} as when conditions
*/
@Override
public Object visit(WhenChangeAST2 n, Object o) {
@SuppressWarnings("unchecked")
List<ChangeEvent> conditionList = (List<ChangeEvent>) o;
VariableReference varRef = (VariableReference) n.getVariableRefAST().accept(this);
ChangeEvent changeEvent = createChangeEvent(/*(ASTNode)*/ n, ChangeKind.CHANGED, varRef);
conditionList.add(changeEvent);
return conditionList;
}
/**
* Creates a {@link ChangeEvent}
* @param n : ASTNode representing the change event
* @param kind : new, delete or changed
* @return the new {@link ChangeEvent}
*/
protected ChangeEvent createChangeEvent(ASTNode n, ChangeKind kind, VariableReference varRef) {
ChangeEvent changeEvent = DefinitionsFactory.eINSTANCE.createChangeEvent();
changeEvent.setChangeKind(ChangeKind.CHANGED);
changeEvent.setVariableReference(varRef);
createNodeInfoFor(n, changeEvent);
return changeEvent;
}
/**
* Visiting a {@link WhenConditionAST}
* @param n : Current AST node of type {@link WhenConditionAST}
* @param o : List of {@link ChangeEvent} as when conditions
*/
@Override
public Object visit(WhenConditionAST n, Object o) {
@SuppressWarnings("unchecked")
List<ChangeEvent> conditionList = (List<ChangeEvent>) o;
n.getWhenConditionAST().accept(this, conditionList);
n.getWhenChangeAST().accept(this, conditionList);
return conditionList;
}
/**
* Visiting a LetRuleAST node and
* creating an LetRule model element.
* @param n : Current AST node of type LetRuleAST
* @param o : Object o is expected to be an ASMRuleInvocation or Rule
*/
@Override
public Object visit(LetRuleAST n, Object o) {
// Create a LetRule
LetRule letRule = CompoundRulesFactory.eINSTANCE.createLetRule();
assignCaller(letRule, o);
// Reset buffer for unresolved variables in the variable definition part
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
// Processing variable definitions
n.getVariableDefinitionsAST().accept(this, letRule);
// Resolve variable references in the condition
modelResolver.resolveVariableRefsInRule(letRule);
modelResolver.getUnresolvedVariableRefsStack().pop();
// Processing the body
ASMRuleInvocation bodyRule = (ASMRuleInvocation) n.getAsmRuleAST().accept(this, letRule);
letRule.setBody(bodyRule);
createNodeInfoFor(n, letRule);
letRule.setName("LetRule");
return letRule;
}
/**
* Visiting a RandomRuleAST node
* creating a RandomRule model element.
* @param n : Current AST node of type RandomRuleAST
* @param o : Object o is expected to be an ASMRuleInvocation
*/
@Override
public Object visit(RandomRuleAST n, Object o) {
// Creating a RandomRule
RandomRule randomRule = CompoundRulesFactory.eINSTANCE.createRandomRule();
assignCaller(randomRule, o);
// Processing the subrules
n.getAsmRulesAST().accept(this, randomRule);
createNodeInfoFor(n, randomRule);
randomRule.setName("RandomRule");
return randomRule;
}
/**
* Visiting a {@link SequentialRuleAST} node
* creating a {@link SequentialRule} model element.
* @param n : Current AST node of type {@link SequentialRuleAST}
* @param o : Object o is expected to be an ASMRuleInvocation
*/
@Override
public Object visit(SequentialRuleAST n, Object o) {
SequentialRule seqRule = CompoundRulesFactory.eINSTANCE.createSequentialRule();
assignCaller(seqRule, o);
n.getAsmRulesAST().accept(this, seqRule);
createNodeInfoFor(n, seqRule);
seqRule.setName("SequentialRule");
return seqRule;
}
/**
* Visiting a {@link ParallelRuleAST} node
* creating a {@link ParallelRule} model element.
* @param n : Current AST node of type {@link ParallelRuleAST}
* @param o : Object o is expected to be an {@link ASMRuleInvocation}
*/
@Override
public Object visit(ParallelRuleAST n, Object o) {
ParallelRule parRule = CompoundRulesFactory.eINSTANCE.createParallelRule();
assignCaller(parRule, o);
n.getAsmRulesAST().accept(this, parRule);
createNodeInfoFor(n, parRule);
parRule.setName("ParallelRule");
return parRule;
}
/**
* Visiting ActualParamsPatternVariablesAST node and return its ActualParams
* @param n : Current AST node of type ActualParamsPatternVariablesAST
* @param o : List of Parameters
*/
@Override
public Object visit(ActualParamsPatternVariablesAST n, Object o) {
@SuppressWarnings("unchecked")
List<VariableReference> paramList = (List<VariableReference>) o;
if (n.getActualParamsPatternVariablesAST() != null) {
n.getActualParamsPatternVariablesAST().accept(this, paramList);
}
VariableReference varRef = (VariableReference) n.getPatternVariableRefAST().accept(this);
paramList.add(varRef);
//createNodeInfoFor(n, varRef);
return paramList;
}
/**
* Visiting an AsmRulesAST node
* @param n : Current AST node of type AsmRulesAST
* @param o : Object o is expected to be a NestedRule
*/
@Override
public Object visit(AsmRulesAST n, Object o) {
NestedRule callerRule = (NestedRule) o;
if (n.getAsmRulesOptAST() != null) {
n.getAsmRulesOptAST().accept(this, callerRule);
}
ASMRuleInvocation bodyRule = (ASMRuleInvocation) n.getAsmRuleAST().accept(this, callerRule);
if (bodyRule != null) {
callerRule.getSubrules().add(bodyRule);
}
return callerRule;
}
/**
* Visiting an AsmRulesOptAST node
* @param n : Current AST node of type AsmRulesOptAST
* @param o : Object o is expected to be a NestedRule
*/
@Override
public Object visit(AsmRulesOptAST n, Object o) {
NestedRule callerRule = (NestedRule) o;
if (n.getAsmRulesOptAST() != null) {
n.getAsmRulesOptAST().accept(this, callerRule);
}
ASMRuleInvocation bodyRule = (ASMRuleInvocation) n.getAsmRuleAST().accept(this, callerRule);
if (bodyRule != null) {
callerRule.getSubrules().add(bodyRule);
}
return callerRule;
}
/**
* Visiting a VariableDefinitionsAST node
* @param n : Current AST node of type VariableDefinitionsAST
* @param o : Object o is expected to be a LetRule
*/
@Override
public Object visit(VariableDefinitionsAST n, Object o) {
LetRule callerRule = (LetRule) o;
n.getVariableDefinitionsAST().accept(this, callerRule);
n.getVariableDefinitionAST().accept(this, callerRule);
return callerRule;
}
/**
* Visiting a VariableDefinitionAST node
* @param n : Current AST node of type VariableDefinitionsAST
* @param o : Object o is expected to be a LetRule
*/
@Override
public Object visit(VariableDefinitionAST n, Object o) {
LetRule callerRule = (LetRule) o;
// Create a variable definition
VariableDefinition varDef = DefinitionsFactory.eINSTANCE.createVariableDefinition();
// Process the variable
Variable var = (Variable) n.getVariableDefAST().accept(this);
varDef.setVariable(var);
varDef.setName(var.getName());
varDef.setFqn(var.getFqn());
// Process the values
Term value = (Term) n.getArithmeticTermAST().accept(this);
varDef.setValue(value);
// Type checking for value
typeChecker.getTermsToCheck().add(value);
// Add new variable to the caller rule
callerRule.getLocalVariables().add(var);
callerRule.getDefinitions().add(varDef);
// Process type information
if (n.getTypeOptAST() != null) {
n.getTypeOptAST().accept(this, var);
}
// Typecheck compatibility of initial value with its type
typeChecker.getVarDefsToCheck().add(varDef);
createNodeInfoFor(n, varDef);
return callerRule;
}
// ***************** Sec. 5.5.3 Model Manipulation Rules *************
/**
* Visiting a {@link CreateRuleAST0} and
* creating an {@link ElementCreateRule} model element
* @param n : Current AST node of type {@link CreateRuleAST0}
* @param o : expected to be an {@link ASMRuleInvocation} or {@link Rule}
* @return rule : ElementCreateRule
*/
@Override
public Object visit(CreateRuleAST0 n, Object o) {
// Reset buffer for unresolved variables
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
ElementCreateRule rule = (ElementCreateRule) n.getCreateModelElementAST().accept(this);
assignCaller(rule, o);
// Resolve variable references in the condition
modelResolver.resolveVariableRefsInRule(rule);
modelResolver.getUnresolvedVariableRefsStack().pop();
rule.setName("ElementCreateRule");
return rule;
}
/**
* Visiting a {@link CreateRuleAST1} and
* creating a {@link RelationshipCreateRule}
* @param n : Current AST node of type {@link CreateRuleAST1}
* @param o : expected to be an {@link ASMRuleInvocation} or {@link Rule}
* @return The created {@link RelationshipCreateRule}
*/
@Override
public Object visit(CreateRuleAST1 n, Object o) {
// Reset buffer for unresolved variables
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
// Create a RelationshipCreateRule
RelationshipCreateRule rule = (RelationshipCreateRule) n.getCreateRelationshipAST().accept(this);
assignCaller(rule, o);
// Resolve variable references in the condition
modelResolver.resolveVariableRefsInRule(rule);
modelResolver.getUnresolvedVariableRefsStack().pop();
createNodeInfoFor(n, rule);
rule.setName("RelationshipCreateRule");
return rule;
}
/**
* Visiting a {@link CreateModelElementAST0} (Entity Creation) and
* creating an {@link EntityCreateRule} model element
* @param n : Current AST node of type {@link CreateModelElementAST0}
* @return The created {@link EntityCreateRule}
*/
@Override
public Object visit(CreateModelElementAST0 n) {
EntityCreateRule rule = CreationFactory.eINSTANCE.createEntityCreateRule();
createNodeInfoFor(n, rule);
String typeStr = (String) n.getQualifiedTypeNameAST().accept(this);
// // The type of the model element is represented as a model element constant
// Constant typeConst = TermsFactory.eINSTANCE.createConstant();
// typeConst.setValue(typeStr);
// typeConst.setKind(ValueKind.MODELELEMENT_LITERAL);
// rule.setType(typeConst);
// This issue should be handled in the interpreter
if (!typeStr.equals("entity") && !typeStr.equals("vpm.entity")) {
// Create an element reference in compliance with the previous parser
ElementReference elemRef = QueryFunctionsFactory.eINSTANCE.createElementReference();
Constant typeConst = TermsFactory.eINSTANCE.createConstant();
String value;
if (!typeStr.contentEquals("")) {
value = typeStr;
} else {
value = n.getQualifiedTypeNameAST().toString();
}
typeConst.setValue(value);
elemRef.setName("ref(" + value + ")");
typeConst.setName(value);
typeConst.setKind(ValueKind.STRING_LITERAL);
elemRef.setArgument(typeConst);
rule.setType(elemRef);
// Resolve the type name
modelResolver.resolveTypesInASMRules(rule, typeStr);
}
VariableReference varRef = (VariableReference) n.getCreateEntityBodyAST().accept(this);
// Type check compatibility of variable reference and its definition
typeChecker.getTermsToCheck().add(varRef);
rule.setTargetVariable(varRef);
if (n.getInConstraintOptAST() != null) {
Term parent = (Term) n.getInConstraintOptAST().accept(this);
rule.setParent(parent);
// Type checking
typeChecker.getTermsToCheck().add(parent);
}
rule.setName("EntityCreateRule");
return rule;
}
/**
* Visiting a {@link CreateModelElementAST1} (Relation Creation) and
* creating a {@link RelationCreateRule} model element
* @param n : Current AST node of type {@link CreateModelElementAST1}
* @return The created {@link RelationCreateRule}
*/
@Override
public Object visit(CreateModelElementAST1 n) {
RelationCreateRule rule = CreationFactory.eINSTANCE.createRelationCreateRule();
createNodeInfoFor(n, rule);
String typeStr = (String) n.getQualifiedTypeNameAST().accept(this);
// // The type of the model element is represented as a model element constant
// Constant typeConst = TermsFactory.eINSTANCE.createConstant();
// typeConst.setKind(ValueKind.MODELELEMENT_LITERAL);
// typeConst.setValue(typeStr);
// rule.setType(typeConst);
// This issue should be handled in the interpreter
if (!typeStr.equals("relation") && !typeStr.equals("vpm.entity.relation")) {
// Create an element reference in compliance with the previous parser
ElementReference elemRef = QueryFunctionsFactory.eINSTANCE.createElementReference();
Constant typeConst = TermsFactory.eINSTANCE.createConstant();
String value;
if (!typeStr.contentEquals("")) {
value = typeStr;
} else {
value = n.getQualifiedTypeNameAST().toString();
}
typeConst.setValue(value);
typeConst.setName(value);
elemRef.setName("ref(" + value + ")");
typeConst.setKind(ValueKind.STRING_LITERAL);
elemRef.setArgument(typeConst);
rule.setType(elemRef);
// Resolve the type name
modelResolver.resolveTypesInASMRules(rule, typeStr);
}
n.getCreateRelationBodyAST().accept(this, rule);
rule.setName("RelationCreateRule");
return rule;
}
/**
* Visiting a {@link CreateEntityBodyAST} and
* returning a {@link VariableReference} model element
* @param n : Current AST node of type {@link CreateEntityBodyAST}
* @return {@link VariableReference}
*/
@Override
public Object visit(CreateEntityBodyAST n) {
return /*(VariableReference)*/ n.getVariableRefAST().accept(this);
}
/**
* Visiting an {@link InConstraintOptAST} and
* returning a {@link Term} model element
* @param n : Current AST node of type {@link InConstraintOptAST}
* @return {@link Term}
*/
@Override
public Object visit(InConstraintOptAST n) {
return /*(Term)*/ n.getArithmeticTermAST().accept(this);
}
/**
* Visiting a {@link CreateRelationBodyAST} and
* setting the source and target of a {@link RelationCreateRule}
* @param n : Current AST node of type {@link CreateRelationBodyAST}
* @return {@link RelationCreateRule}
*/
@Override
public Object visit(CreateRelationBodyAST n, Object o) {
RelationCreateRule rule = (RelationCreateRule) o;
VariableReference varRef = (VariableReference) n.getVariableDefRefAST().accept(this);
// Type check compatibility of variable reference and its definition
typeChecker.getTermsToCheck().add(varRef);
Term src = (Term) n.getArithmeticTermAST().accept(this);
Term trg = (Term) n.getArithmeticTermAST6().accept(this);
rule.setTargetVariable(varRef);
rule.setSource(src);
rule.setTarget(trg);
// Type checking src
typeChecker.getTermsToCheck().add(src);
// Type checking trg
typeChecker.getTermsToCheck().add(trg);
rule.setName("RelationCreateRule");
return rule;
}
/**
* Commonly used code by different types of RelationshipCreateRules
* @param rule : {@link RelationshipCreateRule}
* @param first : {@link Term}
* @param second : {@link Term}
*/
protected void commonCreateTasks(RelationshipCreateRule rule, Term first, Term second) {
rule.setSuper(first);
rule.setSub(second);
}
/**
* Visiting a {@link CreateRelationshipAST0} (supertypeOf) and
* creating a {@link CreateSupertypeOf} rule with
* first parameter as super and second parameter as sub
* @param n : Current AST node of type {@link CreateRelationshipAST0}
* @return The created {@link CreateSupertypeOf} rule
*/
@Override
public Object visit(CreateRelationshipAST0 n) {
List<Term> parameters = new ArrayList<Term>();
n.getTwoParametersAST().accept(this, parameters);
CreateSupertypeOf rule = CreationFactory.eINSTANCE.createCreateSupertypeOf();
commonCreateTasks(rule, parameters.get(0), parameters.get(1));
rule.setName("CreateSupertypeOfRule");
return rule;
}
/**
* Visiting a {@link CreateRelationshipAST1} (subtypeOf) and
* creating a {@link CreateSupertypeOf} rule with
* first parameter as sub and second parameter as super.
* There is no CreateSubtypeOf element in the model.
* @param n : Current AST node of type {@link CreateRelationshipAST1}
* @return The created {@link CreateSupertypeOf} rule
*/
@Override
public Object visit(CreateRelationshipAST1 n) {
List<Term> parameters = new ArrayList<Term>();
n.getTwoParametersAST().accept(this, parameters);
CreateSupertypeOf rule = CreationFactory.eINSTANCE.createCreateSupertypeOf();
commonCreateTasks(rule, parameters.get(1), parameters.get(0));
rule.setName("CreateSubtypeOfRule");
return rule;
}
/**
* Visiting a {@link CreateRelationshipAST2} (typeOf) and
* creating a {@link CreateInstanceOf} rule with
* first parameter as sub and second parameter as super
* @param n : Current AST node of type {@link CreateRelationshipAST2}
* @return The created {@link CreateInstanceOf} rule
*/
@Override
public Object visit(CreateRelationshipAST2 n) {
List<Term> parameters = new ArrayList<Term>();
n.getTwoParametersAST().accept(this, parameters);
CreateInstanceOf rule = CreationFactory.eINSTANCE.createCreateInstanceOf();
commonCreateTasks(rule, parameters.get(0), parameters.get(1));
rule.setName("CreateTypeOfRule");
return rule;
}
/**
* Visiting a {@link CreateRelationshipAST3} (instanceOf) and
* creating a {@link CreateInstanceOf} rule with
* first parameter as super and second parameter as sub
* @param n : Current AST node of type {@link CreateRelationshipAST3}
* @return The created {@link CreateInstanceOf} rule
*/
@Override
public Object visit(CreateRelationshipAST3 n) {
List<Term> parameters = new ArrayList<Term>();
n.getTwoParametersAST().accept(this, parameters);
CreateInstanceOf rule = CreationFactory.eINSTANCE.createCreateInstanceOf();
commonCreateTasks(rule, parameters.get(1), parameters.get(0));
rule.setName("CreateInstanceOfRule");
return rule;
}
/**
* Visiting a {@link DeleteRuleAST0} (model element) and
* creating an {@link ElementDeleteRule} model element
* @param n : Current AST node of type {@link DeleteRuleAST0}
* @param o : expected to be an {@link ASMRuleInvocation} or {@link Rule}
* @return The created {@link ElementDeleteRule}
*/
@Override
public Object visit(DeleteRuleAST0 n, Object o) {
// Reset buffer for unresolved variables
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
// Creating a new delete node
ElementDeleteRule rule = (ElementDeleteRule) n.getDeleteContentsAST().accept(this);
assignCaller(rule, o);
// Resolve variable references in the condition
modelResolver.resolveVariableRefsInRule(rule);
modelResolver.getUnresolvedVariableRefsStack().pop();
createNodeInfoFor(n, rule);
rule.setName("ElementDeleteRule");
return rule;
}
/**
* Visiting a {@link DeleteRuleAST1} (relationship) and
* creating a {@link RelationshipDeleteRule}
* @param n : Current AST node of type {@link DeleteRuleAST1}
* @param o : expected to be an {@link ASMRuleInvocation} or {@link Rule}
* @return The created {@link RelationshipDeleteRule}
*/
@Override
public Object visit(DeleteRuleAST1 n, Object o) {
// Reset buffer for unresolved variables
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
RelationshipDeleteRule rule = (RelationshipDeleteRule) n.getDeleteRelationshipAST().accept(this);
assignCaller(rule, o);
// Resolve variable references in the condition
modelResolver.resolveVariableRefsInRule(rule);
modelResolver.getUnresolvedVariableRefsStack().pop();
createNodeInfoFor(n, rule);
rule.setName("RelationshipDeleteRule");
return rule;
}
@Override
public Object visit(DeleteContentsAST n) {
ElementDeleteRule rule = DeletionFactory.eINSTANCE.createElementDeleteRule();
Term element = (Term) n.getArithmeticTermAST().accept(this);
rule.setElement(element);
// Type checking
typeChecker.getTermsToCheck().add(element);
if (n.getDeleteSemanticsOptAST() != null) {
DeleteSemantics semantics = (DeleteSemantics) n.getDeleteSemanticsOptAST().accept(this);
rule.setSemantics(semantics);
}
else {
// Default semantics: Delete contents, i.e. DROP_CONTENT_LITERAL
rule.setSemantics(DeleteSemantics.DROP_CONTENT_LITERAL);
}
return rule;
}
/**
* Visiting a DeleteSemanticsAST0 node (delete_content) and
* returning DeleteSemantics.DROP_CONTENT_LITERAL
* @param n : Current AST node of type DeleteSemanticsAST0
* @return rule : DeleteSemantics
*/
@Override
public Object visit(DeleteSemanticsAST0 n) {
return DeleteSemantics.DROP_CONTENT_LITERAL;
}
/**
* Visiting a DeleteSemanticsAST1 node (move_content) and
* returning DeleteSemantics.MOVE_CONTENT_LITERAL
* @param n : Current AST node of type DeleteSemanticsAST1
* @return rule : DeleteSemantics
*/
@Override
public Object visit(DeleteSemanticsAST1 n) {
return DeleteSemantics.MOVE_CONTENT_LITERAL;
}
@Override
public Object visit(DeleteSemanticsOptAST n) {
return n.getDeleteSemanticsAST().accept(this);
}
/**
* Commonly used code by different types of {@link RelationshipDeleteRule}s
* @param rule : {@link RelationshipDeleteRule}
* @param first : {@link Term}
* @param second : {@link Term}
*/
protected void commonDeleteTasks(RelationshipDeleteRule rule, Term first, Term second) {
rule.setSuper(first);
rule.setSub(second);
}
/**
* Visiting a {@link DeleteRelationshipAST0} (supertypeOf) and
* creating a {@link DeleteSupertypeOf} rule with
* first parameter as super and second parameter as sub
* @param n : Current AST node of type {@link DeleteRelationshipAST0}
* @return The created {@link DeleteSupertypeOf} rule
*/
@Override
public Object visit(DeleteRelationshipAST0 n) {
List<Term> parameters = new ArrayList<Term>();
n.getTwoParametersAST().accept(this, parameters);
DeleteSupertypeOf rule = DeletionFactory.eINSTANCE.createDeleteSupertypeOf();
commonDeleteTasks(rule, parameters.get(0), parameters.get(1));
rule.setName("DeleteSupertypeOfRule");
return rule;
}
/**
* Visiting a {@link DeleteRelationshipAST1} (subtypeOf) and
* creating a {@link DeleteSupertypeOf} rule with
* first parameter as sub and second parameter as super
* @param n : Current AST node of type {@link DeleteRelationshipAST1}
* @return The created {@link DeleteSupertypeOf} rule
*/
@Override
public Object visit(DeleteRelationshipAST1 n) {
List<Term> parameters = new ArrayList<Term>();
n.getTwoParametersAST().accept(this, parameters);
DeleteSupertypeOf rule = DeletionFactory.eINSTANCE.createDeleteSupertypeOf();
commonDeleteTasks(rule, parameters.get(1), parameters.get(0));
rule.setName("DeleteSubtypeRule");
return rule;
}
/**
* Visiting a {@link DeleteRelationshipAST2} (typeOf) and
* creating a {@link DeleteInstanceOf} rule with
* first parameter as sub and second parameter as super
* @param n : Current AST node of type {@link DeleteRelationshipAST2}
* @return The created {@link DeleteInstanceOf} rule
*/
@Override
public Object visit(DeleteRelationshipAST2 n) {
List<Term> parameters = new ArrayList<Term>();
n.getTwoParametersAST().accept(this, parameters);
DeleteInstanceOf rule = DeletionFactory.eINSTANCE.createDeleteInstanceOf();
commonDeleteTasks(rule, parameters.get(0), parameters.get(1));
rule.setName("DeleteTypeOfRule");
return rule;
}
/**
* Visiting a {@link DeleteRelationshipAST3} (instanceOf) and
* creating a {@link DeleteInstanceOf} rule with
* first parameter as super and second parameter as sub
* @param n : Current AST node of type {@link DeleteRelationshipAST3}
* @return The created {@link DeleteInstanceOf} rule
*/
@Override
public Object visit(DeleteRelationshipAST3 n) {
List<Term> parameters = new ArrayList<Term>();
n.getTwoParametersAST().accept(this, parameters);
DeleteInstanceOf rule = DeletionFactory.eINSTANCE.createDeleteInstanceOf();
commonDeleteTasks(rule, parameters.get(1), parameters.get(0));
rule.setName("DeleteInstanceOfRule");
return rule;
}
/**
* Visiting a {@link CopyRuleAST} and
* creating a {@link ModelCopyRule} model element
* @param n : Current AST node of type {@link CopyRuleAST}
* @param o : expected to be an {@link ASMRuleInvocation} or {@link Rule}
* @return The created {@link ModelCopyRule}
*/
@Override
public Object visit(CopyRuleAST n, Object o) {
// Create copy rule
ModelCopyRule rule = CopymoveFactory.eINSTANCE.createModelCopyRule();
assignCaller(rule, o);
// Reset buffer for unresolved variables
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
// Process the contents of the rule
n.getCopyContentsAST().accept(this, rule);
// Resolve variable references in the condition
modelResolver.resolveVariableRefsInRule(rule);
modelResolver.getUnresolvedVariableRefsStack().pop();
createNodeInfoFor(n, rule);
rule.setName("CopyRule");
return rule;
}
/**
* Visiting a CopyContentsAST and
* setting the contents of the CopyRule model element
* @param n : Current AST node of type MoveRuleAST
* @param o : expected to be a CopyRule
* @return rule : CopyRule
*/
@Override
public Object visit(CopyContentsAST n, Object o) {
ModelCopyRule rule = (ModelCopyRule) o;
Term srcRoot = (Term) n.getArithmeticTermAST().accept(this);
Term trgCont = (Term) n.getArithmeticTermAST3().accept(this);
VariableReference trgVar = (VariableReference) n.getVariableRefAST().accept(this);
CopySemantics semantics = (CopySemantics) n.getCopySemanticsAST().accept(this);
rule.setSrcRoot(srcRoot);
rule.setTrgContainer(trgCont);
rule.setTargetVariable(trgVar);
rule.setSemantics(semantics);
// Type checking
typeChecker.getTermsToCheck().add(srcRoot);
typeChecker.getTermsToCheck().add(trgCont);
rule.setName("CopyRule");
return rule;
}
/**
* Visiting a CopySemanticsAST0 and
* returning CopySemantics.COPY_OUTER_EDGES_LITERAL
* @param n : Current AST node of type CopySemanticsAST0
* @return : CopySemantics
*/
@Override
public Object visit(CopySemanticsAST0 n) {
return CopySemantics.COPY_OUTER_EDGES_LITERAL;
}
/**
* Visiting a CopySemanticsAST1 and
* returning CopySemantics.DROP_OUTER_EDGES_LITERAL
* @param n : Current AST node of type CopySemanticsAST1
* @return : CopySemantics
*/
@Override
public Object visit(CopySemanticsAST1 n) {
return CopySemantics.DROP_OUTER_EDGES_LITERAL;
}
/**
* Visiting a {@link MoveRuleAST} and
* creating a {@link MoveRule} model element
* @param n : Current AST node of type {@link MoveRuleAST}
* @param o : expected to be an {@link ASMRuleInvocation}
* @return The created {@link MoveRule}
*/
@Override
public Object visit(MoveRuleAST n, Object o) {
// Creating a MoveRule
MoveRule rule = CopymoveFactory.eINSTANCE.createMoveRule();
assignCaller(rule, o);
// Reset buffer for unresolved variables
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
// Processing parameters
List<Term> parameters = new ArrayList<Term>();
n.getTwoParametersAST().accept(this, parameters);
rule.setSrcRoot(parameters.get(0));
rule.setTrgContainer(parameters.get(1));
// Resolve variable references in the condition
modelResolver.resolveVariableRefsInRule(rule);
modelResolver.getUnresolvedVariableRefsStack().pop();
createNodeInfoFor(n, rule);
rule.setName("MoveRule");
return rule;
}
/**
* Visiting an ElementUpdateRuleAST and
* creating a SetRule model element
* @param n : Current AST node of type ElementUpdateOpAST0
* @param o : expected to be an ASMRuleInvocation
* @return rule : SetRule
*/
@Override
public Object visit(ElementUpdateRuleAST n, Object o) {
// Reset buffer for unresolved variables
modelResolver.getUnresolvedVariableRefsStack().push(new ArrayList<VariableReference>());
SetRule setRule = (SetRule) n.getElementUpdateOpAST().accept(this);
assignCaller(setRule, o);
// Processing parameters
List<Term> parameters = new ArrayList<Term>();
n.getTwoParametersAST().accept(this, parameters);
setRule.setElement(parameters.get(0));
setRule.setValue(parameters.get(1));
// Resolve variable references in the condition
modelResolver.resolveVariableRefsInRule(setRule);
modelResolver.getUnresolvedVariableRefsStack().pop();
createNodeInfoFor(n, setRule);
return setRule;
}
/**
* Visiting an ElementUpdateOpAST and
* creating a RenameRule model element
* @param n : Current AST node of type ElementUpdateOpAST0
* @return rule : RenameRule
*/
@Override
public Object visit(ElementUpdateOpAST n) {
String updStr = n.toString();
SetRule updRule = null;
if (updStr.equals("rename")) {
updRule = UpdateFactory.eINSTANCE.createRenameRule();
}
else if (updStr.equals("setValue")) {
updRule =UpdateFactory.eINSTANCE.createSetValueRule();
}
else if (updStr.equals("setFrom")) {
updRule = UpdateFactory.eINSTANCE.createSetRelationFrom();
}
else if (updStr.equals("setTo")) {
updRule = UpdateFactory.eINSTANCE.createSetRelationTo();
}
else if (updStr.equals("setMultiplicity")) {
updRule = UpdateFactory.eINSTANCE.createSetMultiplicityRule();
}
else if (updStr.equals("setAggregation")) {
updRule = UpdateFactory.eINSTANCE.createSetAggregationRule();
}
else if (updStr.equals("setInverse")) {
updRule = UpdateFactory.eINSTANCE.createSetInverseRule();
}
if (updRule != null) {
updRule.setName(updStr);
}
return updRule;
}
/**
* Visiting a TwoParametersAST node, and
* setting the parameters of the list passed as parameter
* @param n : Current AST node of type TwoParametersAST
* @param o : expected to be a List of Term
*/
@Override
public Object visit(TwoParametersAST n, Object o) {
@SuppressWarnings("unchecked")
List<Term> parameters = (List<Term>) o;
Term firstParam = (Term) n.getArithmeticTermAST().accept(this);
Term secondParam = (Term) n.getArithmeticTermAST4().accept(this);
parameters.add(firstParam);
parameters.add(secondParam);
// Type checking
typeChecker.getTermsToCheck().add(firstParam);
typeChecker.getTermsToCheck().add(secondParam);
return parameters;
}
// **************** Sec. 5.6.2 Names and Types **************************** //
/**
* Visiting a {@link VariableDefRefAST} node and returning its name as a String
* @param n : Current AST node of type {@link VariableDefRefAST}
*/
@Override
public Object visit(VariableDefRefAST n) {
VariableReference varRef = createVariableReference(n);
varRef.setName(n.toString());
modelResolver.addVariableReferenceToStack(varRef);
return varRef;
}
// /**
// * Visiting a {@link VariableDefRefAST1} node and returning its name as a String
// * @param n : Current AST node of type {@link VariableDefRefAST1}
// */
// @SuppressWarnings("unchecked")
// @Override
// public Object visit(VariableDefRefAST1 n) {
// // No resolution is needed when variable starts with '_'
// // There is no corresponding variable definition for this var reference
// return createVariableReference(n);
// }
/**
* Visiting a VariableDefRefAST node and returning its name as a String
* @param n : Current AST node of type VariableRefAST
* @param o : List of Actual Parameters
*/
@Override
public Object visit(VariableDefRefAST n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a VariableRefAST node and returning its name as a String
* @param n : Current AST node of type VariableRefAST
*/
@Override
public Object visit(VariableRefAST n) {
VariableReference varRef = createVariableReference(n);
varRef.setName(n.toString());
modelResolver.addVariableReferenceToStack(varRef);
return varRef;
}
protected VariableReference createVariableReference(ASTNode n) {
VariableReference varRef = TermsFactory.eINSTANCE.createVariableReference();
varRef.setName(n.toString());
createNodeInfoFor(n, varRef);
return varRef;
}
/**
* Visiting a VariableRefAST node and returning its name as a String
* @param n : Current AST node of type VariableRefAST
* @param o : List of Actual Parameters
*/
@Override
public Object visit(VariableRefAST n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a VariableDefAST node and returning its name as a String
* @param n : Current AST node of type VariableDefAST
*/
@Override
public Object visit(VariableDefAST n) {
Variable var = DefinitionsFactory.eINSTANCE.createVariable();
var.setName(n.toString());
createNodeInfoFor(n, var);
return var;
}
/**
* Visiting a QualifiedTypeNameAST node and returning its FQN as a String
* @param n : Current AST node of type {@link QualifiedTypeNameAST}
*/
@Override
public Object visit(QualifiedTypeNameAST n) {
String leftStr = (String) n.getQualifiedTypeNameAST().accept(this);
String rightStr = (String) n.getTypeNameAST().accept(this);
return new String(leftStr + '.' + rightStr);
}
@Override
public Object visit(QualifiedTypeNameAST n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
// /**
// * Visiting an {@link ASMFunctionNameAST0} node and returning its FQN as a String
// * @param n : Current AST node of type {@link ASMFunctionNameAST0}
// */
// @Override
// public Object visit(ASMFunctionNameAST0 n) {
// // Return the unquoted string by removing the ' ' pair
// return unquote(n.toString());
// }
// @Override
// public Object visit(ASMFunctionNameAST0 n, Object o) {
// return defaultListVisit(n, (List<?>) o);
// }
// /**
// * Visiting {@link ASMFunctionNameAST1} node (an Identifier) and
// * return it as a String
// * @param n : Current AST node of type {@link ASMFunctionNameAST1}
// */
// @Override
// public Object visit(ASMFunctionNameAST1 n) {
// return defaultVisit(n);
// }
// @Override
// public Object visit(ASMFunctionNameAST1 n, Object o) {
// return defaultListVisit(n, (List<?>) o);
// }
// /**
// * Visiting an {@link ASMFunctionNameAST2} node and returning its FQN as a String
// * @param n : Current AST node of type {@link ASMFunctionNameAST2}
// */
// @Override
// public Object visit(ASMFunctionNameAST2 n) {
// String leftStr = (String) n.getQualifiedTypeNameAST().accept(this);
// String rightStr = (String) n.getTypeNameAST().accept(this);
// return new String(leftStr + '.' + rightStr);
// }
// @Override
// public Object visit(ASMFunctionNameAST2 n, Object o) {
// return defaultListVisit(n, (List<?>) o);
// }
/**
* Visiting a ValueQualifiedNameAST node (ModelElementRef)
* and returning an Constant (of kind ModelElement)
* @param n : Current AST node of type ValueQualifiedNameAST
*/
@Override
public Object visit(ValueQualifiedNameAST n) {
// Collect the FQN
String leftStr = (String) n.getQualifiedTypeNameAST().accept(this);
String rightStr = (String) n.getTypeNameAST().accept(this);
return createModelElementConstant(n, leftStr + "." + rightStr);
// // Create a new Constant
// Constant modelElemConst = TermsFactory.eINSTANCE.createConstant();
// modelElemConst.setKind(ValueKind.MODELELEMENT_LITERAL);
// modelElemConst.setValue(leftStr + "." + rightStr);
// // Creating node information
// createNodeInfoFor(n, modelElemConst);
// // Lookup constant value if parent of AST node is not ValueQualifiedNameAST
// // and it is not an AsmFunctionLocation
// if (! (n.getParent() instanceof IValueQualifiedNameAST) &&
// ! (n.getParent() instanceof IAsmFunctionLocationAST) &&
// ! (n.getParent() instanceof IAsmFunctionUpdateLocationAST)) {
// // Initiate lookup
// modelResolver.resolveModelElementConstant(modelElemConst);
// }
// return modelElemConst;
}
@Override
public Object visit(ValueQualifiedNameAST n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting {@link ValueLocalNameAST0} node (a NameLiteral) and
* return it as an unquoted ElementReference
* @param n : Current AST node of type {@link ValueLocalNameAST0}
*/
@Override
public Object visit(ValueLocalNameAST0 n) {
String localStr = unquote( n.toString());
return createModelElementConstant(n, localStr);
}
@Override
public Object visit(ValueLocalNameAST0 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting {@link ValueLocalNameAST1} node (an Identifier) and
* return it as a ElementReference
* @param n : Current AST node of type {@link ValueLocalNameAST1}
*/
@Override
public Object visit(ValueLocalNameAST1 n) {
String localStr = unquote( n.toString());
return createModelElementConstant(n, localStr);
}
@Override
public Object visit(ValueLocalNameAST1 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Creates a model element constant from ASTNode n and
* tries to resolve its name in the model space upon certain conditions
* @param n : AST node
* @return : Constant of kind Model Element
*/
protected Constant createModelElementConstant(ASTNode n, String nameStr) {
// Create a new Constant
Constant modelElemConst = TermsFactory.eINSTANCE.createConstant();
modelElemConst.setKind(ValueKind.MODELELEMENT_LITERAL);
modelElemConst.setValue( nameStr);
modelElemConst.setName(nameStr);
// Creating node information
createNodeInfoFor(n, modelElemConst);
// Lookup constant value if parent of AST node is not ValueQualifiedNameAST
if (! (n.getParent() instanceof IValueQualifiedNameAST) &&
! (n.getParent() instanceof IAsmFunctionLocationAST) &&
! (n.getParent() instanceof IAsmFunctionUpdateLocationAST)) {
// Initiate lookup and set types
String fqnStr = modelResolver.resolveModelElementConstant(modelElemConst);
if (fqnStr != null) {
modelElemConst.setFqn(fqnStr);
}
}
return modelElemConst;
}
/**
* Visiting TypeNameAST0 node (a NameLiteral) and
* return it as an unquoted String
* @param n : Current AST node of type TypeNameAST0
*/
@Override
public Object visit(TypeNameAST0 n) {
// Return the unquoted string by removing the ' ' pair
return unquote(n.toString());
}
@Override
public Object visit(TypeNameAST0 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting TypeNameAST1 node (an Identifier) and
* return it as a String
* @param n : Current AST node of type TypeNameAST1
*/
@Override
public Object visit(TypeNameAST1 n) {
return defaultVisit(n);
}
@Override
public Object visit(TypeNameAST1 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting TypeNameAST2 node (an UpperCaseLiteral) and
* return it as a String
* @param n : Current AST node of type TypeNameAST2
*/
@Override
public Object visit(TypeNameAST2 n) {
return defaultVisit(n);
}
@Override
public Object visit(TypeNameAST2 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
@Override
public String visit(TypeNameAST3 n) {
return unquote((String)defaultVisit(n));
}
/**
* Visiting {@link KeywordAsIdentifier} node as part of an FQN
* return it as a String
* @param n : Current AST node of type {@link KeywordAsIdentifier}
* @param o : List
* @return String for the keyword
*/
@Override
public Object visit(KeywordAsIdentifier n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting {@link KeywordAsIdentifier} node as part of an FQN
* return it as a String
* @param n : Current AST node of type {@link KeywordAsIdentifier}
* @return String for the keyword
*/
@Override
public Object visit(KeywordAsIdentifier n) {
return defaultVisit(n);
}
/**
* The ASTNode node n is visited and added to the list
* @param n : ASTNode
* @param list : List
* @return list: List (with the result from visiting n)
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
protected List defaultListVisit(ASTNode n, List list) {
Object element = n.accept(this);
list.add(element);
return list;
}
/**
* ASTNode n is returned as a string
*/
protected Object defaultVisit(ASTNode n) {
// return new String(n.toString());
return n.toString();
}
// **************** Sec. 5.6.3 Parameters **************************** //
/**
* Visiting {@link ActualParameterDefAST0} node and
* return its ActualParams
* @param n : Current AST node of type {@link ActualParameterDefAST0}
* @param o : List of Parameters
*/
@Override
public Object visit(ActualParameterDefAST0 n, Object o) {
return n.getActualParamsAST().accept(this, o);
}
/**
* Visiting {@link ActualParameterDefAST1} node and
* return its ActualParams
* @param n : Current AST node of type {@link ActualParameterDefAST1}
* @param o : List of Parameters
*/
@Override
public Object visit(ActualParameterDefAST1 n, Object o) {
return o;
}
// /**
// * Visiting a {@link ActualParameterDefAST2} node (ERROR_TOKEN)
// *
// * @param n : {@link ActualParameterDefAST2}
// * @param o : List of Parameters
// */
// @Override
// public Object visit(ActualParameterDefAST2 n, Object o) {
// if (getDiagnoseParser() == null) {
// ParseTable prsTable = new VTCLParserprs();
// DiagnoseParser diagnoseParser = new DiagnoseParser(n.getEnvironment(), prsTable );
// setDiagnoseParser(diagnoseParser);
//// diagnoseParser.diagnose(n.getEnvironment().badToken());
// diagnoseParser.diagnose();
// }
// Constant undef = TermsFactory.eINSTANCE.createConstant();
// undef.setKind(ValueKind.UNDEF_LITERAL);
// undef.setValue("undef");
// return o;
// }
/**
* Visiting ActualParamsAST node and return its ActualParams
* @param n : Current AST node of type ActualParamsAST
* @param o : List of Parameters
*/
@Override
public Object visit(ActualParamsAST n, Object o) {
@SuppressWarnings("unchecked")
List<Term> paramList = (List<Term>) o;
n.getActualParamsAST().accept(this, paramList);
Term lastParameter = (Term) n.getArithmeticTermAST().accept(this);
paramList.add(lastParameter);
//typeChecker.getTermsToCheck().addAll(paramList);
return paramList;
}
/**
* Visiting {@link ActualPatternParameterDefAST0} node and
* return its ActualParams
* @param n : Current AST node of type {@link ActualPatternParameterDefAST0}
* @param paramList : List of Parameters
*/
@Override
public Object visit(ActualPatternParameterDefAST0 n, Object paramList) {
return n.getActualParamsPatternVariablesAST().accept(this, paramList);
}
/**
* Visiting {@link ActualPatternParameterDefAST1} node and
* return its ActualParams
* @param n : Current AST node of type {@link ActualPatternParameterDefAST1}
* @param paramList : List of Parameters
*/
@Override
public Object visit(ActualPatternParameterDefAST1 n, Object paramList) {
return paramList;
}
// /**
// * Visiting {@link ActualPatternParameterDefAST2} node (ERROR_TOKEN)
// * @param n : Current AST node of type {@link ActualPatternParameterDefAST2}
// * @param paramList : List of Parameters
// */
// @Override
// public Object visit(ActualPatternParameterDefAST2 n, Object o) {
// if (getDiagnoseParser() == null) {
// ParseTable prsTable = new VTCLParserprs();
// DiagnoseParser diagnoseParser = new DiagnoseParser(n.getEnvironment(), prsTable );
// setDiagnoseParser(diagnoseParser);
//// diagnoseParser.diagnose(n.getEnvironment().badToken());
// diagnoseParser.diagnose();
// }
// return o;
// }
/**
* Visiting {@link DirectedFormalParameterDefAST0} node and
* return its FormalParams as a list
* @param n : Current AST node of type {@link DirectedFormalParameterDefAST0}
* @param paramList : List of Parameters
*/
@Override
public Object visit(DirectedFormalParameterDefAST0 n, Object paramList) {
return n.getDirectedFormalParamsAST().accept(this, paramList);
}
/**
* Visiting {@link DirectedFormalParameterDefAST1} node and
* return its FormalParams as a list
* @param n : Current AST node of type {@link DirectedFormalParameterDefAST1}
* @param paramList : List of Parameters
*/
@Override
public Object visit(DirectedFormalParameterDefAST1 n, Object paramList) {
return paramList;
}
// /**
// * Visiting DirectedFormalParameterDefAST1 node (ERROR_TOKEN)
// * @param n : Current AST node of type DirectedFormalParameterDefAST1
// * @param paramList : List of Parameters
// */
// @Override
// public Object visit(DirectedFormalParameterDefAST2 n, Object paramList) {
// if (getDiagnoseParser() == null) {
// ParseTable prsTable = new VTCLParserprs();
// DiagnoseParser diagnoseParser = new DiagnoseParser(n.getEnvironment(), prsTable );
// setDiagnoseParser(diagnoseParser);
//// diagnoseParser.diagnose(n.getEnvironment().badToken());
// diagnoseParser.diagnose();
// }
// return paramList;
// }
/**
* Visiting {@link DirectedFormalParamsAST0} node
* @param n : Current AST node of type {@link DirectedFormalParamsAST1}
* @param o : List of parameters (SymbolicRuleParameter)
*/
@Override
public Object visit(DirectedFormalParamsAST0 n, Object o) {
@SuppressWarnings("unchecked")
List<SymbolicRuleParameter> paramList = (List<SymbolicRuleParameter>) o;
// Obtain direction and variable
DirectionKind direction = (DirectionKind) n.getDirectionKindAST().accept(this);
Variable var = (Variable) n.getVariableDefAST().accept(this);
// Retrieve type information
if (n.getTypeOptAST() != null) {
n.getTypeOptAST().accept(this, var);
}
// Create a new SymbolicRuleParameter
addDirectedFormalParam(n, direction, var, paramList);
return paramList;
}
/**
* Visiting {@link DirectedFormalParamsAST1} node
* @param n : Current AST node of type {@link DirectedFormalParamsAST1}
* @param o : List of parameters (SymbolicRuleParameter)
*/
@Override
public Object visit(DirectedFormalParamsAST1 n, Object o) {
@SuppressWarnings("unchecked")
List<SymbolicRuleParameter> paramList = (List<SymbolicRuleParameter>) o;
n.getDirectedFormalParamsAST().accept(this, paramList);
// Obtain direction and variable
DirectionKind direction = (DirectionKind) n.getDirectionKindAST().accept(this);
Variable var = (Variable) n.getVariableDefAST().accept(this);
// Retrieve type information
if (n.getTypeOptAST() != null) {
n.getTypeOptAST().accept(this, var);
}
// Create a new SymbolicRuleParameter
addDirectedFormalParam(n, direction, var, paramList);
return paramList;
}
/**
* Visiting {@link DirectedFormalParamsAST1} node
* @param n : Current AST node of type {@link DirectedFormalParamsAST1}
* @param direction : {@link DirectionKind}
* @param var : {@link Variable}
* @param paramList : List of parameters (SymbolicRuleParameter)
*/
protected void addDirectedFormalParam(ASTNode n, DirectionKind direction, Variable var, List<SymbolicRuleParameter> paramList ) {
// Create a new SymbolicRuleParameter
SymbolicRuleParameter ruleParam = DefinitionsFactory.eINSTANCE.createSymbolicRuleParameter();
ruleParam.setDirection(direction);
ruleParam.setVariable(var);
ruleParam.setName(var.getName());
// Add the new SymbolicRuleParameter to the parameter list
paramList.add(ruleParam);
// Creating node information
createNodeInfoFor(n, ruleParam);
}
/**
* Visiting {@link FormalParameterDefAST0} node (of a GTPattern) and
* returning a list of PatternVariables
* @param n : Current AST node of type {@link FormalParameterDefAST0}
* @param paramList : List of parameters (PatternVariable)
*/
@Override
public Object visit(FormalParameterDefAST0 n, Object paramList) {
return n.getFormalParamsAST().accept(this, paramList);
}
/**
* Visiting {@link FormalParameterDefAST1} node (of a GTPattern) and
* returning a list of PatternVariables
* @param n : Current AST node of type {@link FormalParameterDefAST1}
* @param paramList : List of parameters (PatternVariable)
*/
@Override
public Object visit(FormalParameterDefAST1 n, Object paramList) {
return paramList;
}
// /**
// * Visiting {@link FormalParameterDefAST2} node (ERROR_TOKEN)
// * @param n : Current AST node of type {@link FormalParameterDefAST2}
// * @param paramList : List of parameters (PatternVariable)
// */
// @Override
// public Object visit(FormalParameterDefAST2 n, Object paramList) {
// if (getDiagnoseParser() == null) {
// ParseTable prsTable = new VTCLParserprs();
// DiagnoseParser diagnoseParser = new DiagnoseParser(n.getEnvironment(), prsTable );
// setDiagnoseParser(diagnoseParser);
//// diagnoseParser.diagnose(n.getEnvironment().badToken());
// diagnoseParser.diagnose();
// }
// return paramList;
// }
/**
* Visiting {@link FormalParamsAST0} node (of a GTPattern)
* @param n : Current AST node of type {@link FormalParamsAST0}
* @param o : List of parameters (PatternVariable)
*/
@Override
public Object visit(FormalParamsAST0 n, Object o) {
@SuppressWarnings("unchecked")
List<PatternVariable> paramList = (List<PatternVariable>) o;
PatternVariable lastVar = (PatternVariable) n.getPatternVariableDefAST().accept(this);
// Obtaining type information
if (n.getTypeOptAST() != null) {
n.getTypeOptAST().accept(this, lastVar);
}
paramList.add(lastVar);
return paramList;
}
/**
* Visiting {@link FormalParamsAST1} node (of a GTPattern)
* @param n : Current AST node of type {@link FormalParamsAST1}
* @param o : List of parameters (PatternVariable)
*/
@Override
public Object visit(FormalParamsAST1 n, Object o) {
@SuppressWarnings("unchecked")
List<PatternVariable> paramList = (List<PatternVariable>) o;
n.getFormalParamsAST().accept(this, paramList);
PatternVariable lastVar = (PatternVariable) n.getPatternVariableDefAST().accept(this);
// Obtaining type information
if (n.getTypeOptAST() != null) {
n.getTypeOptAST().accept(this, lastVar);
}
paramList.add(lastVar);
return paramList;
}
/**
* Visiting {@link ConstrainedVariablesAST0} node (appears in ChooseRule and ForallRule)
* @param n : Current AST node of type {@link ConstrainedVariablesAST0}
* @param o : {@link CollectionIteratorRule}
* @return rule: {@link CollectionIteratorRule}
*/
@Override
public Object visit(ConstrainedVariablesAST0 n, Object o) {
CollectionIteratorRule rule = (CollectionIteratorRule) o;
Variable var = (Variable) n.getVariableDefAST().accept(this);
rule.getLocalVariables().add(var);
// Process type information
if (n.getTypeOptAST() != null) {
n.getTypeOptAST().accept(this, var);
}
// Process containment constraints
if (n.getContainmentConstraintOptAST() != null) {
ContainmentConstraint contConst = (ContainmentConstraint) n.getContainmentConstraintOptAST().accept(this);
contConst.setVariable(var);
rule.getContainmentConstraints().add(contConst);
}
return rule;
}
/**
* Visiting {@link ConstrainedVariablesAST1} node (appears in ChooseRule and ForallRule)
* @param n : Current AST node of type {@link ConstrainedVariablesAST1}
* @param o : {@link CollectionIteratorRule}
*/
@Override
public Object visit(ConstrainedVariablesAST1 n, Object o) {
CollectionIteratorRule rule = (CollectionIteratorRule) o;
n.getConstrainedVariablesAST().accept(this, rule);
Variable var = (Variable) n.getVariableDefAST().accept(this);
rule.getLocalVariables().add(var);
// Process type information
if (n.getTypeOptAST() != null) {
n.getTypeOptAST().accept(this, var);
}
// Process containment constraints
if (n.getContainmentConstraintOptAST() != null) {
ContainmentConstraint contConst = (ContainmentConstraint) n.getContainmentConstraintOptAST().accept(this);
contConst.setVariable(var);
rule.getContainmentConstraints().add(contConst);
}
return rule;
}
/**
* Visiting ContainmentConstraintOptAST0 node (IN)
* @param n : Current AST node of type ContainmentConstraintOptAST0
*/
@Override
public Object visit(ContainmentConstraintOptAST0 n) {
Term scope = (Term) n.getArithmeticTermAST().accept(this);
ContainmentConstraint contConstr = GtFactory.eINSTANCE.createContainmentConstraint();
contConstr.setParent(scope);
contConstr.setMode(ContainmentMode.IN_LITERAL);
// Creating node information
createNodeInfoFor(n, scope);
// Type checking for scope
typeChecker.getTermsToCheck().add(scope);
return contConstr;
}
/**
* Visiting ContainmentConstraintOptAST0 node (BELOW)
* @param n : Current AST node of type ContainmentConstraintOptAST0
*/
@Override
public Object visit(ContainmentConstraintOptAST1 n) {
Term scope = (Term) n.getArithmeticTermAST().accept(this);
ContainmentConstraint contConstr = GtFactory.eINSTANCE.createContainmentConstraint();
contConstr.setParent(scope);
contConstr.setMode(ContainmentMode.BELOW_LITERAL);
// Creating node information
createNodeInfoFor(n, scope);
// Type checking for scope
typeChecker.getTermsToCheck().add(scope);
return contConstr;
}
/**
* Visiting DirectionKindAST0 node
* @param n : Current AST node of type DirectionKindAST0
*/
@Override
public Object visit(DirectionKindAST0 n) {
return DirectionKind.IN_LITERAL;
}
/**
* Visiting DirectionKindAST1 node
* @param n : Current AST node of type DirectionKindAST1
*/
@Override
public Object visit(DirectionKindAST1 n) {
return DirectionKind.OUT_LITERAL;
}
/**
* Visiting DirectionKindAST2 node
* @param n : Current AST node of type DirectionKindAST2
*/
@Override
public Object visit(DirectionKindAST2 n) {
return DirectionKind.INOUT_LITERAL;
}
// ****************** Sec. 5.6.4 Constants ****************************
/**
* Visiting the BooleanConstantAST0 node (false) and
* returning a Constant of kind Boolean
* @param n : Current AST node of type BooleanConstantAST0
*/
@Override
public Object visit(BooleanConstantAST0 n) {
Constant constant = TermsFactory.eINSTANCE.createConstant();
constant.setKind(ValueKind.BOOLEAN_LITERAL);
constant.setType("datatypes.Boolean");
constant.setValue(String.valueOf(false));
constant.setName(String.valueOf(false));
// Creating node information
createNodeInfoFor(n, constant);
return constant;
}
@Override
public Object visit(BooleanConstantAST0 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting the BooleanConstantAST1 node (true) and
* returning a Constant of kind Boolean
* @param n : Current AST node of type BooleanConstantAST1
*/
@Override
public Object visit(BooleanConstantAST1 n) {
Constant constant = TermsFactory.eINSTANCE.createConstant();
constant.setKind(ValueKind.BOOLEAN_LITERAL);
constant.setType("datatypes.Boolean");
constant.setValue(String.valueOf(true));
constant.setName(String.valueOf(true));
// Creating node information
createNodeInfoFor(n, constant);
return constant;
}
@Override
public Object visit(BooleanConstantAST1 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a one_to_one MultiplicityConstantAST0 node and
* returning a Constant of kind Multiplicity
* @param n : Current AST node of type MultiplicityConstantAST0
*/
@Override
public Object visit(MultiplicityConstantAST0 n) {
Constant constant = TermsFactory.eINSTANCE.createConstant();
constant.setKind(ValueKind.MULTIPLICITY_LITERAL);
constant.setType("datatypes.MultiplicityKind");
constant.setValue(MultiplicityKind.ONE_TO_ONE_LITERAL.toString());
constant.setName(MultiplicityKind.ONE_TO_ONE_LITERAL.toString());
// Creating node information
createNodeInfoFor(n, constant);
return constant;
}
@Override
public Object visit(MultiplicityConstantAST0 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a one_to_many MultiplicityConstantAST1 node and
* returning a Constant of kind Multiplicity
* @param n : Current AST node of type MultiplicityConstantAST1
*/
@Override
public Object visit(MultiplicityConstantAST1 n) {
Constant constant = TermsFactory.eINSTANCE.createConstant();
constant.setKind(ValueKind.MULTIPLICITY_LITERAL);
constant.setType("datatypes.MultiplicityKind");
constant.setValue(MultiplicityKind.ONE_TO_MANY_LITERAL.toString());
constant.setName(MultiplicityKind.ONE_TO_MANY_LITERAL.toString());
// Creating node information
createNodeInfoFor(n, constant);
return constant;
}
@Override
public Object visit(MultiplicityConstantAST1 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a many_to_one MultiplicityConstantAST2 node and
* returning a Constant of kind Multiplicity
* @param n : Current AST node of type MultiplicityConstantAST2
*/
@Override
public Object visit(MultiplicityConstantAST2 n) {
Constant constant = TermsFactory.eINSTANCE.createConstant();
constant.setKind(ValueKind.MULTIPLICITY_LITERAL);
constant.setType("datatypes.MultiplicityKind");
constant.setValue(MultiplicityKind.MANY_TO_ONE_LITERAL.toString());
constant.setName(MultiplicityKind.MANY_TO_ONE_LITERAL.toString());
// Creating node information
createNodeInfoFor(n, constant);
return constant;
}
@Override
public Object visit(MultiplicityConstantAST2 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a many_to_many MultiplicityConstantAST3 node and
* returning a Constant of kind Multiplicity
* @param n : Current AST node of type MultiplicityConstantAST3
*/
@Override
public Object visit(MultiplicityConstantAST3 n) {
Constant constant = TermsFactory.eINSTANCE.createConstant();
constant.setKind(ValueKind.MULTIPLICITY_LITERAL);
constant.setType("datatypes.MultiplicityKind");
constant.setValue(MultiplicityKind.MANY_TO_MANY_LITERAL.toString());
constant.setName(MultiplicityKind.MANY_TO_MANY_LITERAL.toString());
// Creating node information
createNodeInfoFor(n, constant);
return constant;
}
@Override
public Object visit(MultiplicityConstantAST3 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a NumericConstantAST node (DecimalIntegerLiteral) and
* returning a Constant of kind IntegerLiteral
* @param n : Current AST node of type NumericConstantAST0
*/
@Override
public Object visit(NumericConstantAST0 n) {
Constant constant = TermsFactory.eINSTANCE.createConstant();
constant.setKind(ValueKind.INTEGER_LITERAL);
constant.setType("datatypes.Integer");
constant.setValue(n.toString());
constant.setName(n.toString());
// Creating node information
createNodeInfoFor(n, constant);
return constant;
}
@Override
public Object visit(NumericConstantAST0 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a NumericConstantAST node (IntegerLiteral) and
* returning a Constant of kind IntegerLiteral
* @param n : Current AST node of type NumericConstantAST1
*/
@Override
public Object visit(NumericConstantAST1 n) {
Constant constant = TermsFactory.eINSTANCE.createConstant();
constant.setKind(ValueKind.INTEGER_LITERAL);
constant.setType("datatypes.Integer");
constant.setValue(n.toString());
constant.setName(n.toString());
// Creating node information
createNodeInfoFor(n, constant);
return constant;
}
@Override
public Object visit(NumericConstantAST1 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a NumericConstantAST node (FloatingPointLiteral) and
* returning a Constant of kind DoubleLiteral
* @param n : Current AST node of type NumericConstantAST2
*/
@Override
public Object visit(NumericConstantAST2 n) {
Constant constant = TermsFactory.eINSTANCE.createConstant();
constant.setKind(ValueKind.DOUBLE_LITERAL);
constant.setType("datatypes.Double");
constant.setValue(n.toString());
constant.setName(n.toString());
// Creating node information
createNodeInfoFor(n, constant);
return constant;
}
@Override
public Object visit(NumericConstantAST2 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a NumericConstantAST node (DoubleLiteral) and
* returning a Constant of kind DoubleLiteral
* @param n : Current AST node of type NumericConstantAST2
*/
@Override
public Object visit(NumericConstantAST3 n) {
Constant constant = TermsFactory.eINSTANCE.createConstant();
constant.setKind(ValueKind.DOUBLE_LITERAL);
constant.setType("datatypes.Double");
constant.setValue(n.toString());
constant.setName(n.toString());
// Creating node information
createNodeInfoFor(n, constant);
return constant;
}
@Override
public Object visit(NumericConstantAST3 n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting a StringConstantAST node and returning a Constant of kind String
* @param n : Current AST node of type StringConstantAST
*/
@Override
public Object visit(StringConstantAST n) {
Constant constant = TermsFactory.eINSTANCE.createConstant();
constant.setKind(ValueKind.STRING_LITERAL);
constant.setType("datatypes.String");
constant.setName("datatypes.String");
// Unquoting and unescaping string literal
constant.setValue( StringEscapeUtils.unescapeJava(unquote(n.toString() )));
// Creating node information
createNodeInfoFor(n, constant);
return constant;
}
@Override
public Object visit(StringConstantAST n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
/**
* Visiting an UndefValueAST node and returning an "undef" Constant
* @param n : Current AST node of type UndefValueAST
*/
@Override
public Object visit(UndefValueAST n) {
Constant constant = TermsFactory.eINSTANCE.createConstant();
constant.setKind(ValueKind.UNDEF_LITERAL);
constant.setType("TOP");
constant.setValue("undef");
constant.setName("undef");
// Creating node information
createNodeInfoFor(n, constant);
return constant;
}
@Override
public Object visit(UndefValueAST n, Object o) {
return defaultListVisit(n, (List<?>) o);
}
// ****************** Annotations ****************************
// /**
// * Visiting an {@link AnnotationAST0} node (with empty parameter set)
// * and creating a {@link RuntimeAnnotation}
// * @param n : current AST node of type {@link AnnotationAST0}
// * @param o : the list of annotations attached to an element
// */
// @Override
// public Object visit(AnnotationAST0 n, Object o) {
// EList<RuntimeAnnotation> annotationList = (EList<RuntimeAnnotation>) o;
// RuntimeAnnotation annotation = CoreFactory.eINSTANCE.createRuntimeAnnotation();
// String name = (String) n.getValueQualifiedNameAST().accept(this);
// annotation.setAnnotationName(name);
// // annotation for RuntimeAnnotation
// createNodeInfoFor(n, annotation);
// annotationList.add(annotation);
// return annotationList;
// }
/**
* Visiting an {@link AnnotationAST} node (with parameters)
* and creating a {@link RuntimeAnnotation}
* @param n current AST node of type {@link AnnotationAST}
* @param o the list of {@link RuntimeAnnotation}s attached to an element
*/
@Override
public Object visit(AnnotationAST n, Object o) {
@SuppressWarnings("unchecked")
List<RuntimeAnnotation> annotationList = (List<RuntimeAnnotation>) o;
RuntimeAnnotation annotation = CoreFactory.eINSTANCE.createRuntimeAnnotation();
String annotationName = (String) n.getAnnotationNameAST().accept(this);
annotation.setAnnotationName(annotationName);
n.getAnnotationBodyAST().accept(this, annotation.getElements());
annotationList.add(annotation);
// annotation for RuntimeAnnotation
createNodeInfoFor(n, annotation);
return annotationList;
}
/**
* Visiting an {@link AnnotationBodyAST} node to process its parameters
* @param n : current AST node of type {@link AnnotationBodyAST}
* @param o : the list of {@link RuntimeAnnotationElement}
*/
@Override
public Object visit(AnnotationBodyAST n, Object o) {
@SuppressWarnings("unchecked")
List<RuntimeAnnotationElement> annotationList = (List<RuntimeAnnotationElement>) o;
// Processing subelements first
n.getAnnotationBodyAST().accept(this, annotationList);
n.getKeyValuePairAST().accept(this,annotationList);
return annotationList;
}
/**
* Visiting an {@link AnnotationsAST} related to a GTASM element
* @param n : current AST node of type {@link AnnotationsAST}
* @param o : the list of {@link RuntimeAnnotation}s
*/
@Override
public Object visit(AnnotationsAST n, Object o) {
@SuppressWarnings("unchecked")
List<RuntimeAnnotation> annotationList = (List<RuntimeAnnotation>) o;
n.getAnnotationsAST().accept(this, annotationList);
n.getAnnotationAST().accept(this,annotationList);
return annotationList;
}
/**
* Visiting a {@link KeyValuePairAST} node and create
* a {@link RuntimeAnnotationElement} model element
* @param n : current AST node of type {@link KeyValuePairAST}
* @param o : the list of {@link RuntimeAnnotationElement}
*/
@Override
public Object visit(KeyValuePairAST n, Object o) {
@SuppressWarnings("unchecked")
List<RuntimeAnnotationElement> annotationList = (List<RuntimeAnnotationElement>) o;
RuntimeAnnotationElement annotationElement = CoreFactory.eINSTANCE.createRuntimeAnnotationElement();
// Visiting key and value
String key = (String) n.getTypeNameAST().accept(this);
String value = (String) n.getTypeNameAST3().accept(this);
annotationElement.setKey(key);
annotationElement.setValue(value);
annotationList.add(annotationElement);
// Create node information
createNodeInfoFor(n, annotationElement);
return annotationElement;
}
/**
* This method should be called as an AnnotationAST
*/
@Override
public Object visit(AnnotationNameAST n, Object o) {
@SuppressWarnings("unchecked")
List<RuntimeAnnotation> annotationList = (List<RuntimeAnnotation>) o;
RuntimeAnnotation annotation = CoreFactory.eINSTANCE.createRuntimeAnnotation();
String name = n.toString();
annotation.setAnnotationName(name);
// annotation for RuntimeAnnotation
createNodeInfoFor(n, annotation);
annotationList.add(annotation);
return annotationList;
}
/**
* This method should be called inside an Annotation with parameters
*/
@Override
public Object visit(AnnotationNameAST n) {
return defaultVisit(n);
}
// ****************** Type declaration for variables ****************************
/**
* Visiting a {@link TypeOptAST} and return a corresponding
* model element {@link Constant}
* @param n : current AST node of type {@link TypeOptAST}
* @param o : the typed variable
* @return model element {@link Constant}
*/
@Override
public Object visit(TypeOptAST n, Object o) {
Variable var = (Variable) o;
String typeStr = (String) n.getQualifiedTypeNameAST().accept(this);
TypeConstant typeConst = createTypeConstant(n, typeStr);
var.setVariableType(typeConst);
modelResolver.resolveAsmType(var, typeConst.getName());
// TypeConstant typeConst = DefinitionsFactory.eINSTANCE.createTypeConstant();
// typeConst.setName(typeStr);
// var.setVariableType(typeConst);
// // Creating node information
// createNodeInfoFor(n, typeConst);
// // Resolve type constant
// modelResolver.resolveAsmType(var, typeStr);
// // Note that the kind parameter of constants corresponding to a type
// // are used differently here. While formally, they should be always strings,
// // they are resolved according to the "typeStr" by getValueKind()
// typeConst.setKind(getValueKind(typeStr));
return typeConst;
}
/**
* Visiting a {@link ReturnTypeOptAST} (of an ASMFunction)
* and return a corresponding model element {@link TypeConstant} as its type
* @param n : current AST node of type {@link ReturnTypeOptAST}
* @param o : the typed ASM function
* @return model element {@link TypeConstant}
*/
@Override
public Object visit(ReturnTypeOptAST n, Object o) {
ASMFunction asmFun = (ASMFunction) o;
String typeStr = (String) n.getQualifiedTypeNameAST().accept(this);
TypeConstant typeConst = createTypeConstant(n, typeStr);
asmFun.setReturnType(typeConst);
// Resolve type constant
modelResolver.resolveAsmType(asmFun, typeStr);
// TypeConstant typeConst = DefinitionsFactory.eINSTANCE.createTypeConstant();
// typeConst.setName(typeStr);
// asmFun.setReturnType(typeConst);
// // Creating node information
// createNodeInfoFor(n, typeConst);
// // Resolve type constant
// modelResolver.resolveAsmType(asmFun, typeStr);
// // Note that the kind parameter of constants corresponding to a type
// // are used differently. While formally, they should be always strings,
// // they are resolved according to the "typeStr" by getValueKind()
// typeConst.setKind(getValueKind(typeStr));
return typeConst;
}
/**
* Visiting a {@link TypeConstantsAST0} (of an ASMFunction)
* and return a corresponding model element {@link TypeConstant} as its type
* @param n : current AST node of type {@link TypeConstantsAST0}
* @param o : the typed ASM function
* @return ASM function {@link ASMFunction}
*/
@Override
public Object visit(TypeConstantsAST0 n, Object o) {
ASMFunction asmFun = (ASMFunction) o;
String typeStr = (String) n.getQualifiedTypeNameAST().accept(this);
TypeConstant typeConst = createTypeConstant(n, typeStr);
asmFun.getArgumentTypes().add(typeConst);
// Resolve type constant
modelResolver.resolveAsmType(typeConst, typeStr);
return asmFun;
}
/**
* Visiting a {@link TypeConstantsAST1} (of an ASMFunction)
* and return a corresponding model element {@link TypeConstant} as its type
* @param n : current AST node of type {@link TypeConstantsAST1}
* @param o : the typed ASM function
* @return ASM function {@link ASMFunction}
*/
@Override
public Object visit(TypeConstantsAST1 n, Object o) {
ASMFunction asmFun = (ASMFunction) o;
String typeStr = (String) n.getQualifiedTypeNameAST().accept(this);
TypeConstant typeConst = createTypeConstant(n, typeStr);
asmFun.getArgumentTypes().add(typeConst);
// Resolve type constant
modelResolver.resolveAsmType(typeConst, typeStr);
// Process other type constants
n.getTypeConstantsAST().accept(this, asmFun);
return asmFun;
}
protected TypeConstant createTypeConstant(ASTNode n, String typeStr) {
TypeConstant typeConst = DefinitionsFactory.eINSTANCE.createTypeConstant();
if ("ENTITY".equals(typeStr.toUpperCase())) {
typeStr = "ENTITY";
} else if ("RELATION".equals(typeStr.toUpperCase())) {
typeStr = "RELATION";
}
typeConst.setName(typeStr);
typeConst.setFqn(typeStr); //Required for type checker
// Creating node information
createNodeInfoFor(n, typeConst);
// Note that the kind parameter of constants corresponding to a type
// are used differently. While formally, they should be always strings,
// they are resolved according to the "typeStr" by getValueKind()
typeConst.setKind(typeChecker.getTypeResolver().getValueKind(typeStr));
return typeConst;
}
private Object loadDocumentationComments(ASTNode n, Object o) {
AnnotatedElement element = (AnnotatedElement) o;
List<Annotation> annotations = element.getAnnotations();
Annotation doc = CoreFactory.eINSTANCE.createAnnotation();
//Loading documentation string
IToken[] adjuncts = n.getPrecedingAdjuncts();
String text = "";
for (IToken adjunct : adjuncts) {
String adjString = adjunct.toString();
if (adjString.startsWith("/**")) {
text = adjString;
}
}
if (text == "") return null;
/*
* Preprocessing text: removing all line breaks, multiple whitespaces
* and starting star characters.
*/
text = text.substring(text.indexOf("/**") + 3);
text = text.replaceAll("\\r", "");
text = text.replaceAll("\\*/", "");
String[] lines = text.split("\\n");
StringBuilder sb = new StringBuilder();
for (String line : lines) {
int index = 0;
while (index < line.length()
&& (Character.isWhitespace(line.charAt(index)) || line
.charAt(index) == '*')) {
index++;
}
sb.append(line.substring(index));
sb.append(" ");
}
text = sb.toString().replaceAll("\\s+", " ");
// Adding annotations
doc.setKey("viatradoc");
doc.setValue(text);
annotations.add(doc);
return doc;
}
}