use of com.perl5.lang.perl.psi.PerlSubDefinitionElement in project Perl5-IDEA by Camelcade.
the class PerlCodeGeneratorImpl method getOverrideCodeText.
@Nullable
@Override
public String getOverrideCodeText(PsiElement subBase) {
if (subBase instanceof PerlSubElement) {
PerlSubElement perlSubBase = (PerlSubElement) subBase;
StringBuilder code = new StringBuilder();
code.append("#@override\n");
PerlSubAnnotations annotations = perlSubBase.getAnnotations();
if (annotations != null) {
if (annotations.isDeprecated()) {
code.append("#@deprecated\n");
}
if (annotations.isAbstract()) {
code.append("#@abstract\n");
}
if (annotations.isMethod() || subBase instanceof PerlMethodDefinition) {
code.append("#@method\n");
}
if (StringUtil.isNotEmpty(annotations.getReturns())) {
code.append("#@returns ");
code.append(annotations.getReturns());
code.append("\n");
}
}
code.append("sub ");
code.append(perlSubBase.getSubName());
code.append("{\n");
List<String> superArgs = new ArrayList<>();
List<PerlSubArgument> arguments = Collections.emptyList();
if (perlSubBase instanceof PerlSubDefinitionElement) {
// noinspection unchecked
arguments = ((PerlSubDefinitionElement) perlSubBase).getSubArgumentsList();
if (!arguments.isEmpty()) {
boolean useShift = false;
for (PerlSubArgument argument : arguments) {
if (StringUtil.isNotEmpty(argument.getVariableClass())) {
useShift = true;
break;
}
}
if (useShift) {
for (PerlSubArgument argument : arguments) {
if (!argument.isEmpty()) {
code.append("my ");
code.append(argument.getVariableClass());
code.append(" ");
String superArg = argument.toStringShort();
superArgs.add(superArg);
code.append(superArg);
code.append(" = ");
}
code.append("shift;\n");
}
} else {
code.append("my ");
code.append('(');
boolean insertComma = false;
for (PerlSubArgument argument : arguments) {
if (insertComma) {
code.append(", ");
} else {
insertComma = true;
}
String superArg = argument.toStringShort();
superArgs.add(superArg);
code.append(superArg);
}
code.append(") = @_;\n");
}
} else {
code.append("my ($self) = @_;\n");
}
}
if (!superArgs.isEmpty()) {
superArgs.remove(0);
}
if (!arguments.isEmpty() && !arguments.get(0).isEmpty()) {
// noinspection StringConcatenationInsideStringBufferAppend
code.append(arguments.get(0).toStringShort() + "->SUPER::" + perlSubBase.getSubName() + "(" + StringUtil.join(superArgs, ", ") + ");\n");
}
code.append("}");
return code.toString();
}
return null;
}
use of com.perl5.lang.perl.psi.PerlSubDefinitionElement in project Perl5-IDEA by Camelcade.
the class PerlSubReference method resolveInner.
@NotNull
@Override
protected ResolveResult[] resolveInner(boolean incompleteCode) {
PsiElement myElement = getElement();
assert myElement instanceof PerlSubNameElement;
PsiElement parent = myElement.getParent();
if (parent instanceof PerlSubDeclarationElement || parent instanceof PerlSubDefinitionElement) {
return ResolveResult.EMPTY_ARRAY;
}
PerlSubNameElement subNameElement = (PerlSubNameElement) myElement;
List<PsiElement> relatedItems = new ArrayList<>();
String packageName = subNameElement.getPackageName();
String subName = subNameElement.getName();
Project project = subNameElement.getProject();
PerlNamespaceElement expliclitPackageElement = null;
if (parent instanceof PerlNamespaceElementContainer) {
expliclitPackageElement = ((PerlNamespaceElementContainer) parent).getNamespaceElement();
}
if (!subName.isEmpty()) {
if (parent instanceof PerlMethod && ((PerlMethod) parent).isObjectMethod()) {
boolean isSuper = expliclitPackageElement != null && expliclitPackageElement.isSUPER();
relatedItems.addAll(PerlMro.resolveSub(project, isSuper ? PerlPackageUtil.getContextPackageName(subNameElement) : packageName, subName, isSuper));
} else // static resolution
{
if (PerlSharedSettings.getInstance(project).SIMPLE_MAIN_RESOLUTION && // fixme this is a dirty hack until proper names resolution implemented
PerlPackageUtil.isMain(packageName)) {
PsiFile file = subNameElement.getContainingFile();
GlobalSearchScope fileScope = GlobalSearchScope.fileScope(file);
collectRelatedItems(packageName + PerlPackageUtil.PACKAGE_SEPARATOR + subName, project, parent, relatedItems, fileScope);
// if (file instanceof PerlFile)
// ((PerlFile) file).getElementsResolveScope();
// System.err.println("Checking for " + subName);
}
if (relatedItems.isEmpty()) {
GlobalSearchScope globalSearchScope = GlobalSearchScope.allScope(project);
// check indexes for defined subs
collectRelatedItems(packageName + PerlPackageUtil.PACKAGE_SEPARATOR + subName, project, parent, relatedItems, globalSearchScope);
if (expliclitPackageElement == null) {
// check for imports to the current file
PerlNamespaceDefinitionElement namespaceContainer = PerlPackageUtil.getNamespaceContainerForElement(subNameElement);
if (namespaceContainer != null) {
for (PerlExportDescriptor exportDescriptor : namespaceContainer.getImportedSubsDescriptors()) {
if (exportDescriptor.getImportedName().equals(subName)) {
int currentSize = relatedItems.size();
collectRelatedItems(exportDescriptor.getTargetCanonicalName(), project, parent, relatedItems, globalSearchScope);
if (// imported, but not found, attempting autoload
relatedItems.size() == currentSize) {
collectRelatedItems(exportDescriptor.getRealPackage() + PerlSubUtil.SUB_AUTOLOAD_WITH_PREFIX, project, parent, relatedItems, globalSearchScope);
}
}
}
}
} else // check imports to target namespace
{
String targetPackageName = expliclitPackageElement.getCanonicalName();
if (targetPackageName != null) {
// fixme partially not DRY with previous block
for (PerlNamespaceDefinitionElement namespaceDefinition : PerlPackageUtil.getNamespaceDefinitions(project, targetPackageName)) {
for (PerlExportDescriptor exportDescriptor : namespaceDefinition.getImportedSubsDescriptors()) {
if (exportDescriptor.getImportedName().equals(subName)) {
collectRelatedItems(exportDescriptor.getTargetCanonicalName(), project, parent, relatedItems, globalSearchScope);
}
}
}
}
}
// check for builtins
if (relatedItems.isEmpty()) {
PerlSubDefinitionElement builtInSub = PerlBuiltInSubsService.getInstance(project).findSub(subName);
if (builtInSub != null) {
relatedItems.add(builtInSub);
}
}
// check for autoload
if (relatedItems.isEmpty() && // don't check for UNIVERSAL::AUTOLOAD
!PerlPackageUtil.isUNIVERSAL(packageName)) {
collectRelatedItems(packageName + PerlSubUtil.SUB_AUTOLOAD_WITH_PREFIX, project, parent, relatedItems, globalSearchScope);
}
}
}
}
List<ResolveResult> result = getResolveResults(relatedItems);
return result.toArray(new ResolveResult[result.size()]);
}
use of com.perl5.lang.perl.psi.PerlSubDefinitionElement in project Perl5-IDEA by Camelcade.
the class PerlSubReferenceSimple method getResolveResults.
@NotNull
public List<ResolveResult> getResolveResults(List<PsiElement> relatedItems) {
List<ResolveResult> result = new ArrayList<>();
resetFlags();
for (PsiElement element : relatedItems) {
if (!isAutoloaded() && element instanceof PerlIdentifierOwner && PerlSubUtil.SUB_AUTOLOAD.equals(((PerlIdentifierOwner) element).getName())) {
setAutoloaded();
}
if (!isConstant() && element instanceof PerlLightConstantDefinitionElement) {
setConstant();
}
if (!isDeclared() && element instanceof PerlSubDeclarationElement) {
setDeclared();
}
if (!isDefined() && element instanceof PerlSubDefinitionElement) {
setDefined();
}
if (!isXSub() && element instanceof PerlSubElement && ((PerlSubElement) element).isXSub()) {
setXSub();
}
if (!isAliased() && element instanceof PerlGlobVariable) {
setAliased();
}
result.add(new PsiElementResolveResult(element));
}
return result;
}
use of com.perl5.lang.perl.psi.PerlSubDefinitionElement 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);
if (elementType == NYI_STATEMENT) {
holder.createInfoAnnotation(element, "Unimplemented statement").setTextAttributes(CodeInsightColors.TODO_DEFAULT_ATTRIBUTES);
} else if (element instanceof PerlGlobVariable && ((PerlGlobVariable) element).isBuiltIn()) {
holder.createInfoAnnotation(element, null).setTextAttributes(PERL_GLOB_BUILTIN);
} else if (element instanceof PerlVariable && ((PerlVariable) element).isBuiltIn()) {
holder.createInfoAnnotation(element, null).setTextAttributes(VARIABLE_KEYS_MAP.get(element.getClass()));
} else if (elementType == LABEL_DECLARATION || elementType == LABEL_EXPR) {
holder.createInfoAnnotation(element.getFirstChild(), null).setTextAttributes(PerlSyntaxHighlighter.PERL_LABEL);
} else if (elementType == PACKAGE) {
assert element instanceof PerlNamespaceElement;
PerlNamespaceElement namespaceElement = (PerlNamespaceElement) element;
PsiElement parent = namespaceElement.getParent();
if (parent instanceof PerlNamespaceDefinitionWithIdentifier) {
decorateElement(namespaceElement, holder, PerlSyntaxHighlighter.PERL_PACKAGE_DEFINITION, false);
} else {
if (namespaceElement.isPragma()) {
decorateElement(namespaceElement, holder, PerlSyntaxHighlighter.PERL_PACKAGE_PRAGMA, false);
} else if (namespaceElement.isBuiltin()) {
decorateElement(namespaceElement, holder, PerlSyntaxHighlighter.PERL_PACKAGE_CORE, false);
}
}
} else if (element instanceof PerlPolyNamedElement) {
TextAttributesKey subAttribute = PerlSyntaxHighlighter.PERL_SUB_DEFINITION;
if (elementType == PerlConstantsWrapperElementType.CONSTANT_WRAPPER) {
// fixme some interface?
subAttribute = PerlSyntaxHighlighter.PERL_CONSTANT;
}
for (PerlDelegatingLightNamedElement lightNamedElement : ((PerlPolyNamedElement) element).getLightElements()) {
TextAttributesKey currentKey = lightNamedElement instanceof PerlSubDefinition ? subAttribute : PerlSyntaxHighlighter.PERL_PACKAGE_DEFINITION;
PsiElement navigationElement = lightNamedElement.getNavigationElement();
holder.createInfoAnnotation(ElementManipulators.getValueTextRange(navigationElement).shiftRight(lightNamedElement.getTextOffset()), null).setEnforcedTextAttributes(adjustTextAttributes(currentScheme.getAttributes(currentKey), false));
}
} else if (// instanceof PerlSubNameElement
elementType == SUB_NAME) {
PsiElement parent = element.getParent();
if (parent instanceof PsiPerlSubDeclaration) {
holder.createInfoAnnotation(element, null).setTextAttributes(PerlSyntaxHighlighter.PERL_SUB_DECLARATION);
} else if (parent instanceof PerlSubDefinitionElement) {
if ("AUTOLOAD".equals(((PerlSubNameElement) element).getName())) {
holder.createInfoAnnotation(element, null).setTextAttributes(PerlSyntaxHighlighter.PERL_AUTOLOAD);
} else {
holder.createInfoAnnotation(element, null).setTextAttributes(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?
!(grandParent instanceof PsiPerlNestedCall) && // no explicit NS or it's core
(methodNamespace == null || methodNamespace.isCORE()) && ((PerlSubNameElement) element).isBuiltIn()) {
decorateElement(element, holder, PerlSyntaxHighlighter.PERL_SUB_BUILTIN);
} else {
PsiReference reference = element.getReference();
if (reference instanceof PerlSubReference) {
((PerlSubReference) reference).multiResolve(false);
if (((PerlSubReference) reference).isConstant()) {
holder.createInfoAnnotation(element, "Constant").setTextAttributes(PerlSyntaxHighlighter.PERL_CONSTANT);
} else if (((PerlSubReference) reference).isAutoloaded()) {
holder.createInfoAnnotation(element, "Auto-loaded sub").setTextAttributes(PerlSyntaxHighlighter.PERL_AUTOLOAD);
} else if (((PerlSubReference) reference).isXSub()) {
holder.createInfoAnnotation(element, "XSub").setTextAttributes(PerlSyntaxHighlighter.PERL_XSUB);
}
}
}
}
}
}
use of com.perl5.lang.perl.psi.PerlSubDefinitionElement in project Perl5-IDEA by Camelcade.
the class SubSelectionHandler method handleInsert.
@Override
public void handleInsert(final InsertionContext context, LookupElement item) {
final Editor editor = context.getEditor();
int caretOffset = editor.getCaretModel().getOffset();
PsiElement targetElement = context.getFile().findElementAt(caretOffset);
if (targetElement != null && targetElement.getNode().getElementType() == LEFT_PAREN) {
return;
}
PsiElement subDefitnition = item.getPsiElement();
EditorModificationUtil.insertStringAtCaret(editor, "()");
// todo we need hint with prototype here, but prototypes handling NYI
if (!(subDefitnition instanceof PerlSubDefinitionElement && ((PerlSubDefinitionElement) subDefitnition).getSubArgumentsList().isEmpty())) {
editor.getCaretModel().moveCaretRelatively(-1, 0, false, false, true);
}
}
Aggregations