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;
}
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;
}
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;
}
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;
}
Aggregations