public static void clearCaches( @NotNull PsiFile injected, @NotNull DocumentWindowImpl documentWindow) { VirtualFileWindowImpl virtualFile = (VirtualFileWindowImpl) injected.getVirtualFile(); PsiManagerEx psiManagerEx = (PsiManagerEx) injected.getManager(); if (psiManagerEx.getProject().isDisposed()) return; psiManagerEx.getFileManager().setViewProvider(virtualFile, null); PsiElement context = InjectedLanguageManager.getInstance(injected.getProject()).getInjectionHost(injected); PsiFile hostFile; if (context != null) { hostFile = context.getContainingFile(); } else { VirtualFile delegate = virtualFile.getDelegate(); hostFile = delegate.isValid() ? psiManagerEx.findFile(delegate) : null; } if (hostFile != null) { // modification of cachedInjectedDocuments must be under PsiLock synchronized (PsiLock.LOCK) { List<DocumentWindow> cachedInjectedDocuments = getCachedInjectedDocuments(hostFile); for (int i = cachedInjectedDocuments.size() - 1; i >= 0; i--) { DocumentWindow cachedInjectedDocument = cachedInjectedDocuments.get(i); if (cachedInjectedDocument == documentWindow) { cachedInjectedDocuments.remove(i); } } } } }
public static boolean isValidName( final Project project, final PsiElement psiElement, final String newName) { if (newName == null || newName.length() == 0) { return false; } final Condition<String> inputValidator = RenameInputValidatorRegistry.getInputValidator(psiElement); if (inputValidator != null) { return inputValidator.value(newName); } if (psiElement instanceof PsiFile || psiElement instanceof PsiDirectory) { return newName.indexOf('\\') < 0 && newName.indexOf('/') < 0; } if (psiElement instanceof PomTargetPsiElement) { return !StringUtil.isEmptyOrSpaces(newName); } final PsiFile file = psiElement.getContainingFile(); final Language elementLanguage = psiElement.getLanguage(); final Language fileLanguage = file == null ? null : file.getLanguage(); Language language = fileLanguage == null ? elementLanguage : fileLanguage.isKindOf(elementLanguage) ? fileLanguage : elementLanguage; return LanguageNamesValidation.INSTANCE .forLanguage(language) .isIdentifier(newName.trim(), project); }
public String getAttributeValue(String _name, String namespace) { if (namespace == null) { return getAttributeValue(_name); } XmlTagImpl current = this; PsiElement parent = getParent(); while (current != null) { BidirectionalMap<String, String> map = current.initNamespaceMaps(parent); if (map != null) { List<String> keysByValue = map.getKeysByValue(namespace); if (keysByValue != null && !keysByValue.isEmpty()) { for (String prefix : keysByValue) { if (prefix != null && prefix.length() > 0) { final String value = getAttributeValue(prefix + ":" + _name); if (value != null) return value; } } } } current = parent instanceof XmlTag ? (XmlTagImpl) parent : null; parent = parent.getParent(); } if (namespace.length() == 0 || getNamespace().equals(namespace)) { return getAttributeValue(_name); } return null; }
public static void enumerate( @NotNull PsiElement host, @NotNull PsiFile containingFile, boolean probeUp, @NotNull PsiLanguageInjectionHost.InjectedPsiVisitor visitor) { // do not inject into nonphysical files except during completion if (!containingFile.isPhysical() && containingFile.getOriginalFile() == containingFile) { final PsiElement context = InjectedLanguageManager.getInstance(containingFile.getProject()) .getInjectionHost(containingFile); if (context == null) return; final PsiFile file = context.getContainingFile(); if (file == null || !file.isPhysical() && file.getOriginalFile() == file) return; } if (containingFile.getViewProvider() instanceof InjectedFileViewProvider) return; // no injection inside injection PsiElement inTree = loadTree(host, containingFile); if (inTree != host) { host = inTree; containingFile = host.getContainingFile(); } MultiHostRegistrarImpl registrar = probeElementsUp(host, containingFile, probeUp); if (registrar == null) { return; } List<Pair<Place, PsiFile>> places = registrar.getResult(); for (Pair<Place, PsiFile> pair : places) { PsiFile injectedPsi = pair.second; visitor.visit(injectedPsi, pair.first); } }
// returns (injected psi, leaf element at the offset, language of the leaf element) // since findElementAt() is expensive, we trying to reuse its result @NotNull private static Trinity<PsiElement, PsiElement, Language> tryOffset( @NotNull PsiFile hostFile, final int offset, @NotNull PsiDocumentManager documentManager) { FileViewProvider provider = hostFile.getViewProvider(); Language leafLanguage = null; PsiElement leafElement = null; for (Language language : provider.getLanguages()) { PsiElement element = provider.findElementAt(offset, language); if (element != null) { if (leafLanguage == null) { leafLanguage = language; leafElement = element; } PsiElement injected = findInside(element, hostFile, offset, documentManager); if (injected != null) return Trinity.create(injected, element, language); } // maybe we are at the border between two psi elements, then try to find injection at the end // of the left element if (offset != 0 && (element == null || element.getTextRange().getStartOffset() == offset)) { PsiElement leftElement = provider.findElementAt(offset - 1, language); if (leftElement != null && leftElement.getTextRange().getEndOffset() == offset) { PsiElement injected = findInside(leftElement, hostFile, offset, documentManager); if (injected != null) return Trinity.create(injected, element, language); } } } return Trinity.create(null, leafElement, leafLanguage); }
void loadFromEditor(@NotNull Editor editor) { assertDispatchThread(); LOG.assertTrue(!editor.isDisposed()); clear(); PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject); documentManager.commitDocument(editor.getDocument()); PsiFile file = documentManager.getPsiFile(editor.getDocument()); SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(myProject); EditorFoldingInfo info = EditorFoldingInfo.get(editor); FoldRegion[] foldRegions = editor.getFoldingModel().getAllFoldRegions(); for (FoldRegion region : foldRegions) { if (!region.isValid()) continue; PsiElement element = info.getPsiElement(region); boolean expanded = region.isExpanded(); boolean collapseByDefault = element != null && FoldingPolicy.isCollapseByDefault(element) && !FoldingUtil.caretInsideRange(editor, TextRange.create(region)); if (collapseByDefault == expanded || element == null) { FoldingInfo fi = new FoldingInfo(region.getPlaceholderText(), expanded); if (element != null) { myPsiElements.add(smartPointerManager.createSmartPsiElementPointer(element, file)); element.putUserData(FOLDING_INFO_KEY, fi); } else if (region.isValid()) { myRangeMarkers.add(region); region.putUserData(FOLDING_INFO_KEY, fi); } } } }
public static void initOffsets(final PsiFile file, final OffsetMap offsetMap) { int offset = Math.max( offsetMap.getOffset(CompletionInitializationContext.SELECTION_END_OFFSET), offsetMap.getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET)); PsiElement element = file.findElementAt(offset); if (element instanceof PsiWhiteSpace && (!element.textContains('\n') || CodeStyleSettingsManager.getSettings(file.getProject()) .getCommonSettings(JavaLanguage.INSTANCE) .METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE)) { element = file.findElementAt(element.getTextRange().getEndOffset()); } if (element == null) return; if (LEFT_PAREN.accepts(element)) { offsetMap.addOffset(LPAREN_OFFSET, element.getTextRange().getStartOffset()); PsiElement list = element.getParent(); PsiElement last = list.getLastChild(); if (last instanceof PsiJavaToken && ((PsiJavaToken) last).getTokenType() == JavaTokenType.RPARENTH) { offsetMap.addOffset(RPAREN_OFFSET, last.getTextRange().getStartOffset()); } offsetMap.addOffset(ARG_LIST_END_OFFSET, list.getTextRange().getEndOffset()); } }
public static String getUnescapedText( PsiFile file, @Nullable final PsiElement startElement, @Nullable final PsiElement endElement) { final InjectedLanguageManager manager = InjectedLanguageManager.getInstance(file.getProject()); if (manager.getInjectionHost(file) == null) { return file.getText() .substring( startElement == null ? 0 : startElement.getTextRange().getStartOffset(), endElement == null ? file.getTextLength() : endElement.getTextRange().getStartOffset()); } final StringBuilder sb = new StringBuilder(); file.accept( new PsiRecursiveElementWalkingVisitor() { Boolean myState = startElement == null ? Boolean.TRUE : null; @Override public void visitElement(PsiElement element) { if (element == startElement) myState = Boolean.TRUE; if (element == endElement) myState = Boolean.FALSE; if (Boolean.FALSE == myState) return; if (Boolean.TRUE == myState && element.getFirstChild() == null) { sb.append(getUnescapedLeafText(element, false)); } else { super.visitElement(element); } } }); return sb.toString(); }
public static TextWithImports getEditorText(final Editor editor) { if (editor == null) { return null; } final Project project = editor.getProject(); if (project == null) return null; String defaultExpression = editor.getSelectionModel().getSelectedText(); if (defaultExpression == null) { int offset = editor.getCaretModel().getOffset(); PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); if (psiFile != null) { PsiElement elementAtCursor = psiFile.findElementAt(offset); if (elementAtCursor != null) { final EditorTextProvider textProvider = EditorTextProvider.EP.forLanguage(elementAtCursor.getLanguage()); if (textProvider != null) { final TextWithImports editorText = textProvider.getEditorText(elementAtCursor); if (editorText != null) return editorText; } } } } else { return new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, defaultExpression); } return null; }
private static PsiElement getNextElement(PsiElement element) { PsiElement sibling = element.getNextSibling(); if (sibling != null) return sibling; element = element.getParent(); if (element != null) return getNextElement(element); return null; }
@NotNull public UsageViewPresentation createPresentation( @NotNull FindUsagesHandler handler, @NotNull FindUsagesOptions findUsagesOptions) { PsiElement element = handler.getPsiElement(); LOG.assertTrue(element.isValid()); return createPresentation(element, findUsagesOptions, myToOpenInNewTab); }
public PsiDirectory[] getSelectedDirectories() { final PsiElement[] elements = getSelectedPSIElements(); if (elements.length == 1) { final PsiElement element = elements[0]; if (element instanceof PsiDirectory) { return new PsiDirectory[] {(PsiDirectory) element}; } else if (element instanceof PsiDirectoryContainer) { return ((PsiDirectoryContainer) element).getDirectories(); } else { final PsiFile containingFile = element.getContainingFile(); if (containingFile != null) { final PsiDirectory psiDirectory = containingFile.getContainingDirectory(); if (psiDirectory != null) { return new PsiDirectory[] {psiDirectory}; } final VirtualFile file = containingFile.getVirtualFile(); if (file instanceof VirtualFileWindow) { final VirtualFile delegate = ((VirtualFileWindow) file).getDelegate(); final PsiFile delegatePsiFile = containingFile.getManager().findFile(delegate); if (delegatePsiFile != null && delegatePsiFile.getContainingDirectory() != null) { return new PsiDirectory[] {delegatePsiFile.getContainingDirectory()}; } } return PsiDirectory.EMPTY_ARRAY; } } } else { final DefaultMutableTreeNode selectedNode = getSelectedNode(); if (selectedNode != null) { return getSelectedDirectoriesInAmbiguousCase(selectedNode); } } return PsiDirectory.EMPTY_ARRAY; }
public static boolean isClassEquivalentTo(@NotNull PsiClass aClass, PsiElement another) { if (aClass == another) return true; if (!(another instanceof PsiClass)) return false; String name1 = aClass.getName(); if (name1 == null) return false; if (!another.isValid()) return false; String name2 = ((PsiClass) another).getName(); if (name2 == null) return false; if (name1.hashCode() != name2.hashCode()) return false; if (!name1.equals(name2)) return false; String qName1 = aClass.getQualifiedName(); String qName2 = ((PsiClass) another).getQualifiedName(); if (qName1 == null || qName2 == null) { //noinspection StringEquality if (qName1 != qName2) return false; if (aClass instanceof PsiTypeParameter && another instanceof PsiTypeParameter) { PsiTypeParameter p1 = (PsiTypeParameter) aClass; PsiTypeParameter p2 = (PsiTypeParameter) another; return p1.getIndex() == p2.getIndex() && aClass.getManager().areElementsEquivalent(p1.getOwner(), p2.getOwner()); } else { return false; } } if (qName1.hashCode() != qName2.hashCode() || !qName1.equals(qName2)) { return false; } if (originalElement(aClass).equals(originalElement((PsiClass) another))) { return true; } final PsiFile file1 = aClass.getContainingFile().getOriginalFile(); final PsiFile file2 = another.getContainingFile().getOriginalFile(); // see com.intellij.openapi.vcs.changes.PsiChangeTracker // see com.intellij.psi.impl.PsiFileFactoryImpl#createFileFromText(CharSequence,PsiFile) final PsiFile original1 = file1.getUserData(PsiFileFactory.ORIGINAL_FILE); final PsiFile original2 = file2.getUserData(PsiFileFactory.ORIGINAL_FILE); if (original1 == original2 && original1 != null || original1 == file2 || original2 == file1 || file1 == file2) { return compareClassSeqNumber(aClass, (PsiClass) another); } final FileIndexFacade fileIndex = ServiceManager.getService(file1.getProject(), FileIndexFacade.class); final VirtualFile vfile1 = file1.getViewProvider().getVirtualFile(); final VirtualFile vfile2 = file2.getViewProvider().getVirtualFile(); boolean lib1 = fileIndex.isInLibraryClasses(vfile1); boolean lib2 = fileIndex.isInLibraryClasses(vfile2); return (fileIndex.isInSource(vfile1) || lib1) && (fileIndex.isInSource(vfile2) || lib2); }
@Override public void replaceDotToken(PsiElement newDot) { if (newDot == null) return; if (!TokenSets.DOTS.contains(newDot.getNode().getElementType())) return; final PsiElement oldDot = getDotToken(); if (oldDot == null) return; getNode().replaceChild(oldDot.getNode(), newDot.getNode()); }
@Nullable protected PsiElement getPSIElement(@Nullable final Object element) { if (element instanceof PsiElement) { PsiElement psiElement = (PsiElement) element; if (psiElement.isValid()) { return psiElement; } } return null; }
private static PsiType doFun(GrReferenceExpression refExpr) { if (ResolveUtil.isClassReference(refExpr)) { GrExpression qualifier = refExpr.getQualifier(); LOG.assertTrue(qualifier != null); return TypesUtil.createJavaLangClassType( qualifier.getType(), refExpr.getProject(), refExpr.getResolveScope()); } if (PsiUtil.isCompileStatic(refExpr)) { final GroovyResolveResult resolveResult = refExpr.advancedResolve(); final PsiElement resolvedF = resolveResult.getElement(); final PsiType type; if (resolvedF instanceof GrField) { type = ((GrField) resolvedF).getType(); } else if (resolvedF instanceof GrAccessorMethod) { type = ((GrAccessorMethod) resolvedF).getProperty().getType(); } else { type = null; } if (type != null) { return resolveResult.getSubstitutor().substitute(type); } } final PsiElement resolved = refExpr.resolve(); final PsiType nominal = refExpr.getNominalType(); Boolean reassigned = GrReassignedLocalVarsChecker.isReassignedVar(refExpr); if (reassigned != null && reassigned.booleanValue()) { return GrReassignedLocalVarsChecker.getReassignedVarType(refExpr, true); } final PsiType inferred = getInferredTypes(refExpr, resolved); if (inferred == null) { if (nominal == null) { // inside nested closure we could still try to infer from variable initializer. Not sound, // but makes sense if (resolved instanceof GrVariable) { LOG.assertTrue(resolved.isValid()); return ((GrVariable) resolved).getTypeGroovy(); } } return nominal; } if (nominal == null) return inferred; if (!TypeConversionUtil.isAssignable(TypeConversionUtil.erasure(nominal), inferred, false)) { if (resolved instanceof GrVariable && ((GrVariable) resolved).getTypeElementGroovy() != null) { return nominal; } } return inferred; }
private void getInjectedPsiFiles( @NotNull final List<PsiElement> elements1, @NotNull final List<PsiElement> elements2, @NotNull final ProgressIndicator progress, @NotNull final Set<PsiFile> outInjected) { List<DocumentWindow> injected = InjectedLanguageUtil.getCachedInjectedDocuments(myFile); Collection<PsiElement> hosts = new THashSet<PsiElement>(elements1.size() + elements2.size() + injected.size()); // rehighlight all injected PSI regardless the range, // since change in one place can lead to invalidation of injected PSI in (completely) other // place. for (DocumentWindow documentRange : injected) { progress.checkCanceled(); if (!documentRange.isValid()) continue; PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(documentRange); if (file == null) continue; PsiElement context = InjectedLanguageManager.getInstance(file.getProject()).getInjectionHost(file); if (context != null && context.isValid() && !file.getProject().isDisposed() && (myUpdateAll || new ProperTextRange(myStartOffset, myEndOffset) .intersects(context.getTextRange()))) { hosts.add(context); } } hosts.addAll(elements1); hosts.addAll(elements2); final PsiLanguageInjectionHost.InjectedPsiVisitor visitor = new PsiLanguageInjectionHost.InjectedPsiVisitor() { @Override public void visit( @NotNull PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) { synchronized (outInjected) { outInjected.add(injectedPsi); } } }; if (!JobUtil.invokeConcurrentlyUnderProgress( new ArrayList<PsiElement>(hosts), progress, false, new Processor<PsiElement>() { @Override public boolean process(PsiElement element) { progress.checkCanceled(); InjectedLanguageUtil.enumerate(element, myFile, false, visitor); return true; } })) throw new ProcessCanceledException(); }
@Nullable public static String getUnescapedLeafText(PsiElement element, boolean strict) { String unescaped = element.getCopyableUserData(LeafPatcher.UNESCAPED_TEXT); if (unescaped != null) { return unescaped; } if (!strict && element.getFirstChild() == null) { return element.getText(); } return null; }
public PomModelEvent runInner() throws IncorrectOperationException { final ASTNode anchor = expandTag(); if (myChild.getElementType() == XmlElementType.XML_TAG) { // compute where to insert tag according to DTD or XSD final XmlElementDescriptor parentDescriptor = getDescriptor(); final XmlTag[] subTags = getSubTags(); final PsiElement declaration = parentDescriptor != null ? parentDescriptor.getDeclaration() : null; // filtring out generated dtds if (declaration != null && declaration.getContainingFile() != null && declaration.getContainingFile().isPhysical() && subTags.length > 0) { final XmlElementDescriptor[] childElementDescriptors = parentDescriptor.getElementsDescriptors(XmlTagImpl.this); int subTagNum = -1; for (final XmlElementDescriptor childElementDescriptor : childElementDescriptors) { final String childElementName = childElementDescriptor.getName(); while (subTagNum < subTags.length - 1 && subTags[subTagNum + 1].getName().equals(childElementName)) { subTagNum++; } if (childElementName.equals( XmlChildRole.START_TAG_NAME_FINDER.findChild(myChild).getText())) { // insert child just after anchor // insert into the position specified by index if (subTagNum >= 0) { final ASTNode subTag = (ASTNode) subTags[subTagNum]; if (subTag.getTreeParent() != XmlTagImpl.this) { // in entity final XmlEntityRef entityRef = PsiTreeUtil.getParentOfType(subTags[subTagNum], XmlEntityRef.class); throw new IncorrectOperationException( "Can't insert subtag to the entity. Entity reference text: " + (entityRef == null ? "" : entityRef.getText())); } myNewElement = XmlTagImpl.super.addInternal(myChild, myChild, subTag, Boolean.FALSE); } else { final ASTNode child = XmlChildRole.START_TAG_END_FINDER.findChild(XmlTagImpl.this); myNewElement = XmlTagImpl.super.addInternal(myChild, myChild, child, Boolean.FALSE); } return null; } } } else { final ASTNode child = XmlChildRole.CLOSING_TAG_START_FINDER.findChild(XmlTagImpl.this); myNewElement = XmlTagImpl.super.addInternal(myChild, myChild, child, Boolean.TRUE); return null; } } myNewElement = XmlTagImpl.super.addInternal(myChild, myChild, anchor, Boolean.TRUE); return null; }
@NotNull private static PsiElement originalElement(@NotNull PsiClass aClass) { final PsiElement originalElement = aClass.getOriginalElement(); ASTNode node = originalElement.getNode(); if (node != null) { final PsiCompiledElement compiled = node.getUserData(ClsElementImpl.COMPILED_ELEMENT); if (compiled != null) { return compiled; } } return originalElement; }
public static PsiFile getTopLevelFile(@NotNull PsiElement element) { PsiFile containingFile = element.getContainingFile(); if (containingFile == null) return null; Document document = PsiDocumentManager.getInstance(element.getProject()).getCachedDocument(containingFile); if (document instanceof DocumentWindow) { PsiElement host = InjectedLanguageManager.getInstance(containingFile.getProject()) .getInjectionHost(containingFile); if (host != null) containingFile = host.getContainingFile(); } return containingFile; }
@NotNull public static GlobalSearchScope getMaximalScope(@NotNull FindUsagesHandler handler) { PsiElement element = handler.getPsiElement(); Project project = element.getProject(); PsiFile file = element.getContainingFile(); if (file != null && ProjectFileIndex.SERVICE .getInstance(project) .isInContent(file.getViewProvider().getVirtualFile())) { return GlobalSearchScope.projectScope(project); } return GlobalSearchScope.allScope(project); }
private static int getSeqNumber(@NotNull PsiClass aClass) { // sequence number of this class among its parent' child classes named the same PsiElement parent = aClass.getParent(); if (parent == null) return -1; int seqNo = 0; for (PsiElement child : parent.getChildren()) { if (child == aClass) return seqNo; if (child instanceof PsiClass && Comparing.strEqual(aClass.getName(), ((PsiClass) child).getName())) { seqNo++; } } return -1; }
public static PsiMethod findPsiMethod(PsiFile file, int offset) { PsiElement element = null; while (offset >= 0) { element = file.findElementAt(offset); if (element != null) break; offset--; } for (; element != null; element = element.getParent()) { if (element instanceof PsiClass) return null; if (element instanceof PsiMethod) return (PsiMethod) element; } return null; }
@NotNull public String getNamespaceByPrefix(String prefix) { final PsiElement parent = getParent(); LOG.assertTrue(parent.isValid()); BidirectionalMap<String, String> map = initNamespaceMaps(parent); if (map != null) { final String ns = map.get(prefix); if (ns != null) return ns; } if (parent instanceof XmlTag) return ((XmlTag) parent).getNamespaceByPrefix(prefix); // The prefix 'xml' is by definition bound to the namespace name // http://www.w3.org/XML/1998/namespace. It MAY, but need not, be declared if (XML_NS_PREFIX.equals(prefix)) return XmlUtil.XML_NAMESPACE_URI; if (prefix.length() > 0 && !hasNamespaceDeclarations() && getNamespacePrefix().equals(prefix)) { // When there is no namespace declarations then qualified names should be just used in dtds // this implies that we may have "" namespace prefix ! (see last paragraph in Namespaces in // Xml, Section 5) String result = ourGuard.doPreventingRecursion( "getNsByPrefix", true, new Computable<String>() { @Override public String compute() { final String nsFromEmptyPrefix = getNamespaceByPrefix(""); final XmlNSDescriptor nsDescriptor = getNSDescriptor(nsFromEmptyPrefix, false); final XmlElementDescriptor descriptor = nsDescriptor != null ? nsDescriptor.getElementDescriptor(XmlTagImpl.this) : null; final String nameFromRealDescriptor = descriptor != null && descriptor.getDeclaration() != null && descriptor.getDeclaration().isPhysical() ? descriptor.getName() : ""; if (nameFromRealDescriptor.equals(getName())) return nsFromEmptyPrefix; return XmlUtil.EMPTY_URI; } }); if (result != null) { return result; } } return XmlUtil.EMPTY_URI; }
@Override public PsiElement handleElementRenameSimple(String newElementName) throws IncorrectOperationException { if (!PsiUtil.isValidReferenceName(newElementName)) { final PsiElement old = getReferenceNameElement(); if (old == null) throw new IncorrectOperationException("ref has no name element"); PsiElement element = GroovyPsiElementFactory.getInstance(getProject()) .createStringLiteralForReference(newElementName); old.replace(element); return this; } return super.handleElementRenameSimple(newElementName); }
@Override @Nullable public List<Pair<PsiElement, TextRange>> getInjectedPsiFiles(@NotNull final PsiElement host) { if (!(host instanceof PsiLanguageInjectionHost) || !((PsiLanguageInjectionHost) host).isValidHost()) { return null; } final PsiElement inTree = InjectedLanguageUtil.loadTree(host, host.getContainingFile()); final List<Pair<PsiElement, TextRange>> result = new SmartList<Pair<PsiElement, TextRange>>(); InjectedLanguageUtil.enumerate( inTree, new PsiLanguageInjectionHost.InjectedPsiVisitor() { @Override public void visit( @NotNull PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) { for (PsiLanguageInjectionHost.Shred place : places) { if (place.getHost() == inTree) { result.add( new Pair<PsiElement, TextRange>(injectedPsi, place.getRangeInsideHost())); } } } }); return result.isEmpty() ? null : result; }
public static boolean isInInjectedLanguagePrefixSuffix(@NotNull final PsiElement element) { PsiFile injectedFile = element.getContainingFile(); if (injectedFile == null) return false; Project project = injectedFile.getProject(); InjectedLanguageManager languageManager = InjectedLanguageManager.getInstance(project); if (!languageManager.isInjectedFragment(injectedFile)) return false; TextRange elementRange = element.getTextRange(); List<TextRange> editables = languageManager.intersectWithAllEditableFragments(injectedFile, elementRange); int combinedEdiablesLength = 0; for (TextRange editable : editables) { combinedEdiablesLength += editable.getLength(); } return combinedEdiablesLength != elementRange.getLength(); }
@Override @Nullable public String getReferenceName() { PsiElement nameElement = getReferenceNameElement(); if (nameElement != null) { IElementType nodeType = nameElement.getNode().getElementType(); if (TokenSets.STRING_LITERAL_SET.contains(nodeType)) { final Object value = GrLiteralImpl.getLiteralValue(nameElement); if (value instanceof String) { return (String) value; } } return nameElement.getText(); } return null; }
public static void renameNonCodeUsages( @NotNull Project project, @NotNull NonCodeUsageInfo[] usages) { PsiDocumentManager.getInstance(project).commitAllDocuments(); Map<Document, List<UsageOffset>> docsToOffsetsMap = new HashMap<Document, List<UsageOffset>>(); final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project); for (NonCodeUsageInfo usage : usages) { PsiElement element = usage.getElement(); if (element == null) continue; element = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(element, true); if (element == null) continue; final ProperTextRange rangeInElement = usage.getRangeInElement(); if (rangeInElement == null) continue; final PsiFile containingFile = element.getContainingFile(); final Document document = psiDocumentManager.getDocument(containingFile); final Segment segment = usage.getSegment(); LOG.assertTrue(segment != null); int fileOffset = segment.getStartOffset(); List<UsageOffset> list = docsToOffsetsMap.get(document); if (list == null) { list = new ArrayList<UsageOffset>(); docsToOffsetsMap.put(document, list); } list.add(new UsageOffset(fileOffset, fileOffset + rangeInElement.getLength(), usage.newText)); } for (Document document : docsToOffsetsMap.keySet()) { List<UsageOffset> list = docsToOffsetsMap.get(document); LOG.assertTrue(list != null, document); UsageOffset[] offsets = list.toArray(new UsageOffset[list.size()]); Arrays.sort(offsets); for (int i = offsets.length - 1; i >= 0; i--) { UsageOffset usageOffset = offsets[i]; document.replaceString(usageOffset.startOffset, usageOffset.endOffset, usageOffset.newText); } PsiDocumentManager.getInstance(project).commitDocument(document); } PsiDocumentManager.getInstance(project).commitAllDocuments(); }