Search in sources :

Example 6 with Range

use of nl.ramsolutions.sw.magik.analysis.Range in project magik-tools by StevenLooman.

the class CompletionProvider method provideGlobalCompletion.

/**
 * Provide global completion.
 * @param magikFile MagikFile.
 * @param position Position in source.
 * @param tokenNode Current node.
 * @return Completions items.
 */
@SuppressWarnings("checkstyle:NestedIfDepth")
private List<CompletionItem> provideGlobalCompletion(final MagikTypedFile magikFile, final Position position, @Nullable final AstNode tokenNode) {
    final List<CompletionItem> items = new ArrayList<>();
    // Keyword entries.
    Stream.of(MagikKeyword.values()).map(magikKeyword -> {
        final String name = magikKeyword.toString().toLowerCase();
        final CompletionItem item = new CompletionItem(name);
        item.setKind(CompletionItemKind.Keyword);
        item.setInsertText(magikKeyword.getValue());
        return item;
    }).forEach(items::add);
    // Scope entries.
    final AstNode topNode = magikFile.getTopNode();
    AstNode scopeNode = AstQuery.nodeSurrounding(topNode, Lsp4jConversion.positionFromLsp4j(position));
    if (scopeNode != null) {
        if (scopeNode.getFirstChild(MagikGrammar.BODY) != null) {
            scopeNode = scopeNode.getFirstChild(MagikGrammar.BODY);
        }
        final GlobalScope globalScope = magikFile.getGlobalScope();
        final Scope scopeForNode = globalScope.getScopeForNode(scopeNode);
        if (scopeForNode != null) {
            scopeForNode.getSelfAndAncestorScopes().stream().flatMap(scope -> scope.getScopeEntriesInScope().stream()).filter(scopeEntry -> {
                final AstNode definingNode = scopeEntry.getNode();
                final Range range = new Range(definingNode);
                return Lsp4jConversion.positionFromLsp4j(position).isAfterRange(range);
            }).map(scopeEntry -> {
                final CompletionItem item = new CompletionItem(scopeEntry.getIdentifier());
                item.setInsertText(scopeEntry.getIdentifier());
                item.setDetail(scopeEntry.getIdentifier());
                item.setKind(CompletionItemKind.Variable);
                return item;
            }).forEach(items::add);
        }
    }
    // Slots.
    final ITypeKeeper typeKeeper = magikFile.getTypeKeeper();
    if (scopeNode != null) {
        final AstNode methodDefinitionNode = scopeNode.getFirstAncestor(MagikGrammar.METHOD_DEFINITION);
        if (methodDefinitionNode != null) {
            final MethodDefinitionNodeHelper helper = new MethodDefinitionNodeHelper(methodDefinitionNode);
            final GlobalReference globalRef = helper.getTypeGlobalReference();
            final AbstractType type = typeKeeper.getType(globalRef);
            type.getSlots().stream().map(slot -> {
                final String slotName = slot.getName();
                final String fullSlotName = slot.getOwner().getFullName() + "." + slot.getName();
                final CompletionItem item = new CompletionItem(slotName);
                item.setInsertText(slotName);
                item.setDetail(fullSlotName);
                item.setKind(CompletionItemKind.Property);
                return item;
            }).forEach(items::add);
        }
    }
    // Global types.
    final String identifierPart = tokenNode != null ? tokenNode.getTokenValue() : "";
    typeKeeper.getTypes().stream().filter(type -> type.getFullName().indexOf(identifierPart) != -1).map(type -> {
        final CompletionItem item = new CompletionItem(type.getFullName());
        // TODO: if visible from current package, don't prefix package.
        item.setInsertText(type.getFullName());
        item.setDetail(type.getFullName());
        item.setDocumentation(type.getDoc());
        item.setKind(CompletionItemKind.Class);
        return item;
    }).forEach(items::add);
    return items;
}
Also used : AstNode(com.sonar.sslr.api.AstNode) Arrays(java.util.Arrays) MethodDefinitionNodeHelper(nl.ramsolutions.sw.magik.analysis.helpers.MethodDefinitionNodeHelper) MagikPunctuator(nl.ramsolutions.sw.magik.api.MagikPunctuator) MagikOperator(nl.ramsolutions.sw.magik.api.MagikOperator) LoggerFactory(org.slf4j.LoggerFactory) SelfType(nl.ramsolutions.sw.magik.analysis.typing.types.SelfType) ITypeKeeper(nl.ramsolutions.sw.magik.analysis.typing.ITypeKeeper) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LocalTypeReasoner(nl.ramsolutions.sw.magik.analysis.typing.LocalTypeReasoner) UndefinedType(nl.ramsolutions.sw.magik.analysis.typing.types.UndefinedType) MagikKeyword(nl.ramsolutions.sw.magik.api.MagikKeyword) AbstractType(nl.ramsolutions.sw.magik.analysis.typing.types.AbstractType) CompletionItemKind(org.eclipse.lsp4j.CompletionItemKind) Lsp4jConversion(nl.ramsolutions.sw.magik.languageserver.Lsp4jConversion) Map(java.util.Map) Position(org.eclipse.lsp4j.Position) AstQuery(nl.ramsolutions.sw.magik.analysis.AstQuery) MagikGrammar(nl.ramsolutions.sw.magik.api.MagikGrammar) Nullable(javax.annotation.Nullable) GlobalScope(nl.ramsolutions.sw.magik.analysis.scope.GlobalScope) MagikCommentExtractor(nl.ramsolutions.sw.magik.parser.MagikCommentExtractor) GlobalReference(nl.ramsolutions.sw.magik.analysis.typing.types.GlobalReference) Logger(org.slf4j.Logger) MagikTypedFile(nl.ramsolutions.sw.magik.MagikTypedFile) Set(java.util.Set) Collectors(java.util.stream.Collectors) ServerCapabilities(org.eclipse.lsp4j.ServerCapabilities) CompletionItem(org.eclipse.lsp4j.CompletionItem) List(java.util.List) Stream(java.util.stream.Stream) CompletionOptions(org.eclipse.lsp4j.CompletionOptions) Optional(java.util.Optional) Range(nl.ramsolutions.sw.magik.analysis.Range) Scope(nl.ramsolutions.sw.magik.analysis.scope.Scope) Collections(java.util.Collections) CheckForNull(javax.annotation.CheckForNull) ExpressionResult(nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult) GlobalScope(nl.ramsolutions.sw.magik.analysis.scope.GlobalScope) GlobalReference(nl.ramsolutions.sw.magik.analysis.typing.types.GlobalReference) ArrayList(java.util.ArrayList) MethodDefinitionNodeHelper(nl.ramsolutions.sw.magik.analysis.helpers.MethodDefinitionNodeHelper) Range(nl.ramsolutions.sw.magik.analysis.Range) ITypeKeeper(nl.ramsolutions.sw.magik.analysis.typing.ITypeKeeper) GlobalScope(nl.ramsolutions.sw.magik.analysis.scope.GlobalScope) Scope(nl.ramsolutions.sw.magik.analysis.scope.Scope) CompletionItem(org.eclipse.lsp4j.CompletionItem) AbstractType(nl.ramsolutions.sw.magik.analysis.typing.types.AbstractType) AstNode(com.sonar.sslr.api.AstNode)

Example 7 with Range

use of nl.ramsolutions.sw.magik.analysis.Range in project magik-tools by StevenLooman.

the class DocumentSymbolProvider method convertDefinition.

private DocumentSymbol convertDefinition(final Definition definition) {
    final SymbolKind symbolKind = this.symbolKindForDefinition(definition);
    final DocumentSymbol documentSymbol = new DocumentSymbol(definition.getName(), symbolKind, Lsp4jConversion.rangeToLsp4j(new Range(definition.getNode())), Lsp4jConversion.rangeToLsp4j(new Range(definition.getNode())));
    if (definition instanceof SlottedExemplarDefinition) {
        final SlottedExemplarDefinition exemplarDefinition = (SlottedExemplarDefinition) definition;
        final List<DocumentSymbol> slotSymbols = this.convertedSlotsFromDefinition(exemplarDefinition);
        documentSymbol.setChildren(slotSymbols);
    }
    return documentSymbol;
}
Also used : SymbolKind(org.eclipse.lsp4j.SymbolKind) DocumentSymbol(org.eclipse.lsp4j.DocumentSymbol) Range(nl.ramsolutions.sw.magik.analysis.Range) SlottedExemplarDefinition(nl.ramsolutions.sw.magik.analysis.definitions.SlottedExemplarDefinition)

Example 8 with Range

use of nl.ramsolutions.sw.magik.analysis.Range in project magik-tools by StevenLooman.

the class RenameProvider method provideRename.

/**
 * Provide rename.
 * @param magikFile Magik file.
 * @param position Position in magik source.
 * @param newName New name.
 * @return Edits to workspace.
 */
public WorkspaceEdit provideRename(final MagikTypedFile magikFile, final Position position, final String newName) {
    // Parse magik.
    final AstNode topNode = magikFile.getTopNode();
    // Should always be on an identifier.
    final AstNode node = AstQuery.nodeAt(topNode, Lsp4jConversion.positionFromLsp4j(position), MagikGrammar.IDENTIFIER);
    if (node == null) {
        return null;
    }
    // Set up scope.
    final ScopeEntry scopeEntry = this.findScopeEntry(magikFile, node);
    if (scopeEntry == null || scopeEntry.isType(ScopeEntry.Type.GLOBAL) || scopeEntry.isType(ScopeEntry.Type.DYNAMIC) || scopeEntry.isType(ScopeEntry.Type.IMPORT)) {
        return null;
    }
    // Provide edits.
    final String uri = magikFile.getUri().toString();
    final AstNode definitionNode = scopeEntry.getNode();
    final List<TextEdit> textEdits = Stream.concat(Stream.of(definitionNode), scopeEntry.getUsages().stream()).map(renameNode -> renameNode.isNot(MagikGrammar.IDENTIFIER) ? renameNode.getFirstChild(MagikGrammar.IDENTIFIER) : renameNode).map(Range::new).map(Lsp4jConversion::rangeToLsp4j).map(range -> new TextEdit(range, newName)).collect(Collectors.toList());
    return new WorkspaceEdit(Map.of(uri, textEdits));
}
Also used : GlobalScope(nl.ramsolutions.sw.magik.analysis.scope.GlobalScope) AstNode(com.sonar.sslr.api.AstNode) MagikTypedFile(nl.ramsolutions.sw.magik.MagikTypedFile) PrepareRenameResult(org.eclipse.lsp4j.PrepareRenameResult) Collectors(java.util.stream.Collectors) ServerCapabilities(org.eclipse.lsp4j.ServerCapabilities) List(java.util.List) Stream(java.util.stream.Stream) TextEdit(org.eclipse.lsp4j.TextEdit) WorkspaceEdit(org.eclipse.lsp4j.WorkspaceEdit) RenameOptions(org.eclipse.lsp4j.RenameOptions) Lsp4jConversion(nl.ramsolutions.sw.magik.languageserver.Lsp4jConversion) Map(java.util.Map) Either(org.eclipse.lsp4j.jsonrpc.messages.Either) ScopeEntry(nl.ramsolutions.sw.magik.analysis.scope.ScopeEntry) Position(org.eclipse.lsp4j.Position) Range(nl.ramsolutions.sw.magik.analysis.Range) Scope(nl.ramsolutions.sw.magik.analysis.scope.Scope) CheckForNull(javax.annotation.CheckForNull) AstQuery(nl.ramsolutions.sw.magik.analysis.AstQuery) MagikGrammar(nl.ramsolutions.sw.magik.api.MagikGrammar) ScopeEntry(nl.ramsolutions.sw.magik.analysis.scope.ScopeEntry) TextEdit(org.eclipse.lsp4j.TextEdit) WorkspaceEdit(org.eclipse.lsp4j.WorkspaceEdit) AstNode(com.sonar.sslr.api.AstNode) Lsp4jConversion(nl.ramsolutions.sw.magik.languageserver.Lsp4jConversion)

Aggregations

Range (nl.ramsolutions.sw.magik.analysis.Range)8 AstNode (com.sonar.sslr.api.AstNode)4 Location (nl.ramsolutions.sw.magik.analysis.Location)3 URI (java.net.URI)2 List (java.util.List)2 Map (java.util.Map)2 Collectors (java.util.stream.Collectors)2 Stream (java.util.stream.Stream)2 CheckForNull (javax.annotation.CheckForNull)2 MagikTypedFile (nl.ramsolutions.sw.magik.MagikTypedFile)2 AstQuery (nl.ramsolutions.sw.magik.analysis.AstQuery)2 Position (nl.ramsolutions.sw.magik.analysis.Position)2 GlobalScope (nl.ramsolutions.sw.magik.analysis.scope.GlobalScope)2 Scope (nl.ramsolutions.sw.magik.analysis.scope.Scope)2 ScopeEntry (nl.ramsolutions.sw.magik.analysis.scope.ScopeEntry)2 MagikGrammar (nl.ramsolutions.sw.magik.api.MagikGrammar)2 Lsp4jConversion (nl.ramsolutions.sw.magik.languageserver.Lsp4jConversion)2 Position (org.eclipse.lsp4j.Position)2 ServerCapabilities (org.eclipse.lsp4j.ServerCapabilities)2 ArrayList (java.util.ArrayList)1