use of com.sonar.sslr.api.AstNode in project magik-tools by StevenLooman.
the class HoverProvider method provideHoverMethodInvocation.
/**
* Provide hover for a method invocation.
* @param magikFile Magik file.
* @param hoveredNode Hovered node.
* @param builder Builder to add text to.
*/
private void provideHoverMethodInvocation(final MagikTypedFile magikFile, final AstNode hoveredNode, final StringBuilder builder) {
final AstNode providingNode = hoveredNode.getParent();
final AstNode previousSiblingNode = providingNode.getPreviousSibling();
if (previousSiblingNode != null) {
final MethodInvocationNodeHelper helper = new MethodInvocationNodeHelper(providingNode);
final String methodName = helper.getMethodName();
LOGGER.debug("Providing hover for node: {}, method: {}", previousSiblingNode.getTokenValue(), methodName);
if (methodName != null) {
final ITypeKeeper typeKeeper = magikFile.getTypeKeeper();
final LocalTypeReasoner reasoner = magikFile.getTypeReasoner();
this.buildMethodDoc(typeKeeper, reasoner, previousSiblingNode, methodName, builder);
}
}
}
use of com.sonar.sslr.api.AstNode 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 com.sonar.sslr.api.AstNode in project magik-tools by StevenLooman.
the class HoverProvider method provideHover.
/**
* Provide a hover at the given position.
* @param magikFile Magik file.
* @param position Position in file.
* @return Hover at position.
*/
public Hover provideHover(final MagikTypedFile magikFile, final Position position) {
// Parse and reason magik.
final AstNode node = magikFile.getTopNode();
final AstNode hoveredTokenNode = AstQuery.nodeAt(node, Lsp4jConversion.positionFromLsp4j(position));
if (hoveredTokenNode == null) {
return null;
}
final AstNode hoveredNode = hoveredTokenNode.getParent();
LOGGER.debug("Hovering on: {}", hoveredNode.getTokenValue());
// See what we should provide a hover for.
final StringBuilder builder = new StringBuilder();
if (hoveredNode.is(MagikGrammar.IDENTIFIER) && hoveredNode.getParent().is(MagikGrammar.METHOD_DEFINITION)) {
// Method definition (exemplar or method name).
this.provideHoverMethodDefinition(magikFile, hoveredNode, builder);
} else if (hoveredNode.is(MagikGrammar.IDENTIFIER) && hoveredNode.getParent().is(MagikGrammar.METHOD_INVOCATION)) {
this.provideHoverMethodInvocation(magikFile, hoveredNode, builder);
} else if (hoveredNode.getParent().is(MagikGrammar.ATOM) || hoveredNode.getParent().is(MagikGrammar.SLOT)) {
final AstNode atomNode = hoveredNode.getFirstAncestor(MagikGrammar.ATOM);
this.provideHoverAtom(magikFile, atomNode, builder);
} else if (hoveredNode.getParent().is(MagikGrammar.PARAMETER)) {
final AstNode parameterNode = hoveredNode.getParent();
this.provideHoverAtom(magikFile, parameterNode, builder);
}
final MarkupContent contents = new MarkupContent(MarkupKind.MARKDOWN, builder.toString());
final Range range = new Range(hoveredTokenNode);
final org.eclipse.lsp4j.Range rangeLsp4j = Lsp4jConversion.rangeToLsp4j(range);
return new Hover(contents, rangeLsp4j);
}
use of com.sonar.sslr.api.AstNode in project magik-tools by StevenLooman.
the class LocalTypeReasoner method getMethodOwnerType.
// endregion
private AbstractType getMethodOwnerType(final AstNode node) {
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.
return UndefinedType.INSTANCE;
}
final MethodDefinitionNodeHelper helper = new MethodDefinitionNodeHelper(methodDefNode);
final GlobalReference globalRef = helper.getTypeGlobalReference();
return this.typeKeeper.getType(globalRef);
}
use of com.sonar.sslr.api.AstNode in project magik-tools by StevenLooman.
the class LocalTypeReasoner method walkPostSlot.
// region: Atoms
@Override
protected void walkPostSlot(final AstNode node) {
// Get class type.
final AbstractType type = this.getMethodOwnerType(node);
if (type == UndefinedType.INSTANCE) {
LOGGER.debug("Unknown type for node: {}", node);
return;
}
// Get slot type.
final AstNode identifierNode = node.getFirstChild(MagikGrammar.IDENTIFIER);
final String slotName = identifierNode.getTokenValue();
final Slot slot = type.getSlot(slotName);
final AbstractType slotType = slot != null ? slot.getType() : UndefinedType.INSTANCE;
Objects.requireNonNull(slotType);
this.assignAtom(node, slotType);
}
Aggregations