void (final ASTNode node, final AnnotationHolder holder, PropertiesHighlighter highlighter) { Lexer lexer = highlighter.getHighlightingLexer(); final String s = node.getText(); lexer.start(s); while (lexer.getTokenType() != null) { IElementType elementType = lexer.getTokenType(); TextAttributesKey[] keys = highlighter.getTokenHighlights(elementType); for (TextAttributesKey key : keys) { final String displayName = PropertiesComponent.getDisplayName(key); final HighlightSeverity severity = PropertiesComponent.getSeverity(key); if (severity != null && displayName != null) { int start = lexer.getTokenStart() + node.getTextRange().getStartOffset(); int end = lexer.getTokenEnd() + node.getTextRange().getStartOffset(); TextRange textRange = new TextRange(start, end); TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(key); AnnotationBuilder builder = holder.newAnnotation(severity, displayName).range(textRange).enforcedTextAttributes(attributes); int startOffset = textRange.getStartOffset(); if (key == PropertiesComponent.PROPERTIES_INVALID_STRING_ESCAPE.getTextAttributesKey()) { builder = builder.withFix(new ModCommandAction() { @Override @NotNull public String getFamilyName() { return PropertiesBundle.message("unescape"); } @Override public @Nullable Presentation getPresentation(@NotNull ActionContext context) { if (!BaseIntentionAction.canModify(context.file())) return null; String text = context.file().getText(); return text.length() > startOffset && text.charAt(startOffset) == '\\' ? Presentation.of(getFamilyName()) : null; } @Override public @NotNull ModCommand perform(@NotNull ActionContext context) { return ModCommand.psiUpdate(context, updater -> { updater.getWritable(context.file()).getViewProvider().getDocument().deleteString(startOffset, startOffset + 1); }); } }); } builder.create(); } } lexer.advance(); } }