Skip to content
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

Initial SendLogNotification #1066

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ You'll find all ReScript specific settings under the scope `rescript.settings`.
| Inlay Hints (experimental) | This allows an editor to place annotations inline with text to display type hints. Enable using `rescript.settings.inlayHints.enable: true` |
| Code Lens (experimental) | This tells the editor to add code lenses to function definitions, showing its full type above the definition. Enable using `rescript.settings.codeLens: true` |
| Signature Help | This tells the editor to show signature help when you're writing function calls. Enable using `rescript.settings.signatureHelp.enabled: true` |
| Log level | This tells the editor which log messages to show in the Output window. The options are `"error"`, `"warning"`, `"info"`, `"log"` with default `"info"`. Set via `"rescript.settings.logLevel"`. |

**Default settings:**

Expand All @@ -126,6 +127,9 @@ You'll find all ReScript specific settings under the scope `rescript.settings`.

// Enable (experimental) code lens for function definitions.
"rescript.settings.codeLens": true

// Set log level ("error", "warning", "info", "log").
"rescript.settings.logLevel": "info"
```

## 🚀 Code Analyzer
Expand Down
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,12 @@
],
"default": null,
"description": "Path to the directory where platform-specific ReScript binaries are. You can use it if you haven't or don't want to use the installed ReScript from node_modules in your project."
},
"rescript.settings.logLevel": {
"type": "string",
"enum": ["error", "warning", "info", "log"],
"default": "info",
"description": "Controls the log level of the language server. Logs below this level will be filtered out."
}
}
},
Expand Down
2 changes: 2 additions & 0 deletions server/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export interface extensionConfiguration {
enable?: boolean;
};
};
logLevel: "error" | "warning" | "info" | "log"
}

// All values here are temporary, and will be overridden as the server is
Expand Down Expand Up @@ -55,6 +56,7 @@ let config: { extensionConfiguration: extensionConfiguration } = {
enable: true,
},
},
logLevel: "info"
},
};

Expand Down
69 changes: 54 additions & 15 deletions server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,38 @@ import * as ic from "./incrementalCompilation";
import config, { extensionConfiguration } from "./config";
import { projectsFiles } from "./projectFiles";

const notificationLevelMap = new Map([
["error", p.MessageType.Error],
["warning", p.MessageType.Warning],
["info", p.MessageType.Info],
["log", p.MessageType.Log]
])

/**
* Sends an LSP log notification that will appear in the ReScript Language Server Output window in VSCode.
* Other LSP clients will also receive this notification,
* as we utilize LanguageClient in the VSCode extension, providing this functionality at no extra cost.
*/
function sendLogNotification(level: p.MessageType, message: string) {
const currentLogLevel = notificationLevelMap.get(config.extensionConfiguration.logLevel) || p.MessageType.Info;

if (currentLogLevel >= level) {
const logMessageParams: p.LogMessageParams = {
type: level,
message
}
const notificationMessage: p.NotificationMessage = {
method: "window/logMessage",
jsonrpc: c.jsonrpcVersion,
params: logMessageParams
}

if (send) {
send(notificationMessage);
}
}
}

// This holds client capabilities specific to our extension, and not necessarily
// related to the LS protocol. It's for enabling/disabling features that might
// work in one client, like VSCode, but perhaps not in others, like vim.
Expand Down Expand Up @@ -55,18 +87,18 @@ let stupidFileContentCache: Map<string, string> = new Map();
let codeActionsFromDiagnostics: codeActions.filesCodeActions = {};

// will be properly defined later depending on the mode (stdio/node-rpc)
let send: (msg: p.Message) => void = (_) => {};
let send: (msg: p.Message) => void = (_) => { };

let findRescriptBinary = (projectRootPath: p.DocumentUri | null) =>
config.extensionConfiguration.binaryPath == null
? lookup.findFilePathFromProjectRoot(
projectRootPath,
path.join(c.nodeModulesBinDir, c.rescriptBinName)
)
projectRootPath,
path.join(c.nodeModulesBinDir, c.rescriptBinName)
)
: utils.findBinary(
config.extensionConfiguration.binaryPath,
c.rescriptBinName
);
config.extensionConfiguration.binaryPath,
c.rescriptBinName
);

let createInterfaceRequest = new v.RequestType<
p.TextDocumentIdentifier,
Expand Down Expand Up @@ -333,9 +365,9 @@ let openedFile = (fileUri: string, fileContent: string) => {
message:
config.extensionConfiguration.binaryPath == null
? `Can't find ReScript binary in ${path.join(
projectRootPath,
c.nodeModulesBinDir
)} or parent directories. Did you install it? It's required to use "rescript" > 9.1`
projectRootPath,
c.nodeModulesBinDir
)} or parent directories. Did you install it? It's required to use "rescript" > 9.1`
: `Can't find ReScript binary in the directory ${config.extensionConfiguration.binaryPath}`,
},
};
Expand Down Expand Up @@ -419,6 +451,7 @@ export default function listen(useStdio = false) {
send = (msg: p.Message) => process.send!(msg);
process.on("message", onMessage);
}
utils.setSendLogNotification(sendLogNotification);
}

function hover(msg: p.RequestMessage) {
Expand Down Expand Up @@ -1183,15 +1216,15 @@ function onMessage(msg: p.Message) {
inlayHintProvider: config.extensionConfiguration.inlayHints?.enable,
codeLensProvider: config.extensionConfiguration.codeLens
? {
workDoneProgress: false,
}
workDoneProgress: false,
}
: undefined,
signatureHelpProvider: config.extensionConfiguration.signatureHelp
?.enabled
? {
triggerCharacters: ["("],
retriggerCharacters: ["=", ","],
}
triggerCharacters: ["("],
retriggerCharacters: ["=", ","],
}
: undefined,
},
};
Expand All @@ -1202,6 +1235,12 @@ function onMessage(msg: p.Message) {
};
initialized = true;

let rescriptVersion = undefined;
if (initParams.workspaceFolders && initParams.workspaceFolders.length > 0) {
rescriptVersion = utils.findReScriptVersion(initParams.workspaceFolders[0].uri);
}
sendLogNotification(p.MessageType.Info, `LSP Server started! Rescript Version ${rescriptVersion}`);

// Periodically pull configuration from the client.
pullConfigurationPeriodically = setInterval(() => {
askForAllCurrentConfiguration();
Expand Down
28 changes: 19 additions & 9 deletions server/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ import { reportError } from "./errorReporter";
import config from "./config";
import { filesDiagnostics, projectsFiles } from "./projectFiles";

// This is a bit dirty but avoids passing down this function each time.
export type SendLogNotification = (level: p.MessageType, message: string) => void
let sendLogNotification: SendLogNotification = () => { };
export function setSendLogNotification(send: SendLogNotification) {
sendLogNotification = send;
}

let tempFilePrefix = "rescript_format_file_" + process.pid + "_";
let tempFileId = 0;

Expand Down Expand Up @@ -92,19 +99,19 @@ export let findBinary = (

type execResult =
| {
kind: "success";
result: string;
}
kind: "success";
result: string;
}
| {
kind: "error";
error: string;
};
kind: "error";
error: string;
};

type formatCodeResult =
| execResult
| {
kind: "blocked-using-built-in-formatter";
};
kind: "blocked-using-built-in-formatter";
};

export let formatCode = (
bscPath: p.DocumentUri | null,
Expand Down Expand Up @@ -265,6 +272,9 @@ export let runAnalysisAfterSanityCheck = (

let stdout = "";
try {
if(args.includes("completion")){
sendLogNotification(p.MessageType.Log, `Running completion: ${binaryPath} ${args.join(" ")}`);
}
stdout = childProcess.execFileSync(binaryPath, args, options).toString();
return JSON.parse(stdout);
} catch (e) {
Expand Down Expand Up @@ -693,7 +703,7 @@ export let parseCompilerLogOutput = (
diagnostic,
diagnosticMessage,
file,
range,
range
});

result[file].push(diagnostic);
Expand Down
Loading