public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull final InspectionManager manager, final boolean isOnTheFly) { if (!(file instanceof PropertiesFile)) return null; final List<IProperty> properties = ((PropertiesFile)file).getProperties(); final List<ProblemDescriptor> descriptors = new SmartList<ProblemDescriptor>(); for (IProperty property : properties) { ProgressManager.checkCanceled(); final PropertyImpl propertyImpl = (PropertyImpl)property; for (ASTNode node : ContainerUtil.ar(propertyImpl.getKeyNode(), propertyImpl.getValueNode())) { if (node != null) { PsiElement key = node.getPsi(); TextRange textRange = getTrailingSpaces(key, myIgnoreVisibleSpaces); if (textRange != null) { descriptors.add(manager.createProblemDescriptor(key, textRange, "Trailing spaces", ProblemHighlightType.GENERIC_ERROR_OR_WARNING, true, new RemoveTrailingSpacesFix(myIgnoreVisibleSpaces))); } } } } return descriptors.toArray(new ProblemDescriptor[descriptors.size()]); }
@NotNull @Override public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) { if (!(holder.getFile() instanceof PropertiesFileImpl)) { return PsiElementVisitor.EMPTY_VISITOR; } final PropertiesCodeStyleSettings codeStyleSettings = PropertiesCodeStyleSettings.getInstance(holder.getProject()); final char codeStyleKeyValueDelimiter = codeStyleSettings.KEY_VALUE_DELIMITER; return new PsiElementVisitor() { @Override public void visitElement(PsiElement element) { if (element instanceof PropertyImpl) { final Character delimiter = ((PropertyImpl)element).getKeyValueDelimiter(); if (delimiter != null && !delimiter.equals(codeStyleKeyValueDelimiter)) { holder.registerProblem(element, PropertiesBundle.message("wrong.property.key.value.delimiter.inspection.display.name"), new ReplaceKeyValueDelimiterQuickFix(element)); } } } }; }
public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { if (!(element instanceof IProperty)) return; final Property property = (Property)element; PropertiesFile propertiesFile = property.getPropertiesFile(); Collection<IProperty> others = propertiesFile.findPropertiesByKey(property.getUnescapedKey()); ASTNode keyNode = ((PropertyImpl)property).getKeyNode(); if (others.size() != 1) { Annotation annotation = holder.createErrorAnnotation(keyNode, PropertiesBundle.message("duplicate.property.key.error.message")); annotation.registerFix(PropertiesQuickFixFactory.getInstance().createRemovePropertyFix(property)); } highlightTokens(property, keyNode, holder, new PropertiesHighlighter()); ASTNode valueNode = ((PropertyImpl)property).getValueNode(); if (valueNode != null) { highlightTokens(property, valueNode, holder, new PropertiesValueHighlighter()); } }
public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { if (!(element instanceof IProperty)) return; final Property property = (Property)element; PropertiesFile propertiesFile = property.getPropertiesFile(); Collection<IProperty> others = propertiesFile.findPropertiesByKey(property.getUnescapedKey()); ASTNode keyNode = ((PropertyImpl)property).getKeyNode(); if (others.size() != 1) { Annotation annotation = holder.createErrorAnnotation(keyNode, PropertiesBundle.message("duplicate.property.key.error.message")); annotation.registerFix(new RemovePropertyFix(property)); } highlightTokens(property, keyNode, holder, new PropertiesHighlighter()); ASTNode valueNode = ((PropertyImpl)property).getValueNode(); if (valueNode != null) { highlightTokens(property, valueNode, holder, new PropertiesValueHighlighter()); } }
public void testNonDefaultKeyValueDelimiter() { final PropertiesCodeStyleSettings codeStyleSettings = PropertiesCodeStyleSettings.getInstance(getProject()); codeStyleSettings.KEY_VALUE_DELIMITER = ':'; final PropertyImpl property = (PropertyImpl)PropertiesElementFactory.createProperty(getProject(), "xxx", "yyy"); final Character delimiter = property.getKeyValueDelimiter(); assertNotNull(delimiter); assertEquals(':', (char)delimiter); assertEquals("xxx:yyy", property.getPsiElement().getText()); codeStyleSettings.KEY_VALUE_DELIMITER = PropertiesCodeStyleSettings.DEFAULT_KEY_VALUE_DELIMITER; }
@Nullable private static TextRange getTrailingSpaces(PsiElement element, boolean ignoreVisibleTrailingSpaces) { String key = element.getText(); if (ignoreVisibleTrailingSpaces) { for (int i = key.length() - 1; i > -1; i--) { if (key.charAt(i) != ' ' && key.charAt(i) != '\t') { return i == key.length() - 1 ? null : new TextRange(i + 1, key.length()); } } return element.getTextRange(); } else { return PropertyImpl.trailingSpaces(key); } }
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { PsiElement element = descriptor.getPsiElement(); PsiElement parent = element == null ? null : element.getParent(); if (!(parent instanceof PropertyImpl)) return; TextRange textRange = getTrailingSpaces(element, myIgnoreVisibleSpaces); if (textRange != null) { Document document = PsiDocumentManager.getInstance(project).getDocument(element.getContainingFile()); TextRange docRange = textRange.shiftRight(element.getTextRange().getStartOffset()); document.deleteString(docRange.getStartOffset(), docRange.getEndOffset()); } }
public ApplicationEnvironment(CoreApplicationEnvironment appEnvironment) { appEnvironment.registerFileType(PropertiesFileType.INSTANCE, "properties"); appEnvironment.addExplicitExtension(SyntaxHighlighterFactory.LANGUAGE_FACTORY, PropertiesLanguage.INSTANCE, new PropertiesSyntaxHighlighterFactory()); appEnvironment.addExplicitExtension(LanguageParserDefinitions.INSTANCE, PropertiesLanguage.INSTANCE, new PropertiesParserDefinition()); appEnvironment.addExtension(FileBasedIndexExtension.EXTENSION_POINT_NAME, new XmlPropertiesIndex()); appEnvironment.addExtension(StubIndexExtension.EP_NAME, new PropertyKeyIndex()); appEnvironment.registerApplicationService(PropertiesQuickFixFactory.class, new EmptyPropertiesQuickFixFactory()); appEnvironment.registerApplicationService(PropertiesRefactoringSettings.class, new PropertiesRefactoringSettings()); appEnvironment.addExplicitExtension(LanguageAnnotators.INSTANCE, PropertiesLanguage.INSTANCE, new PropertiesAnnotator()); appEnvironment.addExplicitExtension(LanguageFindUsages.INSTANCE, PropertiesLanguage.INSTANCE, new PropertiesFindUsagesProvider()); appEnvironment.addExplicitExtension(LanguageASTFactory.INSTANCE, PropertiesLanguage.INSTANCE, new PropertiesASTFactory()); appEnvironment.addExplicitExtension(LanguageFolding.INSTANCE, PropertiesLanguage.INSTANCE, new PropertiesFoldingBuilder()); appEnvironment.addExplicitExtension(ElementManipulators.INSTANCE, PropertyImpl.class, new PropertyManipulator()); appEnvironment.addExplicitExtension(ElementManipulators.INSTANCE, PropertyKeyImpl.class, new PropertyKeyManipulator()); appEnvironment.addExplicitExtension(ElementManipulators.INSTANCE, PropertyValueImpl.class, new PropertyValueManipulator()); final StubElementTypeHolderEP stubElementTypeHolderBean = new StubElementTypeHolderEP(); stubElementTypeHolderBean.holderClass = PropertiesElementTypes.class.getName(); appEnvironment.addExtension(StubElementTypeHolderEP.EP_NAME, stubElementTypeHolderBean); appEnvironment.addExplicitExtension(LanguageCommenters.INSTANCE, PropertiesLanguage.INSTANCE, new PropertiesCommenter()); appEnvironment.addExplicitExtension(IdIndexers.INSTANCE, PropertiesFileType.INSTANCE, new PropertiesIdIndexer()); appEnvironment.addExplicitExtension(TodoIndexers.INSTANCE, PropertiesFileType.INSTANCE, new PropertiesTodoIndexer()); appEnvironment.addExtension(IconProvider.EXTENSION_POINT_NAME, new XmlPropertiesIconProvider()); }
@Override public PropertyImpl handleContentChange(@NotNull PropertyImpl element, @NotNull TextRange range, String newContent) throws IncorrectOperationException { TextRange valueRange = getRangeInElement(element); final String oldText = element.getText(); String newText = oldText.substring(0, range.getStartOffset()) + newContent + oldText.substring(range.getEndOffset()); element.setValue(newText.substring(valueRange.getStartOffset()).replaceAll("([^\\s])\n", "$1 \n")); // add explicit space before \n return element; }
@NotNull @Override public TextRange getRangeInElement(@NotNull PropertyImpl element) { ASTNode valueNode = element.getValueNode(); if (valueNode == null) return TextRange.from(element.getTextLength(), 0); TextRange range = valueNode.getTextRange(); return TextRange.from(range.getStartOffset() - element.getTextRange().getStartOffset(), range.getLength()); }
@NotNull public PsiElement createElement(ASTNode node) { final IElementType type = node.getElementType(); if (type == PropertiesElementTypes.PROPERTY) { return new PropertyImpl(node); } else if (type == PropertiesElementTypes.PROPERTIES_LIST) { return new PropertiesListImpl(node); } throw new AssertionError("Alien element type [" + type + "]. Can't create Property PsiElement for that."); }
@NotNull @Override public Tokenizer getTokenizer(PsiElement element) { if (element instanceof PropertyValueImpl) { return myPropertyValueTokenizer; } if (element instanceof PropertyImpl) { return myPropertyTokenizer; } return super.getTokenizer(element); }
@Override public PropertyImpl handleContentChange(PropertyImpl element, TextRange range, String newContent) throws IncorrectOperationException { TextRange valueRange = getRangeInElement(element); final String oldText = element.getText(); String newText = oldText.substring(0, range.getStartOffset()) + newContent + oldText.substring(range.getEndOffset()); element.setValue(newText.substring(valueRange.getStartOffset()).replaceAll("([^\\s])\n", "$1 \n")); // add explicit space before \n return element; }
@Override public TextRange getRangeInElement(PropertyImpl element) { ASTNode valueNode = element.getValueNode(); if (valueNode == null) return TextRange.from(element.getTextLength(), 0); TextRange range = valueNode.getTextRange(); return TextRange.from(range.getStartOffset() - element.getTextRange().getStartOffset(), range.getLength()); }
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { PsiElement element = descriptor.getPsiElement(); PsiElement parent = element == null ? null : element.getParent(); if (!(parent instanceof PropertyImpl)) return; TextRange textRange = getTrailingSpaces(element); if (textRange != null) { Document document = PsiDocumentManager.getInstance(project).getDocument(element.getContainingFile()); TextRange docRange = textRange.shiftRight(element.getTextRange().getStartOffset()); document.deleteString(docRange.getStartOffset(), docRange.getEndOffset()); } }
@Override public void invoke(@NotNull Project project, @NotNull PsiFile file, @NotNull PsiElement element, @NotNull PsiElement endElement) { ((PropertyImpl) element).replaceKeyValueDelimiterWithDefault(); }
public Property createPsi(@NotNull final PropertyStub stub) { return new PropertyImpl(stub, this); }
public void indexStub(@NotNull final PropertyStub stub, @NotNull final IndexSink sink) { sink.occurrence(PropertyKeyIndex.KEY, PropertyImpl.unescape(stub.getKey())); }
public void tokenize(@NotNull PropertyImpl element, TokenConsumer consumer) { String key = element.getKey(); consumer.consumeToken(element, key, true, 0, TextRange.allOf(key), PropertiesSplitter.getInstance()); }
private static TextRange getTrailingSpaces(PsiElement element) { String key = element.getText(); return PropertyImpl.trailingSpaces(key); }