@Nullable protected Pair<PsiElement, TextRange> getRangePair(final PsiFile file, final Editor editor) { final int offset = editor.getCaretModel().getOffset(); final PsiLanguageInjectionHost host = PsiTreeUtil.getParentOfType(file.findElementAt(offset), PsiLanguageInjectionHost.class, false); if (host == null || ElementManipulators.getManipulator(host) == null) return null; final List<Pair<PsiElement, TextRange>> injections = InjectedLanguageManager.getInstance(host.getProject()).getInjectedPsiFiles(host); if (injections == null || injections.isEmpty()) return null; final int offsetInElement = offset - host.getTextRange().getStartOffset(); final Pair<PsiElement, TextRange> rangePair = ContainerUtil.find(injections, new Condition<Pair<PsiElement, TextRange>>() { @Override public boolean value(final Pair<PsiElement, TextRange> pair) { return pair.second.containsRange(offsetInElement, offsetInElement); } }); if (rangePair != null) { final Language language = rangePair.first.getContainingFile().getLanguage(); final Object action = language.getUserData(EDIT_ACTION_AVAILABLE); if (action != null && action.equals(false)) return null; myLastLanguageName = language.getDisplayName(); } return rangePair; }
@NotNull public List<TextRange> getInjectedArea(final PsiElement element) { final TextRange textRange = ElementManipulators.getValueTextRange(element); if (myCompiledValuePattern == null) { return Collections.singletonList(textRange); } else { final LiteralTextEscaper<? extends PsiLanguageInjectionHost> textEscaper = ((PsiLanguageInjectionHost)element).createLiteralTextEscaper(); final StringBuilder sb = new StringBuilder(); textEscaper.decode(textRange, sb); final List<TextRange> ranges = getMatchingRanges(myCompiledValuePattern.matcher(StringPattern.newBombedCharSequence(sb)), sb.length()); return !ranges.isEmpty() ? ContainerUtil.map(ranges, new Function<TextRange, TextRange>() { public TextRange fun(TextRange s) { return new TextRange(textEscaper.getOffsetInHost(s.getStartOffset(), textRange), textEscaper.getOffsetInHost(s.getEndOffset(), textRange)); } }) : Collections.<TextRange>emptyList(); } }
protected void checkValue( XmlAttributeValue value, XmlFile file, XmlRefCountHolder refHolder, XmlTag tag, ProblemsHolder holder ) { if( refHolder.isValidatable( tag.getParent() ) && ((XmlAttribute)(value).getParent()).getName().equals( "xmi:id" ) ) { int matches = StringUtils.countMatches( file.getText(), ((XmlAttribute)(value).getParent()).getText() ); if( matches > 1 ) { holder.registerProblem( value, "XMI Duplicate id", ProblemHighlightType.GENERIC_ERROR, ElementManipulators.getValueTextRange( value ), new DuplicateIdQuickFix() ); } } }
@NotNull @Override public PsiReference[] createReferences(GenericDomValue value, final PsiElement element, final ConvertContext context) { String text = value.getStringValue(); TextRange range = ElementManipulators.getValueTextRange(element); return new PsiReference[]{new MavenUrlPsiReference(element, text, range) { @NotNull @Override public Object[] getVariants() { Module module = context.getModule(); if (module != null) { String name = MavenRepositoriesProvider.getInstance().getRepositoryUrl(getRepositoryId(context)); if (!StringUtil.isEmptyOrSpaces(name)) return new Object[]{name}; } return super.getVariants(); } }}; }
@NotNull public PsiReference[] createReferences(final GenericDomValue genericDomValue, final PsiElement element, final ConvertContext context) { final String s = genericDomValue.getStringValue(); if (s != null) { final int offset = ElementManipulators.getOffsetInElement(element); final ArrayList<PsiReference> list = new ArrayList<PsiReference>(); int pos = -1; while (true) { while (pos + 1 < s.length()) { if (!Character.isWhitespace(s.charAt(pos + 1))) { break; } pos++; } int nextPos = s.indexOf(',', pos + 1); if (nextPos == -1) { createReference(element, s.substring(pos + 1), pos + 1 + offset, list); break; } else { createReference(element, s.substring(pos + 1, nextPos), pos + 1 + offset, list); pos = nextPos; } } return list.toArray(new PsiReference[list.size()]); } return PsiReference.EMPTY_ARRAY; }
public void testManipulatorRegistered() { LanguageExtensionPoint[] extensions = Extensions.getExtensions(new ExtensionPointName<LanguageExtensionPoint>("com.intellij.lang.parserDefinition")); Set<String> classes = new HashSet<String>(); List<String> failures = new ArrayList<String>(); int total = 0; for (LanguageExtensionPoint e : extensions) { ParserDefinition definition = (ParserDefinition)e.getInstance(); for (IElementType type : IElementType.enumerate(IElementType.TRUE)) { if (type instanceof ILeafElementType) continue; try { CompositeElement treeElement = ASTFactory.composite(type); total++; PsiElement element = treeElement instanceof PsiElement? (PsiElement)treeElement : definition.createElement(treeElement); if (element instanceof PsiLanguageInjectionHost && classes.add(element.getClass().getName())) { boolean ok = ElementManipulators.getManipulator(element) != null; System.out.println((ok ? "OK " : "FAIL") + " " + element.getClass().getSimpleName() + " [" + definition.getClass().getSimpleName() + "]"); if (!ok) failures.add(element.getClass().getName()); } } catch (Throwable ignored) { } } } System.out.println("count: " + classes.size() + ", total: " + total); assertEmpty("PsiLanguageInjectionHost requires " + ElementManipulators.EP_NAME, failures); }
@NotNull public static <T extends PsiElement> ElementManipulator<T> getManipulator(T currentElement){ ElementManipulator<T> manipulator = ElementManipulators.getManipulator(currentElement); if (manipulator == null) { throw new IncorrectOperationException("Manipulator for this element is not defined: " + currentElement + "; " + currentElement.getClass()); } return manipulator; }
@Override public boolean createReferences(@NotNull final PsiElement psiElement, final @NotNull List<PsiReference> references, final boolean soft) { final TextRange range = ElementManipulators.getValueTextRange(psiElement); int offset = range.getStartOffset(); int endOffset = range.getEndOffset(); final String elementText = psiElement.getText(); for (DynamicContextProvider provider: Extensions.getExtensions(DynamicContextProvider.EP_NAME)) { final int dynamicOffset = provider.getOffset(psiElement, offset, elementText); if (dynamicOffset == -1) { return false; } else if (dynamicOffset != offset) { offset = dynamicOffset; } } final int pos = getLastPosOfURL(offset, elementText); if (pos != -1 && pos < endOffset) { endOffset = pos; } try { final String text = elementText.substring(offset, endOffset); return createReferences(psiElement, offset, text, references, soft); } catch (StringIndexOutOfBoundsException e) { LOG.error("Cannot process string: '" + psiElement.getParent().getParent().getText() + "'", e); return false; } }
@Override public List<TextRange> select(PsiElement e, CharSequence editorText, int cursorOffset, Editor editor) { final IElementType type = e.getNode().getElementType(); final StringLiteralLexer lexer = new StringLiteralLexer(type == SINGLE_QUOTED_STRING ? '\'' : '"', type, false, "/", false, false); final List<TextRange> result = new ArrayList<TextRange>(); SelectWordUtil.addWordHonoringEscapeSequences(editorText, e.getTextRange(), cursorOffset, lexer, result); final PsiElement parent = e.getParent(); result.add(ElementManipulators.getValueTextRange(parent).shiftRight(parent.getTextOffset())); return result; }
@Override public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { final String canonicalText = getCanonicalText(); final PsiElement element = ElementManipulators.getManipulator(myElement) .handleContentChange(myElement, getRangeInElement(), newElementName); myRange = new TextRange(myRange.getStartOffset(),myRange.getEndOffset() - (canonicalText.length() - newElementName.length())); return element; }
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { return ElementManipulators.getManipulator(myElement).handleContentChange( myElement, getRangeInElement(), newElementName ); }
public static SchemaPrefix createJspPrefix(XmlAttributeValue element, String prefix) { TextRange range = ElementManipulators.getValueTextRange(element).shiftRight(element.getStartOffsetInParent()); return new SchemaPrefix((XmlAttribute)element.getParent(), range, prefix) { @Override protected String getNamespace() { return ((XmlAttribute)getParent()).getParent().getAttributeValue("uri"); } }; }
@Override public PsiElement setName(@NotNull String name) throws IncorrectOperationException { final PsiElement nameElement = getNameElement(); if (nameElement != null) { return ElementManipulators.getManipulator(nameElement).handleContentChange( nameElement, new TextRange(0,nameElement.getTextLength()), name ); } return null; }
@Override public boolean createReferences(@NotNull final PsiElement psiElement, @NotNull final List<PsiReference> references, final boolean soft) { final TextRange range = ElementManipulators.getValueTextRange(psiElement); final String elementText = psiElement.getText(); final int anchorOffset = elementText.indexOf('#'); if (anchorOffset == -1) { return false; } final boolean dynamic = isDynamic(psiElement, anchorOffset + 1, elementText); if (dynamic) { return false; } FileReference fileReference = null; if (range.getStartOffset() != anchorOffset) { fileReference = findFileReference(references); if (fileReference == null || fileReference.resolve() == null) { return false; } } final int pos = elementText.indexOf('?', anchorOffset); final String anchor; try { int endIndex = pos != -1 ? pos : range.getEndOffset(); if (endIndex <= anchorOffset) { endIndex = anchorOffset + 1; } anchor = elementText.substring(anchorOffset + 1, endIndex); } catch (StringIndexOutOfBoundsException e) { throw new RuntimeException(elementText, e); } final AnchorReferenceImpl anchorReference = new AnchorReferenceImpl(anchor, fileReference, psiElement, anchorOffset + 1, soft); references.add(anchorReference); return false; }
@Override public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { return ElementManipulators.getManipulator(myElement).handleContentChange( myElement, getRangeInElement(), newElementName ); }
public void testPathQuickFixForInvalidValue() throws Throwable { createProjectPom("<groupId>test</groupId>" + "<artifactId>project</artifactId>" + "<version>1</version>"); VirtualFile m = createModulePom("bar", "<groupId>test</groupId>" + "<artifactId>one</artifactId>" + "<version>1</version>"); importProjects(myProjectPom, m); createProjectPom("<groupId>test</groupId>" + "<artifactId>project</artifactId>" + "<version>1</version>" + "<parent>" + " <groupId>test</groupId>" + " <artifactId>one</artifactId>" + " <version>1</version>" + " <relativePath><caret>xxx</relativePath>" + "</parent>"); IntentionAction i = getIntentionAtCaret("Fix Relative Path"); assertNotNull(i); myFixture.launchAction(i); PsiElement el = getElementAtCaret(myProjectPom); assertEquals("bar/pom.xml", ElementManipulators.getValueText(el)); }
public static void addMacrodefParameterRefs(@NotNull XmlAttributeValue element, final Collection<PsiReference> refs) { final DomElement domElement = DomUtil.getDomElement(element); if (domElement == null) { return; } final AntDomMacroDef macrodef = domElement.getParentOfType(AntDomMacroDef.class, true); if (macrodef == null) { return; } final String text = ElementManipulators.getValueText(element); final int valueBeginingOffset = Math.abs(element.getTextRange().getStartOffset() - element.getValueTextRange().getStartOffset()); int startIndex; int endIndex = -1; while ((startIndex = text.indexOf("@{", endIndex + 1)) > endIndex) { startIndex += 2; endIndex = startIndex; int nestedBrackets = 0; while (text.length() > endIndex) { final char ch = text.charAt(endIndex); if (ch == '}') { if (nestedBrackets == 0) { break; } --nestedBrackets; } else if (ch == '{') { ++nestedBrackets; } ++endIndex; } if(nestedBrackets > 0 || endIndex == text.length()) return; if (endIndex >= startIndex) { //final String name = text.substring(startIndex, endIndex); refs.add(new AntDomMacrodefAttributeReference(element, new TextRange(valueBeginingOffset + startIndex, valueBeginingOffset + endIndex))); } endIndex = startIndex; } }
@NotNull public PsiReference[] createReferences(GenericDomValue<TargetResolver.Result> value, PsiElement element, ConvertContext context) { final XmlElement xmlElement = value.getXmlElement(); if (!(xmlElement instanceof XmlAttribute)) { return PsiReference.EMPTY_ARRAY; } final XmlAttributeValue valueElement = ((XmlAttribute)xmlElement).getValueElement(); if (valueElement == null) { return PsiReference.EMPTY_ARRAY; } final String refsString = value.getStringValue(); if (refsString == null) { return PsiReference.EMPTY_ARRAY; } final List<PsiReference> refs = new ArrayList<PsiReference>(); final AntDomTargetReference.ReferenceGroup group = new AntDomTargetReference.ReferenceGroup(); final TextRange wholeStringRange = ElementManipulators.getValueTextRange(valueElement); final StringTokenizer tokenizer = new StringTokenizer(refsString, ",", false); while (tokenizer.hasMoreTokens()) { final String token = tokenizer.nextToken(); int tokenStartOffset = tokenizer.getCurrentPosition() - token.length(); final String ref = token.trim(); if (ref.length() != token.length()) { for (int idx = 0; idx < token.length(); idx++) { if (Character.isWhitespace(token.charAt(idx))) { tokenStartOffset++; } else { break; } } } refs.add(new AntDomTargetReference(element, TextRange.from(wholeStringRange.getStartOffset() + tokenStartOffset, ref.length()), group)); } return refs.toArray(new PsiReference[refs.size()]); }
public AntDomFileReferenceSet(final GenericAttributeValue attribValue, final String pathSubstring, int beginOffset, boolean validateFileRefs) { super(cutTrailingSlash(FileUtil.toSystemIndependentName(pathSubstring)), attribValue.getXmlAttributeValue(), ElementManipulators.getOffsetInElement(attribValue.getXmlAttributeValue()) + beginOffset, null, SystemInfo.isFileSystemCaseSensitive ); myValue = attribValue; for (FileReference reference : getAllReferences()) { if (reference instanceof AntDomReference) { ((AntDomReference)reference).setShouldBeSkippedByAnnotator(!validateFileRefs); } } }
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()); }
public PsiElement setName(@NotNull String name) throws IncorrectOperationException { final PsiElement nameElement = getNameElement(); if (nameElement != null) { return ElementManipulators.getManipulator(nameElement).handleContentChange( nameElement, new TextRange(0,nameElement.getTextLength()), name ); } return null; }
public boolean createReferences(@NotNull final PsiElement psiElement, final @NotNull List<PsiReference> references, final boolean soft) { final TextRange range = ElementManipulators.getValueTextRange(psiElement); final String elementText = psiElement.getText(); final int anchorOffset = elementText.indexOf('#'); if (anchorOffset == -1) { return false; } final boolean dynamic = isDynamic(psiElement, anchorOffset + 1, elementText); if (dynamic) { return false; } FileReference fileReference = null; if (range.getStartOffset() != anchorOffset) { fileReference = findFileReference(references); if (fileReference == null || fileReference.resolve() == null) { return false; } } final int pos = elementText.indexOf('?', anchorOffset); final String anchor; try { int endIndex = pos != -1 ? pos : range.getEndOffset(); if (endIndex <= anchorOffset) { endIndex = anchorOffset + 1; } anchor = elementText.substring(anchorOffset + 1, endIndex); } catch (StringIndexOutOfBoundsException e) { throw new RuntimeException(elementText, e); } final AnchorReference anchorReference = new AnchorReference(anchor, fileReference, psiElement, anchorOffset + 1, soft); references.add(anchorReference); return false; }
@Override public PsiElement bindToElement(@NotNull final PsiElement element) throws IncorrectOperationException { if(!(element instanceof HaxePackage)) { throw new IncorrectOperationException("Cannot bind to " + element); } final String newName = ((HaxePackage) element).getQualifiedName(); final TextRange range = new TextRange(getReferenceSet().getReference(0).getRangeInElement().getStartOffset(), getRangeInElement().getEndOffset()); final ElementManipulator<PsiElement> manipulator = ElementManipulators.getManipulator(getElement()); return manipulator.handleContentChange(getElement(), range, newName); }
public AntDomFileReferenceSet(final GenericAttributeValue attribValue, final String pathSubstring, int beginOffset, boolean validateFileRefs) { super(cutTrailingSlash(FileUtil.toSystemIndependentName(pathSubstring)), attribValue.getXmlAttributeValue(), ElementManipulators.getOffsetInElement(attribValue.getXmlAttributeValue()) + beginOffset, null, SystemInfo.isFileSystemCaseSensitive); myValue = attribValue; for(FileReference reference : getAllReferences()) { if(reference instanceof AntDomReference) { ((AntDomReference) reference).setShouldBeSkippedByAnnotator(!validateFileRefs); } } }
@Nonnull public static <T extends PsiElement> ElementManipulator<T> getManipulator(T currentElement){ ElementManipulator<T> manipulator = ElementManipulators.getManipulator(currentElement); if (manipulator == null) { throw new IncorrectOperationException("Manipulator for this element is not defined: " + currentElement + "; " + currentElement.getClass()); } return manipulator; }