Search in sources :

Example 6 with PerlUseStatementElement

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

the class ExceptionClassProcessor method processExceptionElement.

private void processExceptionElement(@NotNull List<PsiElement> listElements, int currentIndex, @NotNull List<PerlDelegatingLightNamedElement<?>> result, @NotNull PerlUseStatementElement useStatementElement) {
    PsiElement listElement = listElements.get(currentIndex);
    if (!useStatementElement.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<>(useStatementElement, FIELDS_METHOD_NAME, LIGHT_METHOD_DEFINITION, fieldsEntry.keyElement, namespaceName, Collections.emptyList(), null));
            // fields themselves
            throwArguments = new LinkedHashSet<>();
            for (PsiElement fieldElement : elements) {
                if (useStatementElement.isAcceptableIdentifierElement(fieldElement)) {
                    String fieldName = PerlScalarUtil.getStringContent(fieldElement);
                    if (StringUtil.isNotEmpty(fieldName)) {
                        throwArguments.add(PerlSubArgument.mandatoryScalar(fieldName));
                        result.add(new PerlLightMethodDefinitionElement<>(useStatementElement, 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(useStatementElement, namespaceName, LIGHT_NAMESPACE_DEFINITION, listElement, PerlMroType.DFS, Collections.singletonList(parentClass), PerlNamespaceAnnotations.tryToFindAnnotations(listElement, useStatementElement), Collections.emptyList(), Collections.emptyList(), Collections.emptyMap()));
    // making alias
    PerlHashEntry aliasEntry = exceptionSettings.get("alias");
    if (aliasEntry != null && aliasEntry.isComplete()) {
        if (useStatementElement.isAcceptableIdentifierElement(aliasEntry.valueElement)) {
            String aliasName = aliasEntry.getValueString();
            if (StringUtil.isNotEmpty(aliasName)) {
                result.add(new PerlLightSubDefinitionElement<>(useStatementElement, aliasName, LIGHT_SUB_DEFINITION, aliasEntry.getNonNullValueElement(), PerlPackageUtil.getContextNamespaceName(useStatementElement), new ArrayList<>(throwArguments), PerlSubAnnotations.tryToFindAnnotations(aliasEntry.keyElement, aliasEntry.valueElement), UNKNOWN_VALUE_PROVIDER, null));
            }
        }
    }
}
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 7 with PerlUseStatementElement

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

the class PerlPackageProcessorBase method getImports.

@Override
@NotNull
public List<PerlExportDescriptor> getImports(@NotNull PerlUseStatementElement useStatement) {
    String packageName = useStatement.getPackageName();
    if (packageName == null) {
        return Collections.emptyList();
    }
    PerlTimeLogger logger = PerlTimeLogger.create(LOG);
    List<PerlExportDescriptor> result = new ArrayList<>();
    List<String> importParameters = getImportParameters(useStatement);
    Set<String> exportNames = new HashSet<>();
    Set<String> exportOkNames = new HashSet<>();
    addExports(useStatement, exportNames, exportOkNames);
    if (importParameters == null) {
        exportNames.forEach(name -> result.add(createDescriptor(packageName, name)));
    } else {
        importParameters.stream().filter(exportOkNames::contains).forEach(name -> result.add(createDescriptor(packageName, name)));
    }
    logger.debug("Collected imports for ", packageName);
    return result;
}
Also used : PerlTimeLogger(com.perl5.lang.perl.util.PerlTimeLogger) NotNull(org.jetbrains.annotations.NotNull)

Example 8 with PerlUseStatementElement

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

the class PerlPackageProcessorBase method addExports.

@Override
public void addExports(@NotNull PerlUseStatementElement useStatement, @NotNull Set<String> export, @NotNull Set<String> exportOk) {
    String packageName = useStatement.getPackageName();
    if (StringUtil.isEmpty(packageName)) {
        return;
    }
    // fixme handle tags
    GlobalSearchScope scope = GlobalSearchScope.allScope(useStatement.getProject());
    for (PerlNamespaceDefinitionElement namespaceDefinition : PerlPackageUtil.getNamespaceDefinitions(useStatement.getProject(), scope, packageName)) {
        export.addAll(namespaceDefinition.getEXPORT());
        exportOk.addAll(namespaceDefinition.getEXPORT_OK());
    }
    exportOk.addAll(export);
}
Also used : GlobalSearchScope(com.intellij.psi.search.GlobalSearchScope) PerlNamespaceDefinitionElement(com.perl5.lang.perl.psi.PerlNamespaceDefinitionElement)

Example 9 with PerlUseStatementElement

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

the class PerlAnnotator method annotate.

@Override
public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolder holder) {
    IElementType elementType = PsiUtilCore.getElementType(element);
    BiConsumer<String, TextAttributesKey> defaultAnnotationProducer = (msg, key) -> createInfoAnnotation(holder, element, msg, key);
    Consumer<TextAttributesKey> defaultSilentProducer = (key) -> createInfoAnnotation(holder, element, null, key);
    if (elementType == NYI_STATEMENT) {
        defaultAnnotationProducer.accept("Unimplemented statement", CodeInsightColors.TODO_DEFAULT_ATTRIBUTES);
    } else if (element instanceof PerlGlobVariable && ((PerlGlobVariable) element).isBuiltIn()) {
        defaultSilentProducer.accept(PERL_GLOB_BUILTIN);
    } else if (element instanceof PerlVariable && ((PerlVariable) element).isBuiltIn()) {
        defaultSilentProducer.accept(VARIABLE_KEYS_MAP.get(element.getClass()));
    } else if (elementType == LABEL_DECLARATION || elementType == LABEL_EXPR) {
        createInfoAnnotation(holder, element.getFirstChild(), null, PerlSyntaxHighlighter.PERL_LABEL);
    } else if (elementType == PACKAGE) {
        assert element instanceof PerlNamespaceElement;
        PerlNamespaceElement namespaceElement = (PerlNamespaceElement) element;
        PsiElement parent = namespaceElement.getParent();
        if (parent instanceof PerlNamespaceDefinitionWithIdentifier) {
            createInfoAnnotation(holder, namespaceElement, null, PerlSyntaxHighlighter.PERL_PACKAGE_DEFINITION);
        } else {
            if (namespaceElement.isPragma()) {
                createInfoAnnotation(holder, namespaceElement, null, PerlSyntaxHighlighter.PERL_PACKAGE_PRAGMA);
            } else if (namespaceElement.isBuiltin()) {
                createInfoAnnotation(holder, namespaceElement, null, PerlSyntaxHighlighter.PERL_PACKAGE_CORE);
            }
        }
    } else if (element instanceof PerlCharSubstitution) {
        int codePoint = ((PerlCharSubstitution) element).getCodePoint();
        if (codePoint >= 0) {
            StringBuilder sb = new StringBuilder("<ul>");
            String chars = ((PerlCharSubstitution) element).getNonIgnorableChars();
            if (StringUtil.isEmptyOrSpaces(chars)) {
                chars = PerlBundle.message("perl.annotator.char.non.printable");
            }
            sb.append("<li>").append(PerlBundle.message("perl.annotator.char.character")).append(": ").append(chars).append(" (").append(Character.getName(codePoint)).append(")").append("</li>");
            sb.append("<li>").append(PerlBundle.message("perl.annotator.char.codepoint")).append(": ").append("0x").append(Integer.toHexString(codePoint).toUpperCase()).append(" (").append(codePoint).append(")").append("</li>");
            sb.append("</ul>");
            holder.newAnnotation(HighlightSeverity.INFORMATION, chars).range(element).tooltip(sb.toString()).create();
        }
    } else if (element instanceof PerlPolyNamedElement) {
        TextAttributesKey subAttribute = PerlSyntaxHighlighter.PERL_SUB_DEFINITION;
        if (element instanceof PerlUseStatementElement && ((PerlUseStatementElement) element).getPackageProcessor() instanceof ConstantProcessor) {
            subAttribute = PerlSyntaxHighlighter.PERL_CONSTANT;
        }
        for (PerlDelegatingLightNamedElement<?> lightNamedElement : ((PerlPolyNamedElement<?>) element).getLightElements()) {
            if (lightNamedElement.isImplicit()) {
                continue;
            }
            TextAttributesKey currentKey = lightNamedElement instanceof PerlSubDefinition ? subAttribute : PerlSyntaxHighlighter.PERL_PACKAGE_DEFINITION;
            PsiElement navigationElement = lightNamedElement.getNavigationElement();
            holder.newSilentAnnotation(HighlightSeverity.INFORMATION).range(ElementManipulators.getValueTextRange(navigationElement).shiftRight(lightNamedElement.getTextOffset())).enforcedTextAttributes(adjustTextAttributes(currentScheme.getAttributes(currentKey), false)).create();
        }
    } else if (elementType == SUB_NAME) {
        PsiElement parent = element.getParent();
        if (parent instanceof PsiPerlSubDeclaration) {
            defaultSilentProducer.accept(PerlSyntaxHighlighter.PERL_SUB_DECLARATION);
        } else if (parent instanceof PerlSubDefinitionElement) {
            if (PerlSubUtil.SUB_AUTOLOAD.equals(((PerlSubNameElement) element).getName())) {
                defaultSilentProducer.accept(PerlSyntaxHighlighter.PERL_AUTOLOAD);
            } else {
                defaultSilentProducer.accept(PerlSyntaxHighlighter.PERL_SUB_DEFINITION);
            }
        } else if (parent instanceof PerlMethod) {
            // fixme don't we need to take multiple references here?
            PsiElement grandParent = parent.getParent();
            PerlNamespaceElement methodNamespace = ((PerlMethod) parent).getNamespaceElement();
            if (// / not ...->method fixme shouldn't we use isObjectMethod here?
            !PerlSubCallElement.isNestedCall(grandParent) && // no explicit NS or it's core
            (methodNamespace == null || methodNamespace.isCORE()) && ((PerlSubNameElement) element).isBuiltIn()) {
                createInfoAnnotation(holder, element, null, PerlSyntaxHighlighter.PERL_SUB_BUILTIN);
            } else {
                PsiReference reference = element.getReference();
                if (reference instanceof PerlSubReference) {
                    ((PerlSubReference) reference).multiResolve(false);
                    if (((PerlSubReference) reference).isConstant()) {
                        defaultAnnotationProducer.accept("Constant", PerlSyntaxHighlighter.PERL_CONSTANT);
                    } else if (((PerlSubReference) reference).isAutoloaded()) {
                        defaultAnnotationProducer.accept("Auto-loaded sub", PerlSyntaxHighlighter.PERL_AUTOLOAD);
                    } else if (((PerlSubReference) reference).isXSub()) {
                        defaultAnnotationProducer.accept("XSub", PerlSyntaxHighlighter.PERL_XSUB);
                    }
                }
            }
        }
    }
}
Also used : ElementManipulators(com.intellij.psi.ElementManipulators) com.perl5.lang.perl.psi.impl(com.perl5.lang.perl.psi.impl) PerlDelegatingLightNamedElement(com.perl5.lang.perl.psi.light.PerlDelegatingLightNamedElement) PerlSubUtil(com.perl5.lang.perl.util.PerlSubUtil) IElementType(com.intellij.psi.tree.IElementType) PerlBundle(com.perl5.PerlBundle) StringUtil(com.intellij.openapi.util.text.StringUtil) HighlightSeverity(com.intellij.lang.annotation.HighlightSeverity) ConstantProcessor(com.perl5.lang.perl.extensions.packageprocessor.impl.ConstantProcessor) PsiReference(com.intellij.psi.PsiReference) THashMap(gnu.trove.THashMap) AnnotationHolder(com.intellij.lang.annotation.AnnotationHolder) Consumer(java.util.function.Consumer) TextAttributesKey(com.intellij.openapi.editor.colors.TextAttributesKey) CodeInsightColors(com.intellij.openapi.editor.colors.CodeInsightColors) PsiUtilCore(com.intellij.psi.util.PsiUtilCore) Map(java.util.Map) PsiElement(com.intellij.psi.PsiElement) BiConsumer(java.util.function.BiConsumer) com.perl5.lang.perl.psi(com.perl5.lang.perl.psi) PerlSyntaxHighlighter(com.perl5.lang.perl.idea.highlighter.PerlSyntaxHighlighter) PerlSubReference(com.perl5.lang.perl.psi.references.PerlSubReference) NotNull(org.jetbrains.annotations.NotNull) PerlSubReference(com.perl5.lang.perl.psi.references.PerlSubReference) ConstantProcessor(com.perl5.lang.perl.extensions.packageprocessor.impl.ConstantProcessor) PsiReference(com.intellij.psi.PsiReference) TextAttributesKey(com.intellij.openapi.editor.colors.TextAttributesKey) IElementType(com.intellij.psi.tree.IElementType) PsiElement(com.intellij.psi.PsiElement)

Example 10 with PerlUseStatementElement

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

the class ConstantProcessor method computeLightElementsFromPsi.

@Override
@NotNull
public List<PerlDelegatingLightNamedElement<?>> computeLightElementsFromPsi(@NotNull PerlUseStatementElement useStatementElement) {
    PsiPerlExpr useArguments = useStatementElement.getExpr();
    if (useArguments == null) {
        return Collections.emptyList();
    }
    boolean multipleDefinition = useArguments instanceof PsiPerlAnonHash;
    List<PerlDelegatingLightNamedElement<?>> result = new ArrayList<>();
    PerlHashUtil.processHashElements(useArguments, (keyElement, valElement) -> {
        if (useStatementElement.isAcceptableIdentifierElement(keyElement)) {
            result.add(new PerlLightConstantDefinitionElement(useStatementElement, ElementManipulators.getValueText(keyElement), LIGHT_SUB_DEFINITION, keyElement, PerlPackageUtil.getContextNamespaceName(useStatementElement), Collections.emptyList(), PerlSubAnnotations.tryToFindAnnotations(keyElement, useArguments, useStatementElement), PerlValuesManager.lazy(valElement)));
        }
        return multipleDefinition;
    });
    return result;
}
Also used : PerlLightConstantDefinitionElement(com.perl5.lang.perl.parser.constant.psi.light.PerlLightConstantDefinitionElement) PerlDelegatingLightNamedElement(com.perl5.lang.perl.psi.light.PerlDelegatingLightNamedElement) ArrayList(java.util.ArrayList) PsiPerlAnonHash(com.perl5.lang.perl.psi.PsiPerlAnonHash) PsiPerlExpr(com.perl5.lang.perl.psi.PsiPerlExpr) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

PerlUseStatementElement (com.perl5.lang.perl.psi.impl.PerlUseStatementElement)9 NotNull (org.jetbrains.annotations.NotNull)8 PsiElement (com.intellij.psi.PsiElement)5 PerlVisitor (com.perl5.lang.perl.psi.PerlVisitor)4 PsiFile (com.intellij.psi.PsiFile)3 PerlPackageProcessor (com.perl5.lang.perl.extensions.packageprocessor.PerlPackageProcessor)3 PerlDelegatingLightNamedElement (com.perl5.lang.perl.psi.light.PerlDelegatingLightNamedElement)3 FileType (com.intellij.openapi.fileTypes.FileType)2 LightVirtualFile (com.intellij.testFramework.LightVirtualFile)2 PerlFileType (com.perl5.lang.perl.fileTypes.PerlFileType)2 PerlUsePackageQuickFix (com.perl5.lang.perl.idea.quickfixes.PerlUsePackageQuickFix)2 PerlNamespaceDefinitionElement (com.perl5.lang.perl.psi.PerlNamespaceDefinitionElement)2 PsiPerlExpr (com.perl5.lang.perl.psi.PsiPerlExpr)2 ArrayList (java.util.ArrayList)2 LocalQuickFix (com.intellij.codeInspection.LocalQuickFix)1 AnnotationHolder (com.intellij.lang.annotation.AnnotationHolder)1 HighlightSeverity (com.intellij.lang.annotation.HighlightSeverity)1 CodeInsightColors (com.intellij.openapi.editor.colors.CodeInsightColors)1 TextAttributesKey (com.intellij.openapi.editor.colors.TextAttributesKey)1 Project (com.intellij.openapi.project.Project)1