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);
}
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);
}
}
}
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);
}
});
}
}
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);
});
}
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);
});
}
Aggregations