-
Notifications
You must be signed in to change notification settings - Fork 323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Execute yjs from insight script #11965
base: develop
Are you sure you want to change the base?
Changes from all commits
2512bb9
4477b4a
31c97b9
936bf45
d9ce757
50266f9
93ba1dc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import { deserializeIdMap } from 'ydoc-server' | ||
import * as Ast from 'ydoc-shared/ast' | ||
import { splitFileContents } from 'ydoc-shared/ensoFile' | ||
import { DistributedProject, ModuleDoc } from 'ydoc-shared/yjsModel' | ||
Check warning on line 4 in app/ydoc-server-polyglot/src/insight.ts GitHub Actions / 🧹 GUI Lint Resultsapp/ydoc-server-polyglot/src/insight.ts#L4
|
||
import { WebsocketProvider } from 'y-websocket' | ||
import * as Y from 'yjs' | ||
|
||
interface SubdocsEvent { | ||
loaded: Set<Y.Doc> | ||
added: Set<Y.Doc> | ||
removed: Set<Y.Doc> | ||
} | ||
|
||
print("Initializing Insight: " + JSON.stringify(insight)); | ||
|
||
const PROJECT_NAME = 'NewProject1' | ||
const RETURN_VALUE_KEY = 'insight_return_value' | ||
|
||
//const doc = new ModuleDoc(new Y.Doc()) | ||
const doc = new Y.Doc() | ||
const syncModule = new Ast.MutableModule(doc) | ||
let spanMap = null | ||
|
||
function attachProvider(url: string, room: string, doc: Y.Doc) { | ||
Check warning on line 24 in app/ydoc-server-polyglot/src/insight.ts GitHub Actions / 🧹 GUI Lint Resultsapp/ydoc-server-polyglot/src/insight.ts#L24
Check warning on line 24 in app/ydoc-server-polyglot/src/insight.ts GitHub Actions / 🧹 GUI Lint Resultsapp/ydoc-server-polyglot/src/insight.ts#L24
|
||
print(`attachProvider ${url} ${room}`) | ||
const provider = new WebsocketProvider(url, room, doc) | ||
const onSync = () => doc.emit('sync', [true, doc]) | ||
const onDrop = () => doc.emit('sync', [false, doc]) | ||
|
||
const attachedSubdocs = new Map<Y.Doc, ReturnType<typeof attachProvider>>() | ||
|
||
function onSubdocs(e: SubdocsEvent) { | ||
e.loaded.forEach((subdoc) => { | ||
attachedSubdocs.set(subdoc, attachProvider(url, subdoc.guid, subdoc)) | ||
}) | ||
e.removed.forEach((subdoc) => { | ||
const subdocProvider = attachedSubdocs.get(subdoc) | ||
attachedSubdocs.delete(subdoc) | ||
if (subdocProvider != null) { | ||
subdocProvider.dispose() | ||
} | ||
}) | ||
} | ||
|
||
provider.on('sync', onSync) | ||
provider.on('connection-close', onDrop) | ||
provider.on('connection-error', onDrop) | ||
doc.on('subdocs', onSubdocs) | ||
|
||
function dispose() { | ||
provider.disconnect() | ||
provider.off('sync', onSync) | ||
provider.off('connection-close', onDrop) | ||
provider.off('connection-error', onDrop) | ||
doc.off('subdocs', onSubdocs) | ||
attachedSubdocs.forEach((subdocProvider) => { | ||
subdocProvider.dispose() | ||
}) | ||
} | ||
return { provider, dispose } | ||
} | ||
|
||
const d = new Y.Doc() | ||
const project = new DistributedProject(d) | ||
//const provider = attachProvider('ws://[::1]:5976/project', 'index', d) | ||
|
||
function parseContents(contents: string, syncModule: Ast.MutableModule) { | ||
const { code, idMapJson, metadataJson } = splitFileContents(contents) | ||
Check warning on line 68 in app/ydoc-server-polyglot/src/insight.ts GitHub Actions / 🧹 GUI Lint Resultsapp/ydoc-server-polyglot/src/insight.ts#L68
Check warning on line 68 in app/ydoc-server-polyglot/src/insight.ts GitHub Actions / 🧹 GUI Lint Resultsapp/ydoc-server-polyglot/src/insight.ts#L68
|
||
const parsedIdMap = deserializeIdMap(idMapJson) | ||
|
||
const { root, spans } = Ast.parseModuleWithSpans(code, syncModule) | ||
syncModule.setRoot(root) | ||
spanMap = spans | ||
|
||
Ast.setExternalIds(syncModule, spans, parsedIdMap) | ||
print(`[parseContents] idMap.entries=${parsedIdMap.entries()}`) | ||
} | ||
|
||
insight.on("source", function(ctx, frame) { | ||
Check warning on line 79 in app/ydoc-server-polyglot/src/insight.ts GitHub Actions / 🧹 GUI Lint Resultsapp/ydoc-server-polyglot/src/insight.ts#L79
|
||
print(`[source] ctx.uri=${ctx.name}`) | ||
if (ctx.name.includes(PROJECT_NAME)) { | ||
print(`[source] MATCHED ctx=${JSON.stringify(ctx)}`) | ||
parseContents(ctx.characters, syncModule) | ||
} | ||
}) | ||
|
||
function resultToString(result: any): string { | ||
return '' + result; | ||
} | ||
|
||
/* | ||
class IdMap { | ||
private readonly rangeToExpr: Map<SourceRange, ExternalId> | ||
} | ||
interface SpanMap { | ||
nodes: Map<NodeKey, Ast[]> | ||
tokens: Map<TokenKey, Token> | ||
} | ||
type NodeKey = TokenKey = SourceRangeKey | ||
*/ | ||
insight.on("return", function(ctx, frame) { | ||
print(`[return] ctx='${JSON.stringify(ctx)}'`) | ||
print(`[return] frame='${JSON.stringify(frame)}'`) | ||
print(`[return] ctx.returnValue='${ctx.returnValue(frame)}'`) | ||
|
||
const p = project | ||
Check warning on line 106 in app/ydoc-server-polyglot/src/insight.ts GitHub Actions / 🧹 GUI Lint Resultsapp/ydoc-server-polyglot/src/insight.ts#L106
Check warning on line 106 in app/ydoc-server-polyglot/src/insight.ts GitHub Actions / 🧹 GUI Lint Resultsapp/ydoc-server-polyglot/src/insight.ts#L106
|
||
const result = ctx.returnValue(frame) | ||
if (result && spanMap) { | ||
const key = Ast.nodeKey(ctx.charIndex, ctx.charEndIndex - ctx.charIndex) | ||
const asts = spanMap.nodes.get(key) | ||
if (asts) { | ||
const resultValue = resultToString(result) | ||
for (const ast of asts) { | ||
const editAst = syncModule.getVersion(ast) | ||
if (editAst.widgetMetadata(RETURN_VALUE_KEY) !== resultValue) { | ||
print(`[return] setWidgetMetadata ${ast.code()} : ${resultValue}`) | ||
editAst.setWidgetMetadata(RETURN_VALUE_KEY, resultValue) | ||
} | ||
} | ||
} | ||
} | ||
}, { | ||
expressions: true, | ||
statements: false, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe |
||
roots: false, | ||
rootNameFilter: ".*main" | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ | |
import org.enso.logging.config.LoggerSetup; | ||
import org.graalvm.polyglot.Context; | ||
import org.graalvm.polyglot.HostAccess; | ||
import org.graalvm.polyglot.io.IOAccess; | ||
import org.graalvm.polyglot.io.MessageTransport; | ||
import org.slf4j.event.Level; | ||
|
||
|
@@ -165,6 +166,7 @@ public Context build() { | |
Context.newBuilder() | ||
.allowExperimentalOptions(true) | ||
.allowAllAccess(true) | ||
.allowIO(IOAccess.ALL) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this good for? I don't think our JavaScript is performing any I/O by itself! The JavaScript code calls into the |
||
.allowHostAccess(allWithTypeMapping()) | ||
.option(RuntimeOptions.STRICT_ERRORS, Boolean.toString(strictErrors)) | ||
.option(RuntimeOptions.DISABLE_LINTING, Boolean.toString(disableLinting)) | ||
|
@@ -252,7 +254,7 @@ public Context build() { | |
} | ||
|
||
private static HostAccess allWithTypeMapping() { | ||
return HostAccess.newBuilder() | ||
return HostAccess.newBuilder(HostAccess.EXPLICIT) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Starting with |
||
.allowPublicAccess(true) | ||
.allowAllImplementations(true) | ||
.allowAllClassImplementations(true) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -316,6 +316,11 @@ class MainModule(serverConfig: LanguageServerConfig, logLevel: Level) { | |
RuntimeOptions.JOB_PARALLELISM, | ||
Runtime.getRuntime.availableProcessors().toString | ||
) | ||
if (System.getProperty("enso.dev.inspectPort") != null) { | ||
val inspectPort = Integer.getInteger("enso.dev.inspectPort", 34567); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is necessary. Just use regular
but yeah, I am not sure if it works in "language server" mode. I'd rather got it working then designing new |
||
extraOptions.put("inspect", s":$inspectPort") | ||
stdErr.attach(arr => System.out.write(arr)) | ||
} | ||
|
||
val builder = ContextFactory | ||
.create() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Whenever we get an
insight.on('return', ...)
event, we look appropriateasts
and update them. I am not sure how fast this is, but it certainly seems good enough for demonstration purposes.