Skip to content

Commit ab5f916

Browse files
authored
Merge pull request #91 from MontiCore/cd4c-lsp
Add CD4C language server
2 parents ae424e3 + f8bbd69 commit ab5f916

File tree

10 files changed

+338
-0
lines changed

10 files changed

+338
-0
lines changed

language-server/build.gradle

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,37 @@ task autoconfigure(type: de.mclsg.task.AutoconfigureTask) {
7272
including(TaskTypes.VSCODE_PLUGIN)
7373
}
7474
}
75+
76+
task autoconfigureCD4Code(type: de.mclsg.task.AutoconfigureTask) {
77+
mclsg {
78+
languageName = "de.monticore.CD4Code"
79+
fileExtension = "cd"
80+
}
81+
if(("true").equals(getProperty('buildVscodePlugin'))){
82+
including(TaskTypes.VSCODE_PLUGIN)
83+
}
84+
}
85+
7586
compileJava.dependsOn autoconfigure
87+
compileJava.dependsOn autoconfigureCD4Code
88+
89+
packCD4AnalysisLanguageServer {
90+
getArchiveBaseName().set("cd4a-language-server")
91+
}
92+
93+
packCD4CodeLanguageServer {
94+
getArchiveBaseName().set("cd4c-language-server")
95+
}
7696

7797
tasks.generateCD4AnalysisLanguageServer.dependsOn(project(":cdlang").tasks.grammarsJar)
7898
tasks.generateCD4AnalysisLanguageServer.dependsOn(project(":cdlang").tasks.grammarsForVariantJar)
7999
tasks.packCD4AnalysisLanguageServer.dependsOn(project(":cdlang").tasks.jar)
100+
101+
tasks.generateCD4CodeLanguageServer.dependsOn(project(":cdlang").tasks.grammarsJar)
102+
tasks.generateCD4CodeLanguageServer.dependsOn(project(":cdlang").tasks.grammarsForVariantJar)
103+
tasks.packCD4CodeLanguageServer.dependsOn(project(":cdlang").tasks.jar)
104+
105+
if(("true").equals(getProperty('buildVscodePlugin'))) {
106+
tasks.buildCD4CodeVscodePlugin.dependsOn(tasks.packageCD4CodeVscodePlugin)
107+
tasks.buildCD4AnalysisVscodePlugin.dependsOn(tasks.packageCD4AnalysisVscodePlugin)
108+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/* (c) https://github.com/MontiCore/monticore */
2+
package de.monticore.cd4code._lsp;
3+
4+
import de.mclsg.lsp.modelpath.multiproject.ProjectLayout;
5+
import de.mclsg.lsp.ISymbolUsageResolutionProvider;
6+
import de.mclsg.lsp.document_management.DocumentManager;
7+
import de.monticore.cd4code._lsp.features.code_action.CD4CodeCodeActionProvider;
8+
import de.monticore.cd4analysis._lsp.features.code_action.CollapseHierarchyCodeActionStrategy;
9+
import de.monticore.cd4analysis._lsp.features.code_action.ExtractSuperClassCodeActionStrategy;
10+
import de.monticore.cd4analysis._lsp.features.code_action.PullUpFieldCodeActionStrategy;
11+
import de.monticore.cd4analysis._lsp.features.code_action.UnfoldByAttributesStrategy;
12+
import de.monticore.cd4code._lsp.language_access.CD4CodeScopeManager;
13+
14+
public class CD4CodeLanguageServer extends CD4CodeLanguageServerTOP {
15+
16+
public CD4CodeLanguageServer(DocumentManager documentManager, ProjectLayout layout,
17+
CD4CodeScopeManager scopeManager,
18+
ISymbolUsageResolutionProvider symbolUsageResolutionProvider) {
19+
super(documentManager, layout, scopeManager, symbolUsageResolutionProvider);
20+
21+
CD4CodeCodeActionProvider codeActionProvider = new CD4CodeCodeActionProvider(documentManager,
22+
languageAccess.getPrettyPrinter().orElseThrow());
23+
codeActionProvider.addCodeActionStrategy(new PullUpFieldCodeActionStrategy(documentManager,
24+
symbolUsageResolutionProvider, languageAccess.getPrettyPrinter().orElseThrow()));
25+
codeActionProvider.addCodeActionStrategy(new ExtractSuperClassCodeActionStrategy(
26+
documentManager, languageAccess.getPrettyPrinter().orElseThrow()));
27+
codeActionProvider.addCodeActionStrategy(new CollapseHierarchyCodeActionStrategy(
28+
documentManager, languageAccess.getPrettyPrinter().orElseThrow(),
29+
symbolUsageResolutionProvider));
30+
codeActionProvider.addCodeActionStrategy(new UnfoldByAttributesStrategy(documentManager,
31+
languageAccess.getPrettyPrinter().orElseThrow()));
32+
textDocumentService.register(codeActionProvider);
33+
}
34+
35+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/* (c) https://github.com/MontiCore/monticore */
2+
package de.monticore.cd4code._lsp;
3+
4+
import de.mclsg.lsp.CommonLanguageServer;
5+
import de.mclsg.lsp.ISymbolUsageResolutionProvider;
6+
import de.mclsg.lsp.document_management.DocumentManager;
7+
import de.monticore.cd4code._lsp.features.code_lens.CD4CodeCodeLensProvider;
8+
import de.monticore.cd4code._lsp.language_access.CD4CodeLanguageAccess;
9+
import org.eclipse.lsp4j.services.LanguageClient;
10+
11+
public class CD4CodeTextDocumentService extends CD4CodeTextDocumentServiceTOP {
12+
13+
public CD4CodeTextDocumentService(CommonLanguageServer languageServer,
14+
DocumentManager documentManager, LanguageClient languageClient,
15+
CD4CodeLanguageAccess languageAccess,
16+
ISymbolUsageResolutionProvider symbolUsageResolutionProvider) {
17+
super(languageServer, documentManager, languageClient, languageAccess,
18+
symbolUsageResolutionProvider);
19+
}
20+
21+
@Override
22+
protected void registerDefaultCodeLensProvider() {
23+
register(new CD4CodeCodeLensProvider(referencesProvider, documentManager,
24+
symbolUsageResolutionProvider));
25+
}
26+
27+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/* (c) https://github.com/MontiCore/monticore */
2+
package de.monticore.cd4code._lsp.features.code_action;
3+
4+
import de.mclsg.lsp.document_management.DocumentManager;
5+
import de.monticore.cd4analysis._lsp.features.code_action.CodeActionStrategy;
6+
import de.monticore.cdbasis._ast.ASTCDCompilationUnit;
7+
import de.monticore.prettyprint.AstPrettyPrinter;
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
import org.eclipse.lsp4j.CodeAction;
11+
import org.eclipse.lsp4j.CodeActionContext;
12+
import org.eclipse.lsp4j.Command;
13+
import org.eclipse.lsp4j.Range;
14+
import org.eclipse.lsp4j.TextDocumentItem;
15+
import org.eclipse.lsp4j.jsonrpc.messages.Either;
16+
17+
public class CD4CodeCodeActionProvider extends CD4CodeCodeActionProviderTOP {
18+
19+
private final List<CodeActionStrategy> strategies;
20+
21+
public CD4CodeCodeActionProvider(DocumentManager documentManager,
22+
AstPrettyPrinter<ASTCDCompilationUnit> prettyPrinter) {
23+
super(documentManager, prettyPrinter);
24+
this.strategies = new ArrayList<>();
25+
}
26+
27+
public void addCodeActionStrategy(CodeActionStrategy codeActionStrategy) {
28+
strategies.add(codeActionStrategy);
29+
}
30+
31+
@Override
32+
public List<Either<Command, CodeAction>> codeAction(TextDocumentItem document,
33+
CodeActionContext context, Range range) {
34+
List<Either<Command, CodeAction>> baseActions = super.codeAction(document, context, range);
35+
36+
strategies.stream().flatMap(strategy -> strategy.apply(document, context, range).stream())
37+
.forEach(baseActions::add);
38+
39+
return baseActions;
40+
}
41+
42+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/* (c) https://github.com/MontiCore/monticore */
2+
package de.monticore.cd4code._lsp.features.code_lens;
3+
4+
import de.mclsg.lsp.ISymbolUsageResolutionProvider;
5+
import de.mclsg.lsp.document_management.DocumentInformation;
6+
import de.mclsg.lsp.document_management.DocumentManager;
7+
import de.mclsg.lsp.features.code_lens.CodeLensStrategy;
8+
import de.mclsg.lsp.features.reference.CommonReferencesProvider;
9+
import java.util.List;
10+
import java.util.Optional;
11+
import java.util.stream.Collectors;
12+
13+
import de.monticore.cd4analysis._lsp.features.code_lens.AssociationCodeLensStrategy;
14+
import org.eclipse.lsp4j.CodeLens;
15+
import org.eclipse.lsp4j.TextDocumentItem;
16+
17+
public class CD4CodeCodeLensProvider extends CD4CodeCodeLensProviderTOP {
18+
19+
private final DocumentManager documentManager;
20+
21+
public CD4CodeCodeLensProvider(DocumentManager documentManager) {
22+
super(documentManager);
23+
throw new IllegalStateException();
24+
}
25+
26+
public CD4CodeCodeLensProvider(CommonReferencesProvider referencesProvider,
27+
DocumentManager documentManager,
28+
ISymbolUsageResolutionProvider symbolUsageResolutionProvider) {
29+
super(documentManager);
30+
this.documentManager = documentManager;
31+
this.strategyManager.registerCodeLensStrategy(new AssociationCodeLensStrategy(
32+
referencesProvider, documentManager, symbolUsageResolutionProvider));
33+
}
34+
35+
public void registerCodeLensStrategy(CodeLensStrategy codeLensStrategy) {
36+
strategyManager.registerCodeLensStrategy(codeLensStrategy);
37+
}
38+
39+
@Override
40+
public List<? extends CodeLens> codeLens(TextDocumentItem document) {
41+
Optional<DocumentInformation> documentInformation = documentManager.getDocumentInformation(
42+
document);
43+
if (documentInformation.isEmpty())
44+
return List.of();
45+
46+
return documentInformation.get().getMatchedNameTokens().stream().map(
47+
matchedToken -> strategyManager.getCodeLensStrategies(matchedToken).stream().map(
48+
codeLensStrategy -> codeLensStrategy.apply(matchedToken)).flatMap(Optional::stream)
49+
.collect(Collectors.toList())).flatMap(List::stream).collect(Collectors.toList());
50+
}
51+
52+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/* (c) https://github.com/MontiCore/monticore */
2+
package de.monticore.cd4code._lsp.features.code_lens;
3+
4+
import java.util.List;
5+
import org.eclipse.lsp4j.CodeLens;
6+
import org.eclipse.lsp4j.Command;
7+
import org.eclipse.lsp4j.Range;
8+
9+
public class CD4CodeServerCommandCodeLens extends CodeLens {
10+
11+
public CD4CodeServerCommandCodeLens(Range range, String title, String command,
12+
List<Object> arguments) {
13+
super(range, new Command(title, command, arguments), null);
14+
}
15+
16+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/* (c) https://github.com/MontiCore/monticore */
2+
package de.monticore.cd4code._lsp.language_access;
3+
4+
import de.monticore.cd4code._prettyprint.CD4CodeFullPrettyPrinter;
5+
import de.monticore.cdbasis._ast.ASTCDCompilationUnit;
6+
import de.monticore.prettyprint.AstPrettyPrinter;
7+
import de.monticore.prettyprint.IndentPrinter;
8+
9+
public class CD4CodeAstPrettyPrinter implements AstPrettyPrinter<ASTCDCompilationUnit> {
10+
11+
private final CD4CodeFullPrettyPrinter prettyPrinter = new CD4CodeFullPrettyPrinter(
12+
new IndentPrinter());
13+
14+
@Override
15+
public String prettyPrint(ASTCDCompilationUnit node) {
16+
return prettyPrinter.prettyprint(node);
17+
}
18+
19+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/* (c) https://github.com/MontiCore/monticore */
2+
package de.monticore.cd4code._lsp.language_access;
3+
4+
import de.mclsg.lsp.document_management.DocumentManager;
5+
import de.monticore.cdbasis._ast.ASTCDCompilationUnit;
6+
import de.monticore.prettyprint.AstPrettyPrinter;
7+
import java.util.Optional;
8+
9+
public class CD4CodeLanguageAccess extends CD4CodeLanguageAccessTOP {
10+
11+
private final CD4CodeAstPrettyPrinter prettyPrinter;
12+
13+
public CD4CodeLanguageAccess(DocumentManager documentManager, CD4CodeScopeManager scopeManager) {
14+
super(documentManager, scopeManager);
15+
this.prettyPrinter = new CD4CodeAstPrettyPrinter();
16+
}
17+
18+
@Override
19+
public Optional<AstPrettyPrinter<ASTCDCompilationUnit>> getPrettyPrinter() {
20+
return Optional.of(prettyPrinter);
21+
}
22+
23+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/* (c) https://github.com/MontiCore/monticore */
2+
package de.monticore.cd4code._lsp.language_access;
3+
4+
import de.mclsg.lsp.document_management.DocumentManager;
5+
import de.monticore.cd4code._cocos.CD4CodeCoCoChecker;
6+
import de.monticore.cd4code.cocos.CD4CodeCoCosDelegator;
7+
import de.monticore.cdbasis._ast.ASTCDCompilationUnit;
8+
9+
public class CD4CodeLspCoCoRunner extends CD4CodeLspCoCoRunnerTOP {
10+
11+
private CD4CodeCoCoChecker checker;
12+
13+
public CD4CodeLspCoCoRunner(DocumentManager documentManager) {
14+
super(documentManager);
15+
CD4CodeCoCosDelegator cd4CodeCoCos = new CD4CodeCoCosDelegator();
16+
checker = cd4CodeCoCos.getCheckerForAllCoCos();
17+
}
18+
19+
@Override
20+
public boolean needsSymbols() {
21+
return true;
22+
}
23+
24+
@Override
25+
public void runAllCoCos(ASTCDCompilationUnit ast) {
26+
checker.checkAll(ast);
27+
}
28+
29+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/* (c) https://github.com/MontiCore/monticore */
2+
package de.monticore.cd4code._lsp.language_access;
3+
4+
import de.monticore.cd._symboltable.BuiltInTypes;
5+
import de.monticore.cd4code._symboltable.CD4CodeSymbolTableCompleter;
6+
import de.monticore.cd4code._symboltable.ICD4CodeArtifactScope;
7+
import de.monticore.cd4code.trafo.CD4CodeDirectCompositionTrafo;
8+
import de.monticore.cdbasis._ast.ASTCDCompilationUnit;
9+
import de.monticore.io.paths.MCPath;
10+
import de.monticore.symbols.basicsymbols.BasicSymbolsMill;
11+
import de.se_rwth.commons.logging.Log;
12+
import java.util.Collection;
13+
import java.util.LinkedHashMap;
14+
import java.util.Map;
15+
16+
public class CD4CodeScopeManager extends CD4CodeScopeManagerTOP {
17+
18+
@Override
19+
public void initGlobalScope(MCPath modelPath) {
20+
super.initGlobalScope(modelPath);
21+
syncAccessGlobalScope(gs -> {
22+
BuiltInTypes.addBuiltInTypes(gs);
23+
BasicSymbolsMill.initializeString();
24+
});
25+
}
26+
27+
@Override
28+
public CD4CodeArtifactScopeWithFindings createArtifactScope(ASTCDCompilationUnit ast,
29+
ICD4CodeArtifactScope old) {
30+
// Apply transformations required after parsing
31+
new CD4CodeDirectCompositionTrafo().transform(ast);
32+
33+
CD4CodeArtifactScopeWithFindings res = super.createArtifactScope(ast, old);
34+
ast.accept(new CD4CodeSymbolTableCompleter(ast).getTraverser());
35+
res.findings.addAll(Log.getFindings());
36+
37+
return res;
38+
}
39+
40+
@Override
41+
public Map<ASTCDCompilationUnit, CD4CodeArtifactScopeWithFindings> createAllArtifactScopes(
42+
Collection<ASTCDCompilationUnit> astNodes) {
43+
final Map<ASTCDCompilationUnit, CD4CodeArtifactScopeWithFindings> res = new LinkedHashMap<>();
44+
syncAccessGlobalScope(gs -> {
45+
clearGlobalScope();
46+
if (supportsIterativeScopeAppending()) {
47+
for (ASTCDCompilationUnit node : astNodes) {
48+
Log.getFindings().clear();
49+
// Apply transformations
50+
new CD4CodeDirectCompositionTrafo().transform(node);
51+
// Use super.createArtifactScope, so that the completer is not used
52+
res.put(node, super.createArtifactScope(node, null));
53+
}
54+
55+
// Phase 2: complete symbol table when base structure is finished
56+
for (ASTCDCompilationUnit ast : astNodes) {
57+
Log.getFindings().clear();
58+
ast.accept(new CD4CodeSymbolTableCompleter(ast).getTraverser());
59+
res.get(ast).findings.addAll(Log.getFindings());
60+
}
61+
}
62+
});
63+
return res;
64+
}
65+
66+
}

0 commit comments

Comments
 (0)