use of com.perl5.lang.pod.parser.psi.PodFile in project Perl5-IDEA by Camelcade.
the class PerlDocumentationProvider method getCustomDocumentationElement.
@Nullable
@Override
public PsiElement getCustomDocumentationElement(@NotNull Editor editor, @NotNull PsiFile file, @Nullable PsiElement contextElement) {
if (contextElement == null || contextElement.getLanguage() != PerlLanguage.INSTANCE) {
return null;
}
IElementType elementType = contextElement.getNode().getElementType();
if (contextElement instanceof PerlVariable) {
// fixme try to search doc in package or declaration
return PerlDocUtil.getPerlVarDoc((PerlVariable) contextElement);
} else if (elementType == REGEX_MODIFIER) {
return PerlDocUtil.getRegexModifierDoc(contextElement);
} else if (elementType == REGEX_TOKEN) {
return PerlDocUtil.resolveDocLink("perlretut", contextElement);
} else if (elementType == VERSION_ELEMENT) {
return PerlDocUtil.resolveDocLink("perldata/\"Version Strings\"", contextElement);
} else if (isFunc(contextElement)) {
return PerlDocUtil.getPerlFuncDoc(contextElement);
} else if (isOp(contextElement)) {
return PerlDocUtil.getPerlOpDoc(contextElement);
} else if (contextElement instanceof PerlSubNameElement) {
String packageName = ((PerlSubNameElement) contextElement).getPackageName();
String subName = ((PerlSubNameElement) contextElement).getName();
if (StringUtil.isNotEmpty(subName)) {
PsiElement result = null;
// search by link
if (StringUtil.isNotEmpty(packageName) && !StringUtil.equals(PerlPackageUtil.MAIN_PACKAGE, packageName)) {
result = PerlDocUtil.resolveDocLink(packageName + "/" + ((PerlSubNameElement) contextElement).getName(), contextElement);
}
// not found or main::
if (result == null) {
PsiElement target = null;
if (contextElement.getParent() instanceof PerlSubElement) {
target = contextElement.getParent();
} else {
PsiReference reference = contextElement.getReference();
if (reference != null) {
target = reference.resolve();
}
}
if (target != null) {
PsiFile targetFile = target.getContainingFile();
if (targetFile != null) {
PsiFile podFile = targetFile.getViewProvider().getPsi(PodLanguage.INSTANCE);
if (podFile != null) {
result = PerlDocUtil.searchPodElement(targetFile, PodDocumentPattern.headingAndItemPattern(subName));
}
}
}
}
if (result != null) {
return result;
}
}
} else if (contextElement instanceof PerlNamespaceElement) {
String packageName = ((PerlNamespaceElement) contextElement).getCanonicalName();
if (StringUtil.equals(PerlPackageUtil.SUPER_PACKAGE, packageName)) {
return PerlDocUtil.resolveDocLink("perlobj/Inheritance", contextElement);
} else if (StringUtil.isNotEmpty(packageName)) {
return PerlDocUtil.resolveDocLink(packageName, contextElement);
}
}
return super.getCustomDocumentationElement(editor, file, contextElement);
}
use of com.perl5.lang.pod.parser.psi.PodFile in project Perl5-IDEA by Camelcade.
the class PodTypedHandler method beforeCharTyped.
@Override
public Result beforeCharTyped(char c, Project project, Editor editor, PsiFile file, FileType fileType) {
if (file instanceof PodFile) {
if (c == '<') {
CaretModel caretModel = editor.getCaretModel();
int offset = caretModel.getOffset() - 1;
PsiElement element = file.findElementAt(offset);
IElementType elementType = element == null ? null : element.getNode().getElementType();
String text = element == null ? null : element.getText();
if (elementType == POD_IDENTIFIER && text != null) {
if (text.length() == 1 && StringUtil.containsChar(POD_COMMANDS, text.charAt(0))) {
EditorModificationUtil.insertStringAtCaret(editor, ">", false, false, 0);
}
} else if (elementType == POD_ANGLE_LEFT || POD_COMMANDS_TOKENSET.contains(elementType)) {
// noinspection ConstantConditions
extendAngles(element.getParent());
caretModel.moveToOffset(offset + 2);
return Result.STOP;
}
} else if (// '>'
c == '>') {
CaretModel caretModel = editor.getCaretModel();
int offset = caretModel.getOffset();
PsiElement element = file.findElementAt(offset);
IElementType elementType = element == null ? null : element.getNode().getElementType();
int extraOffset = 0;
if (elementType != POD_ANGLE_RIGHT) {
offset--;
element = file.findElementAt(offset);
elementType = element == null ? null : element.getNode().getElementType();
extraOffset++;
}
if (elementType == POD_ANGLE_RIGHT) {
// noinspection ConstantConditions
caretModel.moveToOffset(offset + extendAngles(element.getParent()) + extraOffset);
return Result.STOP;
}
}
}
return super.beforeCharTyped(c, project, editor, file, fileType);
}
use of com.perl5.lang.pod.parser.psi.PodFile in project Perl5-IDEA by Camelcade.
the class PerlStructureViewElement method getChildren.
@NotNull
@Override
public TreeElement[] getChildren() {
List<TreeElement> result = new ArrayList<>();
Set<String> implementedMethods = new HashSet<>();
if (myElement instanceof PerlFile) {
FileViewProvider viewProvider = ((PerlFile) myElement).getViewProvider();
PsiFile podFile = viewProvider.getPsi(PodLanguage.INSTANCE);
if (podFile != null && podFile.getChildren().length > 1) {
result.add(new PodStructureViewElement(podFile));
}
Language targetLanguage = null;
for (Language language : viewProvider.getLanguages()) {
if (language == PerlLanguage.INSTANCE) {
targetLanguage = language;
break;
} else if (targetLanguage == null && language.isKindOf(PerlLanguage.INSTANCE)) {
targetLanguage = language;
}
}
if (targetLanguage != null) {
viewProvider.getPsi(targetLanguage).accept(new PerlRecursiveVisitor() {
@Override
public void visitNamespaceDefinitionElement(@NotNull PerlNamespaceDefinitionElement o) {
result.add(new PerlNamespaceStructureViewElement(o));
super.visitNamespaceDefinitionElement(o);
}
});
}
}
if (myElement instanceof PerlNamespaceDefinitionElement) {
// global variables
for (PerlVariableDeclarationElement child : PsiTreeUtil.findChildrenOfType(myElement, PerlVariableDeclarationElement.class)) {
if (child.isGlobalDeclaration() && myElement.isEquivalentTo(PerlPackageUtil.getNamespaceContainerForElement(child))) {
result.add(new PerlVariableDeclarationStructureViewElement(child));
}
}
Project project = myElement.getProject();
GlobalSearchScope projectScope = GlobalSearchScope.projectScope(project);
// imported scalars
for (PerlExportDescriptor exportDescritptor : ((PerlNamespaceDefinitionElement) myElement).getImportedScalarDescriptors()) {
String canonicalName = exportDescritptor.getTargetCanonicalName();
Collection<PerlVariableDeclarationElement> variables = PerlScalarUtil.getGlobalScalarDefinitions(project, canonicalName);
for (PerlVariableDeclarationElement variable : variables) {
result.add(new PerlVariableDeclarationStructureViewElement(variable).setImported(exportDescritptor));
}
// globs
Collection<PsiPerlGlobVariable> items = PerlGlobUtil.getGlobsDefinitions(project, canonicalName, projectScope);
if (items.isEmpty()) {
items = PerlGlobUtil.getGlobsDefinitions(project, canonicalName);
}
for (PerlGlobVariable item : items) {
result.add(new PerlGlobStructureViewElement(item).setImported(exportDescritptor));
}
}
// imported arrays
for (PerlExportDescriptor exportDescritptor : ((PerlNamespaceDefinitionElement) myElement).getImportedArrayDescriptors()) {
String canonicalName = exportDescritptor.getTargetCanonicalName();
Collection<PerlVariableDeclarationElement> variables = PerlArrayUtil.getGlobalArrayDefinitions(project, canonicalName);
for (PerlVariableDeclarationElement variable : variables) {
result.add(new PerlVariableDeclarationStructureViewElement(variable).setImported(exportDescritptor));
}
// globs
Collection<PsiPerlGlobVariable> items = PerlGlobUtil.getGlobsDefinitions(project, canonicalName, projectScope);
if (items.isEmpty()) {
items = PerlGlobUtil.getGlobsDefinitions(project, canonicalName);
}
for (PerlGlobVariable item : items) {
result.add(new PerlGlobStructureViewElement(item).setImported(exportDescritptor));
}
}
// imported hashes
for (PerlExportDescriptor exportDescritptor : ((PerlNamespaceDefinitionElement) myElement).getImportedHashDescriptors()) {
String canonicalName = exportDescritptor.getTargetCanonicalName();
Collection<PerlVariableDeclarationElement> variables = PerlHashUtil.getGlobalHashDefinitions(project, canonicalName);
for (PerlVariableDeclarationElement variable : variables) {
result.add(new PerlVariableDeclarationStructureViewElement(variable).setImported(exportDescritptor));
}
// globs
Collection<PsiPerlGlobVariable> items = PerlGlobUtil.getGlobsDefinitions(project, canonicalName, projectScope);
if (items.isEmpty()) {
items = PerlGlobUtil.getGlobsDefinitions(project, canonicalName);
}
for (PerlGlobVariable item : items) {
result.add(new PerlGlobStructureViewElement(item).setImported(exportDescritptor));
}
}
// Imported subs
for (PerlExportDescriptor exportDescritptor : ((PerlNamespaceDefinitionElement) myElement).getImportedSubsDescriptors()) {
String canonicalName = exportDescritptor.getTargetCanonicalName();
// declarations
Collection<PerlSubDeclarationElement> subDeclarations = PerlSubUtil.getSubDeclarations(project, canonicalName, projectScope);
if (subDeclarations.isEmpty()) {
subDeclarations = PerlSubUtil.getSubDeclarations(project, canonicalName);
}
for (PerlSubDeclarationElement item : subDeclarations) {
result.add(new PerlSubStructureViewElement(item).setImported(exportDescritptor));
}
// definitions
Collection<PerlSubDefinitionElement> subDefinitions = PerlSubUtil.getSubDefinitions(project, canonicalName, projectScope);
if (subDefinitions.isEmpty()) {
subDefinitions = PerlSubUtil.getSubDefinitions(project, canonicalName);
}
for (PerlSubDefinitionElement item : subDefinitions) {
result.add(new PerlSubStructureViewElement(item).setImported(exportDescritptor));
}
// globs
Collection<PsiPerlGlobVariable> items = PerlGlobUtil.getGlobsDefinitions(project, canonicalName, projectScope);
if (items.isEmpty()) {
items = PerlGlobUtil.getGlobsDefinitions(project, canonicalName);
}
for (PerlGlobVariable item : items) {
result.add(new PerlGlobStructureViewElement(item).setImported(exportDescritptor));
}
}
myElement.accept(new PerlRecursiveVisitor() {
@Override
public void visitPerlSubDefinitionElement(@NotNull PerlSubDefinitionElement child) {
if (myElement.isEquivalentTo(PerlPackageUtil.getNamespaceContainerForElement(child))) {
implementedMethods.add(child.getName());
result.add(new PerlSubStructureViewElement(child));
}
super.visitPerlSubDefinitionElement(child);
}
@Override
public void visitSubDeclarationElement(@NotNull PerlSubDeclarationElement child) {
if (myElement.isEquivalentTo(PerlPackageUtil.getNamespaceContainerForElement(child))) {
result.add(new PerlSubStructureViewElement(child));
}
super.visitSubDeclarationElement(child);
}
@Override
public void visitGlobVariable(@NotNull PsiPerlGlobVariable child) {
if (child.isLeftSideOfAssignment() && myElement.isEquivalentTo(PerlPackageUtil.getNamespaceContainerForElement(child))) {
implementedMethods.add(child.getName());
result.add(new PerlGlobStructureViewElement(child));
}
super.visitGlobVariable(child);
}
});
}
// inherited elements
if (myElement instanceof PerlNamespaceDefinitionWithIdentifier) {
List<TreeElement> inheritedResult = new ArrayList<>();
String packageName = ((PerlNamespaceDefinitionElement) myElement).getPackageName();
if (packageName != null) {
for (PsiElement element : PerlMro.getVariants(myElement, packageName, true)) {
if (element instanceof PerlIdentifierOwner && !implementedMethods.contains(((PerlIdentifierOwner) element).getName())) {
if (element instanceof PerlLightConstantDefinitionElement) {
inheritedResult.add(new PerlSubStructureViewElement((PerlSubDefinitionElement) element).setInherited());
} else if (element instanceof PerlSubDefinitionElement) {
inheritedResult.add(new PerlSubStructureViewElement((PerlSubDefinitionElement) element).setInherited());
} else if (element instanceof PerlSubDeclarationElement) {
inheritedResult.add(new PerlSubStructureViewElement((PerlSubDeclarationElement) element).setInherited());
} else if (element instanceof PerlGlobVariable && ((PerlGlobVariable) element).isLeftSideOfAssignment() && ((PerlGlobVariable) element).getName() != null) {
inheritedResult.add(new PerlGlobStructureViewElement((PerlGlobVariable) element).setInherited());
}
}
}
}
if (!inheritedResult.isEmpty()) {
result.addAll(0, inheritedResult);
}
}
return result.toArray(new TreeElement[result.size()]);
}
use of com.perl5.lang.pod.parser.psi.PodFile in project Perl5-IDEA by Camelcade.
the class PodBackspaceHandler method charDeleted.
@Override
public boolean charDeleted(char c, PsiFile file, Editor editor) {
if (file instanceof PodFile) {
CaretModel caretModel = editor.getCaretModel();
int offset = caretModel.getOffset();
PsiElement element = file.findElementAt(offset);
IElementType elementType = element == null ? null : element.getNode().getElementType();
if (elementType == POD_ANGLE_RIGHT) {
@SuppressWarnings("ConstantConditions") PsiElement formatterBlock = element.getParent();
if (formatterBlock != null) {
PsiElement openAngles = formatterBlock.getFirstChild();
openAngles = openAngles == null ? null : openAngles.getNextSibling();
if (openAngles != null) {
int openAnglesOffset = openAngles.getTextRange().getStartOffset();
editor.getDocument().deleteString(openAnglesOffset, openAnglesOffset + 1);
return true;
}
}
} else if (elementType == POD_ANGLE_LEFT) {
@SuppressWarnings("ConstantConditions") PsiElement formatterBlock = element.getParent();
if (formatterBlock != null) {
PsiElement closeAngles = formatterBlock.getLastChild();
if (closeAngles != null) {
int closeAnglesOffset = closeAngles.getTextRange().getStartOffset();
editor.getDocument().deleteString(closeAnglesOffset - 1, closeAnglesOffset);
return true;
}
}
return true;
}
}
return false;
}
Aggregations