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