Монако - завершение кода для обычных JS модулей без LSP - PullRequest
1 голос
/ 06 апреля 2020

Я интегрирую редактор Monaco в Eclipse Dirigible Web IDE.

Вот так встроен редактор: ide-monaco / editor. html

В Dirigible мы используем серверную сторону JavaScript, основан на Mozila Rhino, Nashorn, J2V8 или GraalVM (не NodeJS) в качестве целевого языка программирования.

Для достижения модульности мы загружаем модули через require(...moduleName..) в соответствии с общей спецификацией JS.

Вот пример такого модуля (API), который у нас есть:

Здесь Это пример использования этого API:

Теперь возвращаюсь к Монако topi c, я пытаюсь для достижения завершения кода для загруженных модулей, например:

var response = require("http/v4/response");
...

Я нашел пример того, как предоставить внешнюю библиотеку:

monaco.languages.typescript.javascriptDefaults.addExtraLib('var response = {println: /** Prints the text in the response */ function(text) {}}', 'js:response.js');

Дирижабль Монако Код Завершение с Extra Lib

Но как только var response объявлен, он затеняет варианты завершения кода:

Dirigible Monaco Shadowed Code Complet Опции Ion

Я обнаружил, что доступно несколько вариантов Monaco CompilerOptions :

  • source Root
  • module
  • moduleResolution
  • baseUrl
  • paths
  • rootDir
  • ...

, но я не смог получить завершение кода работы внешних модулей.

Есть ли способ установить своего рода "поставщика исходного кода" для редактора Monaco, поэтому, как только найден оператор require(...), он запускает загрузку этого модуля и в конце концов получится ли завершить работу кода? Нам удалось реализовать такой подход для Ориона и Терна. js: ide-orion / editorBuild / common js-упрощенный

1 Ответ

0 голосов
/ 10 апреля 2020

Ссылочная реализация на основе Желудь. js можно найти здесь:

  1. Интеграция на стороне сервера:

    • Сторона сервера модуль для извлечения модулей JavaScript в Системе и обеспечения завершения кода для каждого импортированного модуля: дирижабль / ide-monaco-extensions
    • Желудь. js модуль дирижабля: желудь / желудь js
    • Парсер предложений:

    exports.parse = function(moduleName) {
        var content = contentManager.getText(moduleName + ".js");
        var comments = [];
        var nodes = acorn.parse(content, {
            onComment: comments,
            ranges: true
        });
    
        var functionDeclarations = nodes.body
            .filter(e => e.type === "FunctionDeclaration")
            .map(function(element) {
                let name = element.id.name;
                let expression = element.expression
                let functions = element.body.body
                    .filter(e => e.type === "ExpressionStatement")
                    .map(e => extractExpression(e, comments))
                    .filter(e => e !== null);
                return {
                    name: name,
                    functions: functions
                }
            });
    
        var result = nodes.body
            .filter(e => e.type === "ExpressionStatement")
            .map(function(element) {
                return extractExpression(element, comments, functionDeclarations);
            }).filter(e => e !== null);
    
        return result;
    }
    
    function extractExpression(element, comments, functionDeclarations) {
        let expression = element.expression;
        if (expression && expression.type === "AssignmentExpression" && expression.operator === "=") {
            let left = expression.left;
            let right = expression.right;
            if (right.type === "FunctionExpression") {
                let properties = right.params.map(e => e.name);
                let name = left.property.name + "(" + properties.join(", ") + ")"; 
                let documentation = extractDocumentation(comments, element, name);
                documentation = formatDocumentation(documentation, name, true);
                let returnStatement = right.body.body.filter(e => e.type === "ReturnStatement")[0];
                let returnType = null;
                if (functionDeclarations && returnStatement && returnStatement.argument.type === "NewExpression") {
                    returnType = returnStatement.argument.callee.name;
                    returnType = functionDeclarations.filter(e => e.name === returnType)[0];
                }
                return {
                    name: name,
                    documentation: documentation,
                    returnType: returnType,
                    isFunction: true
                };
            } else if (right.type === "Literal") {
                let name = left.property.name;
                let documentation = extractDocumentation(comments, element, name);
                documentation = formatDocumentation(documentation, name, false);
                return {
                    name: name,
                    documentation: documentation,
                    isProperty: true
                };
            }
        }
        return null;
    }
    ...
    

    Полный файл можно найти здесь: ideasParser. js

  2. Интеграция на стороне клиента

...