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