Search in sources :

Example 1 with PerlContextType

use of com.perl5.lang.perl.psi.utils.PerlContextType in project Perl5-IDEA by Camelcade.

the class PerlValuesManager method from.

@NotNull
public static PerlValue from(@NotNull PsiElement target, @Nullable PerlAssignExpression.PerlAssignValueDescriptor assignValueDescriptor) {
    if (assignValueDescriptor == null) {
        return UNKNOWN_VALUE;
    }
    List<PsiElement> elements = assignValueDescriptor.getElements();
    PerlContextType targetContextType = PerlContextType.from(target);
    if (targetContextType == PerlContextType.SCALAR) {
        int startIndex = assignValueDescriptor.getStartIndex();
        if (elements.size() == 1 && (PerlContextType.isScalar(elements.get(0)) || startIndex == -1)) {
            return PerlScalarContextValue.create(from(elements.get(0)));
        } else if (elements.size() > 1 || PerlContextType.isList(ContainerUtil.getFirstItem(elements))) {
            return PerlArrayElementValue.create(PerlArrayValue.builder().addPsiElements(elements).build(), PerlScalarValue.create(startIndex));
        }
    } else if (targetContextType == PerlContextType.LIST && assignValueDescriptor.getStartIndex() == 0) {
        IElementType elementType = PsiUtilCore.getElementType(target);
        if (elementType == HASH_VARIABLE || elementType == HASH_CAST_EXPR) {
            return PerlMapValue.builder().addPsiElements(elements).build();
        }
        return PerlArrayValue.builder().addPsiElements(elements).build();
    }
    return UNKNOWN_VALUE;
}
Also used : IElementType(com.intellij.psi.tree.IElementType) PsiElement(com.intellij.psi.PsiElement) PerlContextType(com.perl5.lang.perl.psi.utils.PerlContextType) NotNull(org.jetbrains.annotations.NotNull)

Example 2 with PerlContextType

use of com.perl5.lang.perl.psi.utils.PerlContextType in project Perl5-IDEA by Camelcade.

the class PerlOneOfValue method getContextType.

@Override
@Nullable
protected PerlContextType getContextType() {
    if (myVariants.isEmpty()) {
        return null;
    }
    PerlContextType contextType = null;
    boolean first = true;
    for (PerlValue variant : myVariants) {
        if (first) {
            contextType = variant.getContextType();
            first = false;
            continue;
        }
        if (contextType != variant.getContextType()) {
            return null;
        }
    }
    return contextType;
}
Also used : PerlContextType(com.perl5.lang.perl.psi.utils.PerlContextType) Nullable(org.jetbrains.annotations.Nullable)

Example 3 with PerlContextType

use of com.perl5.lang.perl.psi.utils.PerlContextType in project Perl5-IDEA by Camelcade.

the class PerlAssignExpression method getRightPartOfAssignment.

/**
 * @return a descriptor of value assigned to the {@code leftPartElement} if any. Descriptor contains a list of {@code psiElement}s and index in
 * the element, if it's necessary. null means there is no element, or assignment, or it's the rightmost part of it.
 * <br/>
 * In case of {@code my ($var, $var2) = @_;} for {@code $var2} will return a descriptor with
 * {@code @_} as PsiElement and 1 as index.
 * <br/>
 * In case of transitive assignments, always returns rightmost value. E.g. {@code $var1 = $var2 = $var3;} will return a
 * {@code $var3} for {@code $var1} and {@code $var2}
 * <br/>
 * In case of {@code my @arr = ($var1, $var2)} will return a descriptor of {@code $var1} and {@code $var2} and zero index.
 * fixme use real right part. To handle my $var = undef = $var;
 */
@Nullable
default PerlAssignValueDescriptor getRightPartOfAssignment(@NotNull PsiElement leftPartElement) {
    List<PsiElement> children = PerlPsiUtil.cleanupChildren(getChildren());
    if (children.size() < 2) {
        return null;
    }
    TextRange leftPartTextRange = leftPartElement.getTextRange();
    PsiElement leftAssignPart = null;
    PsiElement rightAssignPart = null;
    for (int i = 0; i < children.size() - 1; i++) {
        PsiElement child = children.get(i);
        if (child.getTextRange().contains(leftPartTextRange)) {
            leftAssignPart = child;
            rightAssignPart = children.get(i + 1);
            break;
        }
    }
    if (leftAssignPart == null) {
        return null;
    }
    boolean found = false;
    int leftElementIndex = 0;
    for (PsiElement leftElement : flattenAssignmentPart(leftAssignPart)) {
        if (leftElement.getTextRange().equals(leftPartTextRange)) {
            found = true;
            break;
        }
        if (PerlContextType.isList(leftElement)) {
            return null;
        }
        leftElementIndex++;
    }
    if (!found) {
        return null;
    }
    List<PsiElement> rightElements = flattenAssignmentPart(rightAssignPart);
    if (rightElements.isEmpty()) {
        return null;
    }
    if (PerlContextType.isScalar(leftAssignPart)) {
        PsiElement lastItem = ContainerUtil.getLastItem(rightElements);
        return new PerlAssignValueDescriptor(Objects.requireNonNull(lastItem), PerlContextType.isList(lastItem) ? -1 : 0);
    }
    PerlContextType leftContextType = PerlContextType.from(leftPartElement);
    for (int i = 0; i < rightElements.size(); i++) {
        PsiElement rightElement = rightElements.get(i);
        if (leftElementIndex == 0) {
            if (leftContextType == SCALAR) {
                return new PerlAssignValueDescriptor(rightElement);
            }
            return new PerlAssignValueDescriptor(rightElements.subList(i, rightElements.size()));
        }
        if (PerlContextType.from(rightElement) == LIST) {
            return new PerlAssignValueDescriptor(rightElements.subList(i, rightElements.size()), leftElementIndex);
        }
        leftElementIndex--;
    }
    return null;
}
Also used : TextRange(com.intellij.openapi.util.TextRange) PsiElement(com.intellij.psi.PsiElement) PerlContextType(com.perl5.lang.perl.psi.utils.PerlContextType) Nullable(org.jetbrains.annotations.Nullable)

Example 4 with PerlContextType

use of com.perl5.lang.perl.psi.utils.PerlContextType in project Perl5-IDEA by Camelcade.

the class PerlParameterInfoHandler method markActiveparametersRecursively.

private static int markActiveparametersRecursively(PsiElement element, PerlParameterInfo[] parameterInfos, int currentIndex, int offset) {
    while (element != null) {
        if (parameterInfos.length <= currentIndex) {
            return currentIndex;
        }
        IElementType elementType = PsiUtilCore.getElementType(element);
        if (element instanceof PsiPerlParenthesisedExprImpl || element instanceof PsiPerlCommaSequenceExprImpl) {
            currentIndex = markActiveparametersRecursively(element.getFirstChild(), parameterInfos, currentIndex, offset);
        } else {
            if (isComma(elementType)) {
                if (parameterInfos[currentIndex].getArgument().getContextType() == PerlContextType.SCALAR) {
                    currentIndex++;
                }
            }
        }
        if (element.getTextRange().getEndOffset() >= offset) {
            if (element instanceof PerlCompositeElementImpl) {
                PerlContextType valueContextType = PerlContextType.from(element);
                if (valueContextType == PerlContextType.SCALAR) {
                    if (currentIndex < parameterInfos.length) {
                        parameterInfos[currentIndex].setSelected(true);
                    }
                    return parameterInfos.length;
                } else if (// consumes all arguments to the end
                valueContextType == PerlContextType.LIST) {
                    while (currentIndex < parameterInfos.length) {
                        parameterInfos[currentIndex++].setSelected(true);
                    }
                    return currentIndex;
                }
            }
            // space, comma or smth
            if (currentIndex < parameterInfos.length) {
                parameterInfos[currentIndex].setSelected(true);
            }
            return parameterInfos.length;
        } else if (elementType == SUB_EXPR && element.getFirstChild() instanceof PsiPerlBlock) {
            PsiElement nextSibling = PerlPsiUtil.getNextSignificantSibling(element);
            if (!isComma(PsiUtilCore.getElementType(nextSibling))) {
                currentIndex++;
            }
        } else if (isPrintHandleArgument(element)) {
            currentIndex++;
        }
        element = element.getNextSibling();
    }
    return currentIndex;
}
Also used : IElementType(com.intellij.psi.tree.IElementType) PsiPerlCommaSequenceExprImpl(com.perl5.lang.perl.psi.impl.PsiPerlCommaSequenceExprImpl) PerlCompositeElementImpl(com.perl5.lang.perl.psi.impl.PerlCompositeElementImpl) PsiPerlParenthesisedExprImpl(com.perl5.lang.perl.psi.impl.PsiPerlParenthesisedExprImpl) PerlContextType(com.perl5.lang.perl.psi.utils.PerlContextType) PsiElement(com.intellij.psi.PsiElement)

Aggregations

PerlContextType (com.perl5.lang.perl.psi.utils.PerlContextType)4 PsiElement (com.intellij.psi.PsiElement)3 IElementType (com.intellij.psi.tree.IElementType)2 Nullable (org.jetbrains.annotations.Nullable)2 TextRange (com.intellij.openapi.util.TextRange)1 PerlCompositeElementImpl (com.perl5.lang.perl.psi.impl.PerlCompositeElementImpl)1 PsiPerlCommaSequenceExprImpl (com.perl5.lang.perl.psi.impl.PsiPerlCommaSequenceExprImpl)1 PsiPerlParenthesisedExprImpl (com.perl5.lang.perl.psi.impl.PsiPerlParenthesisedExprImpl)1 NotNull (org.jetbrains.annotations.NotNull)1