use of com.sonar.sslr.api.AstNode 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);
}
use of com.sonar.sslr.api.AstNode in project magik-tools by StevenLooman.
the class ArgumentsNodeHelper method getArgument.
/**
* Get the nth argument.
* @param nth Nth argument.
* @return Nth argument.
*/
@CheckForNull
public AstNode getArgument(final int nth) {
final List<AstNode> argumentNodes = this.node.getChildren(MagikGrammar.ARGUMENT);
if (argumentNodes.size() - 1 < nth) {
return null;
}
final AstNode argumentNode = argumentNodes.get(nth);
return argumentNode.getFirstChild(MagikGrammar.EXPRESSION);
}
use of com.sonar.sslr.api.AstNode in project magik-tools by StevenLooman.
the class ExpressionNodeHelper method getConstant.
/**
* Get a constant (literal) from the encapsulated expresion.
* @return Constant (literal) value, if found.
*/
@CheckForNull
public String getConstant() {
AstNode atomNode = node.getFirstChild(MagikGrammar.ATOM);
if (atomNode == null) {
return null;
}
AstNode valueNode = atomNode.getFirstChild(MagikGrammar.NUMBER, MagikGrammar.SYMBOL, MagikGrammar.STRING, MagikGrammar.CHARACTER, MagikGrammar.REGEXP, MagikGrammar.GLOBAL_REF);
if (valueNode == null) {
return null;
}
return valueNode.getTokens().stream().map(Token::getValue).collect(Collectors.joining());
}
use of com.sonar.sslr.api.AstNode in project magik-tools by StevenLooman.
the class LeaveStatementNodeHelper method getRelatedBodyNode.
/**
* Get the related BODY node we're leaving from.
* @return Body node.
*/
@SuppressWarnings("checkstyle:NestedIfDepth")
public AstNode getRelatedBodyNode() {
final AstNode wantedLabelNode = this.node.getFirstChild(MagikGrammar.LABEL);
if (wantedLabelNode != null) {
final LabelNodeHelper labelHelper = new LabelNodeHelper(wantedLabelNode);
final String wantedLabel = labelHelper.getIdentifier();
// Find parent BODY node with label
AstNode bodyNode = this.node.getFirstAncestor(MagikGrammar.BODY);
while (bodyNode != null) {
// Check if current BODY node has our wanted label.
final AstNode bodyLabelNode = bodyNode.getPreviousSibling();
if (bodyLabelNode != null && bodyLabelNode.is(MagikGrammar.LABEL)) {
final LabelNodeHelper bodyLabelHelper = new LabelNodeHelper(bodyLabelNode);
final String bodyLabel = bodyLabelHelper.getIdentifier();
if (bodyLabel.equals(wantedLabel)) {
return bodyNode;
}
}
// Continue searching upwards.
bodyNode = bodyNode.getFirstAncestor(MagikGrammar.BODY);
}
}
// If no BODY node was found and statement is a LEAVE, then find nearest _loop.
// Find nearest LOOP or BODY statement.
final AstNode loopNode = node.getFirstAncestor(MagikGrammar.LOOP);
if (loopNode != null) {
return loopNode.getFirstChild(MagikGrammar.BODY);
}
if (node.is(MagikGrammar.RETURN_STATEMENT)) {
// Find furthest BODY statement.
final AstNode procedureNode = node.getFirstAncestor(MagikGrammar.PROCEDURE_DEFINITION, MagikGrammar.METHOD_DEFINITION);
final AstNode bodyNode = procedureNode.getFirstChild(MagikGrammar.BODY);
if (bodyNode != null) {
return bodyNode;
}
}
// Last resort, use nearest body.
return node.getFirstAncestor(MagikGrammar.BODY);
}
use of com.sonar.sslr.api.AstNode in project magik-tools by StevenLooman.
the class MethodInvocationNodeHelper method getMethodName.
/**
* Get invoked method name.
* @return Invoked method name.
*/
public String getMethodName() {
// Get arguments
final AstNode argumentsNode = node.getFirstChild(MagikGrammar.ARGUMENTS);
final List<AstNode> argumentNodes = argumentsNode != null ? argumentsNode.getChildren(MagikGrammar.ARGUMENT) : Collections.emptyList();
// Construct name.
String methodName = "";
final AstNode identifierNode = node.getFirstChild(MagikGrammar.IDENTIFIER);
methodName += identifierNode != null ? identifierNode.getTokenValue() : "";
if (argumentsNode != null) {
if (this.anyChildTokenIs(argumentsNode, MagikPunctuator.SQUARE_L)) {
methodName += "[";
int commaCount = Math.max(argumentNodes.size() - 1, 0);
methodName += ",".repeat(commaCount);
methodName += "]";
}
if (this.anyChildTokenIs(argumentsNode, MagikPunctuator.PAREN_L)) {
methodName += MagikPunctuator.PAREN_L.getValue() + MagikPunctuator.PAREN_R.getValue();
}
}
if (this.anyChildTokenIs(node, MagikOperator.CHEVRON)) {
methodName += MagikOperator.CHEVRON.getValue();
}
if (this.anyChildTokenIs(node, MagikOperator.BOOT_CHEVRON)) {
methodName += MagikOperator.BOOT_CHEVRON.getValue();
}
return methodName;
}
Aggregations