Search in sources :

Example 6 with AstNode

use of com.sonar.sslr.api.AstNode in project magik-tools by StevenLooman.

the class HoverProvider method provideHoverMethodInvocation.

/**
 * Provide hover for a method invocation.
 * @param magikFile Magik file.
 * @param hoveredNode Hovered node.
 * @param builder Builder to add text to.
 */
private void provideHoverMethodInvocation(final MagikTypedFile magikFile, final AstNode hoveredNode, final StringBuilder builder) {
    final AstNode providingNode = hoveredNode.getParent();
    final AstNode previousSiblingNode = providingNode.getPreviousSibling();
    if (previousSiblingNode != null) {
        final MethodInvocationNodeHelper helper = new MethodInvocationNodeHelper(providingNode);
        final String methodName = helper.getMethodName();
        LOGGER.debug("Providing hover for node: {}, method: {}", previousSiblingNode.getTokenValue(), methodName);
        if (methodName != null) {
            final ITypeKeeper typeKeeper = magikFile.getTypeKeeper();
            final LocalTypeReasoner reasoner = magikFile.getTypeReasoner();
            this.buildMethodDoc(typeKeeper, reasoner, previousSiblingNode, methodName, builder);
        }
    }
}
Also used : LocalTypeReasoner(nl.ramsolutions.sw.magik.analysis.typing.LocalTypeReasoner) AstNode(com.sonar.sslr.api.AstNode) MethodInvocationNodeHelper(nl.ramsolutions.sw.magik.analysis.helpers.MethodInvocationNodeHelper) ITypeKeeper(nl.ramsolutions.sw.magik.analysis.typing.ITypeKeeper)

Example 7 with AstNode

use of com.sonar.sslr.api.AstNode in project magik-tools by StevenLooman.

the class HoverProvider method buildTypeDoc.

/**
 * Build hover text for type doc.
 * @param typeKeeper TypeKeeper.
 * @param reasoner {{LocalTypeReasoner}} which has reasoned over the AST.
 * @param node {{AstNode}} to get info from.
 * @param builder {{StringBuilder}} to fill.
 */
private void buildTypeDoc(final ITypeKeeper typeKeeper, final LocalTypeReasoner reasoner, final AstNode node, final StringBuilder builder) {
    // Get type from reasoner.
    final ExpressionResult result = reasoner.getNodeType(node);
    // We know what self is.
    AbstractType type = result.get(0, UndefinedType.INSTANCE);
    if (type == SelfType.INSTANCE) {
        final AstNode methodDefNode = node.getFirstAncestor(MagikGrammar.METHOD_DEFINITION);
        if (methodDefNode == null) {
            // This can happen in case of a procedure definition calling a method on _self.
            type = UndefinedType.INSTANCE;
        } else {
            final MethodDefinitionNodeHelper methodDefHelper = new MethodDefinitionNodeHelper(methodDefNode);
            final GlobalReference globalRef = methodDefHelper.getTypeGlobalReference();
            type = typeKeeper.getType(globalRef);
        }
    }
    this.buildTypeSignatureDoc(type, builder);
}
Also used : ExpressionResult(nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult) GlobalReference(nl.ramsolutions.sw.magik.analysis.typing.types.GlobalReference) AbstractType(nl.ramsolutions.sw.magik.analysis.typing.types.AbstractType) MethodDefinitionNodeHelper(nl.ramsolutions.sw.magik.analysis.helpers.MethodDefinitionNodeHelper) AstNode(com.sonar.sslr.api.AstNode)

Example 8 with AstNode

use of com.sonar.sslr.api.AstNode in project magik-tools by StevenLooman.

the class HoverProvider method provideHover.

/**
 * Provide a hover at the given position.
 * @param magikFile Magik file.
 * @param position Position in file.
 * @return Hover at position.
 */
public Hover provideHover(final MagikTypedFile magikFile, final Position position) {
    // Parse and reason magik.
    final AstNode node = magikFile.getTopNode();
    final AstNode hoveredTokenNode = AstQuery.nodeAt(node, Lsp4jConversion.positionFromLsp4j(position));
    if (hoveredTokenNode == null) {
        return null;
    }
    final AstNode hoveredNode = hoveredTokenNode.getParent();
    LOGGER.debug("Hovering on: {}", hoveredNode.getTokenValue());
    // See what we should provide a hover for.
    final StringBuilder builder = new StringBuilder();
    if (hoveredNode.is(MagikGrammar.IDENTIFIER) && hoveredNode.getParent().is(MagikGrammar.METHOD_DEFINITION)) {
        // Method definition (exemplar or method name).
        this.provideHoverMethodDefinition(magikFile, hoveredNode, builder);
    } else if (hoveredNode.is(MagikGrammar.IDENTIFIER) && hoveredNode.getParent().is(MagikGrammar.METHOD_INVOCATION)) {
        this.provideHoverMethodInvocation(magikFile, hoveredNode, builder);
    } else if (hoveredNode.getParent().is(MagikGrammar.ATOM) || hoveredNode.getParent().is(MagikGrammar.SLOT)) {
        final AstNode atomNode = hoveredNode.getFirstAncestor(MagikGrammar.ATOM);
        this.provideHoverAtom(magikFile, atomNode, builder);
    } else if (hoveredNode.getParent().is(MagikGrammar.PARAMETER)) {
        final AstNode parameterNode = hoveredNode.getParent();
        this.provideHoverAtom(magikFile, parameterNode, builder);
    }
    final MarkupContent contents = new MarkupContent(MarkupKind.MARKDOWN, builder.toString());
    final Range range = new Range(hoveredTokenNode);
    final org.eclipse.lsp4j.Range rangeLsp4j = Lsp4jConversion.rangeToLsp4j(range);
    return new Hover(contents, rangeLsp4j);
}
Also used : Hover(org.eclipse.lsp4j.Hover) Range(nl.ramsolutions.sw.magik.analysis.Range) MarkupContent(org.eclipse.lsp4j.MarkupContent) AstNode(com.sonar.sslr.api.AstNode)

Example 9 with AstNode

use of com.sonar.sslr.api.AstNode in project magik-tools by StevenLooman.

the class LocalTypeReasoner method getMethodOwnerType.

// endregion
private AbstractType getMethodOwnerType(final AstNode node) {
    final AstNode methodDefNode = node.getFirstAncestor(MagikGrammar.METHOD_DEFINITION);
    if (methodDefNode == null) {
        // This can happen in case of a procedure definition calling a method on _self.
        return UndefinedType.INSTANCE;
    }
    final MethodDefinitionNodeHelper helper = new MethodDefinitionNodeHelper(methodDefNode);
    final GlobalReference globalRef = helper.getTypeGlobalReference();
    return this.typeKeeper.getType(globalRef);
}
Also used : GlobalReference(nl.ramsolutions.sw.magik.analysis.typing.types.GlobalReference) MethodDefinitionNodeHelper(nl.ramsolutions.sw.magik.analysis.helpers.MethodDefinitionNodeHelper) AstNode(com.sonar.sslr.api.AstNode)

Example 10 with AstNode

use of com.sonar.sslr.api.AstNode in project magik-tools by StevenLooman.

the class LocalTypeReasoner method walkPostSlot.

// region: Atoms
@Override
protected void walkPostSlot(final AstNode node) {
    // Get class type.
    final AbstractType type = this.getMethodOwnerType(node);
    if (type == UndefinedType.INSTANCE) {
        LOGGER.debug("Unknown type for node: {}", node);
        return;
    }
    // Get slot type.
    final AstNode identifierNode = node.getFirstChild(MagikGrammar.IDENTIFIER);
    final String slotName = identifierNode.getTokenValue();
    final Slot slot = type.getSlot(slotName);
    final AbstractType slotType = slot != null ? slot.getType() : UndefinedType.INSTANCE;
    Objects.requireNonNull(slotType);
    this.assignAtom(node, slotType);
}
Also used : AbstractType(nl.ramsolutions.sw.magik.analysis.typing.types.AbstractType) Slot(nl.ramsolutions.sw.magik.analysis.typing.types.Slot) AstNode(com.sonar.sslr.api.AstNode)

Aggregations

AstNode (com.sonar.sslr.api.AstNode)491 Test (org.junit.Test)108 Test (org.junit.jupiter.api.Test)91 ExpressionResult (nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult)71 Token (com.sonar.sslr.api.Token)50 AbstractType (nl.ramsolutions.sw.magik.analysis.typing.types.AbstractType)49 Token (org.sonar.plugins.python.api.tree.Token)46 MagikTypedFile (nl.ramsolutions.sw.magik.MagikTypedFile)41 YieldExpression (org.sonar.plugins.python.api.tree.YieldExpression)40 FormattedExpression (org.sonar.plugins.python.api.tree.FormattedExpression)39 QualifiedExpression (org.sonar.plugins.python.api.tree.QualifiedExpression)39 AssignmentExpression (org.sonar.plugins.python.api.tree.AssignmentExpression)38 ComprehensionExpression (org.sonar.plugins.python.api.tree.ComprehensionExpression)38 ConditionalExpression (org.sonar.plugins.python.api.tree.ConditionalExpression)38 Expression (org.sonar.plugins.python.api.tree.Expression)38 LambdaExpression (org.sonar.plugins.python.api.tree.LambdaExpression)38 List (java.util.List)35 RuleTest (org.sonar.python.parser.RuleTest)34 ArrayList (java.util.ArrayList)33 MagikType (nl.ramsolutions.sw.magik.analysis.typing.types.MagikType)33