Search in sources :

Example 21 with IntRange

use of org.apache.commons.lang.math.IntRange in project intellij-elixir by KronicDeth.

the class ElixirPsiImplUtil method exportedArity.

@Contract(pure = true)
public static int exportedArity(@NotNull final UnqualifiedNoParenthesesCall unqualifiedNoParenthesesCall) {
    int arity = MaybeExported.UNEXPORTED_ARITY;
    if (isExported(unqualifiedNoParenthesesCall)) {
        Pair<String, IntRange> nameArityRange = CallDefinitionClause.nameArityRange(unqualifiedNoParenthesesCall);
        if (nameArityRange != null) {
            IntRange arityRange = nameArityRange.second;
            if (arityRange != null) {
                int minimumArity = arityRange.getMinimumInteger();
                int maximumArity = arityRange.getMaximumInteger();
                if (minimumArity == maximumArity) {
                    arity = minimumArity;
                }
            }
        }
    }
    return arity;
}
Also used : IntRange(org.apache.commons.lang.math.IntRange) Contract(org.jetbrains.annotations.Contract)

Example 22 with IntRange

use of org.apache.commons.lang.math.IntRange in project intellij-elixir by KronicDeth.

the class CallDefinitionClause method multiResolve.

/**
     * Returns the results of resolving the reference.
     *
     * @param incompleteCode if true, the code in the context of which the reference is
     *                       being resolved is considered incomplete, and the method may return additional
     *                       invalid results.
     * @return the array of results for resolving the reference.
     */
@NotNull
@Override
public ResolveResult[] multiResolve(boolean incompleteCode) {
    Call enclosingModularMacroCall = enclosingModularMacroCall(moduleAttribute);
    List<ResolveResult> resolveResultList = null;
    if (enclosingModularMacroCall != null) {
        Call[] siblings = macroChildCalls(enclosingModularMacroCall);
        if (siblings != null && siblings.length > 0) {
            Pair<String, Integer> nameArity = typeNameArity(myElement);
            String name = nameArity.first;
            int arity = nameArity.second;
            for (Call call : siblings) {
                if (org.elixir_lang.structure_view.element.CallDefinitionClause.is(call)) {
                    Pair<String, IntRange> callNameArityRange = org.elixir_lang.structure_view.element.CallDefinitionClause.nameArityRange(call);
                    if (callNameArityRange != null) {
                        String callName = callNameArityRange.first;
                        if (callName.equals(name)) {
                            IntRange callArityRange = callNameArityRange.second;
                            if (callArityRange.containsInteger(arity)) {
                                resolveResultList = add(resolveResultList, call, true);
                            } else if (arity < callArityRange.getMaximumInteger()) {
                                resolveResultList = add(resolveResultList, call, false);
                            }
                        } else if (incompleteCode && callName.startsWith(name)) {
                            IntRange callArityRange = callNameArityRange.second;
                            if (callArityRange.containsInteger(arity)) {
                                resolveResultList = add(resolveResultList, call, false);
                            } else if (arity < callArityRange.getMaximumInteger()) {
                                resolveResultList = add(resolveResultList, call, false);
                            }
                        }
                    }
                }
            }
        }
    }
    ResolveResult[] resolveResults;
    if (resolveResultList != null) {
        resolveResults = resolveResultList.toArray(new ResolveResult[resolveResultList.size()]);
    } else {
        resolveResults = new ResolveResult[0];
    }
    return resolveResults;
}
Also used : Call(org.elixir_lang.psi.call.Call) CallDefinitionClause.enclosingModularMacroCall(org.elixir_lang.structure_view.element.CallDefinitionClause.enclosingModularMacroCall) AtUnqualifiedNoParenthesesCall(org.elixir_lang.psi.AtUnqualifiedNoParenthesesCall) IntRange(org.apache.commons.lang.math.IntRange) NotNull(org.jetbrains.annotations.NotNull)

Example 23 with IntRange

use of org.apache.commons.lang.math.IntRange in project intellij-elixir by KronicDeth.

the class CallDefinitionClause method nameArityRange.

/**
     * The name and arity range of the call definition this clause belongs to.
     *
     * @param call
     * @return The name and arities of the {@link CallDefinition} this clause belongs.  Multiple arities occur when
     * default arguments are used, which produces an arity for each default argument that is turned on and off.
     * @see Call#resolvedFinalArityRange()
     */
@Nullable
public static Pair<String, IntRange> nameArityRange(Call call) {
    PsiElement head = head(call);
    Pair<String, IntRange> pair = null;
    if (head != null) {
        pair = CallDefinitionHead.nameArityRange(head);
    }
    return pair;
}
Also used : IntRange(org.apache.commons.lang.math.IntRange) PsiElement(com.intellij.psi.PsiElement) Nullable(org.jetbrains.annotations.Nullable)

Example 24 with IntRange

use of org.apache.commons.lang.math.IntRange in project intellij-elixir by KronicDeth.

the class Used method provideNodesFromChild.

public static Collection<TreeElement> provideNodesFromChild(@NotNull TreeElement child) {
    Collection<TreeElement> nodes = null;
    if (child instanceof Use) {
        Use use = (Use) child;
        PsiElement[] finalArguments = ElixirPsiImplUtil.finalArguments(use.call());
        assert finalArguments != null;
        if (finalArguments.length > 0) {
            PsiElement firstFinalArgument = finalArguments[0];
            if (firstFinalArgument instanceof ElixirAccessExpression) {
                PsiElement accessExpressionChild = stripAccessExpression(firstFinalArgument);
                if (accessExpressionChild instanceof QualifiableAlias) {
                    PsiReference reference = accessExpressionChild.getReference();
                    if (reference != null) {
                        PsiElement ancestor = reference.resolve();
                        while (ancestor != null && !(ancestor instanceof PsiFile)) {
                            if (ancestor instanceof Call) {
                                Call call = (Call) ancestor;
                                if (Module.is(call)) {
                                    Module module = new Module(call);
                                    Call[] childCalls = ElixirPsiImplUtil.macroChildCalls(call);
                                    if (childCalls != null) {
                                        Map<Pair<String, Integer>, CallDefinition> macroByNameArity = new HashMap<Pair<String, Integer>, CallDefinition>(childCalls.length);
                                        for (Call childCall : childCalls) {
                                            /* portion of {@link org.elixir_lang.structure_view.element.enclosingModular.Module#childCallTreeElements}
                                                       dealing with macros, restricted to __using__/1 */
                                            if (CallDefinitionClause.isMacro(childCall)) {
                                                Pair<String, IntRange> nameArityRange = CallDefinitionClause.nameArityRange(childCall);
                                                if (nameArityRange != null) {
                                                    String name = nameArityRange.first;
                                                    IntRange arityRange = nameArityRange.second;
                                                    if (name.equals(USING) && arityRange.containsInteger(1)) {
                                                        addClausesToCallDefinition(childCall, name, arityRange, macroByNameArity, module, Timed.Time.COMPILE, new Inserter<CallDefinition>() {

                                                            @Override
                                                            public void insert(CallDefinition element) {
                                                            }
                                                        });
                                                    }
                                                }
                                            }
                                        }
                                        if (macroByNameArity.size() > 0) {
                                            PsiElement[] usingArguments;
                                            CallDefinition macro;
                                            CallDefinitionClause matchingClause = null;
                                            if (finalArguments.length > 1) {
                                                usingArguments = Arrays.copyOfRange(finalArguments, 1, finalArguments.length);
                                                Pair<String, Integer> nameArity = pair(USING, usingArguments.length);
                                                macro = macroByNameArity.get(nameArity);
                                                if (macro != null) {
                                                    matchingClause = macro.matchingClause(usingArguments);
                                                }
                                            } else {
                                                /* `use <ALIAS>` will calls `__using__/1` even though there is
                                                           no additional argument, but it obviously can't select a clause. */
                                                Pair<String, Integer> nameArity = pair(USING, 1);
                                                macro = macroByNameArity.get(nameArity);
                                                List<CallDefinitionClause> macroClauseList = macro.clauseList();
                                                if (macroClauseList.size() == 1) {
                                                    matchingClause = macroClauseList.get(0);
                                                } else {
                                                // TODO match default argument clause/head to non-default argument clause that would be executed.
                                                }
                                            }
                                            if (matchingClause != null) {
                                                TreeElement[] callDefinitionClauseChildren = matchingClause.getChildren();
                                                int length = callDefinitionClauseChildren.length;
                                                if (length > 0) {
                                                    TreeElement lastCallDefinitionClauseChild = callDefinitionClauseChildren[length - 1];
                                                    if (lastCallDefinitionClauseChild instanceof Quote) {
                                                        Quote quote = (Quote) lastCallDefinitionClauseChild;
                                                        Quote injectedQuote = quote.used(use);
                                                        TreeElement[] injectedQuoteChildren = injectedQuote.getChildren();
                                                        nodes = new ArrayList<TreeElement>(injectedQuoteChildren.length);
                                                        for (TreeElement injectedQuoteChild : injectedQuoteChildren) {
                                                            if (!(injectedQuoteChild instanceof Overridable)) {
                                                                nodes.add(injectedQuoteChild);
                                                            }
                                                        }
                                                        break;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                } else {
                                    break;
                                }
                            }
                            ancestor = ancestor.getParent();
                        }
                    }
                }
            }
        }
    }
    if (nodes == null) {
        nodes = Collections.emptyList();
    }
    return nodes;
}
Also used : Module.addClausesToCallDefinition(org.elixir_lang.structure_view.element.modular.Module.addClausesToCallDefinition) PsiFile(com.intellij.psi.PsiFile) PsiElement(com.intellij.psi.PsiElement) Pair(com.intellij.openapi.util.Pair) Call(org.elixir_lang.psi.call.Call) QualifiableAlias(org.elixir_lang.psi.QualifiableAlias) ElixirAccessExpression(org.elixir_lang.psi.ElixirAccessExpression) IntRange(org.apache.commons.lang.math.IntRange) PsiReference(com.intellij.psi.PsiReference) TreeElement(com.intellij.ide.util.treeView.smartTree.TreeElement) Module(org.elixir_lang.structure_view.element.modular.Module)

Example 25 with IntRange

use of org.apache.commons.lang.math.IntRange in project intellij-elixir by KronicDeth.

the class Module method addClausesToCallDefinition.

/*
     *
     * Static Methods
     *
     */
/*
     * Public Static Methods
     */
public static void addClausesToCallDefinition(@NotNull Call call, @NotNull Map<Pair<String, Integer>, CallDefinition> callDefinitionByNameArity, @NotNull Modular modular, @NotNull Timed.Time time, @NotNull Inserter<CallDefinition> callDefinitionInserter) {
    Pair<String, IntRange> nameArityRange = CallDefinitionClause.nameArityRange(call);
    if (nameArityRange != null) {
        String name = nameArityRange.first;
        IntRange arityRange = nameArityRange.second;
        addClausesToCallDefinition(call, name, arityRange, callDefinitionByNameArity, modular, time, callDefinitionInserter);
    }
}
Also used : IntRange(org.apache.commons.lang.math.IntRange)

Aggregations

IntRange (org.apache.commons.lang.math.IntRange)31 Call (org.elixir_lang.psi.call.Call)10 PsiElement (com.intellij.psi.PsiElement)6 File (java.io.File)6 Nullable (org.jetbrains.annotations.Nullable)6 ArrayList (java.util.ArrayList)5 NotNull (org.jetbrains.annotations.NotNull)4 Test (org.testng.annotations.Test)4 Pair (com.intellij.openapi.util.Pair)3 DataType (com.linkedin.pinot.common.data.FieldSpec.DataType)3 DataGeneratorSpec (com.linkedin.pinot.tools.data.generator.DataGeneratorSpec)3 List (java.util.List)3 AtUnqualifiedNoParenthesesCall (org.elixir_lang.psi.AtUnqualifiedNoParenthesesCall)3 LineMarkerInfo (com.intellij.codeInsight.daemon.LineMarkerInfo)2 PsiReference (com.intellij.psi.PsiReference)2 FieldSpec (com.linkedin.pinot.common.data.FieldSpec)2 FieldType (com.linkedin.pinot.common.data.FieldSpec.FieldType)2 DataGenerator (com.linkedin.pinot.tools.data.generator.DataGenerator)2 HashMap (java.util.HashMap)2 TimeUnit (java.util.concurrent.TimeUnit)2