/** | |
* 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; | |
} | |
} |