Skip to content

Commit

Permalink
Add Language Server support for the ros (component level) DSLs
Browse files Browse the repository at this point in the history
  • Loading branch information
ipa-nhg committed Sep 25, 2023
1 parent 6c69852 commit fca6bbd
Show file tree
Hide file tree
Showing 9 changed files with 492 additions and 12 deletions.
5 changes: 4 additions & 1 deletion plugins/de.fraunhofer.ipa.ros.xtext.ide/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ Require-Bundle: de.fraunhofer.ipa.ros.xtext,
de.fraunhofer.ipa.ros,
org.eclipse.xtext.ide,
org.eclipse.xtext.xbase.ide,
org.antlr.runtime;bundle-version="4.7.2"
org.antlr.runtime;bundle-version="4.7.2",
org.eclipse.lsp4j.jsonrpc,
org.eclipse.lsp4j,
com.google.gson
Bundle-RequiredExecutionEnvironment: JavaSE-11
Export-Package: de.fraunhofer.ipa.ros.ide.contentassist.antlr.internal,
de.fraunhofer.ipa.ros.ide.contentassist.antlr,
Expand Down
108 changes: 105 additions & 3 deletions plugins/de.fraunhofer.ipa.ros.xtext.ide/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,124 @@
<packaging>eclipse-plugin</packaging>

<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
<exclude>**/*.xtend</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>add-source</id>
<phase>initialize</phase>
<goals>
<goal>add-source</goal>
<goal>add-resource</goal>
</goals>
<configuration>
<sources>
<source>src-gen</source>
</sources>
<resources>
<resource>
<directory>src-gen</directory>
<excludes>
<exclude>**/*.java</exclude>
<exclude>**/*.g</exclude>
</excludes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>de.fraunhofer.ipa.ros.ide.launch.ServerLauncher</mainClass>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>plugin.properties</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer">
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/INDEX.LIST</exclude>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>.options</exclude>
<exclude>.api_description</exclude>
<exclude>*.profile</exclude>
<exclude>*.html</exclude>
<exclude>about.*</exclude>
<exclude>about_files/*</exclude>
<exclude>plugin.xml</exclude>
<exclude>systembundle.properties</exclude>
<exclude>profile.list</exclude>
<exclude>**/*._trace</exclude>
<exclude>**/*.g</exclude>
<exclude>**/*.mwe2</exclude>
<exclude>**/*.xtext</exclude>
</excludes>
</filter>
</filters>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>ls</shadedClassifierName>
<minimizeJar>false</minimizeJar>
</configuration>
<executions>
<execution>
<id>xtend-gen-clean</id>
<phase>clean</phase>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>de.fraunhofer.ipa.ros.xtext</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.xtext</groupId>
<artifactId>org.eclipse.xtext.ide</artifactId>
<version>${xtextVersion}</version>
</dependency>
<dependency>
<groupId>org.eclipse.xtext</groupId>
<artifactId>org.eclipse.xtext.xbase.ide</artifactId>
<version>${xtextVersion}</version>
</dependency>
</dependencies>
</project>

Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package de.fraunhofer.ipa.ros.ide.launch;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.Channels;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.function.Function;

import org.eclipse.lsp4j.jsonrpc.Launcher;
import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
import org.eclipse.lsp4j.services.LanguageClient;
import org.eclipse.xtext.ide.server.LanguageServerImpl;
import org.eclipse.xtext.ide.server.ServerModule;

import com.google.inject.Guice;
import com.google.inject.Injector;

public class ServerLauncher {
public static void main(String[] args) throws InterruptedException, IOException {
Injector injector = Guice.createInjector(new ServerModule());
LanguageServerImpl languageServer = injector.getInstance(LanguageServerImpl.class);
Function<MessageConsumer, MessageConsumer> wrapper = consumer -> {
MessageConsumer result = consumer;
return result;
};
Launcher<LanguageClient> launcher = createSocketLauncher(languageServer, LanguageClient.class,
new InetSocketAddress("localhost", 5008), Executors.newCachedThreadPool(), wrapper);
languageServer.connect(launcher.getRemoteProxy());
Future<?> future = launcher.startListening();
while (!future.isDone()) {
Thread.sleep(10_000l);
}
}

static <T> Launcher<T> createSocketLauncher(Object localService, Class<T> remoteInterface,
SocketAddress socketAddress, ExecutorService executorService,
Function<MessageConsumer, MessageConsumer> wrapper) throws IOException {
AsynchronousServerSocketChannel serverSocket = AsynchronousServerSocketChannel.open().bind(socketAddress);
AsynchronousSocketChannel socketChannel;
try {
socketChannel = serverSocket.accept().get();
return Launcher.createIoLauncher(localService, remoteInterface, Channels.newInputStream(socketChannel),
Channels.newOutputStream(socketChannel), executorService, wrapper);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ Require-Bundle: de.fraunhofer.ipa.ros1.xtext,
org.eclipse.xtext.xbase.ide,
org.antlr.runtime;bundle-version="4.7.2",
de.fraunhofer.ipa.ros.xtext,
de.fraunhofer.ipa.ros.xtext.ui
de.fraunhofer.ipa.ros.xtext.ui,
org.eclipse.lsp4j;bundle-version="0.21.1",
org.eclipse.lsp4j.jsonrpc;bundle-version="0.21.1",
com.google.gson
Bundle-RequiredExecutionEnvironment: JavaSE-11
Export-Package: de.fraunhofer.ipa.ros1.ide.contentassist.antlr.internal,
de.fraunhofer.ipa.ros1.ide.contentassist.antlr.lexer,
Expand Down
108 changes: 105 additions & 3 deletions plugins/de.fraunhofer.ipa.ros1.xtext.ide/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,124 @@
<packaging>eclipse-plugin</packaging>

<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
<exclude>**/*.xtend</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>add-source</id>
<phase>initialize</phase>
<goals>
<goal>add-source</goal>
<goal>add-resource</goal>
</goals>
<configuration>
<sources>
<source>src-gen</source>
</sources>
<resources>
<resource>
<directory>src-gen</directory>
<excludes>
<exclude>**/*.java</exclude>
<exclude>**/*.g</exclude>
</excludes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>de.fraunhofer.ipa.ros1.ide.launch.ServerLauncher</mainClass>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>plugin.properties</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer">
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/INDEX.LIST</exclude>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>.options</exclude>
<exclude>.api_description</exclude>
<exclude>*.profile</exclude>
<exclude>*.html</exclude>
<exclude>about.*</exclude>
<exclude>about_files/*</exclude>
<exclude>plugin.xml</exclude>
<exclude>systembundle.properties</exclude>
<exclude>profile.list</exclude>
<exclude>**/*._trace</exclude>
<exclude>**/*.g</exclude>
<exclude>**/*.mwe2</exclude>
<exclude>**/*.xtext</exclude>
</excludes>
</filter>
</filters>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>ls</shadedClassifierName>
<minimizeJar>false</minimizeJar>
</configuration>
<executions>
<execution>
<id>xtend-gen-clean</id>
<phase>clean</phase>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>de.fraunhofer.ipa.ros.xtext</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.xtext</groupId>
<artifactId>org.eclipse.xtext.ide</artifactId>
<version>${xtextVersion}</version>
</dependency>
<dependency>
<groupId>org.eclipse.xtext</groupId>
<artifactId>org.eclipse.xtext.xbase.ide</artifactId>
<version>${xtextVersion}</version>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package de.fraunhofer.ipa.ros1.ide.launch;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.Channels;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.function.Function;

import org.eclipse.lsp4j.jsonrpc.Launcher;
import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
import org.eclipse.lsp4j.services.LanguageClient;
import org.eclipse.xtext.ide.server.LanguageServerImpl;
import org.eclipse.xtext.ide.server.ServerModule;

import com.google.inject.Guice;
import com.google.inject.Injector;

public class ServerLauncher {
public static void main(String[] args) throws InterruptedException, IOException {
Injector injector = Guice.createInjector(new ServerModule());
LanguageServerImpl languageServer = injector.getInstance(LanguageServerImpl.class);
Function<MessageConsumer, MessageConsumer> wrapper = consumer -> {
MessageConsumer result = consumer;
return result;
};
Launcher<LanguageClient> launcher = createSocketLauncher(languageServer, LanguageClient.class,
new InetSocketAddress("localhost", 5008), Executors.newCachedThreadPool(), wrapper);
languageServer.connect(launcher.getRemoteProxy());
Future<?> future = launcher.startListening();
while (!future.isDone()) {
Thread.sleep(10_000l);
}
}

static <T> Launcher<T> createSocketLauncher(Object localService, Class<T> remoteInterface,
SocketAddress socketAddress, ExecutorService executorService,
Function<MessageConsumer, MessageConsumer> wrapper) throws IOException {
AsynchronousServerSocketChannel serverSocket = AsynchronousServerSocketChannel.open().bind(socketAddress);
AsynchronousSocketChannel socketChannel;
try {
socketChannel = serverSocket.accept().get();
return Launcher.createIoLauncher(localService, remoteInterface, Channels.newInputStream(socketChannel),
Channels.newOutputStream(socketChannel), executorService, wrapper);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
return null;
}
}
Loading

0 comments on commit fca6bbd

Please sign in to comment.