blob: 6bfadaaba9ef31a701cf524fe98108028caab4eb [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2020 CEA LIST.
*
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
* Ansgar Radermacher ansgar.radermacher@cea.fr
*
*****************************************************************************/
package org.eclipse.papyrus.robotics.ros2.cdteditor.sync;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.papyrus.commands.Activator;
import org.eclipse.papyrus.robotics.ros2.cdteditor.sync.PortInfo.ProviderKind;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.uml2.uml.Classifier;
public class SyncPortsFromSource {
private static final String CREATE_PUBLISHER = "create_publisher"; //$NON-NLS-1$
private static final String CREATE_SUBSCRIPTION = "create_subscription"; //$NON-NLS-1$
private static final String CREATE_SERVICE = "create_service"; //$NON-NLS-1$
private static final String CREATE_CLIENT = "create_client"; //$NON-NLS-1$
private static final String EXTERNAL_FILES = "External Files"; //$NON-NLS-1$
public static void updatePorts(Classifier cl, IASTNode node) {
List<PortInfo> portInfoList = new ArrayList<PortInfo>();
scanFunctions(node, portInfoList);
for (PortInfo pi : portInfoList) {
System.err.println(pi.dtQName);
// NamedElement namedElemParamType = ElementUtils.getQualifiedElementFromRS(element, expr2);
}
}
public static void scanFunctions(IASTNode node, List<PortInfo> portInfoList) {
for (IASTNode child : node.getChildren()) {
if (child instanceof IASTFunctionDefinition) {
IASTFunctionDefinition definition = (IASTFunctionDefinition) child;
scanBody(definition.getBody(), portInfoList);
}
if (child instanceof ICPPASTNamespaceDefinition) {
// recurse into namespaces
scanFunctions(child, portInfoList);
}
}
}
public static String getASTName(IASTExpression expr) {
if (expr instanceof IASTFieldReference) {
IASTName fieldName = ((IASTFieldReference) expr).getFieldName();
if (fieldName != null) {
return fieldName.toString();
}
return ""; //$NON-NLS-1$
} else {
return expr.toString();
}
}
public static ProviderKind getProviderFromCall(String fctName) {
if (fctName.equals(CREATE_CLIENT)) {
return ProviderKind.CLIENT;
}
if (fctName.equals(CREATE_SERVICE)) {
return ProviderKind.SERVER;
}
if (fctName.equals(CREATE_SUBSCRIPTION)) {
return ProviderKind.SUBSCRIBER;
}
if (fctName.equals(CREATE_PUBLISHER)) {
return ProviderKind.PUBLISHER;
}
return null;
}
public static PortInfo obtainCallDetails(ProviderKind pk, IASTExpression expr1, IASTExpression expr2) {
IASTExpression expr2b = ((IASTBinaryExpression) expr1).getOperand2();
IASTExpression topicExpr = null;
if (expr2 instanceof IASTUnaryExpression) {
IASTExpression arguments = ((IASTUnaryExpression) expr2).getOperand();
if (arguments instanceof IASTExpressionList) {
topicExpr = ((IASTExpressionList) arguments).getExpressions()[0];
} else {
topicExpr = arguments;
}
}
String topicName = topicExpr.toString();
// remove quotes
if (topicName.startsWith("\"") && topicName.length()>=2) { //$NON-NLS-1$
topicName = topicName.substring(1, topicName.length()-1);
}
PortInfo portInfo = new PortInfo();
portInfo.pk = pk;
portInfo.dtQName = getASTName(expr2b);
portInfo.topic = topicName;
return portInfo;
}
public static void scanBody(IASTNode node, List<PortInfo> portList) {
if (node instanceof IASTBinaryExpression) {
IASTBinaryExpression expr = (IASTBinaryExpression) node;
IASTExpression expr1 = expr.getOperand1();
IASTExpression expr2 = expr.getOperand2();
if (expr1 instanceof IASTBinaryExpression) {
IASTExpression expr1b = ((IASTBinaryExpression) expr1).getOperand1();
String fieldName = getASTName(expr1b);
if (fieldName != null) {
ProviderKind pk = getProviderFromCall(fieldName);
if (pk != null) {
PortInfo portInfo = obtainCallDetails(pk, expr1, expr2);
if (portInfo != null) {
portList.add(portInfo);
}
}
}
}
}
for (IASTNode child : node.getChildren()) {
// recurse into all children
scanBody(child, portList);
}
}
public static void tst() {
IWorkspace ws = ResourcesPlugin.getWorkspace();
IProject project = ws.getRoot().getProject(EXTERNAL_FILES);
try {
if (!project.exists())
project.create(null);
if (!project.isOpen())
project.open(null);
Shell shell = Display.getDefault().getActiveShell();
String name = (1 == 0) ? "/local/home/ansgar/prog/ros2/demos/demo_nodes_cpp/src/services/add_two_ints_client.cpp" : new FileDialog(shell, SWT.OPEN).open();
if (name == null)
return;
IPath location = new Path(name);
IFile srcFile = project.getFile(location.lastSegment());
boolean exists = srcFile.exists();
if (exists) {
srcFile.delete(false, null);
}
srcFile.createLink(location, IResource.NONE, null);
ITranslationUnit itu = (ITranslationUnit) CoreModel.getDefault().create(srcFile);
IASTTranslationUnit ast = itu.getAST();
scanFunctions(ast, new ArrayList<PortInfo>());
} catch (CoreException e) {
Activator.log.error(e);
}
}
}