use of nl.ramsolutions.sw.magik.analysis.definitions.ParameterDefinition in project magik-tools by StevenLooman.
the class MagikIndexer method handleDefinition.
private void handleDefinition(final MagikFile magikFile, final MethodDefinition definition) {
final AstNode node = definition.getNode();
if (node.isNot(MagikGrammar.METHOD_DEFINITION)) {
// No slot accessors, shared variables, shared constants.
this.handleMethodDefinitionOther(magikFile, definition);
return;
}
// Get exemplar.
final GlobalReference globalRef = definition.getTypeGlobalReference();
final AbstractType exemplarType = this.typeKeeper.getType(globalRef);
if (exemplarType == UndefinedType.INSTANCE) {
LOGGER.warn("Unknown type: {}", globalRef);
return;
}
// Combine parameter types with method docs.
final NewDocParser newDocParser = new NewDocParser(node);
final Map<String, String> parameterTypes = newDocParser.getParameterTypes();
final List<Parameter> parameters = definition.getParameters().stream().map(parameterDefinition -> {
final String name = parameterDefinition.getName();
final AbstractType type;
if (!parameterTypes.containsKey(name)) {
type = UndefinedType.INSTANCE;
} else {
final String parameterType = parameterTypes.get(name);
type = this.typeParser.parseTypeString(parameterType, globalRef.getPakkage());
}
final Parameter.Modifier modifier = MagikIndexer.PARAMETER_MODIFIER_MAPPING.get(parameterDefinition.getModifier());
return new Parameter(name, modifier, type);
}).collect(Collectors.toList());
final ParameterDefinition assignParamDef = definition.getAssignmentParameter();
final Parameter assignmentParameter = assignParamDef != null ? new Parameter(assignParamDef.getName(), MagikIndexer.PARAMETER_MODIFIER_MAPPING.get(assignParamDef.getModifier())) : null;
// Combine iterator types with method docs.
final ExpressionResult loopResult = newDocParser.getLoopTypes().stream().map(type -> this.typeParser.parseTypeString(type, globalRef.getPakkage())).collect(ExpressionResult.COLLECTOR);
// Combine return types with method docs.
final ExpressionResult callResult = newDocParser.getReturnTypes().stream().map(type -> this.typeParser.parseTypeString(type, globalRef.getPakkage())).collect(ExpressionResult.COLLECTOR);
// Create method.
final MagikType magikType = (MagikType) exemplarType;
final EnumSet<Method.Modifier> modifiers = definition.getModifiers().stream().map(modifier -> MagikIndexer.METHOD_MODIFIER_MAPPING.get(modifier)).collect(Collectors.toCollection(() -> EnumSet.noneOf(Method.Modifier.class)));
final URI uri = magikFile.getUri();
final Location location = new Location(uri, node);
final String methodName = definition.getMethodName();
final Method method = magikType.addMethod(modifiers, location, methodName, parameters, assignmentParameter, callResult, loopResult);
// Method doc.
final String methodDoc = MagikCommentExtractor.extractDocComments(node).map(Token::getValue).map(// Strip '##'
line -> line.substring(2)).collect(Collectors.joining("\n"));
method.setDoc(methodDoc);
// Save used types.
final AstNode bodyNode = node.getFirstChild(MagikGrammar.BODY);
final GlobalScope globalScope = magikFile.getGlobalScope();
final Scope bodyScope = globalScope.getScopeForNode(bodyNode);
Objects.requireNonNull(bodyScope);
bodyScope.getSelfAndDescendantScopes().stream().flatMap(scope -> scope.getScopeEntriesInScope().stream()).filter(scopeEntry -> scopeEntry.isType(ScopeEntry.Type.GLOBAL) || scopeEntry.isType(ScopeEntry.Type.DYNAMIC)).map(ScopeEntry::getIdentifier).map(identifier -> {
AbstractType type = this.typeKeeper.getType(globalRef);
if (type == UndefinedType.INSTANCE) {
return null;
} else if (type == SelfType.INSTANCE) {
// TODO: Does this actually happen?
type = this.typeKeeper.getType(globalRef);
}
return type;
}).filter(Objects::nonNull).forEach(method::addUsedType);
// Save called method names (thus without type).
node.getDescendants(MagikGrammar.METHOD_INVOCATION).stream().map(invocationNode -> {
final MethodInvocationNodeHelper invocationHelper = new MethodInvocationNodeHelper(invocationNode);
return invocationHelper.getMethodName();
}).forEach(method::addCalledMethod);
// Save used slot names.
node.getDescendants(MagikGrammar.SLOT).stream().map(slotNode -> slotNode.getFirstChild(MagikGrammar.IDENTIFIER).getTokenValue()).forEach(method::addUsedSlot);
final Path path = Paths.get(magikFile.getUri());
this.indexedMethods.get(path).add(method);
LOGGER.debug("Indexed method: {}", method);
}
Aggregations