Search in sources :

Example 1 with ParameterDefinition

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);
}
Also used : Method(nl.ramsolutions.sw.magik.analysis.typing.types.Method) MagikType(nl.ramsolutions.sw.magik.analysis.typing.types.MagikType) AstNode(com.sonar.sslr.api.AstNode) SlottedExemplarDefinition(nl.ramsolutions.sw.magik.analysis.definitions.SlottedExemplarDefinition) IndexedType(nl.ramsolutions.sw.magik.analysis.typing.types.IndexedType) LoggerFactory(org.slf4j.LoggerFactory) SlottedType(nl.ramsolutions.sw.magik.analysis.typing.types.SlottedType) Package(nl.ramsolutions.sw.magik.analysis.typing.types.Package) AliasType(nl.ramsolutions.sw.magik.analysis.typing.types.AliasType) IndexedExemplarDefinition(nl.ramsolutions.sw.magik.analysis.definitions.IndexedExemplarDefinition) UndefinedType(nl.ramsolutions.sw.magik.analysis.typing.types.UndefinedType) EnumerationDefinition(nl.ramsolutions.sw.magik.analysis.definitions.EnumerationDefinition) Map(java.util.Map) URI(java.net.URI) Path(java.nio.file.Path) MagikGrammar(nl.ramsolutions.sw.magik.api.MagikGrammar) EnumSet(java.util.EnumSet) MethodInvocationNodeHelper(nl.ramsolutions.sw.magik.analysis.helpers.MethodInvocationNodeHelper) MethodDefinition(nl.ramsolutions.sw.magik.analysis.definitions.MethodDefinition) TypeAnnotationHandler(nl.ramsolutions.sw.magik.analysis.typing.TypeAnnotationHandler) PackageNodeHelper(nl.ramsolutions.sw.magik.analysis.helpers.PackageNodeHelper) Set(java.util.Set) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) List(java.util.List) Stream(java.util.stream.Stream) ParameterDefinition(nl.ramsolutions.sw.magik.analysis.definitions.ParameterDefinition) GlobalDefinition(nl.ramsolutions.sw.magik.analysis.definitions.GlobalDefinition) HashMap(java.util.HashMap) SelfType(nl.ramsolutions.sw.magik.analysis.typing.types.SelfType) ITypeKeeper(nl.ramsolutions.sw.magik.analysis.typing.ITypeKeeper) HashSet(java.util.HashSet) TypeParser(nl.ramsolutions.sw.magik.analysis.typing.TypeParser) AbstractType(nl.ramsolutions.sw.magik.analysis.typing.types.AbstractType) Location(nl.ramsolutions.sw.magik.analysis.Location) Nullable(javax.annotation.Nullable) GlobalScope(nl.ramsolutions.sw.magik.analysis.scope.GlobalScope) MagikCommentExtractor(nl.ramsolutions.sw.magik.parser.MagikCommentExtractor) GlobalReference(nl.ramsolutions.sw.magik.analysis.typing.types.GlobalReference) Token(com.sonar.sslr.api.Token) Slot(nl.ramsolutions.sw.magik.analysis.typing.types.Slot) Logger(org.slf4j.Logger) MagikFile(nl.ramsolutions.sw.magik.MagikFile) IOException(java.io.IOException) Parameter(nl.ramsolutions.sw.magik.analysis.typing.types.Parameter) NewDocParser(nl.ramsolutions.sw.magik.parser.NewDocParser) BinaryOperatorDefinition(nl.ramsolutions.sw.magik.analysis.definitions.BinaryOperatorDefinition) MixinDefinition(nl.ramsolutions.sw.magik.analysis.definitions.MixinDefinition) IntrinsicType(nl.ramsolutions.sw.magik.analysis.typing.types.IntrinsicType) PackageDefinition(nl.ramsolutions.sw.magik.analysis.definitions.PackageDefinition) Paths(java.nio.file.Paths) Definition(nl.ramsolutions.sw.magik.analysis.definitions.Definition) ScopeEntry(nl.ramsolutions.sw.magik.analysis.scope.ScopeEntry) Scope(nl.ramsolutions.sw.magik.analysis.scope.Scope) Collections(java.util.Collections) BinaryOperator(nl.ramsolutions.sw.magik.analysis.typing.BinaryOperator) ExpressionResult(nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult) Path(java.nio.file.Path) GlobalScope(nl.ramsolutions.sw.magik.analysis.scope.GlobalScope) GlobalReference(nl.ramsolutions.sw.magik.analysis.typing.types.GlobalReference) ExpressionResult(nl.ramsolutions.sw.magik.analysis.typing.types.ExpressionResult) Token(com.sonar.sslr.api.Token) Method(nl.ramsolutions.sw.magik.analysis.typing.types.Method) URI(java.net.URI) MagikType(nl.ramsolutions.sw.magik.analysis.typing.types.MagikType) MethodInvocationNodeHelper(nl.ramsolutions.sw.magik.analysis.helpers.MethodInvocationNodeHelper) NewDocParser(nl.ramsolutions.sw.magik.parser.NewDocParser) GlobalScope(nl.ramsolutions.sw.magik.analysis.scope.GlobalScope) Scope(nl.ramsolutions.sw.magik.analysis.scope.Scope) AbstractType(nl.ramsolutions.sw.magik.analysis.typing.types.AbstractType) Parameter(nl.ramsolutions.sw.magik.analysis.typing.types.Parameter) AstNode(com.sonar.sslr.api.AstNode) ParameterDefinition(nl.ramsolutions.sw.magik.analysis.definitions.ParameterDefinition) Location(nl.ramsolutions.sw.magik.analysis.Location)

Aggregations

AstNode (com.sonar.sslr.api.AstNode)1 Token (com.sonar.sslr.api.Token)1 IOException (java.io.IOException)1 URI (java.net.URI)1 Path (java.nio.file.Path)1 Paths (java.nio.file.Paths)1 Collections (java.util.Collections)1 EnumSet (java.util.EnumSet)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Map (java.util.Map)1 Objects (java.util.Objects)1 Set (java.util.Set)1 Collectors (java.util.stream.Collectors)1 Stream (java.util.stream.Stream)1 Nullable (javax.annotation.Nullable)1 MagikFile (nl.ramsolutions.sw.magik.MagikFile)1 Location (nl.ramsolutions.sw.magik.analysis.Location)1 BinaryOperatorDefinition (nl.ramsolutions.sw.magik.analysis.definitions.BinaryOperatorDefinition)1