microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
163.62k stars 29.03k forks source link

[json] Relative path wrongly resolved #112376

Open DaanV2 opened 3 years ago

DaanV2 commented 3 years ago

Does this issue occur when all extensions are disabled?: Yes

Vscode is resolving $ref, filepaths incorrectly. I have set up in the reproduce a couple of steps you can follow.

Steps to Reproduce:

  1. Clone https://github.com/DaanV2/Minecraft-bedrock-json-schemas
  2. Observe the error thrown by data\data 1.8.0.json
  3. Observe the error thrown by data\data 1.8.5.json
  4. Observe the no errors by data\data 1.8.6.json

errors returned image

For the error in data 1.8.0.json: In behaviour/entities/1.8.0/filters/clock_time.json is the ref should be pointing to the base_subject.json image

However, it ends up a folder too high. So I thought they might use a different home folder to resolve the path on.

So I made version 1.8.5 which instead this reference:

"$ref": "./types/base_subject.json",

I used this references:

"$ref": "./filters/types/base_subject.json",

But this now returns the following: .../1.8.5/filters/filters/types/base_subject.json'. Which is a folder too deep.

After this, I copied the files in question and made version 1.8.6, which now has no errors. As the files are where vscode expected them, but not where they actually should be.

DaanV2 commented 3 years ago

Little more information after some tinkering.

I found out that what is probably is going wrong is checking if the file exists but still returning the right relative path.

In version 1.8.6 I updated the titles of the references JSON to include the word RIGHT or WRONG to see which of the 2 it would take. image

So it seems vscode is checking the wrong location if the file exists.

If you need any help btw, I have no idea where to start looking, but if you have any Idea I would be happy to dive deeper 😄

aeschli commented 3 years ago

I can reproduce with your example project. I first thought it's a regression from https://github.com/microsoft/vscode-json-languageservice/commit/c91518682ba7545dd2160eb9f932b0f94662a02b but it seems we had that issue before. Likely so bug resolving relative references too late.

I'm afraid I currently don't have the time to look into this. If you want to dig deeper, the JSON schema code is in https://github.com/microsoft/vscode-json-languageservice.

https://github.com/microsoft/vscode-json-languageservice/blob/master/src/services/jsonSchemaService.ts#L455 is is where resolving happens.

DaanV2 commented 3 years ago

So I managed to delve deeper and found out the specific issue, but It seems that the schema resolver is going to need a rework to solve this one. I tried solving it but only causing other issues like circular refs to pop back up.

The specific issue: jsonSchemaService.ts

merge(node, unresolvedSchema.schema, uri, refSegment);
return resolveRefs(node, unresolvedSchema.schema, uri, referencedHandle.dependenci

So in short, what is happening: the unresolved schema gets merged with the master version. Then a promise is launched. But because promises don't start immediately, all the extra added $refs are processed and seen as part of the root schema. and thus the relative paths are resolved from there. Then afterward the promise fires and solves what it is given. So there is a weird double solving going on, but quite some other mechanics are dependent on this.

Also just a note, it causes issues if you try to correct it, but the merge in this example fills in the parent as the node to resolve and the child as the parent node.