use of org.ballerinalang.plugins.idea.psi.AnnotationAttributeNode in project ballerina by ballerina-lang.
the class BallerinaUnresolvedReferenceInspection 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];
}
List<ProblemDescriptor> problemDescriptors = new LinkedList<>();
Collection<PackageNameNode> packageNameNodes = PsiTreeUtil.findChildrenOfType(file, PackageNameNode.class);
for (PackageNameNode packageNameNode : packageNameNodes) {
ProgressManager.checkCanceled();
if (packageNameNode == null) {
continue;
}
AliasNode aliasNode = PsiTreeUtil.getParentOfType(packageNameNode, AliasNode.class);
if (aliasNode != null) {
continue;
}
PackageDeclarationNode packageDeclarationNode = PsiTreeUtil.getParentOfType(packageNameNode, PackageDeclarationNode.class);
if (packageDeclarationNode != null) {
continue;
}
XmlAttribNode xmlAttribNode = PsiTreeUtil.getParentOfType(packageNameNode, XmlAttribNode.class);
if (xmlAttribNode != null) {
continue;
}
LocalQuickFix[] availableFixes;
ImportDeclarationNode importDeclarationNode = PsiTreeUtil.getParentOfType(packageNameNode, ImportDeclarationNode.class);
if (importDeclarationNode != null) {
availableFixes = new LocalQuickFix[0];
} else {
BallerinaImportPackageQuickFix quickFix = new BallerinaImportPackageQuickFix(packageNameNode);
availableFixes = new LocalQuickFix[] { quickFix };
}
PsiElement nameIdentifier = packageNameNode.getNameIdentifier();
if (nameIdentifier == null) {
continue;
}
PsiReference reference = nameIdentifier.getReference();
if (reference == null || reference.resolve() == null) {
if (reference instanceof PackageNameReference) {
ResolveResult[] resolveResults = ((PackageNameReference) reference).multiResolve(false);
if (resolveResults.length > 0) {
continue;
}
}
problemDescriptors.add(createProblemDescriptor(manager, packageNameNode, isOnTheFly, availableFixes));
}
}
// Todo - Add new quick fixes.
LocalQuickFix[] availableFixes = new LocalQuickFix[0];
Collection<NameReferenceNode> nameReferenceNodes = PsiTreeUtil.findChildrenOfType(file, NameReferenceNode.class);
problemDescriptors.addAll(getUnresolvedNameReferenceDescriptors(manager, isOnTheFly, availableFixes, nameReferenceNodes));
Collection<AnnotationAttributeNode> annotationAttributeNodes = PsiTreeUtil.findChildrenOfType(file, AnnotationAttributeNode.class);
problemDescriptors.addAll(getUnresolvedReferenceDescriptors(manager, isOnTheFly, availableFixes, annotationAttributeNodes));
Collection<ConnectorReferenceNode> connectorReferenceNodes = PsiTreeUtil.findChildrenOfType(file, ConnectorReferenceNode.class);
problemDescriptors.addAll(getUnresolvedReferenceDescriptors(manager, isOnTheFly, availableFixes, connectorReferenceNodes));
Collection<ActionInvocationNode> actionInvocationNodes = PsiTreeUtil.findChildrenOfType(file, ActionInvocationNode.class);
problemDescriptors.addAll(getUnresolvedReferenceDescriptors(manager, isOnTheFly, availableFixes, actionInvocationNodes));
Collection<FunctionReferenceNode> functionReferenceNodes = PsiTreeUtil.findChildrenOfType(file, FunctionReferenceNode.class);
problemDescriptors.addAll(getUnresolvedReferenceDescriptors(manager, isOnTheFly, availableFixes, functionReferenceNodes));
return problemDescriptors.toArray(new ProblemDescriptor[problemDescriptors.size()]);
}
use of org.ballerinalang.plugins.idea.psi.AnnotationAttributeNode in project ballerina by ballerina-lang.
the class BallerinaAnnotator method canHighlightParameters.
/**
* Checks whether the query,path parameters can be highlighted in the given element.
*
* @param element element which needs to be checked
* @return {@code true} if parameters can be highlighted, {@code false} otherwise.
*/
private boolean canHighlightParameters(@NotNull PsiElement element) {
AnnotationAttributeNode annotationAttributeNode = PsiTreeUtil.getParentOfType(element, AnnotationAttributeNode.class);
if (annotationAttributeNode == null) {
return false;
}
AnnotationAttachmentNode annotationAttachmentNode = PsiTreeUtil.getParentOfType(annotationAttributeNode, AnnotationAttachmentNode.class);
if (annotationAttachmentNode == null) {
return false;
}
AnnotationReferenceNode annotationReferenceNode = PsiTreeUtil.getChildOfType(annotationAttachmentNode, AnnotationReferenceNode.class);
if (annotationReferenceNode == null) {
return false;
}
IdentifierPSINode annotationName = PsiTreeUtil.getChildOfType(annotationReferenceNode, IdentifierPSINode.class);
return annotationName != null && "resourceConfig".equals(annotationName.getText());
}
use of org.ballerinalang.plugins.idea.psi.AnnotationAttributeNode in project ballerina by ballerina-lang.
the class BallerinaAnnotator method annotateLeafPsiElementNodes.
private void annotateLeafPsiElementNodes(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
IElementType elementType = ((LeafPsiElement) element).getElementType();
PsiElement parentElement = element.getParent();
if (elementType == BallerinaTypes.AT && parentElement instanceof AnnotationAttachmentNode) {
Annotation annotation = holder.createInfoAnnotation(element, null);
annotation.setTextAttributes(BallerinaSyntaxHighlightingColors.ANNOTATION);
} else if (elementType == BallerinaTypes.QUOTED_STRING) {
// In here, we annotate valid escape characters.
String text = element.getText();
Matcher matcher = VALID_ESCAPE_CHAR_PATTERN.matcher(text);
// Get the start offset of the element.
int startOffset = ((LeafPsiElement) element).getStartOffset();
// Iterate through each match.
while (matcher.find()) {
// Get the matching group.
String group = matcher.group(0);
// Calculate the start and end offsets and create the range.
TextRange range = new TextRange(startOffset + matcher.start(), startOffset + matcher.start() + group.length());
// Create the annotation.
Annotation annotation = holder.createInfoAnnotation(range, null);
annotation.setTextAttributes(BallerinaSyntaxHighlightingColors.VALID_STRING_ESCAPE);
}
// Annotate invalid escape characters.
matcher = INVALID_ESCAPE_CHAR_PATTERN.matcher(text);
// Get the start offset of the element.
startOffset = ((LeafPsiElement) element).getStartOffset();
// Iterate through each match.
while (matcher.find()) {
// Get the matching group.
String group = matcher.group(3);
if (group != null) {
// Calculate the start and end offsets and create the range.
TextRange range = new TextRange(startOffset + matcher.start(3), startOffset + matcher.start(3) + group.length());
// Create the annotation.
Annotation annotation = holder.createInfoAnnotation(range, "Invalid string escape");
annotation.setTextAttributes(BallerinaSyntaxHighlightingColors.INVALID_STRING_ESCAPE);
}
}
AnnotationAttributeNode annotationAttributeNode = PsiTreeUtil.getParentOfType(element, AnnotationAttributeNode.class);
boolean canHighlightParameters = canHighlightParameters(element);
if (canHighlightParameters && annotationAttributeNode != null) {
// Annotate query parameters in annotation attachments.
matcher = PATH_PARAMETERS_PATTERN.matcher(text);
// Get the start offset of the element.
startOffset = ((LeafPsiElement) element).getStartOffset();
// Iterate through each match.
while (matcher.find()) {
// Get the matching value without the enclosing {}.
String value = matcher.group(2);
if (value == null) {
continue;
}
// Calculate the start and end offsets and create the range. We need to add 2 to include the
// {} ignored.
TextRange range = new TextRange(startOffset + matcher.start(1), startOffset + matcher.start(1) + value.length() + 2);
// Check whether a matching resource parameter is available.
boolean isMatchAvailable = isMatchingParamAvailable(annotationAttributeNode, value);
// Create the annotation.
if (isMatchAvailable) {
Annotation annotation = holder.createInfoAnnotation(range, "Path parameter '" + value + "'");
annotation.setTextAttributes(BallerinaSyntaxHighlightingColors.TEMPLATE_LANGUAGE_COLOR);
} else {
Annotation annotation = holder.createErrorAnnotation(range, "Path parameter '" + value + "' not found in the resource signature");
annotation.setTextAttributes(BallerinaSyntaxHighlightingColors.INVALID_STRING_ESCAPE);
}
}
}
} else if (elementType == BallerinaTypes.STRING_TEMPLATE_LITERAL_START || elementType == BallerinaTypes.XML_START) {
annotateKeyword(element, holder);
} else if (elementType == BallerinaTypes.DOCUMENTATION_TEMPLATE_START || elementType == BallerinaTypes.DEPRECATED_TEMPLATE_START) {
// This uses an overloaded method so that the color can be easily changeable if required.
annotateKeyword(element, holder, BallerinaSyntaxHighlightingColors.KEYWORD);
} else if (elementType == BallerinaTypes.STRING_TEMPLATE_EXPRESSION_START || elementType == BallerinaTypes.XML_EXPRESSION_START) {
annotateExpressionTemplateStart(element, holder);
} else if (elementType == BallerinaTypes.STRING_TEMPLATE_TEXT || elementType == BallerinaTypes.XML_TEXT) {
annotateText(element, holder);
} else if (elementType == BallerinaTypes.EXPRESSION_END) {
annotateStringLiteralTemplateEnd(element, holder);
} else if (elementType == BallerinaTypes.DOCUMENTATION_TEMPLATE_ATTRIBUTE_START) {
// Doc type.
String msg = null;
switch(element.getText().charAt(0)) {
case 'T':
msg = "Receiver";
break;
case 'P':
msg = "Parameter";
break;
case 'R':
msg = "Return Value";
break;
case 'F':
msg = "Field";
break;
case 'V':
msg = "Variable";
break;
}
TextRange textRange = element.getTextRange();
TextRange newTextRange = new TextRange(textRange.getStartOffset(), textRange.getEndOffset() - 2);
Annotation annotation = holder.createInfoAnnotation(newTextRange, msg);
annotation.setTextAttributes(BallerinaSyntaxHighlightingColors.DOCUMENTATION_INLINE_CODE);
} else if (element instanceof IdentifierPSINode) {
if (parentElement.getParent() instanceof AnnotationAttachmentNode) {
Annotation annotation = holder.createInfoAnnotation(element, null);
annotation.setTextAttributes(BallerinaSyntaxHighlightingColors.ANNOTATION);
return;
}
if (parentElement instanceof DocumentationTemplateAttributeDescriptionNode) {
Annotation annotation = holder.createInfoAnnotation(element, null);
annotation.setTextAttributes(BallerinaSyntaxHighlightingColors.DOCUMENTATION_INLINE_CODE);
}
PsiReference reference = element.getReference();
if (reference == null || reference instanceof RecordKeyReference) {
return;
}
PsiElement resolvedElement = reference.resolve();
if (resolvedElement == null) {
return;
}
PsiElement parent = resolvedElement.getParent();
if (parent instanceof ConstantDefinitionNode) {
Annotation annotation = holder.createInfoAnnotation(element, null);
annotation.setTextAttributes(BallerinaSyntaxHighlightingColors.CONSTANT);
} else if (parent instanceof GlobalVariableDefinitionNode) {
Annotation annotation = holder.createInfoAnnotation(element, null);
annotation.setTextAttributes(BallerinaSyntaxHighlightingColors.GLOBAL_VARIABLE);
}
}
}
Aggregations