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

Changes for supporting resource level operations #295

Closed
wants to merge 1 commit into from

Conversation

gorkem
Copy link

@gorkem gorkem commented Dec 22, 2017

LSP proposal that adds resourceChanges to WorkspaceEditor to allow manipulation of files and folders. This pull request only includes the proposed changes. It is not possible to implement these changes for vscode due to lack of APIs. This PR addresses microsoft/language-server-protocol#272

@gorkem gorkem changed the title Changes for supporting resource level changes Changes for supporting resource level operations Dec 22, 2017
@dbaeumer
Copy link
Member

Thanks a lot for the proposal. When creating a new file shouldn't we provide an option for the content. I would ensure that we can create a file with a predefined content. Since stuff is async we couldn't otherwise.

And do we need to change something for the response to provide better error information. For example a file couldn't be created?

_resourceChanges_

A workspace edit can optionally provide resource changes. If present resource changes are applied before the `changes/documentChanges` has been applied
allowing the `change/documentChanges` to work on affected files. The changes are applied in the order that they are supplied.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes/documentChanges confused me as it made it seem like a notification or a request (like a textDocument/didOpen). Perhaps it might be better to spell it out specifically with "changes or documentChanges" instead?

export interface ResourceChange{

/**
* The resource change operation type
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Period at the end?

* The resource.
*
* If change type is CREATE a new file is created on the uri.
* This operation will not overwrite any existing resources and will fail.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs to be cleared up to state that the operation will fail if the path conflicts with an existing resource.

* This operation will not overwrite any existing resources and will fail.
*
* If change type is DELETE the resource is deleted if it exists. If the
* uri is a folder this operation deletes all its children.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it considered a success or a failure if you try to delete a file or folder that does not exist?

* The new uri for the resource pointed by path.
* Required only if change type is MOVE. Must be compatible with the path
* uri ie. must be a file uri if path is a file uri.
*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary extra space.

export interface ResourceChange{

/**
* The resource change operation type
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

* The resource.
*
* If change type is CREATE a new file is created on the uri.
* This operation will not overwrite any existing resources on this uri.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

* This operation will not overwrite any existing resources on this uri.
*
* If change type is DELETE the resource is deleted if it exists. If the
* uri is a folder this operation deletes all its children.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

* The new uri for the resource pointed by path.
* Required only if change type is MOVE. Must be compatible with the path
* uri ie. must be a file uri if path is a file uri.
*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

workspace: {
workspaceEdit?: {
/**
* The client supports resource changes in `WorkspaceEdit`s
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a period at the end.


_Client Capabilities_:

The client sets the following capability if it is supporting resource Changes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a particular reason as to why "Changes" is capitalized?

/**
* A resource change type
*/
export declare namespace ResourceChangeType{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

* ------------------------------------------------------------------------------------------ */
'use strict'

export interface ResourceChange{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

/**
* A resource change type
*/
export declare namespace ResourceChangeType{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should add a space after ResourceChangeType to be consistent with the other files.

Changes to a folder or file on the workspace.

```ts
export interface ResourceChange{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should add a space after ResourceChange to be consistent with the other files.

```ts
interface WorkspaceEdit{

resourceChanges?: ResourceChange[]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we talk about changes and documentChanges in a WorkspaceEdit, would it be better to also list those properties again here? I'm not sure what would be best since we're extending the interface here (by adding optional properties) without actually creating a new interface. Thoughts, @dbaeumer?

allowing the `change/documentChanges` to work on affected files. The changes are applied in the order that they are supplied.

```ts
interface WorkspaceEdit{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should add a space after WorkspaceEdit to be consistent with the other files.

@gorkem
Copy link
Author

gorkem commented Dec 22, 2017

@dbaeumer I thought the initial content could be provided via changes or documentChanges filed on WorkspaceEdit. resourceChanges are defined to run before TextEdits are applied. Do you think this would not be enough?

@gorkem gorkem force-pushed the resourceChanges branch 2 times, most recently from d8bc061 to 9f6df8f Compare December 22, 2017 22:51
@gorkem
Copy link
Author

gorkem commented Dec 22, 2017

Thanks @rcjsuen very helpful review. I think I have addressed most of them.

@gorkem
Copy link
Author

gorkem commented Dec 22, 2017

@dbaeumer On error information with the response: I think we need to address that on workspace/applyEdit and textDocument/rename which are the users of WorkspaceEdit.

@gorkem
Copy link
Author

gorkem commented Jan 28, 2018

Updated the proposed ResourceChanges so that it no longer requires additional enumeration. vscode's corresponding implementation gives a chance to define an (almost) ordered execution of the text and resource changes but I could not see a way to define it on WorkspaceEdit without breaking or completely defining a new field.

@dbaeumer
Copy link
Member

dbaeumer commented Feb 1, 2018

@gorkem @rcjsuen thanks again for providing this. Please note that VS Code 1.20 will not ship with a resource change API due to problems we discovered with the API during the test pass (see the corresponding vscode issue).

We discussed in detail the order issue and it is our belief that we need one array describing all changes to make the behavior correct.

For the LSP I would do the following: if resource changes are supported the workspace edit result has a property resourceChanges which are either a rename, move, delete or content change.

@gorkem
Copy link
Author

gorkem commented Feb 12, 2018

@dbaeumer did a small change to allow ordered resourceChanges, please take a look if it looks OK, I want to proceed with the implementation.

@spoenemann
Copy link

The type

interface  WorkspaceEdit {
    resourceChanges?: (ResourceChange | TextDocumentEdit)[];
}

is hard to realize in Java because both ResourceChange and TextDocumentEdit are objects, so the only way to create the correct class instance is to look ahead in the JSON token stream, which means we cannot use the default stream parsing approach of the Gson library. See eclipse-lsp4j/lsp4j#173.

I'd propose to split this:

interface  WorkspaceEdit {
    resourceChanges?: ResourceChange[];
    textEdits?: TextDocumentEdit[];
}

@dbaeumer
Copy link
Member

dbaeumer commented Apr 3, 2018

@gorkem regarding: #295 (comment). I think that is not a good idea (e.g. assuming that resource changes are applied before text edits). This would mean it is harder to express to modify the content of a file and then move. The statement should be that at the edits should be one array (but we need to address @spoenemann concern) and that they are executed in order in which they are provided.

@gorkem
Copy link
Author

gorkem commented Apr 12, 2018

@dbaeumer I am not sure if there is a great benefit of having a single ordered list of resource changes and text edits. A WorkspaceEdit is essentially a single unit and it should be fully applied or failed. I think the proposed two arrays is equivalent to having a single array.
What is the use case that you have in mind that requires a single ordered list?

@dbaeumer
Copy link
Member

The case is you create a file and then afterwards want to edit its content.

@gorkem
Copy link
Author

gorkem commented Apr 27, 2018

The original proposal was to execute the resource changes before TextEdits which covers the create file case. The only case I see is modify contents and delete case which would become delete and modify in which case the implementations should drop the TextEdits

@dbaeumer
Copy link
Member

Agree that this would work as well. But why making it more complicated to explain to end users. Having one array which is executed from 0..n is pretty simple to explain. I agree it needs more work on the implementation side.

@spoenemann
Copy link

An alternative solution for the Java problem would be to let ResourceChange extend Partial< TextDocumentEdit> so the WorkspaceEdit can be written as

interface  WorkspaceEdit {
    resourceChanges?: ResourceChange[];
}

@spoenemann
Copy link

...or simply redeclare the properties of TextDocumentEdit as optional in ResourceChange.

Add resourceChanges to WorkspaceEditor to allow manipulation
of files and folders.
@gorkem gorkem force-pushed the resourceChanges branch from e790be9 to 744dcd0 Compare May 1, 2018 20:21
@gorkem
Copy link
Author

gorkem commented May 1, 2018

Let's give this another try; uploaded a new change. Now ResourceChange includesTextDocumentEdit functionality. It now supports ordering and allows initial content for create operations.

@dbaeumer
Copy link
Member

dbaeumer commented May 8, 2018

I see the problem with mapping JSON to Java however the current proposal requires IMO a lot of documentation since it is not obvious what it does. Problems I see:

  • the textDocument property for a resource level operation (e.g. create, move, delete) doesn't need to be a VersionedDocumentIdentifier. It might make sense for move or delete but i might be hard to servers to construct this we we create a file, then change it and then move it.
  • it gives the impression that only text documents could be move, created or deleted

Would a type attribute on the resource chnage help the Java library to implement the right switch early instead if having to check properties ?

@spoenemann
Copy link

Would a type attribute on the resource chnage help the Java library to implement the right switch early instead if having to check properties ?

But then we would still need to parse the type attribute before we can decide which class instance to create?

To be clear: parsing based on attributes / properties is possible also in Java / LSP4J, it just increases the effort for implementing such a parser and is slower at runtime. If the best solution in terms of LSP data structure design requires this, we'll manage to implement it, but it would be good to avoid it if there are acceptable alternatives for the data structure design.

@dbaeumer
Copy link
Member

dbaeumer commented May 9, 2018

@spoenemann thanks for the clarification.

@gorkem
Copy link
Author

gorkem commented Jun 26, 2018

Since this has stalled a bit because I got new responsibilities, @tsmaeder will be taking over this PR, so stay tuned

@spoenemann
Copy link

@dbaeumer @gorkem @tsmaeder I found a solution for parsing object type alternatives in eclipse-lsp4j/lsp4j#230 that is acceptable in terms of additional required code for each such case. From the perspective of LSP4J, we can leave the original declaration

interface  WorkspaceEdit {
    resourceChanges?: (ResourceChange | TextDocumentEdit)[];
}

as it is, since we can now parse it correctly.

@dbaeumer
Copy link
Member

@spoenemann thanks

@dbaeumer
Copy link
Member

Closing PR. Resource edit support is available in latest next releases.

@dbaeumer dbaeumer closed this Aug 28, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants