Skip to content

Commit 9fc353f

Browse files
Support rescript.json (#828)
1 parent 19562b2 commit 9fc353f

File tree

10 files changed

+97
-53
lines changed

10 files changed

+97
-53
lines changed

README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ The only 2 themes we don't (and can't) support, due to their lack of coloring, a
5050
5151
## 💡 Features
5252

53-
- Supports `.res`, `.resi` and `bsconfig.json`.
53+
- Supports `.res`, `.resi`, `rescript.json` and the legacy config file `bsconfig.json`.
5454
- Syntax highlighting.
5555
- Formatting.
5656
- Build diagnostics.
@@ -100,8 +100,8 @@ You'll find all ReScript specific settings under the scope `rescript.settings`.
100100
| Setting | Description |
101101
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
102102
| Prompt to Start Build | If there's no ReScript build running already in the opened project, the extension will prompt you and ask if you want to start a build automatically. You can turn off this automatic prompt via the setting `rescript.settings.askToStartBuild`. |
103-
| ReScript Binary Path | The extension will look for the existence of a `node_modules/.bin/rescript` file and use its directory as the `binaryPath`. If it does not find it at the project root (which is where the nearest `bsconfig.json` resides), it goes up folders in the filesystem recursively until it either finds it (often the case in monorepos) or hits the top level. To override this lookup process, the path can be configured explicitly using the setting `rescript.settings.binaryPath` |
104-
| ReScript Platform Path | The extension will look for the existence of a `node_modules/rescript` directory and use the subdirectory corresponding to the current platform as the `platformPath`. If it does not find it at the project root (which is where the nearest `bsconfig.json` resides), it goes up folders in the filesystem recursively until it either finds it (often the case in monorepos) or hits the top level. To override this lookup process, the path can be configured explicitly using the setting `rescript.settings.platformPath` |
103+
| ReScript Binary Path | The extension will look for the existence of a `node_modules/.bin/rescript` file and use its directory as the `binaryPath`. If it does not find it at the project root (which is where the nearest `rescript.json` resides), it goes up folders in the filesystem recursively until it either finds it (often the case in monorepos) or hits the top level. To override this lookup process, the path can be configured explicitly using the setting `rescript.settings.binaryPath` |
104+
| ReScript Platform Path | The extension will look for the existence of a `node_modules/rescript` directory and use the subdirectory corresponding to the current platform as the `platformPath`. If it does not find it at the project root (which is where the nearest `rescript.json` resides), it goes up folders in the filesystem recursively until it either finds it (often the case in monorepos) or hits the top level. To override this lookup process, the path can be configured explicitly using the setting `rescript.settings.platformPath` |
105105
| Inlay Hints (experimental) | This allows an editor to place annotations inline with text to display type hints. Enable using `rescript.settings.inlayHints.enable: true` |
106106
| 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` |
107107
| Signature Help | This tells the editor to show signature help when you're writing function calls. Enable using `rescript.settings.signatureHelp.enabled: true` |
@@ -140,7 +140,7 @@ The Code Analyzer is a mode in the extension that runs additional code analysis
140140
141141
### Configuring the Code Analyzer
142142

143-
You'll need to configure what code analysis you want to run, and what (if any) directories you want to ignore. Configuration is done via adding `reanalyze` in `bsconfig.json`. You'll get autocomplete for what configuration options are valid. You can also read [all about configuring `reanalyze` here](https://github.com/rescript-association/reanalyze#configuration-via-bsconfigjson).
143+
You'll need to configure what code analysis you want to run, and what (if any) directories you want to ignore. Configuration is done via adding `reanalyze` in `rescript.json`. You'll get autocomplete for what configuration options are valid. You can also read [all about configuring `reanalyze` here](https://github.com/rescript-association/reanalyze#configuration-via-bsconfigjson).
144144

145145
### Usage
146146

analysis/reanalyze/src/Paths.ml

+17-7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ open Common
22
module StringMap = Map_string
33

44
let bsconfig = "bsconfig.json"
5+
let rescriptJson = "rescript.json"
56

67
let readFile filename =
78
try
@@ -13,13 +14,14 @@ let readFile filename =
1314
with _ -> None
1415

1516
let rec findProjectRoot ~dir =
17+
let rescriptJsonFile = Filename.concat dir rescriptJson in
1618
let bsconfigFile = Filename.concat dir bsconfig in
17-
if Sys.file_exists bsconfigFile then dir
19+
if Sys.file_exists rescriptJsonFile || Sys.file_exists bsconfigFile then dir
1820
else
1921
let parent = dir |> Filename.dirname in
2022
if parent = dir then (
2123
prerr_endline
22-
("Error: cannot find project root containing " ^ bsconfig ^ ".");
24+
("Error: cannot find project root containing " ^ rescriptJson ^ ".");
2325
assert false)
2426
else findProjectRoot ~dir:parent
2527

@@ -79,13 +81,13 @@ module Config = struct
7981
| Some False -> RunConfig.transitive false
8082
| _ -> ()
8183

82-
(* Read the config from bsconfig.json and apply it to runConfig and suppress and unsuppress *)
84+
(* Read the config from rescript.json/bsconfig.json and apply it to runConfig and suppress and unsuppress *)
8385
let processBsconfig () =
8486
Lazy.force setReScriptProjectRoot;
87+
let rescriptFile = Filename.concat runConfig.projectRoot rescriptJson in
8588
let bsconfigFile = Filename.concat runConfig.projectRoot bsconfig in
86-
match readFile bsconfigFile with
87-
| None -> ()
88-
| Some text -> (
89+
90+
let processText text =
8991
match Json.parse text with
9092
| None -> ()
9193
| Some json -> (
@@ -97,7 +99,15 @@ module Config = struct
9799
readTransitive conf
98100
| None ->
99101
(* if no "analysis" specified, default to dce *)
100-
RunConfig.dce ()))
102+
RunConfig.dce ())
103+
in
104+
105+
match readFile rescriptFile with
106+
| Some text -> processText text
107+
| None -> (
108+
match readFile bsconfigFile with
109+
| Some text -> processText text
110+
| None -> ())
101111
end
102112

103113
(**

analysis/reanalyze/src/Reanalyze.ml

+3-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,9 @@ let cli () =
139139
"root_path Run all the analyses for all the .cmt files under the root \
140140
path" );
141141
("-ci", Unit (fun () -> Cli.ci := true), "Internal flag for use in CI");
142-
("-config", Unit setConfig, "Read the analysis mode from bsconfig.json");
142+
( "-config",
143+
Unit setConfig,
144+
"Read the analysis mode from rescript.json/bsconfig.json" );
143145
("-dce", Unit (fun () -> setDCE None), "Eperimental DCE");
144146
("-debug", Unit (fun () -> Cli.debug := true), "Print debug information");
145147
( "-dce-cmt",

analysis/src/FindFiles.ml

+14-5
Original file line numberDiff line numberDiff line change
@@ -233,9 +233,10 @@ let findDependencyFiles base config =
233233
Json.bind
234234
(ModuleResolution.resolveNodeModulePath ~startPath:base name)
235235
(fun path ->
236-
let innerPath = path /+ "bsconfig.json" in
237-
match Files.readFile innerPath with
238-
| Some text -> (
236+
let rescriptJsonPath = path /+ "rescript.json" in
237+
let bsconfigJsonPath = path /+ "bsconfig.json" in
238+
239+
let parseText text =
239240
match Json.parse text with
240241
| Some inner -> (
241242
let namespace = getNamespace inner in
@@ -259,9 +260,17 @@ let findDependencyFiles base config =
259260
~path ~sourceDirectories ~libBs
260261
in
261262
Some (compiledDirectories, projectFiles))
262-
| None -> None)
263-
| None -> None)
263+
| None -> None
264+
in
265+
266+
match Files.readFile rescriptJsonPath with
267+
| Some text -> parseText text
268+
| None -> (
269+
match Files.readFile bsconfigJsonPath with
270+
| Some text -> parseText text
271+
| None -> None))
264272
in
273+
265274
match result with
266275
| Some (files, directories) -> (files, directories)
267276
| None ->

analysis/src/Packages.ml

+21-10
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,10 @@ let makePathsForModule ~projectFilesAndPaths ~dependenciesFilesAndPaths =
1212
pathsForModule
1313

1414
let newBsPackage ~rootPath =
15-
let bsconfig = Filename.concat rootPath "bsconfig.json" in
16-
match Files.readFile bsconfig with
17-
| None ->
18-
Log.log ("Unable to read " ^ bsconfig);
19-
None
20-
| Some raw -> (
15+
let rescriptJson = Filename.concat rootPath "rescript.json" in
16+
let bsconfigJson = Filename.concat rootPath "bsconfig.json" in
17+
18+
let parseRaw raw =
2119
let libBs = BuildSystem.getLibBs rootPath in
2220
match Json.parse raw with
2321
| Some config -> (
@@ -92,7 +90,7 @@ let newBsPackage ~rootPath =
9290
|> List.map (fun path -> path @ ["place holder"])
9391
in
9492
Log.log
95-
("Opens from bsconfig: "
93+
("Opens from ReScript config file: "
9694
^ (opens |> List.map pathToString |> String.concat " "));
9795
{
9896
rootPath;
@@ -156,15 +154,28 @@ let newBsPackage ~rootPath =
156154
});
157155
uncurried;
158156
})))
159-
| None -> None)
157+
| None -> None
158+
in
159+
160+
match Files.readFile rescriptJson with
161+
| Some raw -> parseRaw raw
162+
| None -> (
163+
Log.log ("Unable to read " ^ rescriptJson);
164+
match Files.readFile bsconfigJson with
165+
| Some raw -> parseRaw raw
166+
| None ->
167+
Log.log ("Unable to read " ^ bsconfigJson);
168+
None)
160169

161170
let findRoot ~uri packagesByRoot =
162171
let path = Uri.toPath uri in
163172
let rec loop path =
164173
if path = "/" then None
165174
else if Hashtbl.mem packagesByRoot path then Some (`Root path)
166-
else if Files.exists (Filename.concat path "bsconfig.json") then
167-
Some (`Bs path)
175+
else if
176+
Files.exists (Filename.concat path "rescript.json")
177+
|| Files.exists (Filename.concat path "bsconfig.json")
178+
then Some (`Bs path)
168179
else
169180
let parent = Filename.dirname path in
170181
if parent = path then (* reached root *) None else loop parent

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
],
4141
"jsonValidation": [
4242
{
43-
"fileMatch": "bsconfig.json",
43+
"fileMatch": ["bsconfig.json", "rescript.json"],
4444
"url": "https://raw.githubusercontent.com/rescript-lang/rescript-compiler/master/docs/docson/build-schema.json"
4545
}
4646
],

server/src/constants.ts

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export let rescriptNodePartialPath = path.join(
4242

4343
export let bsbLock = ".bsb.lock";
4444
export let bsconfigPartialPath = "bsconfig.json";
45+
export let rescriptJsonPartialPath = "rescript.json";
4546
export let compilerDirPartialPath = path.join("lib", "bs");
4647
export let compilerLogPartialPath = path.join("lib", "bs", ".compiler.log");
4748
export let resExt = ".res";

server/src/lookup.ts

+21-12
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,17 @@ export const findFilePathFromProjectRoot = (
4646
return findFilePathFromProjectRoot(parentDir, filePartialPath);
4747
};
4848

49-
export const readBsConfig = (projDir: p.DocumentUri): BuildSchema | null => {
49+
export const readConfig = (projDir: p.DocumentUri): BuildSchema | null => {
5050
try {
51-
let bsconfigFile = fs.readFileSync(
52-
path.join(projDir, c.bsconfigPartialPath),
51+
let rescriptJson = path.join(projDir, c.rescriptJsonPartialPath);
52+
let bsconfigJson = path.join(projDir, c.bsconfigPartialPath);
53+
54+
let configFile = fs.readFileSync(
55+
fs.existsSync(rescriptJson) ? rescriptJson : bsconfigJson,
5356
{ encoding: "utf-8" }
5457
);
5558

56-
let result: BuildSchema = JSON.parse(bsconfigFile);
59+
let result: BuildSchema = JSON.parse(configFile);
5760
return result;
5861
} catch (e) {
5962
return null;
@@ -108,7 +111,7 @@ export const getFilenameFromBsconfig = (
108111
projDir: string,
109112
partialFilePath: string
110113
): string | null => {
111-
let bsconfig = readBsConfig(projDir);
114+
let bsconfig = readConfig(projDir);
112115

113116
if (!bsconfig) {
114117
return null;
@@ -126,23 +129,29 @@ export const getFilenameFromRootBsconfig = (
126129
projDir: string,
127130
partialFilePath: string
128131
): string | null => {
129-
let rootBsConfigPath = findFilePathFromProjectRoot(
132+
let rootConfigPath = findFilePathFromProjectRoot(
130133
path.join("..", projDir),
131-
c.bsconfigPartialPath
134+
c.rescriptJsonPartialPath
132135
);
133136

134-
if (!rootBsConfigPath) {
137+
if (!rootConfigPath) {
138+
rootConfigPath = findFilePathFromProjectRoot(
139+
path.join("..", projDir),
140+
c.bsconfigPartialPath
141+
);
142+
}
143+
144+
if (!rootConfigPath) {
135145
return null;
136146
}
137147

138-
let rootBsconfig = readBsConfig(path.dirname(rootBsConfigPath));
148+
let rootConfig = readConfig(path.dirname(rootConfigPath));
139149

140-
if (!rootBsconfig) {
150+
if (!rootConfig) {
141151
return null;
142152
}
143153

144-
let [suffix, pathFragment] =
145-
getSuffixAndPathFragmentFromBsconfig(rootBsconfig);
154+
let [suffix, pathFragment] = getSuffixAndPathFragmentFromBsconfig(rootConfig);
146155

147156
let compiledPartialPath = replaceFileExtension(partialFilePath, suffix);
148157

server/src/server.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@ let openCompiledFileRequest = new v.RequestType<
152152
void
153153
>("textDocument/openCompiled");
154154

155-
156155
let getCurrentCompilerDiagnosticsForFile = (
157156
fileUri: string
158157
): p.Diagnostic[] => {
@@ -896,12 +895,12 @@ function createInterface(msg: p.RequestMessage): p.Message {
896895
let resPartialPath = filePath.split(projDir)[1];
897896

898897
// The .cmi filename may have a namespace suffix appended.
899-
let namespaceResult = utils.getNamespaceNameFromBsConfig(projDir);
898+
let namespaceResult = utils.getNamespaceNameFromConfigFile(projDir);
900899

901900
if (namespaceResult.kind === "error") {
902901
let params: p.ShowMessageParams = {
903902
type: p.MessageType.Error,
904-
message: `Error reading bsconfig file.`,
903+
message: `Error reading ReScript config file.`,
905904
};
906905

907906
let response: p.NotificationMessage = {

server/src/utils.ts

+13-10
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ export let findProjectRootOfFile = (
2828
source: p.DocumentUri
2929
): null | p.DocumentUri => {
3030
let dir = path.dirname(source);
31-
if (fs.existsSync(path.join(dir, c.bsconfigPartialPath))) {
31+
if (
32+
fs.existsSync(path.join(dir, c.rescriptJsonPartialPath)) ||
33+
fs.existsSync(path.join(dir, c.bsconfigPartialPath))
34+
) {
3235
return dir;
3336
} else {
3437
if (dir === source) {
@@ -192,23 +195,23 @@ export const toCamelCase = (text: string): string => {
192195
.replace(/(\s|-)+/g, "");
193196
};
194197

195-
export const getNamespaceNameFromBsConfig = (
198+
export const getNamespaceNameFromConfigFile = (
196199
projDir: p.DocumentUri
197200
): execResult => {
198-
let bsconfig = lookup.readBsConfig(projDir);
201+
let config = lookup.readConfig(projDir);
199202
let result = "";
200203

201-
if (!bsconfig) {
204+
if (!config) {
202205
return {
203206
kind: "error",
204-
error: "Could not read bsconfig",
207+
error: "Could not read ReScript config file",
205208
};
206209
}
207210

208-
if (bsconfig.namespace === true) {
209-
result = toCamelCase(bsconfig.name);
210-
} else if (typeof bsconfig.namespace === "string") {
211-
result = toCamelCase(bsconfig.namespace);
211+
if (config.namespace === true) {
212+
result = toCamelCase(config.name);
213+
} else if (typeof config.namespace === "string") {
214+
result = toCamelCase(config.namespace);
212215
}
213216

214217
return {
@@ -223,7 +226,7 @@ export let getCompiledFilePath = (
223226
): execResult => {
224227
let error: execResult = {
225228
kind: "error",
226-
error: "Could not read bsconfig",
229+
error: "Could not read ReScript config file",
227230
};
228231
let partialFilePath = filePath.split(projDir)[1];
229232
let compiledPath = lookup.getFilenameFromBsconfig(projDir, partialFilePath);

0 commit comments

Comments
 (0)