use of org.ballerinalang.plugins.idea.psi.PackageDeclarationNode in project ballerina by ballerina-lang.
the class UnusedImportInspection method checkFile.
@Override
@Nullable
public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
// does not work in tests since CodeInsightTestCase copies file into temporary location
if (ApplicationManager.getApplication().isUnitTestMode()) {
return new ProblemDescriptor[0];
}
if (!(file instanceof BallerinaFile)) {
return new ProblemDescriptor[0];
}
// This is used to track all packages used in the file.
List<String> usedPackages = new LinkedList<>();
LocalQuickFix[] availableFixes = new LocalQuickFix[0];
List<ProblemDescriptor> problemDescriptors = new LinkedList<>();
Collection<PackageNameNode> packageNameNodes = PsiTreeUtil.findChildrenOfType(file, PackageNameNode.class);
for (PackageNameNode packageNameNode : packageNameNodes) {
ProgressManager.checkCanceled();
if (packageNameNode == null) {
continue;
}
PackageDeclarationNode packageDeclarationNode = PsiTreeUtil.getParentOfType(packageNameNode, PackageDeclarationNode.class);
if (packageDeclarationNode != null) {
continue;
}
ImportDeclarationNode importDeclarationNode = PsiTreeUtil.getParentOfType(packageNameNode, ImportDeclarationNode.class);
if (importDeclarationNode != null) {
continue;
}
XmlAttribNode xmlAttribNode = PsiTreeUtil.getParentOfType(packageNameNode, XmlAttribNode.class);
if (xmlAttribNode != null) {
continue;
}
PsiElement nameIdentifier = packageNameNode.getNameIdentifier();
if (nameIdentifier == null) {
continue;
}
usedPackages.add(nameIdentifier.getText());
}
// This is used to keep track of fully qualified imported packages. This will be used to identify redeclared
// import statements.
List<String> fullyQualifiedImportedPackages = new LinkedList<>();
// This is used to keep track of last package in import declaration. This will be used to identify importing
// multiple packages which ends with same name.
List<String> importedPackages = new LinkedList<>();
Collection<ImportDeclarationNode> importDeclarationNodes = PsiTreeUtil.findChildrenOfType(file, ImportDeclarationNode.class);
for (ImportDeclarationNode importDeclarationNode : importDeclarationNodes) {
ProgressManager.checkCanceled();
if (importDeclarationNode == null) {
continue;
}
// Check unused imports. No need to check for fully qualified path since we cant import packages of same
// name.
List<PackageNameNode> packageNames = new ArrayList<>(PsiTreeUtil.findChildrenOfType(importDeclarationNode, PackageNameNode.class));
PackageNameNode lastPackage = ContainerUtil.getLastItem(packageNames);
if (lastPackage == null) {
continue;
}
String lastPackageName = lastPackage.getText();
if (!usedPackages.contains(lastPackageName)) {
problemDescriptors.add(createProblemDescriptor(manager, "Unused import", isOnTheFly, importDeclarationNode, availableFixes, ProblemHighlightType.LIKE_UNUSED_SYMBOL));
}
// Check conflicting imports (which ends with same package name).
if (importedPackages.contains(lastPackageName)) {
problemDescriptors.add(createProblemDescriptor(manager, "Conflicting import", isOnTheFly, importDeclarationNode, availableFixes, ProblemHighlightType.GENERIC_ERROR));
}
importedPackages.add(lastPackageName);
// Check redeclared imports.
FullyQualifiedPackageNameNode fullyQualifiedPackageName = PsiTreeUtil.getChildOfType(importDeclarationNode, FullyQualifiedPackageNameNode.class);
if (fullyQualifiedPackageName == null) {
continue;
}
if (fullyQualifiedImportedPackages.contains(fullyQualifiedPackageName.getText())) {
problemDescriptors.add(createProblemDescriptor(manager, "Redeclared import", isOnTheFly, importDeclarationNode, availableFixes, ProblemHighlightType.GENERIC_ERROR));
}
fullyQualifiedImportedPackages.add(fullyQualifiedPackageName.getText());
}
return problemDescriptors.toArray(new ProblemDescriptor[problemDescriptors.size()]);
}
use of org.ballerinalang.plugins.idea.psi.PackageDeclarationNode in project ballerina by ballerina-lang.
the class WrongPackageStatementInspection method checkFile.
@Override
@Nullable
public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
// does not work in tests since CodeInsightTestCase copies file into temporary location
if (ApplicationManager.getApplication().isUnitTestMode()) {
return new ProblemDescriptor[0];
}
if (!(file instanceof BallerinaFile)) {
return new ProblemDescriptor[0];
}
Module module = ModuleUtil.findModuleForFile(file.getVirtualFile(), file.getProject());
boolean isBallerinaModule = BallerinaSdkService.getInstance(file.getProject()).isBallerinaModule(module);
if (!isBallerinaModule) {
return new ProblemDescriptor[0];
}
BallerinaFile ballerinaFile = (BallerinaFile) file;
PsiDirectory directory = ballerinaFile.getContainingDirectory();
if (directory == null) {
return new ProblemDescriptor[0];
}
List<ProblemDescriptor> problemDescriptors = new LinkedList<>();
String packageName = BallerinaUtil.suggestPackageNameForDirectory(directory);
PackageDeclarationNode packageDeclarationNode = PsiTreeUtil.findChildOfType(file, PackageDeclarationNode.class);
Collection<DefinitionNode> definitionNodes = PsiTreeUtil.findChildrenOfType(file, DefinitionNode.class);
for (DefinitionNode definitionNode : definitionNodes) {
PsiElement firstChild = definitionNode.getFirstChild();
if (firstChild == null || !(firstChild instanceof IdentifierDefSubtree)) {
return new ProblemDescriptor[0];
}
PsiElement nameIdentifier = ((IdentifierDefSubtree) firstChild).getNameIdentifier();
if (nameIdentifier == null) {
return new ProblemDescriptor[0];
}
if (!Comparing.strEqual(packageName, "", true) && packageDeclarationNode == null) {
String description = "Missing package statement: '" + packageName + "'";
ProblemDescriptor problemDescriptor = manager.createProblemDescriptor(nameIdentifier, description, new AdjustPackageNameFix(nameIdentifier, packageName), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, isOnTheFly);
problemDescriptors.add(problemDescriptor);
}
}
if (!problemDescriptors.isEmpty()) {
return problemDescriptors.toArray(new ProblemDescriptor[problemDescriptors.size()]);
}
if (packageDeclarationNode == null) {
return new ProblemDescriptor[0];
}
FullyQualifiedPackageNameNode fullyQualifiedPackageNameNode = PsiTreeUtil.findChildOfType(packageDeclarationNode, FullyQualifiedPackageNameNode.class);
if (fullyQualifiedPackageNameNode == null || fullyQualifiedPackageNameNode.getText().isEmpty()) {
return new ProblemDescriptor[0];
}
Collection<PackageNameNode> packageNames = PsiTreeUtil.findChildrenOfType(packageDeclarationNode, PackageNameNode.class);
if (packageNames.isEmpty()) {
return new ProblemDescriptor[0];
}
LinkedList<PackageNameNode> packageNameNodes = new LinkedList<>();
packageNameNodes.addAll(packageNames);
PackageNameNode lastElement = packageNameNodes.getLast();
if (lastElement == null) {
return new ProblemDescriptor[0];
}
List<LocalQuickFix> availableFixes = new ArrayList<>();
availableFixes.add(new AdjustPackageNameFix(fullyQualifiedPackageNameNode, packageName));
PsiElement packageNameIdentifier = lastElement.getNameIdentifier();
if (packageNameIdentifier == null) {
return getProblemDescriptors(manager, isOnTheFly, packageName, availableFixes, fullyQualifiedPackageNameNode, lastElement);
}
PsiReference reference = packageNameIdentifier.getReference();
if (reference == null) {
return getProblemDescriptors(manager, isOnTheFly, packageName, availableFixes, fullyQualifiedPackageNameNode, lastElement);
}
PsiElement resolvedElement = reference.resolve();
if (!(resolvedElement instanceof PsiDirectory)) {
return getProblemDescriptors(manager, isOnTheFly, packageName, availableFixes, fullyQualifiedPackageNameNode, lastElement);
}
String containingDirectoryPackageName = BallerinaUtil.suggestPackageNameForDirectory(((PsiDirectory) resolvedElement));
if (!Comparing.equal(packageName, containingDirectoryPackageName, true)) {
if (!availableFixes.isEmpty()) {
return getProblemDescriptors(manager, isOnTheFly, packageName, availableFixes, fullyQualifiedPackageNameNode, lastElement);
}
}
return new ProblemDescriptor[0];
}
use of org.ballerinalang.plugins.idea.psi.PackageDeclarationNode in project ballerina by ballerina-lang.
the class BallerinaCompletionContributor method handlePackageNameNode.
/**
* Add lookups for package declarations.
*
* @param parameters parameters which contain details of completion invocation
* @param resultSet result list which is used to add lookups
*/
private void handlePackageNameNode(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet resultSet) {
PsiElement element = parameters.getPosition();
PsiElement parent = element.getParent();
PsiElement superParent = parent.getParent();
// Check whether we are in a package declaration node
if (superParent.getParent() instanceof PackageDeclarationNode) {
// If we are in a package declaration node, suggest packages.
addPackageSuggestions(resultSet, element);
} else if (superParent.getParent() instanceof ImportDeclarationNode && !(superParent instanceof AliasNode)) {
// If the parent is not an AliasNode and is inside the ImportDeclarationNode, we need to suggest
// packages.
addImportSuggestions(resultSet, element);
}
}
use of org.ballerinalang.plugins.idea.psi.PackageDeclarationNode in project ballerina by ballerina-lang.
the class BallerinaKeywordsCompletionContributor method fillCompletionVariants.
@Override
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiElement element = parameters.getPosition();
PsiElement parent = element.getParent();
if (element instanceof LeafPsiElement) {
IElementType elementType = ((LeafPsiElement) element).getElementType();
if (elementType == BallerinaTypes.FLOATING_POINT) {
return;
}
}
if (parent instanceof NameReferenceNode) {
PsiElement prevVisibleLeaf = PsiTreeUtil.prevVisibleLeaf(element);
if (prevVisibleLeaf != null && "public".equals(prevVisibleLeaf.getText())) {
result.addAllElements(getFileLevelKeywordsAsLookups(false, true, true));
}
if (prevVisibleLeaf instanceof IdentifierPSINode) {
result.addElement(getAttachKeyword());
return;
}
ANTLRPsiNode definitionParent = PsiTreeUtil.getParentOfType(parent, CallableUnitBodyNode.class, ServiceBodyNode.class, ConnectorBodyNode.class);
if (definitionParent != null && prevVisibleLeaf != null && "=".equals(prevVisibleLeaf.getText())) {
result.addElement(getCreateKeyword());
result.addElement(getTypeOfKeyword());
result.addElement(getLengthOfKeyword());
result.addAllElements(getValueKeywords());
}
ExpressionNode expressionNode = PsiTreeUtil.getParentOfType(parent, ExpressionNode.class);
if (expressionNode != null && expressionNode.getChildren().length == 1) {
PsiReference referenceAt = parent.findReferenceAt(0);
if (referenceAt == null || referenceAt instanceof NameReference) {
result.addAllElements(getValueKeywords());
}
PsiElement nextVisibleLeaf = PsiTreeUtil.nextVisibleLeaf(element);
if ((prevVisibleLeaf != null && "(".equals(prevVisibleLeaf.getText())) || (nextVisibleLeaf != null && ")".equals(nextVisibleLeaf.getText()) && !":".equals(prevVisibleLeaf.getText()))) {
addOtherTypeAsLookup(result);
addValueTypesAsLookups(result);
addReferenceTypesAsLookups(result);
}
}
AnnotationAttachmentNode attachmentNode = PsiTreeUtil.getParentOfType(parent, AnnotationAttachmentNode.class);
if (attachmentNode != null) {
result.addAllElements(getValueKeywords());
}
TypeNameNode typeNameNode = PsiTreeUtil.getParentOfType(parent, TypeNameNode.class);
if (typeNameNode != null && prevVisibleLeaf != null && !prevVisibleLeaf.getText().matches("[:.=]")) {
AnnotationDefinitionNode annotationDefinitionNode = PsiTreeUtil.getParentOfType(typeNameNode, AnnotationDefinitionNode.class);
if (annotationDefinitionNode == null) {
addOtherTypeAsLookup(result);
addXmlnsAsLookup(result);
addValueTypesAsLookups(result);
addReferenceTypesAsLookups(result);
}
}
}
if (parent instanceof StatementNode) {
PsiElement prevVisibleSibling = PsiTreeUtil.prevVisibleLeaf(element);
if (prevVisibleSibling != null && "=".equals(prevVisibleSibling.getText())) {
result.addElement(getCreateKeyword());
result.addElement(getTypeOfKeyword());
result.addElement(getLengthOfKeyword());
}
}
if (parent instanceof ConstantDefinitionNode || parent instanceof PsiErrorElement) {
PsiElement prevVisibleSibling = PsiTreeUtil.prevVisibleLeaf(element);
if (prevVisibleSibling != null && "const".equals(prevVisibleSibling.getText())) {
addValueTypesAsLookups(result);
return;
}
}
if (parent instanceof PsiErrorElement) {
PsiElement prevVisibleSibling = PsiTreeUtil.prevVisibleLeaf(element);
PsiElement definitionNode = PsiTreeUtil.getParentOfType(element, FunctionDefinitionNode.class, ServiceDefinitionNode.class, ConnectorDefinitionNode.class, ResourceDefinitionNode.class);
if (definitionNode != null) {
if (prevVisibleSibling != null && "=".equals(prevVisibleSibling.getText())) {
result.addElement(getCreateKeyword());
result.addAllElements(getValueKeywords());
result.addElement(getTypeOfKeyword());
result.addElement(getLengthOfKeyword());
}
if (prevVisibleSibling != null && prevVisibleSibling.getText().matches("[;{}]") && !(prevVisibleSibling.getParent() instanceof AnnotationAttachmentNode)) {
// Todo - change method
addOtherTypeAsLookup(result);
addXmlnsAsLookup(result);
addValueTypesAsLookups(result);
addReferenceTypesAsLookups(result);
if (definitionNode instanceof FunctionDefinitionNode) {
result.addAllElements(getFunctionSpecificKeywords());
}
if (definitionNode instanceof ResourceDefinitionNode) {
result.addAllElements(getResourceSpecificKeywords());
}
if (definitionNode instanceof ServiceDefinitionNode) {
result.addAllElements(getServiceSpecificKeywords());
}
if (definitionNode instanceof ConnectorDefinitionNode) {
result.addAllElements(getConnectorSpecificKeywords());
}
if (!(definitionNode instanceof ServiceDefinitionNode || definitionNode instanceof ConnectorDefinitionNode)) {
result.addAllElements(getCommonKeywords());
}
}
if (prevVisibleSibling != null && !prevVisibleSibling.getText().matches("[{}]")) /*|| !(prevVisibleSibling.getParent() instanceof AnnotationAttachmentNode)*/
{
result.addAllElements(getValueKeywords());
}
}
ConnectorBodyNode connectorBodyNode = PsiTreeUtil.getParentOfType(element, ConnectorBodyNode.class);
if (connectorBodyNode != null) {
result.addAllElements(getConnectorSpecificKeywords());
}
ConnectorDefinitionNode connectorDefinitionNode = PsiTreeUtil.getParentOfType(element, ConnectorDefinitionNode.class);
if (connectorDefinitionNode != null) {
result.addAllElements(getConnectorSpecificKeywords());
}
return;
}
if (parent instanceof NameReferenceNode) {
RecordKeyValueNode recordKeyValueNode = PsiTreeUtil.getParentOfType(parent, RecordKeyValueNode.class);
if (recordKeyValueNode == null) {
PsiElement prevVisibleSibling = PsiTreeUtil.prevVisibleLeaf(element);
if (prevVisibleSibling != null && "{".equals(prevVisibleSibling.getText())) {
FunctionDefinitionNode functionDefinitionNode = PsiTreeUtil.getParentOfType(element, FunctionDefinitionNode.class);
if (functionDefinitionNode != null) {
// Todo - change method
addOtherTypeAsLookup(result);
addXmlnsAsLookup(result);
addValueTypesAsLookups(result);
addReferenceTypesAsLookups(result);
result.addAllElements(getFunctionSpecificKeywords());
result.addAllElements(getCommonKeywords());
result.addAllElements(getValueKeywords());
}
ServiceBodyNode serviceBodyNode = PsiTreeUtil.getParentOfType(element, ServiceBodyNode.class);
if (serviceBodyNode != null) {
result.addAllElements(getServiceSpecificKeywords());
}
ConnectorBodyNode connectorBodyNode = PsiTreeUtil.getParentOfType(element, ConnectorBodyNode.class);
if (connectorBodyNode != null) {
result.addAllElements(getConnectorSpecificKeywords());
}
} else if (prevVisibleSibling != null && "}".equals(prevVisibleSibling.getText())) {
result.addAllElements(getFileLevelKeywordsAsLookups(true, false, false));
}
}
}
if (parent instanceof ResourceDefinitionNode) {
result.addAllElements(getServiceSpecificKeywords());
}
if (parent.getPrevSibling() == null) {
GlobalVariableDefinitionNode globalVariableDefinitionNode = PsiTreeUtil.getParentOfType(element, GlobalVariableDefinitionNode.class);
if (globalVariableDefinitionNode != null) {
PsiElement prevVisibleSibling = PsiTreeUtil.prevVisibleLeaf(element);
if (prevVisibleSibling != null && !(";".equals(prevVisibleSibling.getText()))) {
if (!(prevVisibleSibling.getText().matches("[:=]") || prevVisibleSibling instanceof IdentifierPSINode || "create".equals(prevVisibleSibling.getText()))) {
if (prevVisibleSibling instanceof LeafPsiElement) {
IElementType elementType = ((LeafPsiElement) prevVisibleSibling).getElementType();
if (BallerinaParserDefinition.KEYWORDS.contains(elementType)) {
return;
}
}
result.addAllElements(getCommonKeywords());
}
return;
}
PsiElement definitionNode = globalVariableDefinitionNode.getParent();
PackageDeclarationNode prevPackageDeclarationNode = PsiTreeUtil.getPrevSiblingOfType(definitionNode, PackageDeclarationNode.class);
ImportDeclarationNode prevImportDeclarationNode = PsiTreeUtil.getPrevSiblingOfType(definitionNode, ImportDeclarationNode.class);
ConstantDefinitionNode prevConstantDefinitionNode = PsiTreeUtil.getPrevSiblingOfType(definitionNode, ConstantDefinitionNode.class);
DefinitionNode prevDefinitionNode = PsiTreeUtil.getPrevSiblingOfType(definitionNode, DefinitionNode.class);
GlobalVariableDefinitionNode prevGlobalVariableDefinition = PsiTreeUtil.findChildOfType(prevDefinitionNode, GlobalVariableDefinitionNode.class);
if (prevPackageDeclarationNode == null && prevImportDeclarationNode == null && prevConstantDefinitionNode == null && prevGlobalVariableDefinition == null) {
result.addAllElements(getFileLevelKeywordsAsLookups(true, true, true));
} else if ((prevPackageDeclarationNode != null || prevImportDeclarationNode != null) && prevConstantDefinitionNode == null && prevGlobalVariableDefinition == null) {
result.addAllElements(getFileLevelKeywordsAsLookups(true, false, true));
} else {
result.addAllElements(getFileLevelKeywordsAsLookups(true, false, false));
}
addTypeNamesAsLookups(result);
}
}
if (element instanceof IdentifierPSINode) {
PsiReference reference = element.findReferenceAt(element.getTextLength());
if (reference instanceof WorkerReference) {
result.addAllElements(getWorkerInteractionKeywords());
}
}
}
use of org.ballerinalang.plugins.idea.psi.PackageDeclarationNode in project ballerina by ballerina-lang.
the class AdjustPackageNameFix method invoke.
@Override
public void invoke(@NotNull Project project, @NotNull PsiFile file, @Nullable Editor editor, @NotNull PsiElement startElement, @NotNull PsiElement endElement) {
if (!FileModificationService.getInstance().prepareFileForWrite(file)) {
return;
}
PsiDirectory directory = file.getContainingDirectory();
if (directory == null) {
return;
}
String targetPackage = BallerinaUtil.suggestPackageNameForDirectory(directory);
try {
PackageDeclarationNode packageDeclarationNode = PsiTreeUtil.findChildOfType(file, PackageDeclarationNode.class);
if (targetPackage.isEmpty()) {
if (packageDeclarationNode != null) {
packageDeclarationNode.delete();
}
} else {
PackageDeclarationNode newPackageDeclarationNode = BallerinaElementFactory.createPackageDeclaration(project, targetPackage);
if (packageDeclarationNode != null) {
packageDeclarationNode.replace(newPackageDeclarationNode);
} else {
file.addAfter(newPackageDeclarationNode, null);
}
}
} catch (IncorrectOperationException e) {
}
}
Aggregations