Search in sources :

Example 16 with ExpressionResult

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

the class LocalTypeReasoner method walkPostAssignmentParameter.

@Override
protected void walkPostAssignmentParameter(final AstNode node) {
    final ExpressionResult result = ExpressionResult.UNDEFINED;
    this.setNodeType(node, result);
}
Also used : ExpressionResult(nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult)

Example 17 with ExpressionResult

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

the class LocalTypeReasoner method walkPostAugmentedAssignmentExpression.

@Override
protected void walkPostAugmentedAssignmentExpression(final AstNode node) {
    final AbstractType unsetType = this.typeKeeper.getType(SW_UNSET);
    final AbstractType falseType = this.typeKeeper.getType(SW_FALSE);
    // Take result from right hand.
    final AstNode rightNode = node.getLastChild();
    final ExpressionResult rightResult = this.getNodeType(rightNode);
    // Get left hand result.
    final AstNode assignedNode = node.getFirstChild();
    final ExpressionResult leftResult = this.getNodeType(assignedNode);
    // Get operator.
    final AstNode operatorNode = node.getChildren().get(1);
    final String operatorStr = operatorNode.getTokenValue();
    // Evaluate binary operator.
    final AbstractType leftType = leftResult.get(0, unsetType);
    final AbstractType rightType = rightResult.get(0, unsetType);
    final ExpressionResult result;
    switch(operatorStr.toLowerCase()) {
        case "_is":
        case "_isnt":
            result = new ExpressionResult(falseType);
            break;
        // TODO: Not entirely true.
        case "_andif":
        case // TODO: Not entirely true.
        "_orif":
            result = new ExpressionResult(falseType);
            break;
        default:
            final BinaryOperator.Operator operator = BinaryOperator.Operator.valueFor(operatorStr);
            final BinaryOperator binaryOperator = this.typeKeeper.getBinaryOperator(operator, leftType, rightType);
            final AbstractType resultingType = binaryOperator != null ? binaryOperator.getResultType() : UndefinedType.INSTANCE;
            result = new ExpressionResult(resultingType);
            break;
    }
    // Store result of expression.
    this.setNodeType(node, result);
    if (assignedNode.is(MagikGrammar.ATOM)) {
        // Store 'active' type for future reference.
        final Scope scope = this.globalScope.getScopeForNode(assignedNode);
        Objects.requireNonNull(scope);
        final String identifier = assignedNode.getTokenValue();
        final ScopeEntry scopeEntry = scope.getScopeEntry(identifier);
        this.currentScopeEntryNodes.put(scopeEntry, assignedNode);
        this.setNodeType(assignedNode, result);
    }
}
Also used : ScopeEntry(nl.ramsolutions.sw.magik.analysis.scope.ScopeEntry) GlobalScope(nl.ramsolutions.sw.magik.analysis.scope.GlobalScope) Scope(nl.ramsolutions.sw.magik.analysis.scope.Scope) 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 18 with ExpressionResult

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

the class LocalTypeReasoner method walkPostProcedureInvocation.

@Override
protected void walkPostProcedureInvocation(final AstNode node) {
    final AbstractType unsetType = this.typeKeeper.getType(SW_UNSET);
    // Get called type for invocation.
    final AstNode calledNode = node.getPreviousSibling();
    final ExpressionResult calledResult = this.getNodeType(calledNode);
    AbstractType calledType = calledResult.get(0, unsetType);
    final AbstractType originalCalledType = calledType;
    if (calledType == SelfType.INSTANCE) {
        // Replace self type with concrete type, need to know the method we call.
        calledType = this.typeKeeper.getType(SW_PROCEDURE);
    }
    // Clear iterator results.
    this.setIteratorType(null);
    // Perform procedure call.
    ExpressionResult callResult = null;
    if (calledType instanceof ProcedureInstance) {
        final ProcedureInstance procedureType = (ProcedureInstance) calledType;
        final Collection<Method> methods = procedureType.getMethods("invoke()");
        final Method method = methods.stream().findAny().orElse(null);
        Objects.requireNonNull(method);
        callResult = method.getCallResult();
        final ExpressionResult loopbodyResult = method.getLoopbodyResult();
        this.setIteratorType(loopbodyResult);
        if (originalCalledType == SelfType.INSTANCE) {
            callResult = callResult.substituteType(SelfType.INSTANCE, calledType);
            final ExpressionResult subbedResult = this.getIteratorType().substituteType(SelfType.INSTANCE, calledType);
            this.setIteratorType(subbedResult);
        }
    }
    if (callResult == null) {
        callResult = ExpressionResult.UNDEFINED;
        this.setIteratorType(ExpressionResult.UNDEFINED);
    }
    // Store it!
    this.setNodeType(node, callResult);
}
Also used : ExpressionResult(nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult) AbstractType(nl.ramsolutions.sw.magik.analysis.typing.types.AbstractType) ProcedureInstance(nl.ramsolutions.sw.magik.analysis.typing.types.ProcedureInstance) Method(nl.ramsolutions.sw.magik.analysis.typing.types.Method) AstNode(com.sonar.sslr.api.AstNode)

Example 19 with ExpressionResult

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

the class LocalTypeReasonerTest method testReasonMethodReturnProc.

@Test
void testReasonMethodReturnProc() {
    final String code = "" + "_method object.test\n" + "    _return _proc@test()\n" + "                >> 10\n" + "            _endproc\n" + "_endmethod\n";
    // Set up TypeKeeper/TypeReasoner.
    final TypeKeeper typeKeeper = new TypeKeeper();
    // Do analysis.
    final MagikTypedFile magikFile = this.createMagikFile(code, typeKeeper);
    final LocalTypeReasoner reasoner = magikFile.getTypeReasoner();
    // Assert user:object.test type determined.
    final AstNode topNode = magikFile.getTopNode();
    final AstNode methodNode = topNode.getFirstChild(MagikGrammar.METHOD_DEFINITION);
    final ExpressionResult result = reasoner.getNodeType(methodNode);
    assertThat(result.size()).isEqualTo(1);
    final ProcedureInstance resultType = (ProcedureInstance) result.get(0, null);
    assertThat(resultType).isNotNull();
    assertThat(resultType.getProcedureName()).isEqualTo("test");
    final Collection<Method> procMethods = resultType.getMethods("invoke()");
    assertThat(procMethods).isNotEmpty();
    for (final Method procMethod : procMethods) {
        final ExpressionResult procResult = procMethod.getCallResult();
        assertThat(procResult.size()).isEqualTo(1);
        final MagikType procResultType = (MagikType) procResult.get(0, null);
        assertThat(procResultType).isNotNull();
        assertThat(procResultType.getFullName()).isEqualTo("sw:integer");
    }
}
Also used : ExpressionResult(nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult) ProcedureInstance(nl.ramsolutions.sw.magik.analysis.typing.types.ProcedureInstance) Method(nl.ramsolutions.sw.magik.analysis.typing.types.Method) MagikTypedFile(nl.ramsolutions.sw.magik.MagikTypedFile) AstNode(com.sonar.sslr.api.AstNode) MagikType(nl.ramsolutions.sw.magik.analysis.typing.types.MagikType) Test(org.junit.jupiter.api.Test)

Example 20 with ExpressionResult

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

the class LocalTypeReasonerTest method testEmptyLocalDefinition.

@Test
void testEmptyLocalDefinition() {
    final String code = "" + "_method object.test\n" + "    _local a\n" + "    _return a\n" + "_endmethod\n";
    // Set up TypeKeeper/TypeReasoner.
    final TypeKeeper typeKeeper = new TypeKeeper();
    // Do analysis.
    final MagikTypedFile magikFile = this.createMagikFile(code, typeKeeper);
    final LocalTypeReasoner reasoner = magikFile.getTypeReasoner();
    // Assert user:object.test type determined.
    final AstNode topNode = magikFile.getTopNode();
    final AstNode methodNode = topNode.getFirstChild(MagikGrammar.METHOD_DEFINITION);
    final ExpressionResult result = reasoner.getNodeType(methodNode);
    assertThat(result.size()).isEqualTo(1);
    final MagikType resultType = (MagikType) result.get(0, null);
    assertThat(resultType).isNotNull();
    assertThat(resultType.getFullName()).isEqualTo("sw:unset");
}
Also used : ExpressionResult(nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult) MagikTypedFile(nl.ramsolutions.sw.magik.MagikTypedFile) AstNode(com.sonar.sslr.api.AstNode) MagikType(nl.ramsolutions.sw.magik.analysis.typing.types.MagikType) Test(org.junit.jupiter.api.Test)

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