Skip to content

Commit

Permalink
ContextFactory reused to initialize language-server context (#10670)
Browse files Browse the repository at this point in the history
  • Loading branch information
JaroslavTulach authored Jul 29, 2024
1 parent 73cb5d1 commit cb72487
Show file tree
Hide file tree
Showing 77 changed files with 231 additions and 228 deletions.
8 changes: 8 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -1446,6 +1446,12 @@ val testLogProviderOptions = Seq(
"-Dconfig.resource=application-test.conf"
)

/** engine/common project contains classes that are necessary to configure
* GraalVM's polyglot context. Most specifically it contains `ContextFactory`.
* As such it needs to depend on `org.graalvm.polyglot` package. Otherwise
* its dependencies shall be limited - no JSON & co. please. For purposes
* of consistently setting up loaders, the module depends on `logging-utils`.
*/
lazy val `engine-common` = project
.in(file("engine/common"))
.settings(
Expand All @@ -1457,6 +1463,8 @@ lazy val `engine-common` = project
"org.graalvm.polyglot" % "polyglot" % graalMavenPackagesVersion % "provided"
)
)
.dependsOn(`logging-config`)
.dependsOn(`logging-utils`)
.dependsOn(testkit % Test)

lazy val `polyglot-api` = project
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
package org.enso.runner;
package org.enso.common;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;
import org.enso.common.HostAccessFactory;
import org.enso.common.LanguageInfo;

import org.enso.logger.Converter;
import org.enso.logger.JulHandler;
import org.enso.logger.LoggerSetup;
import org.enso.polyglot.PolyglotContext;
import org.enso.polyglot.RuntimeOptions;
import org.enso.polyglot.debugger.DebugServerInfo;
import org.enso.polyglot.debugger.DebuggerSessionManagerEndpoint;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.HostAccess;
import org.graalvm.polyglot.io.MessageTransport;
import org.slf4j.event.Level;

/**
Expand All @@ -23,7 +20,6 @@
* of any projects)
* @param in the input stream for standard in
* @param out the output stream for standard out
* @param repl the Repl manager to use for this context
* @param logLevel the log level for this context
* @param enableIrCaches whether or not IR caching should be enabled
* @param disablePrivateCheck If `private` keyword should be disabled.
Expand All @@ -34,11 +30,12 @@
* @param executionEnvironment optional name of the execution environment to use during execution
* @param warningsLimit maximal number of warnings reported to the user
*/
final class ContextFactory {
public final class ContextFactory {
private String projectRoot;
private InputStream in;
private OutputStream out;
private Repl repl;
private InputStream in = System.in;
private OutputStream out = System.out;
private OutputStream err = System.err;
private MessageTransport messageTransport;
private Level logLevel;
private boolean logMasking;
private boolean enableIrCaches;
Expand Down Expand Up @@ -72,8 +69,13 @@ public ContextFactory out(OutputStream out) {
return this;
}

public ContextFactory repl(Repl repl) {
this.repl = repl;
public ContextFactory err(OutputStream err) {
this.err = err;
return this;
}

public ContextFactory messageTransport(MessageTransport t) {
this.messageTransport = t;
return this;
}

Expand Down Expand Up @@ -132,7 +134,7 @@ public ContextFactory options(Map<String, String> options) {
return this;
}

PolyglotContext build() {
public Context build() {
if (executionEnvironment != null) {
options.put("enso.ExecutionEnvironment", executionEnvironment);
}
Expand All @@ -142,7 +144,7 @@ PolyglotContext build() {
Context.newBuilder()
.allowExperimentalOptions(true)
.allowAllAccess(true)
.allowHostAccess(new HostAccessFactory().allWithTypeMapping())
.allowHostAccess(allWithTypeMapping())
.option(RuntimeOptions.PROJECT_ROOT, projectRoot)
.option(RuntimeOptions.STRICT_ERRORS, Boolean.toString(strictErrors))
.option(RuntimeOptions.WAIT_FOR_PENDING_SERIALIZATION_JOBS, "true")
Expand All @@ -152,19 +154,16 @@ PolyglotContext build() {
.option(RuntimeOptions.DISABLE_IR_CACHES, Boolean.toString(!enableIrCaches))
.option(RuntimeOptions.DISABLE_PRIVATE_CHECK, Boolean.toString(disablePrivateCheck))
.option(RuntimeOptions.ENABLE_STATIC_ANALYSIS, Boolean.toString(enableStaticAnalysis))
.option(DebugServerInfo.ENABLE_OPTION, "true")
.option(RuntimeOptions.LOG_MASKING, Boolean.toString(logMasking))
.options(options)
.option(RuntimeOptions.ENABLE_AUTO_PARALLELISM, Boolean.toString(enableAutoParallelism))
.option(RuntimeOptions.WARNINGS_LIMIT, Integer.toString(warningsLimit))
.out(out)
.in(in)
.serverTransport(
(uri, peer) ->
DebugServerInfo.URI.equals(uri.toString())
? new DebuggerSessionManagerEndpoint(repl, peer)
: null);

.err(err)
.in(in);
if (messageTransport != null) {
builder.serverTransport(messageTransport);
}
builder.option(RuntimeOptions.LOG_LEVEL, logLevelName);
var logHandler = JulHandler.get();
var logLevels = LoggerSetup.get().getConfig().getLoggers();
Expand Down Expand Up @@ -197,7 +196,7 @@ PolyglotContext build() {
.option("java.UseBindingsLoader", "true")
.allowCreateThread(true);
}
return new PolyglotContext(builder.build());
return builder.build();
}

/**
Expand All @@ -217,4 +216,20 @@ PolyglotContext build() {
}
ENGINE_HAS_JAVA = found;
}

private static HostAccess allWithTypeMapping() {
return HostAccess.newBuilder()
.allowPublicAccess(true)
.allowAllImplementations(true)
.allowAllClassImplementations(true)
.allowArrayAccess(true)
.allowListAccess(true)
.allowBufferAccess(true)
.allowIterableAccess(true)
.allowIteratorAccess(true)
.allowMapAccess(true)
.allowAccessInheritance(true)
.build();
}

}
21 changes: 0 additions & 21 deletions engine/common/src/main/java/org/enso/common/HostAccessFactory.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package org.enso.polyglot;
package org.enso.common;

import com.oracle.truffle.api.Option;
import java.util.Arrays;
import org.enso.common.LanguageInfo;
import org.graalvm.options.OptionCategory;

import org.graalvm.options.OptionDescriptor;
import org.graalvm.options.OptionDescriptors;
import org.graalvm.options.OptionKey;

/** Class representing runtime options supported by the Enso engine. */
public class RuntimeOptions {
public final class RuntimeOptions {
private RuntimeOptions() {}
public static final String PROJECT_ROOT = optionName("projectRoot");
public static final OptionKey<String> PROJECT_ROOT_KEY = new OptionKey<>("");
private static final OptionDescriptor PROJECT_ROOT_DESCRIPTOR =
Expand Down Expand Up @@ -124,19 +123,15 @@ public class RuntimeOptions {

public static final String ENABLE_EXECUTION_TIMER = optionName("enableExecutionTimer");

@Option(
help = "Enables timer that counts down the execution time of expressions.",
category = OptionCategory.INTERNAL)
/* Enables timer that counts down the execution time of expressions. */
public static final OptionKey<Boolean> ENABLE_EXECUTION_TIMER_KEY = new OptionKey<>(true);

private static final OptionDescriptor ENABLE_EXECUTION_TIMER_DESCRIPTOR =
OptionDescriptor.newBuilder(ENABLE_EXECUTION_TIMER_KEY, ENABLE_EXECUTION_TIMER).build();

public static final String WARNINGS_LIMIT = optionName("warningsLimit");

@Option(
help = "Maximal number of warnings that can be attached to a value.",
category = OptionCategory.INTERNAL)
/* Maximal number of warnings that can be attached to a value. */
public static final OptionKey<Integer> WARNINGS_LIMIT_KEY = new OptionKey<>(100);

private static final OptionDescriptor WARNINGS_LIMIT_DESCRIPTOR =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
import java.util.logging.Level;
import org.enso.common.LanguageInfo;
import org.enso.common.MethodNames.TopScope;
import org.enso.common.RuntimeOptions;
import org.enso.interpreter.EnsoLanguage;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.error.DataflowError;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.polyglot.RuntimeOptions;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.io.IOAccess;
import org.junit.After;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,17 @@

import akka.event.EventStream;
import java.util.concurrent.Executor;
import org.enso.common.ContextFactory;
import org.enso.common.LanguageInfo;
import org.enso.languageserver.boot.ComponentSupervisor;
import org.enso.languageserver.event.InitializedEvent;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Engine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Initialize the Truffle context. */
public class TruffleContextInitialization extends LockedInitialization {

private final Context.Builder truffleContextBuilder;
private final ContextFactory contextFactory;
private final ComponentSupervisor supervisor;
private final EventStream eventStream;

Expand All @@ -24,34 +23,24 @@ public class TruffleContextInitialization extends LockedInitialization {
*
* @param executor the executor that runs the initialization
* @param eventStream the events stream
* @param truffleContextBuilder the Truffle context builder
* @param supervisor supervisor
* @param factory the Truffle context builder
*/
public TruffleContextInitialization(
Executor executor,
Context.Builder truffleContextBuilder,
ContextFactory factory,
ComponentSupervisor supervisor,
EventStream eventStream) {
super(executor);
this.truffleContextBuilder = truffleContextBuilder;
this.contextFactory = factory;
this.supervisor = supervisor;
this.eventStream = eventStream;
}

@Override
public void initComponent() {
logger.trace("Creating Runtime context");
if (Engine.newBuilder()
.allowExperimentalOptions(true)
.build()
.getLanguages()
.containsKey("java")) {
truffleContextBuilder
.option("java.ExposeNativeJavaVM", "true")
.option("java.Polyglot", "true")
.option("java.UseBindingsLoader", "true")
.allowCreateThread(true);
}
var truffleContext = truffleContextBuilder.build();
var truffleContext = contextFactory.build();
supervisor.registerService(truffleContext);
logger.trace("Created Runtime context [{}]", truffleContext);
logger.debug("Initializing Runtime context [{}]", truffleContext);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,14 @@ import org.enso.librarymanager.LibraryLocations
import org.enso.librarymanager.local.DefaultLocalLibraryProvider
import org.enso.librarymanager.published.PublishedLibraryCache
import org.enso.lockmanager.server.LockManagerService
import org.enso.logger.Converter
import org.enso.logger.masking.Masking
import org.enso.logger.JulHandler
import org.enso.logger.akka.AkkaConverter
import org.enso.common.HostAccessFactory
import org.enso.polyglot.{RuntimeOptions, RuntimeServerInfo}
import org.enso.common.RuntimeOptions
import org.enso.common.ContextFactory
import org.enso.polyglot.RuntimeServerInfo
import org.enso.profiling.events.NoopEventsMonitor
import org.enso.searcher.memory.InMemorySuggestionsRepo
import org.enso.text.{ContentBasedVersioning, Sha3_224VersionCalculator}
import org.graalvm.polyglot.Context
import org.graalvm.polyglot.io.MessageEndpoint
import org.slf4j.event.Level
import org.slf4j.LoggerFactory
Expand Down Expand Up @@ -307,31 +305,29 @@ class MainModule(serverConfig: LanguageServerConfig, logLevel: Level) {
val stdInSink = new ObservableOutputStream
val stdIn = new ObservablePipedInputStream(stdInSink)

val builder = Context
.newBuilder()
.allowAllAccess(true)
.allowHostAccess(new HostAccessFactory().allWithTypeMapping())
.allowExperimentalOptions(true)
.option(RuntimeServerInfo.ENABLE_OPTION, "true")
.option(RuntimeOptions.INTERACTIVE_MODE, "true")
.option(RuntimeOptions.PROJECT_ROOT, serverConfig.contentRootPath)
.option(
RuntimeOptions.LOG_LEVEL,
Converter.toJavaLevel(logLevel).getName
)
.option(RuntimeOptions.STRICT_ERRORS, "false")
.option(RuntimeOptions.LOG_MASKING, Masking.isMaskingEnabled.toString)
.option(RuntimeOptions.EDITION_OVERRIDE, Info.currentEdition)
.option(
RuntimeOptions.JOB_PARALLELISM,
Runtime.getRuntime.availableProcessors().toString
)
.option(RuntimeOptions.PREINITIALIZE, "js")
val extraOptions = new java.util.HashMap[String, String]()
extraOptions.put(RuntimeServerInfo.ENABLE_OPTION, "true")
extraOptions.put(RuntimeOptions.INTERACTIVE_MODE, "true")
extraOptions.put(
RuntimeOptions.LOG_MASKING,
Masking.isMaskingEnabled.toString
)
extraOptions.put(RuntimeOptions.EDITION_OVERRIDE, Info.currentEdition)
extraOptions.put(
RuntimeOptions.JOB_PARALLELISM,
Runtime.getRuntime.availableProcessors().toString
)

val builder = ContextFactory
.create()
.projectRoot(serverConfig.contentRootPath)
.logLevel(logLevel)
.strictErrors(false)
.out(stdOut)
.err(stdErr)
.in(stdIn)
.logHandler(JulHandler.get())
.serverTransport((uri: URI, peerEndpoint: MessageEndpoint) => {
.options(extraOptions)
.messageTransport((uri: URI, peerEndpoint: MessageEndpoint) => {
if (uri.toString == RuntimeServerInfo.URI) {
val connection = new RuntimeConnector.Endpoint(
runtimeConnector,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import org.enso.languageserver.boot.resource.{
import org.enso.languageserver.data.ProjectDirectoriesConfig
import org.enso.languageserver.effect
import org.enso.searcher.memory.InMemorySuggestionsRepo
import org.graalvm.polyglot.Context
import org.enso.common.ContextFactory

import scala.concurrent.ExecutionContextExecutor

Expand All @@ -41,7 +41,7 @@ object ResourcesInitialization {
directoriesConfig: ProjectDirectoriesConfig,
protocolFactory: ProtocolFactory,
suggestionsRepo: InMemorySuggestionsRepo,
truffleContextBuilder: Context#Builder,
truffleContextBuilder: ContextFactory,
truffleContextSupervisor: ComponentSupervisor,
runtime: effect.Runtime,
ydocSupervisor: ComponentSupervisor
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.enso.polyglot

import org.enso.common.RuntimeOptions
import org.graalvm.polyglot.Context
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
Expand Down
Loading

0 comments on commit cb72487

Please sign in to comment.