use of org.lara.language.specification.dsl.Action in project lara-framework by specs-feup.
the class ASTPerform method getOptionsString.
private static String getOptionsString(List<Action> actions) {
String options = "Options:\n";
int pos = 1;
for (Action action : actions) {
String args = action2String(action);
options += "\t" + (pos++) + ") " + args + "\n";
}
return options;
}
use of org.lara.language.specification.dsl.Action in project lara-framework by specs-feup.
the class LanguageSpecificationSideBar method getActions.
private List<Action> getActions(JoinPointClass joinPoint) {
switch(sortingMethod) {
case ALPHABETICALLY:
return getAlphabetical(joinPoint, jp -> jp.getActions());
case HIERARCHICALLY:
List<Action> actions = new ArrayList<>();
getHierarchical(joinPoint, actions, jp -> jp.getActionsSelf(), jp -> new Action(new GenericType(SEPARATOR_TYPE, false), jp.getName()));
return actions;
default:
throw new NotImplementedException(sortingMethod);
}
}
use of org.lara.language.specification.dsl.Action in project lara-framework by specs-feup.
the class LangSpecsXmlParser method parse.
public static LanguageSpecificationV2 parse(InputStream joinPointModel, InputStream attributeModel, InputStream actionModel, boolean validate) {
// System.out.println("JP SCHEMA: " + SchemaResource.JOIN_POINT_SCHEMA.read());
// System.out.println("JP SCHEMA: " + SchemaResource.JOIN_POINT_SCHEMA.getResource());
var jpSchema = validate ? SchemaResource.JOIN_POINT_SCHEMA.toStream() : null;
var attrSchema = validate ? SchemaResource.ATTRIBUTE_SCHEMA.toStream() : null;
var actionSchema = validate ? SchemaResource.ACTION_SCHEMA.toStream() : null;
var joinPointModelNode = XmlDocument.newInstance(joinPointModel, jpSchema);
var attributeModelNode = XmlDocument.newInstance(attributeModel, attrSchema);
var actionModelNode = XmlDocument.newInstance(actionModel, actionSchema);
// Setup global JoinPointClass
LanguageSpecificationV2 langSpecV2 = new LanguageSpecificationV2();
JoinPointClass global = JoinPointClass.globalJoinPoint(langSpecV2);
langSpecV2.setGlobal(global);
// Initialize types (typedef, enums), to have access to available names
for (var type : attributeModelNode.getElementsByName("object")) {
var typeDef = new TypeDef(type.getAttribute("name"));
langSpecV2.add(typeDef);
setOptional(type.getAttribute("tooltip"), typeDef::setToolTip);
}
for (var type : attributeModelNode.getElementsByName("enum")) {
var enumDef = new EnumDef(type.getAttribute("name"));
langSpecV2.add(enumDef);
setOptional(type.getAttribute("tooltip"), enumDef::setToolTip);
List<EnumValue> valuesList = toEnumValues(type.getElementsByName("value"), langSpecV2);
enumDef.setValues(valuesList);
}
List<JoinPointClass> jps = new ArrayList<>();
for (var jpNode : joinPointModelNode.getElementsByName("joinpoint")) {
var jp = new JoinPointClass(jpNode.getAttribute("class"), langSpecV2);
setOptional(jpNode.getAttribute("tooltip"), jp::setToolTip);
jps.add(jp);
}
Collections.sort(jps);
jps.stream().forEach(langSpecV2::add);
var joinpoints = joinPointModelNode.getElementsByName("joinpoints").get(0);
langSpecV2.setRoot(joinpoints.getAttribute("root_class"));
setOptional(joinpoints.getAttribute("root_alias"), langSpecV2::setRootAlias);
// Map of actions according to class
MultiMap<String, XmlElement> joinPointActions = new MultiMap<>();
List<XmlElement> globalActions = new ArrayList<>();
for (var actionNode : actionModelNode.getElementsByName("action")) {
var classNames = actionNode.getAttribute("class");
// Global actions do not have a class value, or its value is '*'
if (classNames.isEmpty() || classNames.equals("*")) {
globalActions.add(actionNode);
continue;
}
// System.out.println("CLASS NAMES: " + classNames);
for (String className : classNames.split(",")) {
// System.out.println("NAME: " + className);
joinPointActions.add(className.strip(), actionNode);
}
}
populateGlobal(joinPointModelNode, attributeModelNode, actionModelNode, langSpecV2, global, globalActions);
// Populate TypeDef
for (var typeNode : attributeModelNode.getElementsByName("object")) {
TypeDef typeDef = langSpecV2.getTypeDefs().get(typeNode.getAttribute("name"));
List<Attribute> attributesList = convertAttributes(typeNode.getElementsByName("attribute"), langSpecV2);
typeDef.setFields(attributesList);
}
for (var jpNode : joinPointModelNode.getElementsByName("joinpoint")) {
String jpClass = jpNode.getAttribute("class");
JoinPointClass jp = langSpecV2.getJoinPoint(jpClass);
String extendsType = jpNode.getAttribute("extends");
if (!extendsType.isEmpty()) {
jp.setExtend(langSpecV2.getJoinPoint(extendsType));
} else {
jp.setExtend(global);
}
// Obtain attribute nodes from artifacts
List<XmlElement> artifactNodes = attributeModelNode.getElementsByName("artifact").stream().filter(attribute -> attribute.getAttribute("class").equals(jpClass)).collect(Collectors.toList());
var attributeNodes = artifactNodes.stream().flatMap(art -> art.getElementsByName("attribute").stream()).collect(Collectors.toList());
// Add attributes
jp.setAttributes(convertAttributes(attributeNodes, langSpecV2));
// Add selects
jp.setSelects(convertSelects(langSpecV2, jpNode.getElementsByName("select")));
// Add actions
jp.setActions(convertActions(langSpecV2, joinPointActions.get(jpClass)));
// Set default attributes
for (var artifact : attributeModelNode.getElementsByName("artifact")) {
var defaultValue = artifact.getAttribute("default");
if (defaultValue.isEmpty()) {
continue;
}
// Get corresponding join point and set default
// System.out.println("ARTIFACT CLASS: " + artifact.getAttribute("class"));
// System.out.println("JP: " + langSpecV2.getJoinPoint(artifact.getAttribute("class")));
var artifactJp = langSpecV2.getJoinPoint(artifact.getAttribute("class"));
if (artifactJp == null) {
SpecsLogs.info("Artifact without join point: " + artifact.getAttribute("class"));
continue;
}
artifactJp.setDefaultAttribute(defaultValue);
// System.out.println("SETTING DEFAULT '" + defaultValue + "' for JP " +
// artifact.getAttribute("class"));
}
}
// Add default global attributes (e.g., joinPointType, instanceOf)
addDefaultGlobalAttributes(langSpecV2);
return langSpecV2;
}
use of org.lara.language.specification.dsl.Action in project lara-framework by specs-feup.
the class LanguageSpecificationTest method testActionModel.
@Test
public void testActionModel() {
var langSpec = LangSpecsXmlParser.parse(JOIN_POINT_MODEL.toStream(), ATTRIBUTE_MODEL.toStream(), ACTION_MODEL.toStream());
StringBuilder actual = new StringBuilder();
actual.append("loop own actions:");
langSpec.getJoinPoint("loop").getActionsSelf().stream().map(Action::getName).forEach(actionName -> actual.append("\n" + actionName));
actual.append("\n");
actual.append("loop all actions:");
langSpec.getJoinPoint("loop").getActions().stream().map(action -> "Name: " + action.getName()).forEach(actionName -> actual.append("\n" + actionName));
actual.append("\n");
actual.append("body all actions:");
langSpec.getJoinPoint("body").getActions().stream().map(action -> "Name: " + action.getName()).forEach(actionName -> actual.append("\n" + actionName));
// actions = am.getAllJoinPointActions(jp, jpm);
ResourceProvider parserTestExpected = () -> "pt/up/fe/specs/lara/langspec/test/ActionModelTest.txt";
assertEquals(SpecsStrings.normalizeFileContents(parserTestExpected.read(), true), SpecsStrings.normalizeFileContents(actual.toString(), true));
}
use of org.lara.language.specification.dsl.Action in project lara-framework by specs-feup.
the class ASTPerform method organize.
@Override
public Object organize(Object obj) {
final LaraC lara = getLara();
var organizer = lara.getOrganizer();
var languageSpec = lara.getLanguageSpec();
// final ActionModel actionModel = languageSpec.getActionModel();
final ASTAction act = (ASTAction) parent;
act.setMethod(action);
// if (!actionModel.contains(action)) {
if (!languageSpec.hasAction(action)) {
lara.warnln("Action '" + action + "' does not exist in the action model. The arguments cannot be verified. Will use action as is.");
final Map<String, ActionArgument> emptyMap = Collections.emptyMap();
act.setArguments(emptyMap);
return null;
}
// Since we accept method overloading then we should verify all possible actions
List<Action> actions = languageSpec.getAction(action);
if (children == null) {
// Base case: no arguments were given to the action and there is an action without parameters
for (Action action : actions) {
if (action.getParameters().isEmpty()) {
final Map<String, ActionArgument> actionParam = organizer.createActionParameters(action);
act.setArguments(actionParam);
validateReturn(lara, action);
return null;
}
}
throwIllegalParameters(actions, children);
// + actionParam.size() + " arguments: '" + actionParam.keySet() + "'");
}
// Get the action arguments
final ASTFunctionCallParameters params = (ASTFunctionCallParameters) children[0];
int callparametersId = LARAEcmaScriptTreeConstants.JJTFUNCTIONCALLPARAMETERS;
// Instantiate the new arguments that will comprise the necessary changes
final ASTFunctionCallParameters newParams = new ASTFunctionCallParameters(callparametersId);
List<Map<String, ActionArgument>> actionsParams = SpecsFactory.newLinkedList();
List<Action> possibleActions = SpecsFactory.newLinkedList();
if (params.areNamed) {
actions: for (Action action : actions) {
final Map<String, ActionArgument> actionParam = organizer.createActionParameters(action);
for (final Node param : params.getChildren()) {
final ASTNamedArgument na = (ASTNamedArgument) param;
if (!actionParam.containsKey(na.value)) {
continue actions;
}
final ActionArgument actArg = actionParam.get(na.value);
actArg.setValue(na.getChild(0));
}
if (argsAreValid(actionParam)) {
actionsParams.add(actionParam);
possibleActions.add(action);
}
}
if (possibleActions.isEmpty()) {
throwIllegalParameters(actions, params.children);
}
if (possibleActions.size() > 1) {
String message = "Conflicting action choice when using named arguments. Given: (show named arguments given by user)";
message += "Conflicting Options:\n";
int i = 0;
for (Action action : possibleActions) {
message += "\t" + i + ") " + action2String(action) + "\n";
}
throw new RuntimeException(message);
}
Map<String, ActionArgument> map = actionsParams.get(0);
Action action = possibleActions.get(0);
organizeWithGivenParams(lara, act, params, newParams, action, map);
} else {
if (params.children == null) {
for (Action action : actions) {
if (action.getParameters().isEmpty()) {
final Map<String, ActionArgument> actionParam = organizer.createActionParameters(action);
act.setArguments(actionParam);
validateReturn(lara, action);
return null;
}
}
} else {
for (Action action : actions) {
int length = params.children.length;
if (length == action.getParameters().size()) {
// Just accept same size of parameters
final Map<String, ActionArgument> actionParam = organizer.createActionParameters(action);
int i = 0;
for (final ActionArgument arg : actionParam.values()) {
arg.setValue((SimpleNode) params.jjtGetChild(i++));
}
organizeWithGivenParams(lara, act, params, newParams, action, actionParam);
return null;
}
}
}
throwIllegalParameters(actions, params.children);
}
return null;
}
Aggregations