Search in sources :

Example 1 with ExpressionResult

use of nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult in project magik-tools by StevenLooman.

the class HoverProvider method buildMethodDoc.

/**
 * Build hover text for method doc.
 * @param typeKeeper TypeKeeper.
 * @param reasoner LocalTypeReasoner.
 * @param node AstNode, METHOD_INVOCATION.
 * @param methodName Name of invoked method.
 * @param builder {{StringBuilder}} to fill.
 */
private void buildMethodDoc(final ITypeKeeper typeKeeper, final LocalTypeReasoner reasoner, final AstNode node, final String methodName, 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 helper = new MethodDefinitionNodeHelper(methodDefNode);
            final GlobalReference globalRef = helper.getTypeGlobalReference();
            type = typeKeeper.getType(globalRef);
        }
    }
    // Get method info.
    final Collection<Method> methods = type.getMethods(methodName);
    if (methods.isEmpty()) {
        this.buildMethodUnknownDoc(type, methodName, builder);
        return;
    }
    methods.forEach(method -> this.buildMethodSignatureDoc(method, 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) Method(nl.ramsolutions.sw.magik.analysis.typing.types.Method) AstNode(com.sonar.sslr.api.AstNode)

Example 2 with ExpressionResult

use of nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult in project magik-tools by StevenLooman.

the class HoverProvider method provideHoverAtom.

/**
 * Provide hover for an atom.
 * @param magikFile Magik file.
 * @param atomNode Atom node hovered on.
 * @param builder Builder to add text to.
 */
private void provideHoverAtom(final MagikTypedFile magikFile, final AstNode atomNode, final StringBuilder builder) {
    final LocalTypeReasoner reasoner = magikFile.getTypeReasoner();
    final ExpressionResult result = reasoner.getNodeTypeSilent(atomNode);
    if (result != null) {
        LOGGER.debug("Providing hover for node: {}", atomNode.getTokenValue());
        final ITypeKeeper typeKeeper = magikFile.getTypeKeeper();
        this.buildTypeDoc(typeKeeper, reasoner, atomNode, builder);
    }
}
Also used : ExpressionResult(nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult) LocalTypeReasoner(nl.ramsolutions.sw.magik.analysis.typing.LocalTypeReasoner) ITypeKeeper(nl.ramsolutions.sw.magik.analysis.typing.ITypeKeeper)

Example 3 with ExpressionResult

use of nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult 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 4 with ExpressionResult

use of nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult in project magik-tools by StevenLooman.

the class LocalTypeReasoner method walkPostBody.

@Override
protected void walkPostBody(final AstNode node) {
    // Get result from upper EXPRESSION.
    final AstNode expressionNode = node.getFirstAncestor(MagikGrammar.EXPRESSION);
    if (expressionNode == null) {
        // Happens with a return, don't do anything.
        return;
    }
    ExpressionResult result = this.getNodeType(expressionNode);
    // BODYs don't always have to result in something.
    // Find STATEMENT -> RETURN/EMIT/LEAVE
    // TODO: what about _loop _if .. _then _leave _with _endif _leave _with _endloop
    AstNode resultingNode = AstQuery.getFirstChildFromChain(node, MagikGrammar.STATEMENT, MagikGrammar.RETURN_STATEMENT);
    if (resultingNode == null) {
        resultingNode = AstQuery.getFirstChildFromChain(node, MagikGrammar.STATEMENT, MagikGrammar.EMIT_STATEMENT);
    }
    if (resultingNode == null) {
        resultingNode = AstQuery.getFirstChildFromChain(node, MagikGrammar.STATEMENT, MagikGrammar.LEAVE_STATEMENT);
    }
    if (resultingNode == null) {
        // Result can also be an unset, as no resulting statement was found.
        // TODO: but... "_block _block _return 1 _endblock _endblock"
        final ExpressionResult emptyResult = new ExpressionResult();
        final AbstractType unsetType = this.typeKeeper.getType(SW_UNSET);
        result = new ExpressionResult(result, emptyResult, unsetType);
    }
    // Set parent EXPRESSION result.
    this.setNodeType(expressionNode, result);
}
Also used : ExpressionResult(nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult) AbstractType(nl.ramsolutions.sw.magik.analysis.typing.types.AbstractType) AstNode(com.sonar.sslr.api.AstNode)

Example 5 with ExpressionResult

use of nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult in project magik-tools by StevenLooman.

the class LocalTypeReasoner method walkPostLoopbody.

@Override
protected void walkPostLoopbody(final AstNode node) {
    final AbstractType unsetType = this.typeKeeper.getType(SW_UNSET);
    // Get results.
    final AstNode multiValueExprNode = node.getFirstChild(MagikGrammar.TUPLE);
    final ExpressionResult result = this.getNodeType(multiValueExprNode);
    // Find related node to store at.
    final AstNode procMethodDefNode = node.getFirstAncestor(MagikGrammar.PROCEDURE_DEFINITION, MagikGrammar.METHOD_DEFINITION);
    // Save results.
    if (this.hasNodeType(procMethodDefNode)) {
        // Combine types.
        final ExpressionResult existingResult = this.getNodeType(procMethodDefNode);
        final ExpressionResult combinedResult = new ExpressionResult(existingResult, result, unsetType);
        this.setLoopbodyNodeType(procMethodDefNode, combinedResult);
    } else {
        this.setLoopbodyNodeType(procMethodDefNode, result);
    }
}
Also used : ExpressionResult(nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult) AbstractType(nl.ramsolutions.sw.magik.analysis.typing.types.AbstractType) AstNode(com.sonar.sslr.api.AstNode)

Aggregations

ExpressionResult (nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult)78 AstNode (com.sonar.sslr.api.AstNode)68 AbstractType (nl.ramsolutions.sw.magik.analysis.typing.types.AbstractType)41 MagikTypedFile (nl.ramsolutions.sw.magik.MagikTypedFile)37 Test (org.junit.jupiter.api.Test)34 MagikType (nl.ramsolutions.sw.magik.analysis.typing.types.MagikType)29 GlobalScope (nl.ramsolutions.sw.magik.analysis.scope.GlobalScope)13 Scope (nl.ramsolutions.sw.magik.analysis.scope.Scope)13 Method (nl.ramsolutions.sw.magik.analysis.typing.types.Method)13 ScopeEntry (nl.ramsolutions.sw.magik.analysis.scope.ScopeEntry)12 GlobalReference (nl.ramsolutions.sw.magik.analysis.typing.types.GlobalReference)12 MethodInvocationNodeHelper (nl.ramsolutions.sw.magik.analysis.helpers.MethodInvocationNodeHelper)9 LocalTypeReasoner (nl.ramsolutions.sw.magik.analysis.typing.LocalTypeReasoner)9 MethodDefinitionNodeHelper (nl.ramsolutions.sw.magik.analysis.helpers.MethodDefinitionNodeHelper)8 SelfType (nl.ramsolutions.sw.magik.analysis.typing.types.SelfType)8 SlottedType (nl.ramsolutions.sw.magik.analysis.typing.types.SlottedType)8 List (java.util.List)7 ITypeKeeper (nl.ramsolutions.sw.magik.analysis.typing.ITypeKeeper)7 Parameter (nl.ramsolutions.sw.magik.analysis.typing.types.Parameter)7 UndefinedType (nl.ramsolutions.sw.magik.analysis.typing.types.UndefinedType)7