Search in sources :

Example 61 with AstNode

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

the class LocalTypeReasonerTest method testParameterType.

@Test
void testParameterType() {
    final String code = "" + "_method a.b(p1)\n" + "  ## @param {sw:float} p1\n" + "_endmethod";
    // Set up TypeKeeper/TypeReasoner.
    final TypeKeeper typeKeeper = new TypeKeeper();
    // Do analysis.
    final MagikTypedFile magikFile = this.createMagikFile(code, typeKeeper);
    final LocalTypeReasoner reasoner = magikFile.getTypeReasoner();
    final AstNode topNode = magikFile.getTopNode();
    final AstNode parameterNode = topNode.getFirstDescendant(MagikGrammar.PARAMETER);
    final ExpressionResult result = reasoner.getNodeType(parameterNode);
    assertThat(result).isNotNull();
    final AbstractType floatType = typeKeeper.getType(GlobalReference.of("sw:float"));
    final AbstractType actualType = result.get(0, null);
    assertThat(actualType).isNotNull().isEqualTo(floatType);
}
Also used : ExpressionResult(nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult) AbstractType(nl.ramsolutions.sw.magik.analysis.typing.types.AbstractType) MagikTypedFile(nl.ramsolutions.sw.magik.MagikTypedFile) AstNode(com.sonar.sslr.api.AstNode) Test(org.junit.jupiter.api.Test)

Example 62 with AstNode

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

the class MethodArgumentCountTypedCheck method walkPostMethodInvocation.

@Override
protected void walkPostMethodInvocation(final AstNode node) {
    // Ensure there are arguments to check.
    final AstNode argumentsNode = node.getFirstChild(MagikGrammar.ARGUMENTS);
    if (argumentsNode == null) {
        return;
    }
    // Don't bother checking scatter.
    final boolean anyScatter = argumentsNode.getChildren(MagikGrammar.ARGUMENT).stream().anyMatch(argumentNode -> {
        AstNode unaryExprNode = AstQuery.getFirstChildFromChain(node, MagikGrammar.EXPRESSION, MagikGrammar.UNARY_EXPRESSION);
        String tokenValue = unaryExprNode != null ? unaryExprNode.getTokenValue() : null;
        return tokenValue != null && tokenValue.equalsIgnoreCase(MagikKeyword.SCATTER.getValue());
    });
    if (anyScatter) {
        return;
    }
    // Get type.
    final AbstractType calledType = this.getTypeInvokedOn(node);
    if (calledType == UndefinedType.INSTANCE) {
        // Cannot give any useful information, so abort.
        return;
    }
    // Get methods.
    final MethodInvocationNodeHelper helper = new MethodInvocationNodeHelper(node);
    final String methodName = helper.getMethodName();
    for (final Method method : calledType.getMethods(methodName)) {
        final List<Parameter> parameters = method.getParameters();
        if (parameters.isEmpty()) {
            continue;
        }
        // Match arguments against method.parameters.
        final List<AstNode> argumentNodes = argumentsNode.getChildren(MagikGrammar.ARGUMENT);
        final List<Parameter> checkedParameters = method.getParameters().stream().filter(parameter -> parameter.is(Parameter.Modifier.NONE)).collect(Collectors.toList());
        if (checkedParameters.size() > argumentNodes.size()) {
            final String message = String.format(MESSAGE, methodName);
            this.addIssue(node, message);
        }
    }
}
Also used : Method(nl.ramsolutions.sw.magik.analysis.typing.types.Method) MethodInvocationNodeHelper(nl.ramsolutions.sw.magik.analysis.helpers.MethodInvocationNodeHelper) AstNode(com.sonar.sslr.api.AstNode) List(java.util.List) 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) MagikTypedCheck(nl.ramsolutions.sw.magik.typedchecks.MagikTypedCheck) Parameter(nl.ramsolutions.sw.magik.analysis.typing.types.Parameter) Collectors(java.util.stream.Collectors) AstQuery(nl.ramsolutions.sw.magik.analysis.AstQuery) MagikGrammar(nl.ramsolutions.sw.magik.api.MagikGrammar) AbstractType(nl.ramsolutions.sw.magik.analysis.typing.types.AbstractType) Parameter(nl.ramsolutions.sw.magik.analysis.typing.types.Parameter) Method(nl.ramsolutions.sw.magik.analysis.typing.types.Method) AstNode(com.sonar.sslr.api.AstNode) MethodInvocationNodeHelper(nl.ramsolutions.sw.magik.analysis.helpers.MethodInvocationNodeHelper)

Example 63 with AstNode

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

the class MethodArgumentParameterTypedCheck method walkPostMethodInvocation.

@Override
protected void walkPostMethodInvocation(final AstNode node) {
    // Ensure there are arguments to check.
    final AstNode argumentsNode = node.getFirstChild(MagikGrammar.ARGUMENTS);
    if (argumentsNode == null) {
        return;
    }
    // Get type.
    final AbstractType calledType = this.getTypeInvokedOn(node);
    if (calledType == UndefinedType.INSTANCE) {
        // Cannot give any useful information, so abort.
        return;
    }
    // Get types for arguments.
    final LocalTypeReasoner reasoner = this.getReasoner();
    final List<AstNode> argumentNodes = argumentsNode.getChildren(MagikGrammar.ARGUMENT).stream().collect(Collectors.toList());
    final List<ExpressionResult> argumentTypes = argumentNodes.stream().map(argumentNode -> argumentNode.getFirstChild(MagikGrammar.EXPRESSION)).map(reasoner::getNodeType).collect(Collectors.toList());
    // Get methods.
    final MethodInvocationNodeHelper helper = new MethodInvocationNodeHelper(node);
    final String methodName = helper.getMethodName();
    for (final Method method : calledType.getMethods(methodName)) {
        final List<Parameter> parameters = method.getParameters();
        if (parameters.isEmpty()) {
            continue;
        }
        final List<AbstractType> parameterTypes = method.getParameters().stream().filter(parameter -> parameter.is(Parameter.Modifier.NONE) || // Don't check gather.
        parameter.is(Parameter.Modifier.OPTIONAL)).map(Parameter::getType).collect(Collectors.toList());
        // Test parameter type against argument type.
        final int size = Math.min(parameterTypes.size(), argumentTypes.size());
        IntStream.range(0, size).forEach(index -> {
            final AbstractType parameterType = parameterTypes.get(index);
            if (parameterType == UndefinedType.INSTANCE) {
                return;
            }
            final AbstractType argumentType = argumentTypes.get(index).get(0, UndefinedType.INSTANCE);
            if (!TypeMatcher.typeMatches(argumentType, parameterType)) {
                final AstNode argumentNode = argumentNodes.get(index);
                final String message = String.format(MESSAGE, argumentType.getFullName(), parameterType.getFullName());
                this.addIssue(argumentNode, message);
            }
        });
    }
}
Also used : ExpressionResult(nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult) LocalTypeReasoner(nl.ramsolutions.sw.magik.analysis.typing.LocalTypeReasoner) Method(nl.ramsolutions.sw.magik.analysis.typing.types.Method) MethodInvocationNodeHelper(nl.ramsolutions.sw.magik.analysis.helpers.MethodInvocationNodeHelper) AbstractType(nl.ramsolutions.sw.magik.analysis.typing.types.AbstractType) Parameter(nl.ramsolutions.sw.magik.analysis.typing.types.Parameter) AstNode(com.sonar.sslr.api.AstNode)

Example 64 with AstNode

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

the class NewDocTypeExistsTypeCheck method checkDefinitionLoops.

private void checkDefinitionLoops(final NewDocParser newDocParser, final String pakkage) {
    // Test @loop types.
    final ITypeKeeper typeKeeper = this.getTypeKeeper();
    final TypeParser typeParser = new TypeParser(typeKeeper);
    newDocParser.getLoopTypeNodes().entrySet().stream().filter(entry -> typeParser.parseTypeString(entry.getValue(), pakkage) == UndefinedType.INSTANCE).forEach(entry -> {
        final AstNode typeNode = entry.getKey();
        final String typeName = entry.getValue();
        final String message = String.format(MESSAGE, typeName);
        this.addIssue(typeNode, message);
    });
}
Also used : TypeParser(nl.ramsolutions.sw.magik.analysis.typing.TypeParser) AstNode(com.sonar.sslr.api.AstNode) UndefinedType(nl.ramsolutions.sw.magik.analysis.typing.types.UndefinedType) DefSlottedExemplarParser(nl.ramsolutions.sw.magik.analysis.definitions.DefSlottedExemplarParser) AbstractType(nl.ramsolutions.sw.magik.analysis.typing.types.AbstractType) PackageNodeHelper(nl.ramsolutions.sw.magik.analysis.helpers.PackageNodeHelper) MagikTypedCheck(nl.ramsolutions.sw.magik.typedchecks.MagikTypedCheck) Map(java.util.Map) NewDocParser(nl.ramsolutions.sw.magik.parser.NewDocParser) ITypeKeeper(nl.ramsolutions.sw.magik.analysis.typing.ITypeKeeper) MagikGrammar(nl.ramsolutions.sw.magik.api.MagikGrammar) TypeParser(nl.ramsolutions.sw.magik.analysis.typing.TypeParser) ITypeKeeper(nl.ramsolutions.sw.magik.analysis.typing.ITypeKeeper) AstNode(com.sonar.sslr.api.AstNode)

Example 65 with AstNode

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

the class NewDocTypeExistsTypeCheck method walkPostProcedureInvocation.

@Override
protected void walkPostProcedureInvocation(final AstNode node) {
    if (!DefSlottedExemplarParser.isDefSlottedExemplar(node)) {
        return;
    }
    final ITypeKeeper typeKeeper = this.getTypeKeeper();
    final TypeParser typeParser = new TypeParser(typeKeeper);
    // Get slot defintions.
    final AstNode statementNode = node.getFirstAncestor(MagikGrammar.STATEMENT);
    final NewDocParser newDocParser = new NewDocParser(statementNode);
    final Map<AstNode, String> slotTypeNodes = newDocParser.getSlotTypeNodes();
    final PackageNodeHelper helper = new PackageNodeHelper(node);
    final String currentPakkage = helper.getCurrentPackage();
    // Test slot types.
    slotTypeNodes.entrySet().stream().filter(entry -> {
        final AbstractType type = typeParser.parseTypeString(entry.getValue(), currentPakkage);
        return type == UndefinedType.INSTANCE;
    }).forEach(entry -> {
        final AstNode typeNode = entry.getKey();
        final String typeName = entry.getValue();
        final String message = String.format(MESSAGE, typeName);
        this.addIssue(typeNode, message);
    });
}
Also used : NewDocParser(nl.ramsolutions.sw.magik.parser.NewDocParser) TypeParser(nl.ramsolutions.sw.magik.analysis.typing.TypeParser) AstNode(com.sonar.sslr.api.AstNode) UndefinedType(nl.ramsolutions.sw.magik.analysis.typing.types.UndefinedType) DefSlottedExemplarParser(nl.ramsolutions.sw.magik.analysis.definitions.DefSlottedExemplarParser) AbstractType(nl.ramsolutions.sw.magik.analysis.typing.types.AbstractType) PackageNodeHelper(nl.ramsolutions.sw.magik.analysis.helpers.PackageNodeHelper) MagikTypedCheck(nl.ramsolutions.sw.magik.typedchecks.MagikTypedCheck) Map(java.util.Map) NewDocParser(nl.ramsolutions.sw.magik.parser.NewDocParser) ITypeKeeper(nl.ramsolutions.sw.magik.analysis.typing.ITypeKeeper) MagikGrammar(nl.ramsolutions.sw.magik.api.MagikGrammar) PackageNodeHelper(nl.ramsolutions.sw.magik.analysis.helpers.PackageNodeHelper) TypeParser(nl.ramsolutions.sw.magik.analysis.typing.TypeParser) AbstractType(nl.ramsolutions.sw.magik.analysis.typing.types.AbstractType) ITypeKeeper(nl.ramsolutions.sw.magik.analysis.typing.ITypeKeeper) AstNode(com.sonar.sslr.api.AstNode)

Aggregations

AstNode (com.sonar.sslr.api.AstNode)492 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