@Override public void annotate(@NotNull final PsiElement element, @NotNull final AnnotationHolder annotationHolder) { // TODO: Fix this // final ModelProvider modelProvider = ModelProvider.INSTANCE; // final ResourceTypeKey resourceKey = KubernetesYamlPsiUtil.findResourceKey(element); // if (resourceKey != null && element instanceof YAMLKeyValue) { // final YAMLKeyValue keyValue = (YAMLKeyValue) element; // final Model model = KubernetesYamlPsiUtil.modelForKey(modelProvider, resourceKey, keyValue); // if (keyValue.getValue() instanceof YAMLMapping && model != null) { // final YAMLMapping mapping = (YAMLMapping) keyValue.getValue(); // final Set<String> expectedProperties = model.getProperties().keySet(); // //noinspection ConstantConditions // mapping.getKeyValues().stream() // .filter(k -> !expectedProperties.contains(k.getKeyText().trim())).forEach( // k -> annotationHolder.createWarningAnnotation(k.getKey(), // "SpringConfigurationMetadataProperty '" + k.getKeyText() // + "' is not expected here.").registerFix(new DeletePropertyIntentionAction())); // } // } }
@Override public void annotate(@NotNull final PsiElement element, @NotNull final AnnotationHolder annotationHolder) { if (element instanceof YAMLMapping) { // TODO: Fix // final YAMLMapping mapping = (YAMLMapping) element; // final Collection<YAMLKeyValue> keyValues = mapping.getKeyValues(); // final Set<String> existingKeys = new HashSet<>(keyValues.size()); // for (final YAMLKeyValue keyValue : keyValues) { // if (keyValue.getKey() != null && !existingKeys.add(keyValue.getKeyText().trim())) { // annotationHolder.createErrorAnnotation(keyValue.getKey(), // "Duplicated PROPERTY '" + keyValue.getKeyText() + "'") // .registerFix(new DeletePropertyIntentionAction()); // } // } } }
@Override public void apply(@NotNull PsiFile file, Collection<BsbErrorAnnotation> annotationResult, @NotNull AnnotationHolder holder) { LineNumbering lineNumbering = new LineNumbering(file.getText()); for (BsbErrorAnnotation annotation : annotationResult) { PsiElement elementAtOffset = null; /* if (annotation.m_element != null) { elementAtOffset = annotation.m_element; } else { int startOffset = lineNumbering.positionToOffset(annotation.m_line, annotation.m_startOffset); elementAtOffset = findElementAtOffset(file, startOffset); } */ if (elementAtOffset != null) { holder.createErrorAnnotation(elementAtOffset, annotation.m_message); BucklescriptProjectComponent.getInstance(file.getProject()).associatePsiElement(file.getVirtualFile(), elementAtOffset); } else { int startOffset = lineNumbering.positionToOffset(annotation.m_line, annotation.m_startOffset); int endOffset = lineNumbering.positionToOffset(annotation.m_line, annotation.m_endOffset); holder.createErrorAnnotation(new TextRangeInterval(startOffset, endOffset), annotation.m_message); } } }
@Override public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder annotationHolder) { if (!(psiElement instanceof StringLiteralExpression)) { return; } StringLiteralExpression literalExpression = (StringLiteralExpression) psiElement; String value = literalExpression.getContents(); if (value.isEmpty()) { return; } for (PsiReference psiReference : literalExpression.getReferences()) { if (psiReference instanceof RouteReference) { annotateRoute(psiElement, annotationHolder, value); } } }
@Override public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder annotationHolder) { if (!(psiElement instanceof StringLiteralExpression)) { return; } StringLiteralExpression literalExpression = (StringLiteralExpression) psiElement; String value = literalExpression.getContents(); if (value.isEmpty()) { return; } PsiElement methodReference = PsiTreeUtil.getParentOfType(psiElement, MethodReference.class); if (PhpElementsUtil.isMethodWithFirstStringOrFieldReference(methodReference, "getIcon")) { annotateIconUsage(psiElement, annotationHolder, value); } }
@Override public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder annotationHolder) { if (psiElement instanceof ChoiceStatementElement) { boolean foundDefault = false; for (PsiElement child : psiElement.getChildren()) { if (!(child instanceof SoyChoiceClause)) { continue; } SoyChoiceClause clause = (SoyChoiceClause) child; if (foundDefault) { if (!clause.isDefault()) { annotationHolder.createErrorAnnotation( child, "{case} clauses are not allowed after {default}."); } else if (clause.isDefault()) { annotationHolder.createErrorAnnotation( child, "There can only be one {default} clause."); } } else if (clause.isDefault()) { foundDefault = true; } } } }
@Override public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolder holder) { if (element instanceof LeafPsiElement) { final LeafPsiElement psiElement = (LeafPsiElement) element; if (psiElement.getElementType().equals(CptTypes.CLASS_NAME)) { final String className = element.getText(); SupportedLanguages.getCptLang(element).ifPresent(lang -> { final CptLangAnnotator annotator = lang.getAnnotator(); if (!annotator.isMatchingType(psiElement, className)) { holder.createErrorAnnotation(element.getTextRange(), "Class not found"); } }); } } }
@Override public void annotate( PsiElement element, AnnotationHolder holder ) { if( DumbService.getInstance( element.getProject() ).isDumb() ) { // skip processing during index rebuild return; } PsiClass psiExtensionClass = findExtensionClass( element ); if( psiExtensionClass != null ) { // The enclosing class a @Extension class, verify usage of @This etc. verifyPackage( element, holder ); verifyExtensionInterfaces( element, holder ); verifyExtensionMethods( element, holder ); } else { // The enclosing class is *not* an extension class; usage of @This or @Extension on methods are errors errrantThisOrExtension( element, holder ); } }
private void verifyExtensionInterfaces( PsiElement element, AnnotationHolder holder ) { if( element instanceof PsiJavaCodeReferenceElementImpl && ((PsiJavaCodeReferenceElementImpl)element).getTreeParent() instanceof ReferenceListElement && ((PsiJavaCodeReferenceElementImpl)element).getTreeParent().getText().startsWith( PsiKeyword.IMPLEMENTS ) ) { final PsiElement resolve = element.getReference().resolve(); if( resolve instanceof PsiExtensibleClass ) { PsiExtensibleClass iface = (PsiExtensibleClass)resolve; if( !isStructuralInterface( iface ) ) { TextRange range = new TextRange( element.getTextRange().getStartOffset(), element.getTextRange().getEndOffset() ); holder.createErrorAnnotation( range, ExtIssueMsg.MSG_ONLY_STRUCTURAL_INTERFACE_ALLOWED_HERE.get( iface.getName() ) ); } } } }
private void errrantThisOrExtension( PsiElement element, AnnotationHolder holder ) { if( element instanceof PsiModifierList ) { PsiModifierList mods = (PsiModifierList)element; PsiAnnotation annotation; if( (annotation = mods.findAnnotation( Extension.class.getName() )) != null || (annotation = mods.findAnnotation( This.class.getName() )) != null) { TextRange range = new TextRange( annotation.getTextRange().getStartOffset(), annotation.getTextRange().getEndOffset() ); //noinspection ConstantConditions holder.createErrorAnnotation( range, ExtIssueMsg.MSG_NOT_IN_EXTENSION_CLASS.get( ClassUtil.extractClassName( annotation.getQualifiedName() ) ) ); } } }
private void checkStructure(PsiElement document, @NotNull AnnotationHolder annotationHolder) { PsiElement[] children = document.getChildren(); List<String> acceptedTag = Arrays.asList("template","element","script", "style"); for (PsiElement element : children) { if (element instanceof HtmlTag) { if (!acceptedTag.contains(((HtmlTag) element).getName().toLowerCase())) { annotationHolder.createErrorAnnotation(element, "Invalid tag '" + ((HtmlTag) element).getName() + "', only the [template, element, script, style] tags are allowed here."); } checkAttributes((XmlTag) element, annotationHolder); } else { if (!(element instanceof PsiWhiteSpace) && !(element instanceof XmlProlog) && !(element instanceof XmlText) && !(element instanceof XmlComment)) { String s = element.getText(); if (s.length() > 20) { s = s.substring(0, 20); } annotationHolder.createErrorAnnotation(element, "Invalid content '" + s + "', only the [template, script, style] tags are allowed here."); } } } }
static void checkMethodReturnType(PsiMethod method, PsiElement toHighlight, AnnotationHolder holder) { final HierarchicalMethodSignature signature = method.getHierarchicalMethodSignature(); final List<HierarchicalMethodSignature> superSignatures = signature.getSuperSignatures(); PsiType returnType = signature.getSubstitutor().substitute(method.getReturnType()); for (HierarchicalMethodSignature superMethodSignature : superSignatures) { PsiMethod superMethod = superMethodSignature.getMethod(); PsiType declaredReturnType = superMethod.getReturnType(); PsiType superReturnType = superMethodSignature.getSubstitutor().substitute(declaredReturnType); if (superReturnType == PsiType.VOID && method instanceof GrMethod && ((GrMethod)method).getReturnTypeElementGroovy() == null) return; if (superMethodSignature.isRaw()) superReturnType = TypeConversionUtil.erasure(declaredReturnType); if (returnType == null || superReturnType == null || method == superMethod) continue; PsiClass superClass = superMethod.getContainingClass(); if (superClass == null) continue; String highlightInfo = checkSuperMethodSignature(superMethod, superMethodSignature, superReturnType, method, signature, returnType); if (highlightInfo != null) { holder.createErrorAnnotation(toHighlight, highlightInfo); return; } } }
private static void annotateMavenDomPlugin(@NotNull MavenDomPlugin plugin, @NotNull AnnotationHolder holder) { XmlTag xmlTag = plugin.getArtifactId().getXmlTag(); if (xmlTag == null) return; DomElement plugins = plugin.getParent(); if (plugins == null) return; DomElement parent = plugins.getParent(); if (parent instanceof MavenDomPluginManagement) { annotateMavenDomPluginInManagement(plugin, holder); return; } MavenDomPlugin managingPlugin = MavenDomProjectProcessorUtils.searchManagingPlugin(plugin); if (managingPlugin != null) { NavigationGutterIconBuilder<MavenDomPlugin> iconBuilder = NavigationGutterIconBuilder.create(AllIcons.General.OverridingMethod, PluginConverter.INSTANCE); iconBuilder. setTargets(Collections.singletonList(managingPlugin)). setTooltipText(MavenDomBundle.message("overriden.plugin.title")). install(holder, xmlTag); } }
private static void checkKindTestArguments(AnnotationHolder holder, XPathNodeTypeTest test, boolean wildcardAllowed, int min, int max) { final XPathExpression[] arguments = test.getArgumentList(); if (arguments.length >= min) { for (XPathExpression arg : arguments) { final PrefixedName argument = findQName(arg); if (argument == null) { holder.createErrorAnnotation(arg, "QName expected"); } else { if (!wildcardAllowed && ("*".equals(argument.getPrefix()) || "*".equals(argument.getLocalName()))) { holder.createErrorAnnotation(arg, "QName expected"); } } } } else { holder.createErrorAnnotation(test, "Missing argument for node kind test"); } markExceedingArguments(holder, arguments, max); }
private void createErrorAnnotations(PsiElement element, PsiFile file, AnnotationHolder holder, List<RuntimeException> annotationResult) { Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file); if (document == null) { return; } PsiElement psiElementWithError = element; for (RuntimeException exception : annotationResult) { if (exception instanceof LocatedRuntimeException) { LocatedRuntimeException locatedException = (LocatedRuntimeException) exception; PsiElement childAtLine = file.findElementAt(document.getLineStartOffset(locatedException.getLineNumber() - 1)); if (childAtLine != null) { psiElementWithError = childAtLine; } } holder.createErrorAnnotation(psiElementWithError, exception.getMessage()); } }
@Override public boolean checkApplicability(@NotNull AnnotationHolder holder, @NotNull GrAnnotation annotation) { final String qname = annotation.getQualifiedName(); if (!GroovyCommonClassNames.GROOVY_TRANSFORM_FIELD.equals(qname)) return false; checkScriptField(holder, annotation); PsiElement annoParent = annotation.getParent(); PsiElement ownerToUse = annoParent instanceof PsiModifierList ? annoParent.getParent() : annoParent; if (!(ownerToUse instanceof GrVariableDeclaration) || !PsiUtil.isLocalVariable(((GrVariableDeclaration)ownerToUse).getVariables()[0])) { return false; } if (!GrAnnotationImpl.isAnnotationApplicableTo(annotation, PsiAnnotation.TargetType.LOCAL_VARIABLE)) { GrCodeReferenceElement ref = annotation.getClassReference(); String target = JavaErrorMessages.message("annotation.target.LOCAL_VARIABLE"); String description = JavaErrorMessages.message("annotation.not.applicable", ref.getText(), target); holder.createErrorAnnotation(ref, description); } return true; }
private static void annotateMavenDomPluginInManagement(@NotNull MavenDomPlugin plugin, @NotNull AnnotationHolder holder) { XmlTag xmlTag = plugin.getArtifactId().getXmlTag(); if (xmlTag == null) return; Collection<MavenDomPlugin> children = MavenDomProjectProcessorUtils.searchManagedPluginUsages(plugin); if (children.size() > 0) { NavigationGutterIconBuilder<MavenDomPlugin> iconBuilder = NavigationGutterIconBuilder.create(AllIcons.General.OverridenMethod, PluginConverter.INSTANCE); iconBuilder. setTargets(children). setPopupTitle(MavenDomBundle.message("navigate.parent.plugin.title")). setCellRenderer(MyListCellRenderer.INSTANCE). setTooltipText(MavenDomBundle.message("overriding.plugin.title")). install(holder, xmlTag); } }
private static void annotateDependencyUsages(@NotNull MavenDomDependency dependency, AnnotationHolder holder) { final XmlTag tag = dependency.getXmlTag(); if (tag == null) return; final Set<MavenDomDependency> children = MavenDomProjectProcessorUtils.searchDependencyUsages(dependency); if (children.size() > 0) { final NavigationGutterIconBuilder<MavenDomDependency> iconBuilder = NavigationGutterIconBuilder.create(AllIcons.General.OverridenMethod, DependencyConverter.INSTANCE); iconBuilder. setTargets(children). setPopupTitle(MavenDomBundle.message("navigate.parent.dependency.title")). setCellRenderer(MyListCellRenderer.INSTANCE). setTooltipText(MavenDomBundle.message("overriding.dependency.title")). install(holder, dependency.getXmlTag()); } }
@Override public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { if (!(element instanceof SQFCommand)) { return; } SQFCommand command = (SQFCommand) element; switch (command.getCommandName().toLowerCase()) { case "if": //fall case "then": //fall case "else": //fall case "for": //fall case "foreach": //fall case "switch": //fall case "case": //fall case "default": //fall case "while"://fall case "do": { Annotation annotation = holder.createInfoAnnotation(command, ""); annotation.setTextAttributes(SQFSyntaxHighlighter.CONTROL_STRUCTURE_COMMAND); break; } } }
@Override public void annotate(@NotNull final PsiElement element, @NotNull final AnnotationHolder annotationHolder) { if (!KubernetesYamlPsiUtil.isKubernetesFile(element)) { return; } final ModelProvider modelProvider = ModelProvider.INSTANCE; final ResourceTypeKey resourceKey = KubernetesYamlPsiUtil.findResourceKey(element); if (resourceKey != null && element instanceof YAMLKeyValue) { final YAMLKeyValue keyValue = (YAMLKeyValue) element; final Model model = KubernetesYamlPsiUtil.modelForKey(modelProvider, resourceKey, keyValue); if (model != null && keyValue.getKey() != null) { if (keyValue.getValue() instanceof YAMLMapping) { final YAMLMapping mapping = (YAMLMapping) keyValue.getValue(); addErrors(annotationHolder, model, keyValue.getKey(), mapping); } else if (keyValue.getValue() instanceof YAMLSequence) { final YAMLSequence sequence = (YAMLSequence) keyValue.getValue(); for (final YAMLSequenceItem item : sequence.getItems()) { if (item.getValue() instanceof YAMLMapping) { addErrors(annotationHolder, model, item.getFirstChild(), (YAMLMapping) item.getValue()); } } } } } }
private static void checkAnnotationValue(@NotNull PsiClass annotation, @NotNull PsiElement identifierToHighlight, @NotNull String name, @NotNull Set<String> usedAttrs, @Nullable GrAnnotationMemberValue value, @NotNull AnnotationHolder holder) { if (usedAttrs.contains(name)) { holder.createErrorAnnotation(identifierToHighlight, GroovyBundle.message("duplicate.attribute")); } usedAttrs.add(name); final PsiMethod[] methods = annotation.findMethodsByName(name, false); if (methods.length == 0) { holder.createErrorAnnotation(identifierToHighlight, GroovyBundle.message("at.interface.0.does.not.contain.attribute", annotation.getQualifiedName(), name)); } else { final PsiMethod method = methods[0]; final PsiType ltype = method.getReturnType(); if (ltype != null && value != null) { checkAnnotationValueByType(holder, value, ltype, true); } } }
@Override public void annotate(@NotNull final PsiElement element, @NotNull final AnnotationHolder annotationHolder) { if (!KubernetesYamlPsiUtil.isKubernetesFile(element)) { return; } if (element instanceof YAMLMapping) { final YAMLMapping mapping = (YAMLMapping) element; final Collection<YAMLKeyValue> keyValues = mapping.getKeyValues(); final Set<String> existingKeys = new HashSet<>(keyValues.size()); for (final YAMLKeyValue keyValue : keyValues) { if (keyValue.getKey() != null && !existingKeys.add(keyValue.getKeyText().trim())) { annotationHolder.createErrorAnnotation(keyValue.getKey(), "Duplicated property '" + keyValue.getKeyText() + "'").registerFix(new DeletePropertyIntentionAction()); } } } }
private static void checkFieldModifiers(AnnotationHolder holder, GrVariableDeclaration fieldDeclaration) { final GrModifierList modifierList = fieldDeclaration.getModifierList(); final GrField member = (GrField)fieldDeclaration.getVariables()[0]; checkAccessModifiers(holder, modifierList, member); checkDuplicateModifiers(holder, modifierList, member); if (modifierList.hasExplicitModifier(PsiModifier.VOLATILE) && modifierList.hasExplicitModifier(PsiModifier.FINAL)) { final Annotation annotation = holder.createErrorAnnotation(modifierList, GroovyBundle.message("illegal.combination.of.modifiers.volatile.and.final")); registerFix(annotation, new GrModifierFix(member, PsiModifier.VOLATILE, true, false, GrModifierFix.MODIFIER_LIST), modifierList); registerFix(annotation, new GrModifierFix(member, PsiModifier.FINAL, true, false, GrModifierFix.MODIFIER_LIST), modifierList); } checkModifierIsNotAllowed(modifierList, PsiModifier.NATIVE, GroovyBundle.message("variable.cannot.be.native"), holder); checkModifierIsNotAllowed(modifierList, PsiModifier.ABSTRACT, GroovyBundle.message("variable.cannot.be.abstract"), holder); if (member.getContainingClass() instanceof GrInterfaceDefinition) { checkModifierIsNotAllowed(modifierList, PsiModifier.PRIVATE, GroovyBundle.message("interface.members.are.not.allowed.to.be", PsiModifier.PRIVATE), holder); checkModifierIsNotAllowed(modifierList, PsiModifier.PROTECTED, GroovyBundle.message("interface.members.are.not.allowed.to.be", PsiModifier.PROTECTED), holder); } }
@Override public void doApplyInformationToEditor() { if (myUnusedDeclarations == null || myUnusedImports == null) { return; } AnnotationHolder annotationHolder = new AnnotationHolderImpl(new AnnotationSession(myFile)); List<HighlightInfo> infos = new ArrayList<HighlightInfo>(myUnusedDeclarations); for (GrImportStatement unusedImport : myUnusedImports) { Annotation annotation = annotationHolder.createWarningAnnotation(calculateRangeToUse(unusedImport), GroovyInspectionBundle.message("unused.import")); annotation.setHighlightType(ProblemHighlightType.LIKE_UNUSED_SYMBOL); annotation.registerFix(GroovyQuickFixFactory.getInstance().createOptimizeImportsFix(false)); infos.add(HighlightInfo.fromAnnotation(annotation)); } UpdateHighlightersUtil.setHighlightersToEditor(myProject, myDocument, 0, myFile.getTextLength(), infos, getColorsScheme(), getId()); if (myUnusedImports != null && !myUnusedImports.isEmpty()) { IntentionAction fix = GroovyQuickFixFactory.getInstance().createOptimizeImportsFix(true); if (fix.isAvailable(myProject, myEditor, myFile) && myFile.isWritable()) { fix.invoke(myProject, myEditor, myFile); } } }
@Override public void annotate(@NotNull final PsiElement element, @NotNull final AnnotationHolder annotationHolder) { // TODO: Complete this // final ModelProvider modelProvider = ModelProvider.INSTANCE; // final ResourceTypeKey resourceKey = KubernetesYamlPsiUtil.findResourceKey(element); // if (resourceKey != null && element instanceof YAMLKeyValue) { // final YAMLKeyValue keyValue = (YAMLKeyValue) element; // final Property property = // KubernetesYamlPsiUtil.propertyForKey(modelProvider, resourceKey, keyValue); // final YAMLValue value = keyValue.getValue(); // if (property != null && property.getType() != null && value != null) { // switch (property.getType()) { // case ARRAY: // if (!(value instanceof YAMLSequence)) { // annotationHolder.createErrorAnnotation(value, // "The content of " + keyValue.getKeyText() + " should be an ARRAY."); // } // break; // case OBJECT: // if (!(value instanceof YAMLMapping)) { // annotationHolder.createErrorAnnotation(value, // "The content of " + keyValue.getKeyText() + " should be an OBJECT."); // } // break; // } // } // } }
@Override public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { PsiElement classElement = null; if (element instanceof TSDatablockDecl) { TSDatablockDecl db = (TSDatablockDecl) element; //Find the first id node, this is kinda wonky since we have to account for whitespace nodes //datablock ClassName(...) ASTNode node = db.getNode(); if (node == null) { return; } node = node.findChildByType(TSTypes.ID); if (node == null) { return; } classElement = node.getPsi(); } else if (element instanceof TSObjectExpr) { TSObjectExpr obj = (TSObjectExpr) element; //Class name should be the second thing in the element: // new ClassName(...) classElement = PsiTreeUtil.getChildOfType(obj, TSClassNameExpr.class); if (classElement == null) { return; } classElement = classElement.getFirstChild(); } if (classElement == null) { return; } //Only annotate if it's an id, can't really tell if it's an expr if (classElement.getNode().getElementType().equals(TSTypes.ID)) { createSuccessAnnotation(classElement, holder, TSSyntaxHighlighter.CLASSNAME); } }
@Override public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { if (element instanceof TSLiteralExpr) { boolean valid = false; TSLiteralReference ref = (TSLiteralReference)element.getReference(); if (ref != null) { valid = ref.multiResolve(false).length > 0; } if (valid) { createSuccessAnnotation(element, holder, TSSyntaxHighlighter.OBJECT_NAME); } } }
private static void createInfoAnnotation(final @NotNull AnnotationHolder holder, final @Nullable PsiElement element, final @Nullable TextAttributesKey attributeKey) { if (element != null && attributeKey != null) { holder.createInfoAnnotation(element, null).setTextAttributes(attributeKey); } }
@Override public void apply(@NotNull PsiFile file, List<MerlinError> annotationResult, @NotNull AnnotationHolder holder) { LineNumbering lineNumbering = new LineNumbering(file.getText()); for (MerlinError error : annotationResult) { if (error.start != null) { int startOffset = lineNumbering.positionToOffset(error.start); int endOffset = lineNumbering.positionToOffset(error.end); if (0 < startOffset && 0 < endOffset && startOffset < endOffset) { holder.createAnnotation(severities.get(error.type), new TextRangeInterval(startOffset, endOffset), "[merlin] " + error.message); } } } }
private void annotateIcon(PsiElement psiElement, AnnotationHolder annotationHolder, String value) { if (IconIndex.getAllAvailableIcons(psiElement.getProject()).contains(value)) { annotationHolder.createInfoAnnotation(psiElement, null); } else { annotationHolder.createWarningAnnotation(psiElement, "Unresolved icon - this may also occur if the icon is defined in your extension, but not in the global icon registry."); } }
@Override public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { if (!(element instanceof StringLiteralExpression)) { return; } String content = ((StringLiteralExpression) element).getContents(); if (!content.startsWith("EXT:") || element.getProject().getBasePath() == null) { return; } String resourceName = content.substring(4, content.length()); if (resourceName.contains(":")) { // resource name points to a sub-resource such as a translation string, not here. return; } if (ResourcePathIndex.projectContainsResourceFile(element.getProject(), content)) { // exact match found return; } if (ResourcePathIndex.projectContainsResourceDirectory(element.getProject(), content)) { return; } createErrorMessage(element, holder, resourceName); }
@Override public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder annotationHolder) { if (!(psiElement instanceof StringLiteralExpression)) { return; } StringLiteralExpression literalExpression = (StringLiteralExpression) psiElement; String value = literalExpression.getContents(); if (TranslationUtil.isTranslationKeyString(value) && value.length() > 4 && !(psiElement.getParent() instanceof ConcatenationExpression)) { annotateTranslationUsage(psiElement, annotationHolder, value); } }
private void annotateTranslation(PsiElement psiElement, AnnotationHolder annotationHolder, String value) { if (TranslationUtil.keyExists(psiElement.getProject(), value)) { annotationHolder.createInfoAnnotation(psiElement, null); } else { annotationHolder.createErrorAnnotation(psiElement, "Unresolved translation - this may occur if you defined the translation key only in TypoScript"); } }
@Override public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder annotationHolder) { if (psiElement instanceof SoyAnyStringLiteral && psiElement.getParent() instanceof SoyExpr && psiElement.getText().startsWith("\"")) { annotationHolder.createErrorAnnotation( psiElement, "Strings in expressions must use single quotes."); } }
@Override public void annotate(PsiElement element, AnnotationHolder holder) { if (element instanceof SoyXidStatement) { if (((SoyXidStatement) element).getCssXidIdentifier().getText().startsWith("%")) { holder.createErrorAnnotation(element, "Xid identifiers cannot start with '%'."); } } if (element instanceof SoyCssStatement) { if (((SoyCssStatement) element).getCssXidIdentifier().getText().contains(".")) { holder.createErrorAnnotation(element, "CSS identifiers cannot contain '.'."); } } }
@Override public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder annotationHolder) { if (psiElement instanceof TagBlockElement) { TagBlockElement block = (TagBlockElement) psiElement; if (block.isIncomplete() && !(block instanceof ChoiceClauseElement)) { annotationHolder.createErrorAnnotation(block.getOpeningTag(), "{" + block.getTagName() + "} is not closed."); } } }
@Override public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder annotationHolder) { if (psiElement instanceof CallStatementElement) { CallStatementElement statement = (CallStatementElement) psiElement; Collection<String> givenParameters = ParamUtils.getGivenParameters(statement); // TODO(thso): Detect data="" in more robust way. if (statement.getText().contains("data=")) return; PsiElement identifier = PsiTreeUtil.findChildOfType(statement, SoyTemplateReferenceIdentifier.class); if (identifier == null) return; List<String> requiredParameters = ParamUtils.getParametersForInvocation(statement, identifier.getText()) .stream() .filter((var) -> !var.isOptional) .map((var) -> var.name) .collect(Collectors.toList()); if (!givenParameters.containsAll(requiredParameters)) { requiredParameters.removeAll(givenParameters); annotationHolder.createErrorAnnotation( identifier, "Missing required parameters: " + String.join(",", requiredParameters)); } } }
@Override public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder annotationHolder) { if (psiElement instanceof SoyVariableReferenceIdentifier && psiElement.getText().equals("$")) { annotationHolder.createErrorAnnotation(psiElement, "Variable name expected."); } else if (psiElement instanceof SoyFieldExpr && psiElement.getText().endsWith(".")) { annotationHolder.createErrorAnnotation(psiElement, "Field name expected."); } }
@Override public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder annotationHolder) { if (psiElement instanceof SoyUnexpectedStatements) { PsiElement parent = psiElement.getParent(); if (parent instanceof CallStatementElement) { annotationHolder.createErrorAnnotation(psiElement, "Expected a {param ...} tag."); } else if (parent instanceof ChoiceStatementElement) { annotationHolder.createErrorAnnotation( psiElement, "Expected a {case ...} or {default ...} tag."); } } }
@Override public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder annotationHolder) { if (psiElement instanceof SoyTemplateBlock) { SoyTemplateBlock block = (SoyTemplateBlock) psiElement; if (block.isDelegate() && block.getName() != null && block.getName().startsWith(".")) { annotationHolder.createErrorAnnotation( // cannot be null since getName is not null block.getDefinitionIdentifier(), "Delegate template names cannot start with '.'."); } } }