Search in sources :

Example 1 with PsiPerlAnonArray

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

the class PerlMooseAttributeWrapper method createMooseAttributes.

@NotNull
private List<PerlDelegatingLightNamedElement> createMooseAttributes(@NotNull List<PsiElement> identifiers, @NotNull List<PsiElement> listElements) {
    List<PerlDelegatingLightNamedElement> result = new ArrayList<>();
    String packageName = PerlPackageUtil.getContextPackageName(this);
    Map<String, PerlHashEntry> parameters = PerlHashUtil.packToHash(listElements.subList(1, listElements.size()));
    // handling is
    PerlHashEntry isParameter = parameters.get("is");
    boolean isWritable = isParameter != null && StringUtil.equals("rw", isParameter.getValueString());
    PsiElement forcedIdentifier = null;
    // handling isa and does
    PerlHashEntry isaEntry = parameters.get("isa");
    String valueClass = null;
    if (isaEntry == null) {
        isaEntry = parameters.get("does");
    }
    if (isaEntry != null && isaEntry.valueElement != null && isAcceptableIdentifierElement(isaEntry.valueElement)) {
        valueClass = isaEntry.getValueString();
        if (StringUtil.isEmpty(valueClass)) {
            valueClass = null;
        }
    }
    // handling accessor, reader, etc.
    List<PerlLightMethodDefinitionElement> secondaryResult = new ArrayList<>();
    for (String key : MOOSE_SUB_NAMES_KEYS) {
        PerlHashEntry entry = parameters.get(key);
        if (entry == null) {
            continue;
        }
        String methodName = entry.getValueString();
        if (StringUtil.isEmpty(methodName)) {
            continue;
        }
        if (!isWritable && key.equals(MUTATOR_KEY)) {
            continue;
        }
        if (!isWritable && key.equals(READER_KEY) || key.equals(ACCESSOR_KEY)) {
            forcedIdentifier = entry.valueElement;
            continue;
        }
        if (!isAcceptableIdentifierElement(entry.valueElement)) {
            continue;
        }
        // fixme we could optimize new_value with subclassing and hardcoding of signature
        PsiElement identifier = entry.getNonNullValueElement();
        PerlLightMethodDefinitionElement<PerlMooseAttributeWrapper> secondaryElement = new PerlLightMethodDefinitionElement<>(this, ElementManipulators.getValueText(identifier), LIGHT_METHOD_DEFINITION, identifier, packageName, key.equals(MUTATOR_KEY) ? Arrays.asList(PerlSubArgument.self(), PerlSubArgument.optionalScalar("new_value", valueClass)) : Collections.emptyList(), PerlSubAnnotations.tryToFindAnnotations(identifier, entry.keyElement, getParent()));
        if (key.equals(READER_KEY) && valueClass != null) {
            String finalClass = valueClass;
            secondaryElement.setReturnsComputation((a, b) -> finalClass);
        }
        secondaryResult.add(secondaryElement);
    }
    // handle handles
    PerlHashEntry handlesEntry = parameters.get("handles");
    if (handlesEntry != null) {
        // to show proper signatures, we need an access to delegates, what requires indexes; we should do this in runtime, not indexing, but store delegation target
        if (handlesEntry.valueElement instanceof PsiPerlAnonHash) {
            // handle handles HASH
            Map<String, PerlHashEntry> delegatesMap = PerlHashUtil.collectHashMap(handlesEntry.valueElement);
            for (PerlHashEntry delegateEntry : delegatesMap.values()) {
                if (!isAcceptableIdentifierElement(delegateEntry.keyElement)) {
                    continue;
                }
                secondaryResult.add(new PerlLightMethodDefinitionElement<>(this, ElementManipulators.getValueText(delegateEntry.keyElement), LIGHT_METHOD_DEFINITION, delegateEntry.keyElement, packageName, Collections.emptyList(), PerlSubAnnotations.tryToFindAnnotations(delegateEntry.keyElement, handlesEntry.keyElement, getParent())));
            }
        } else if (handlesEntry.valueElement instanceof PsiPerlAnonArray) {
            // handle handles ARRAY
            List<PsiElement> delegatesIdentifiers = PerlArrayUtil.collectListElements(((PsiPerlAnonArray) handlesEntry.valueElement).getExpr());
            for (PsiElement identifier : delegatesIdentifiers) {
                if (!isAcceptableIdentifierElement(identifier)) {
                    continue;
                }
                secondaryResult.add(new PerlLightMethodDefinitionElement<>(this, ElementManipulators.getValueText(identifier), LIGHT_METHOD_DEFINITION, identifier, packageName, Collections.emptyList(), PerlSubAnnotations.tryToFindAnnotations(identifier, handlesEntry.keyElement, getParent())));
            }
        }
    }
    for (PsiElement identifier : identifiers) {
        if (forcedIdentifier != null) {
            identifier = forcedIdentifier;
        }
        if (!isAcceptableIdentifierElement(identifier)) {
            continue;
        }
        PerlAttributeDefinition newElement = new PerlAttributeDefinition(this, PerlAttributeDefinition.DEFAULT_NAME_COMPUTATION.fun(ElementManipulators.getValueText(identifier)), LIGHT_ATTRIBUTE_DEFINITION, identifier, packageName, isWritable ? Arrays.asList(PerlSubArgument.self(), PerlSubArgument.optionalScalar("new_value", valueClass)) : Collections.emptyList(), PerlSubAnnotations.tryToFindAnnotations(identifier, getParent()));
        if (valueClass != null) {
            String finalClass = valueClass;
            newElement.setReturnsComputation((a, b) -> finalClass);
        }
        result.add(newElement);
        result.addAll(secondaryResult);
    }
    return result;
}
Also used : PerlHashEntry(com.perl5.lang.perl.util.PerlHashEntry) PerlLightMethodDefinitionElement(com.perl5.lang.perl.psi.light.PerlLightMethodDefinitionElement) PsiPerlAnonArray(com.perl5.lang.perl.psi.PsiPerlAnonArray) PerlDelegatingLightNamedElement(com.perl5.lang.perl.psi.light.PerlDelegatingLightNamedElement) PsiPerlAnonHash(com.perl5.lang.perl.psi.PsiPerlAnonHash) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 2 with PsiPerlAnonArray

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

the class PerlExceptionClassWrapper method processExceptionElement.

private void processExceptionElement(@NotNull List<PsiElement> listElements, int currentIndex, @NotNull List<PerlDelegatingLightNamedElement> result) {
    PsiElement listElement = listElements.get(currentIndex);
    if (!isAcceptableIdentifierElement(listElement)) {
        return;
    }
    String namespaceName = ElementManipulators.getValueText(listElement);
    if (StringUtil.isEmpty(namespaceName)) {
        return;
    }
    Map<String, PerlHashEntry> exceptionSettings = listElements.size() > currentIndex + 1 ? PerlHashUtil.collectHashMap(listElements.get(currentIndex + 1)) : Collections.emptyMap();
    // Building fields
    Set<PerlSubArgument> throwArguments = Collections.emptySet();
    PerlHashEntry fieldsEntry = exceptionSettings.get("fields");
    if (fieldsEntry != null && fieldsEntry.isComplete()) {
        PsiElement fieldsContainer = fieldsEntry.getNonNullValueElement();
        if (fieldsContainer instanceof PsiPerlAnonArray) {
            fieldsContainer = ((PsiPerlAnonArray) fieldsContainer).getExpr();
        }
        List<PsiElement> elements = PerlArrayUtil.collectListElements(fieldsContainer);
        if (!elements.isEmpty()) {
            // Fields method
            result.add(new PerlLightMethodDefinitionElement<>(this, FIELDS_METHOD_NAME, LIGHT_METHOD_DEFINITION, fieldsEntry.keyElement, namespaceName, Collections.emptyList(), null));
            // fields themselves
            throwArguments = new LinkedHashSet<>();
            for (PsiElement fieldElement : elements) {
                if (isAcceptableIdentifierElement(fieldElement)) {
                    String fieldName = PerlScalarUtil.getStringContent(fieldElement);
                    if (StringUtil.isNotEmpty(fieldName)) {
                        throwArguments.add(PerlSubArgument.mandatoryScalar(fieldName));
                        result.add(new PerlLightMethodDefinitionElement<>(this, fieldName, LIGHT_METHOD_DEFINITION, fieldElement, namespaceName, Collections.emptyList(), null));
                    }
                }
            }
        }
    }
    // making exception class
    PerlHashEntry isaEntry = exceptionSettings.get("isa");
    String parentClass = "Exception::Class::Base";
    if (isaEntry != null && isaEntry.isComplete()) {
        String manualIsa = isaEntry.getValueString();
        if (manualIsa != null) {
            parentClass = manualIsa;
        }
    }
    result.add(new PerlLightExceptionClassDefinition(this, namespaceName, LIGHT_NAMESPACE_DEFINITION, listElement, PerlMroType.DFS, Collections.singletonList(parentClass), PerlNamespaceAnnotations.tryToFindAnnotations(listElement, getParent()), Collections.emptyList(), Collections.emptyList(), Collections.emptyMap()));
    // making alias
    PerlHashEntry aliasEntry = exceptionSettings.get("alias");
    if (aliasEntry != null && aliasEntry.isComplete()) {
        if (isAcceptableIdentifierElement(aliasEntry.valueElement)) {
            String aliasName = aliasEntry.getValueString();
            if (StringUtils.isNotEmpty(aliasName)) {
                result.add(new PerlLightSubDefinitionElement<>(this, aliasName, LIGHT_SUB_DEFINITION, aliasEntry.getNonNullValueElement(), PerlPackageUtil.getContextPackageName(this), new ArrayList<>(throwArguments), PerlSubAnnotations.tryToFindAnnotations(aliasEntry.keyElement, aliasEntry.valueElement)));
            }
        }
    }
}
Also used : PerlLightExceptionClassDefinition(com.perl5.lang.perl.parser.Exception.Class.psi.light.PerlLightExceptionClassDefinition) PerlSubArgument(com.perl5.lang.perl.psi.utils.PerlSubArgument) PsiPerlAnonArray(com.perl5.lang.perl.psi.PsiPerlAnonArray) PsiElement(com.intellij.psi.PsiElement)

Example 3 with PsiPerlAnonArray

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

the class PerlMooseAttributeWrapper method getIdentifiersAndListElements.

/**
 * @return pair of lists: identifiers lists and list of has arguments
 * null if something went wrong
 */
@Nullable
private Pair<List<PsiElement>, List<PsiElement>> getIdentifiersAndListElements() {
    PsiElement firstChild = getFirstChild();
    List<PsiElement> listElements = PerlArrayUtil.collectListElements(firstChild);
    if (listElements.isEmpty()) {
        return null;
    }
    PsiElement namesContainer = listElements.get(0);
    if (namesContainer instanceof PsiPerlAnonArray) {
        namesContainer = ((PsiPerlAnonArray) namesContainer).getExpr();
    }
    List<PsiElement> identifiers = ContainerUtil.filter(PerlArrayUtil.collectListElements(namesContainer), this::isAcceptableIdentifierElement);
    if (identifiers.isEmpty()) {
        return null;
    }
    return Pair.create(identifiers, listElements);
}
Also used : PsiPerlAnonArray(com.perl5.lang.perl.psi.PsiPerlAnonArray) PsiElement(com.intellij.psi.PsiElement) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

PsiElement (com.intellij.psi.PsiElement)3 PsiPerlAnonArray (com.perl5.lang.perl.psi.PsiPerlAnonArray)3 PerlLightExceptionClassDefinition (com.perl5.lang.perl.parser.Exception.Class.psi.light.PerlLightExceptionClassDefinition)1 PsiPerlAnonHash (com.perl5.lang.perl.psi.PsiPerlAnonHash)1 PerlDelegatingLightNamedElement (com.perl5.lang.perl.psi.light.PerlDelegatingLightNamedElement)1 PerlLightMethodDefinitionElement (com.perl5.lang.perl.psi.light.PerlLightMethodDefinitionElement)1 PerlSubArgument (com.perl5.lang.perl.psi.utils.PerlSubArgument)1 PerlHashEntry (com.perl5.lang.perl.util.PerlHashEntry)1 NotNull (org.jetbrains.annotations.NotNull)1 Nullable (org.jetbrains.annotations.Nullable)1