use of org.graalvm.tools.lsp.server.TruffleAdapter in project graal by oracle.
the class LSPInstrument method onCreate.
@Override
protected void onCreate(Env env) {
env.registerService(this);
this.environment = env;
options = env.getOptions();
if (options.hasSetOptions()) {
final TruffleAdapter truffleAdapter = launchServer(new PrintWriter(env.out(), true), new PrintWriter(env.err(), true));
SourceSectionFilter eventFilter = SourceSectionFilter.newBuilder().includeInternal(options.get(Internal)).build();
eventFactoryBinding = env.getInstrumenter().attachExecutionEventFactory(eventFilter, new ExecutionEventNodeFactory() {
private final long creatorThreadId = Thread.currentThread().getId();
@Override
public ExecutionEventNode create(final EventContext eventContext) {
final SourceSection section = eventContext.getInstrumentedSourceSection();
if (section != null && section.isAvailable()) {
final Node instrumentedNode = eventContext.getInstrumentedNode();
return new CoverageEventNode(section, instrumentedNode, null, truffleAdapter.surrogateGetter(instrumentedNode.getRootNode().getLanguageInfo()), creatorThreadId);
} else {
return null;
}
}
});
}
}
use of org.graalvm.tools.lsp.server.TruffleAdapter in project graal by oracle.
the class LSPInstrument method launchServer.
private TruffleAdapter launchServer(PrintWriter info, PrintWriter err) {
assert options != null;
assert options.hasSetOptions();
TruffleAdapter truffleAdapter = new TruffleAdapter(environment, options.get(DeveloperMode));
Context.Builder builder = Context.newBuilder();
builder.allowAllAccess(true);
builder.engine(Engine.create());
builder.fileSystem(LSPFileSystem.newReadOnlyFileSystem(truffleAdapter));
ContextAwareExecutor executorWrapper = new ContextAwareExecutorImpl(builder);
setWaitForClose();
executorWrapper.executeWithDefaultContext(() -> {
HostAndPort hostAndPort = options.get(Lsp);
try {
Context context = builder.build();
context.enter();
Instrument instrument = context.getEngine().getInstruments().get(ID);
EnvironmentProvider envProvider = instrument.lookup(EnvironmentProvider.class);
truffleAdapter.register(envProvider.getEnvironment(), executorWrapper);
InetSocketAddress socketAddress = hostAndPort.createSocket();
int port = socketAddress.getPort();
Integer backlog = options.get(SocketBacklogSize);
InetAddress address = socketAddress.getAddress();
ServerSocket serverSocket = new ServerSocket(port, backlog, address);
List<Pair<String, SocketAddress>> delegates = createDelegateSockets(options.get(Delegates));
LanguageServerImpl.create(truffleAdapter, info, err).start(serverSocket, delegates).thenRun(() -> {
try {
executorWrapper.executeWithDefaultContext(() -> {
context.leave();
return null;
}).get();
} catch (ExecutionException | InterruptedException ex) {
}
executorWrapper.shutdown();
notifyClose();
}).exceptionally((throwable) -> {
throwable.printStackTrace(err);
notifyClose();
return null;
});
} catch (ThreadDeath td) {
throw td;
} catch (Throwable e) {
String message = String.format("[Graal LSP] Starting server on %s failed: %s", hostAndPort.getHostPort(), e.getLocalizedMessage());
new LSPIOException(message, e).printStackTrace(err);
}
return null;
});
return truffleAdapter;
}
use of org.graalvm.tools.lsp.server.TruffleAdapter in project graal by oracle.
the class TruffleLSPTest method setup.
@Before
public void setup() {
engine = Engine.newBuilder().allowExperimentalOptions(true).build();
Instrument instrument = engine.getInstruments().get("lsp");
EnvironmentProvider envProvider = instrument.lookup(EnvironmentProvider.class);
truffleAdapter = new TruffleAdapter(envProvider.getEnvironment(), true);
Builder contextBuilder = Context.newBuilder();
contextBuilder.allowAllAccess(true);
contextBuilder.fileSystem(LSPFileSystem.newReadOnlyFileSystem(truffleAdapter));
contextBuilder.engine(engine);
context = contextBuilder.build();
context.enter();
ContextAwareExecutor executorWrapper = new ContextAwareExecutor() {
@Override
public <T> Future<T> executeWithDefaultContext(Callable<T> taskWithResult) {
try {
return CompletableFuture.completedFuture(taskWithResult.call());
} catch (Exception e) {
CompletableFuture<T> cf = new CompletableFuture<>();
cf.completeExceptionally(e);
return cf;
}
}
@Override
public <T> Future<T> executeWithNestedContext(Callable<T> taskWithResult, boolean cached) {
try (Context newContext = contextBuilder.build()) {
newContext.enter();
newContext.initialize("sl");
try {
return CompletableFuture.completedFuture(taskWithResult.call());
} catch (Exception e) {
CompletableFuture<T> cf = new CompletableFuture<>();
cf.completeExceptionally(e);
return cf;
} finally {
newContext.leave();
}
}
}
@Override
public <T> Future<T> executeWithNestedContext(Callable<T> taskWithResult, int timeoutMillis, Callable<T> onTimeoutTask) {
if (timeoutMillis <= 0) {
return executeWithNestedContext(taskWithResult, false);
} else {
CompletableFuture<Future<T>> future = CompletableFuture.supplyAsync(() -> executeWithNestedContext(taskWithResult, false));
try {
return future.get(timeoutMillis, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
future.cancel(true);
try {
return CompletableFuture.completedFuture(onTimeoutTask.call());
} catch (Exception timeoutTaskException) {
CompletableFuture<T> cf = new CompletableFuture<>();
cf.completeExceptionally(timeoutTaskException);
return cf;
}
} catch (InterruptedException | ExecutionException e) {
CompletableFuture<T> cf = new CompletableFuture<>();
cf.completeExceptionally(e);
return cf;
}
}
}
@Override
public void shutdown() {
}
@Override
public void resetContextCache() {
}
};
truffleAdapter.register(envProvider.getEnvironment(), executorWrapper);
}
Aggregations