-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1323 from TypeFox/language-server
Initial prototype of language server protocol extension for Che
- Loading branch information
Showing
86 changed files
with
2,931 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
plugins/plugin-languageserver/che-plugin-languageserver-ide/pom.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- Copyright (c) 2012-2016 TypeFox GmbH. All rights reserved. This program | ||
and the accompanying materials are made available under the terms of the | ||
Eclipse Public License v1.0 which accompanies this distribution, and is available | ||
at http://www.eclipse.org/legal/epl-v10.html Contributors: TypeFox GmbH - | ||
initial API and implementation --> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<artifactId>che-plugin-languageserver-parent</artifactId> | ||
<groupId>org.eclipse.che.plugin</groupId> | ||
<version>4.3.0-RC1-SNAPSHOT</version> | ||
<relativePath>..</relativePath> | ||
</parent> | ||
<artifactId>che-plugin-languageserver-ide</artifactId> | ||
<packaging>jar</packaging> | ||
<name>Che Plugin :: Language Server :: IDE</name> | ||
<dependencies> | ||
<dependency> | ||
<groupId>com.google.guava</groupId> | ||
<artifactId>guava</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.google.gwt.inject</groupId> | ||
<artifactId>gin</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.google.inject</groupId> | ||
<artifactId>guice</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>javax.inject</groupId> | ||
<artifactId>javax.inject</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.eclipse.che.core</groupId> | ||
<artifactId>che-core-commons-gwt</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.eclipse.che.core</groupId> | ||
<artifactId>che-core-ide-api</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.eclipse.che.plugin</groupId> | ||
<artifactId>che-plugin-languageserver-shared</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.vectomatic</groupId> | ||
<artifactId>lib-gwt-svg</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.google.gwt</groupId> | ||
<artifactId>gwt-user</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
</dependencies> | ||
<build> | ||
<resources> | ||
<resource> | ||
<directory>src/main/java</directory> | ||
</resource> | ||
<resource> | ||
<directory>src/main/resources</directory> | ||
</resource> | ||
</resources> | ||
</build> | ||
</project> |
67 changes: 67 additions & 0 deletions
67
...-ide/src/main/java/org/eclipse/che/plugin/languageserver/ide/LanguageServerExtension.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package org.eclipse.che.plugin.languageserver.ide; | ||
|
||
import org.eclipse.che.ide.api.editor.EditorRegistry; | ||
import org.eclipse.che.ide.api.event.FileEvent; | ||
import org.eclipse.che.ide.api.event.FileEventHandler; | ||
import org.eclipse.che.ide.api.extension.Extension; | ||
import org.eclipse.che.ide.api.filetypes.FileType; | ||
import org.eclipse.che.ide.api.filetypes.FileTypeRegistry; | ||
import org.eclipse.che.plugin.languageserver.ide.editor.LanguageServerEditorConfiguration; | ||
import org.eclipse.che.plugin.languageserver.ide.editor.LanguageServerEditorProvider; | ||
import org.eclipse.che.plugin.languageserver.ide.service.TextDocumentServiceClient; | ||
import org.eclipse.che.plugin.languageserver.shared.dto.DtoClientImpls; | ||
import org.eclipse.che.plugin.languageserver.shared.dto.DtoClientImpls.DidCloseTextDocumentParamsDTOImpl; | ||
import org.eclipse.che.plugin.languageserver.shared.dto.DtoClientImpls.DidOpenTextDocumentParamsDTOImpl; | ||
import org.eclipse.che.plugin.languageserver.shared.dto.DtoClientImpls.DidSaveTextDocumentParamsDTOImpl; | ||
import org.eclipse.che.plugin.languageserver.shared.dto.DtoClientImpls.TextDocumentIdentifierDTOImpl; | ||
import org.eclipse.che.plugin.languageserver.shared.dto.DtoClientImpls.TextDocumentItemDTOImpl; | ||
|
||
import com.google.inject.Inject; | ||
import com.google.web.bindery.event.shared.EventBus; | ||
|
||
@Extension(title = "LanguageServer") | ||
public class LanguageServerExtension { | ||
|
||
@Inject | ||
protected void configureFileTypes(FileTypeRegistry fileTypeRegistry, LanguageServerResources resources, | ||
final EditorRegistry editorRegistry, final LanguageServerEditorProvider editorProvider) { | ||
// TODO the file types need to be retrieved from the server. Ideally we | ||
// would listen on messages when new language servers get registered. | ||
FileType fileType = new FileType(resources.file(), "foo"); | ||
fileTypeRegistry.registerFileType(fileType); | ||
// register editor provider | ||
editorRegistry.registerDefaultEditor(fileType, editorProvider); | ||
} | ||
|
||
@Inject protected void registerFileEventHandler(EventBus eventBus, final TextDocumentServiceClient serviceClient) { | ||
eventBus.addHandler(FileEvent.TYPE, new FileEventHandler() { | ||
|
||
@Override | ||
public void onFileOperation(FileEvent event) { | ||
TextDocumentIdentifierDTOImpl documentId = DtoClientImpls.TextDocumentIdentifierDTOImpl.make(); | ||
documentId.setUri(event.getFile().getPath()); | ||
switch (event.getOperationType()) { | ||
case OPEN: | ||
DidOpenTextDocumentParamsDTOImpl openEvent = DtoClientImpls.DidOpenTextDocumentParamsDTOImpl.make(); | ||
TextDocumentItemDTOImpl documentItem = DtoClientImpls.TextDocumentItemDTOImpl.make(); | ||
documentItem.setUri(event.getFile().getPath()); | ||
documentItem.setVersion(LanguageServerEditorConfiguration.INITIAL_DOCUMENT_VERSION); | ||
//TODO send text? | ||
openEvent.setTextDocument(documentItem); | ||
serviceClient.didOpen(openEvent); | ||
break; | ||
case CLOSE: | ||
DidCloseTextDocumentParamsDTOImpl closeEvent = DtoClientImpls.DidCloseTextDocumentParamsDTOImpl.make(); | ||
closeEvent.setTextDocument(documentId); | ||
serviceClient.didClose(closeEvent); | ||
break; | ||
case SAVE: | ||
DidSaveTextDocumentParamsDTOImpl saveEvent = DtoClientImpls.DidSaveTextDocumentParamsDTOImpl.make(); | ||
saveEvent.setTextDocument(documentId); | ||
serviceClient.didSave(saveEvent); | ||
break; | ||
} | ||
} | ||
}); | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
...-ide/src/main/java/org/eclipse/che/plugin/languageserver/ide/LanguageServerResources.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package org.eclipse.che.plugin.languageserver.ide; | ||
|
||
import com.google.gwt.core.client.GWT; | ||
import com.google.gwt.resources.client.ClientBundle; | ||
|
||
import org.vectomatic.dom.svg.ui.SVGResource; | ||
|
||
public interface LanguageServerResources extends ClientBundle { | ||
LanguageServerResources INSTANCE = GWT.create(LanguageServerResources.class); | ||
|
||
@Source("svg/file.svg") | ||
SVGResource file(); | ||
|
||
@Source("svg/category.svg") | ||
SVGResource category(); | ||
} |
107 changes: 107 additions & 0 deletions
107
...a/org/eclipse/che/plugin/languageserver/ide/editor/LanguageServerEditorConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
package org.eclipse.che.plugin.languageserver.ide.editor; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.concurrent.atomic.AtomicInteger; | ||
|
||
import org.eclipse.che.ide.api.editor.annotation.AnnotationModel; | ||
import org.eclipse.che.ide.api.editor.annotation.AnnotationModelImpl; | ||
import org.eclipse.che.ide.api.editor.codeassist.CodeAssistProcessor; | ||
import org.eclipse.che.ide.api.editor.document.Document; | ||
import org.eclipse.che.ide.api.editor.editorconfig.DefaultTextEditorConfiguration; | ||
import org.eclipse.che.ide.api.editor.events.DocumentChangeEvent; | ||
import org.eclipse.che.ide.api.editor.partition.ConstantPartitioner; | ||
import org.eclipse.che.ide.api.editor.partition.DocumentPartitioner; | ||
import org.eclipse.che.ide.api.editor.partition.DocumentPositionMap; | ||
import org.eclipse.che.ide.api.editor.reconciler.Reconciler; | ||
import org.eclipse.che.ide.api.editor.reconciler.ReconcilerWithAutoSave; | ||
import org.eclipse.che.ide.api.editor.text.TextPosition; | ||
import org.eclipse.che.plugin.languageserver.ide.editor.codeassist.LanguageServerCodeAssistProcessor; | ||
import org.eclipse.che.plugin.languageserver.ide.service.TextDocumentServiceClient; | ||
import org.eclipse.che.plugin.languageserver.shared.dto.DtoClientImpls; | ||
import org.eclipse.che.plugin.languageserver.shared.dto.DtoClientImpls.DidChangeTextDocumentParamsDTOImpl; | ||
import org.eclipse.che.plugin.languageserver.shared.dto.DtoClientImpls.PositionDTOImpl; | ||
import org.eclipse.che.plugin.languageserver.shared.dto.DtoClientImpls.RangeDTOImpl; | ||
import org.eclipse.che.plugin.languageserver.shared.dto.DtoClientImpls.TextDocumentContentChangeEventDTOImpl; | ||
import org.eclipse.che.plugin.languageserver.shared.dto.DtoClientImpls.VersionedTextDocumentIdentifierDTOImpl; | ||
|
||
import com.google.inject.Inject; | ||
import com.google.inject.Provider; | ||
|
||
public class LanguageServerEditorConfiguration extends DefaultTextEditorConfiguration { | ||
|
||
public static final int INITIAL_DOCUMENT_VERSION = 0; | ||
|
||
private final LanguageServerCodeAssistProcessor codeAssistProcessor; | ||
private final AnnotationModel annotationModel; | ||
private final DocumentPositionMap documentPositionMap; | ||
private final AtomicInteger version = new AtomicInteger(INITIAL_DOCUMENT_VERSION); | ||
private final ConstantPartitioner constantPartitioner; | ||
private final ReconcilerWithAutoSave reconciler; | ||
|
||
@Inject | ||
public LanguageServerEditorConfiguration(final LanguageServerCodeAssistProcessor codeAssistProcessor, final Provider<DocumentPositionMap> docPositionMapProvider, final TextDocumentServiceClient textDocumentService) { | ||
this.codeAssistProcessor = codeAssistProcessor; | ||
this.documentPositionMap = docPositionMapProvider.get(); | ||
this.annotationModel = new AnnotationModelImpl(documentPositionMap); | ||
|
||
//HACK hijacked the partitioner to get document change events | ||
this.constantPartitioner = new ConstantPartitioner() { | ||
|
||
@Override | ||
public void onDocumentChange(DocumentChangeEvent event) { | ||
super.onDocumentChange(event); | ||
|
||
Document document = event.getDocument().getDocument(); | ||
TextPosition startPosition = document.getPositionFromIndex(event.getOffset()); | ||
TextPosition endPosition = document.getPositionFromIndex(event.getOffset() + event.getLength()); | ||
|
||
DidChangeTextDocumentParamsDTOImpl changeDTO = DtoClientImpls.DidChangeTextDocumentParamsDTOImpl.make(); | ||
String uri = ((Document) document).getFile().getPath(); | ||
changeDTO.setUri(uri); | ||
VersionedTextDocumentIdentifierDTOImpl versionedDocId = DtoClientImpls.VersionedTextDocumentIdentifierDTOImpl.make(); | ||
versionedDocId.setUri(uri); | ||
versionedDocId.setVersion(version.incrementAndGet()); | ||
changeDTO.setTextDocument(versionedDocId); | ||
TextDocumentContentChangeEventDTOImpl actualChange = DtoClientImpls.TextDocumentContentChangeEventDTOImpl.make(); | ||
RangeDTOImpl range = DtoClientImpls.RangeDTOImpl.make(); | ||
PositionDTOImpl start = DtoClientImpls.PositionDTOImpl.make(); | ||
start.setLine(startPosition.getLine()); | ||
start.setCharacter(startPosition.getCharacter()); | ||
PositionDTOImpl end = DtoClientImpls.PositionDTOImpl.make(); | ||
end.setLine(endPosition.getLine()); | ||
end.setCharacter(endPosition.getCharacter()); | ||
range.setStart(start); | ||
range.setEnd(end); | ||
actualChange.setRange(range); | ||
actualChange.setText(event.getText()); | ||
changeDTO.addContentChanges(actualChange); | ||
textDocumentService.didChange(changeDTO); | ||
} | ||
}; | ||
this.reconciler = new ReconcilerWithAutoSave(DocumentPartitioner.DEFAULT_CONTENT_TYPE, constantPartitioner); | ||
} | ||
|
||
@Override | ||
public Map<String, CodeAssistProcessor> getContentAssistantProcessors() { | ||
Map<String, CodeAssistProcessor> map = new HashMap<>(); | ||
map.put(DocumentPartitioner.DEFAULT_CONTENT_TYPE, codeAssistProcessor); | ||
return map; | ||
} | ||
|
||
@Override | ||
public AnnotationModel getAnnotationModel() { | ||
return annotationModel; | ||
} | ||
|
||
@Override | ||
public DocumentPartitioner getPartitioner() { | ||
return constantPartitioner; | ||
} | ||
|
||
@Override | ||
public Reconciler getReconciler() { | ||
return reconciler; | ||
} | ||
|
||
} |
33 changes: 33 additions & 0 deletions
33
...n/java/org/eclipse/che/plugin/languageserver/ide/editor/LanguageServerEditorProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package org.eclipse.che.plugin.languageserver.ide.editor; | ||
|
||
import javax.inject.Inject; | ||
|
||
import org.eclipse.che.ide.api.editor.defaulteditor.AbstractTextEditorProvider; | ||
import org.eclipse.che.ide.api.editor.editorconfig.TextEditorConfiguration; | ||
|
||
import com.google.inject.Provider; | ||
|
||
public class LanguageServerEditorProvider extends AbstractTextEditorProvider { | ||
|
||
private Provider<LanguageServerEditorConfiguration> editorConfigurationProvider; | ||
|
||
@Inject | ||
public LanguageServerEditorProvider(final Provider<LanguageServerEditorConfiguration> editorConfigurationProvider) { | ||
this.editorConfigurationProvider = editorConfigurationProvider; | ||
} | ||
|
||
@Override | ||
public String getId() { | ||
return "LanguageServerEditor"; | ||
} | ||
|
||
@Override | ||
public String getDescription() { | ||
return "Code Editor"; | ||
} | ||
|
||
@Override | ||
protected TextEditorConfiguration getEditorConfiguration() { | ||
return editorConfigurationProvider.get(); | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
...in/java/org/eclipse/che/plugin/languageserver/ide/editor/PublishDiagnosticsProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package org.eclipse.che.plugin.languageserver.ide.editor; | ||
|
||
import org.eclipse.che.ide.api.editor.EditorAgent; | ||
import org.eclipse.che.ide.api.editor.EditorPartPresenter; | ||
import org.eclipse.che.ide.api.editor.annotation.AnnotationModel; | ||
import org.eclipse.che.ide.api.editor.document.Document; | ||
import org.eclipse.che.ide.api.editor.editorconfig.TextEditorConfiguration; | ||
import org.eclipse.che.ide.api.editor.text.Position; | ||
import org.eclipse.che.ide.api.editor.text.TextPosition; | ||
import org.eclipse.che.ide.api.editor.text.annotation.Annotation; | ||
import org.eclipse.che.ide.api.editor.texteditor.TextEditor; | ||
import org.eclipse.che.ide.resource.Path; | ||
import org.eclipse.che.plugin.languageserver.shared.lsapi.DiagnosticDTO; | ||
import org.eclipse.che.plugin.languageserver.shared.lsapi.PublishDiagnosticsParamsDTO; | ||
import org.eclipse.che.plugin.languageserver.shared.lsapi.RangeDTO; | ||
|
||
import com.google.inject.Inject; | ||
import com.google.inject.Singleton; | ||
|
||
import io.typefox.lsapi.Diagnostic; | ||
|
||
@Singleton | ||
public class PublishDiagnosticsProcessor { | ||
|
||
private final EditorAgent editorAgent; | ||
|
||
@Inject | ||
public PublishDiagnosticsProcessor(EditorAgent editorAgent) { | ||
this.editorAgent = editorAgent; | ||
} | ||
|
||
public void processDiagnostics(PublishDiagnosticsParamsDTO diagnosticsMessage) { | ||
EditorPartPresenter openedEditor = editorAgent.getOpenedEditor(new Path(diagnosticsMessage.getUri())); | ||
//TODO add markers | ||
if (openedEditor == null) | ||
return; | ||
if (openedEditor instanceof TextEditor) { | ||
TextEditorConfiguration editorConfiguration = ((TextEditor) openedEditor).getConfiguration(); | ||
AnnotationModel annotationModel = editorConfiguration.getAnnotationModel(); | ||
if (annotationModel != null) { | ||
annotationModel.clear(); | ||
Document document = ((TextEditor) openedEditor).getDocument(); | ||
for (DiagnosticDTO diagnostic : diagnosticsMessage.getDiagnostics()) { | ||
Annotation annotation = new Annotation(true); | ||
annotation.setText(diagnostic.getMessage()); | ||
// TODO generalize id for error and warning. Needs fix in org.eclipse.che.ide.editor.orion.client.OrionEditorWidget.getSeverity(String) | ||
annotation.setType(diagnostic.getSeverity() == Diagnostic.SEVERITY_ERROR ? "org.eclipse.jdt.ui.error" : "org.eclipse.jdt.ui.warning"); | ||
|
||
RangeDTO range = diagnostic.getRange(); | ||
int startIndex = document.getIndexFromPosition(new TextPosition(range.getStart().getLine(), range.getStart().getCharacter())); | ||
int endIndex = document.getIndexFromPosition(new TextPosition(range.getEnd().getLine(), range.getEnd().getCharacter())); | ||
annotationModel.addAnnotation(annotation, new Position(startIndex, endIndex - startIndex)); | ||
} | ||
} | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.