private static void highlightTodos( @NotNull PsiFile file, @NotNull CharSequence text, int startOffset, int endOffset, @NotNull ProgressIndicator progress, @NotNull ProperTextRange priorityRange, @NotNull Collection<HighlightInfo> result, @NotNull Collection<HighlightInfo> outsideResult) { PsiSearchHelper helper = PsiSearchHelper.SERVICE.getInstance(file.getProject()); TodoItem[] todoItems = helper.findTodoItems(file, startOffset, endOffset); if (todoItems.length == 0) return; for (TodoItem todoItem : todoItems) { progress.checkCanceled(); TextRange range = todoItem.getTextRange(); String description = text.subSequence(range.getStartOffset(), range.getEndOffset()).toString(); TextAttributes attributes = todoItem.getPattern().getAttributes().getTextAttributes(); HighlightInfo info = HighlightInfo.createHighlightInfo( HighlightInfoType.TODO, range, description, description, attributes); assert info != null; if (priorityRange.containsRange(info.getStartOffset(), info.getEndOffset())) { result.add(info); } else { outsideResult.add(info); } } }
public void setHighlightingEnabled(@NotNull PsiFile file, boolean value) { if (value) { myDisabledHighlightingFiles.remove(file); } else { myDisabledHighlightingFiles.add(file); } }
private void addAllPointers(@NotNull Collection<VirtualFilePointerImpl> pointers) { List<FilePointerPartNode> out = new ArrayList<FilePointerPartNode>(); for (FilePointerPartNode root : myPointers.values()) { root.getPointersUnder(null, false, "", out); } for (FilePointerPartNode node : out) { pointers.add(node.leaf); } }
@Override public void setHighlightingEnabled(@NotNull PsiFile file, boolean value) { VirtualFile virtualFile = PsiUtilCore.getVirtualFile(file); if (value) { myDisabledHighlightingFiles.remove(virtualFile); } else { myDisabledHighlightingFiles.add(virtualFile); } }
static void importInjections( final Collection<BaseInjection> existingInjections, final Collection<BaseInjection> importingInjections, final Collection<BaseInjection> originalInjections, final Collection<BaseInjection> newInjections) { final MultiValuesMap<InjectionPlace, BaseInjection> placeMap = new MultiValuesMap<InjectionPlace, BaseInjection>(); for (BaseInjection exising : existingInjections) { for (InjectionPlace place : exising.getInjectionPlaces()) { placeMap.put(place, exising); } } main: for (BaseInjection other : importingInjections) { final List<BaseInjection> matchingInjections = ContainerUtil.concat( other.getInjectionPlaces(), new Function<InjectionPlace, Collection<? extends BaseInjection>>() { public Collection<? extends BaseInjection> fun(final InjectionPlace o) { final Collection<BaseInjection> collection = placeMap.get(o); return collection == null ? Collections.<BaseInjection>emptyList() : collection; } }); if (matchingInjections.isEmpty()) { newInjections.add(other); } else { BaseInjection existing = null; for (BaseInjection injection : matchingInjections) { if (injection.equals(other)) continue main; if (existing == null && injection.sameLanguageParameters(other)) { existing = injection; } } if (existing == null) continue main; // skip!! language changed final BaseInjection newInjection = existing.copy(); newInjection.mergeOriginalPlacesFrom(other, true); if (!newInjection.equals(existing)) { originalInjections.add(existing); newInjections.add(newInjection); } } } }
public void setImportHintsEnabled(@NotNull PsiFile file, boolean value) { VirtualFile vFile = file.getVirtualFile(); if (value) { myDisabledHintsFiles.remove(vFile); stopProcess(true); } else { myDisabledHintsFiles.add(vFile); HintManager.getInstance().hideAllHints(); } }
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(); }
public static void loadDisabledPlugins( final String configPath, final Collection<String> disabledPlugins) { final File file = new File(configPath, DISABLED_PLUGINS_FILENAME); if (file.isFile()) { try { BufferedReader reader = new BufferedReader(new FileReader(file)); try { String id; while ((id = reader.readLine()) != null) { disabledPlugins.add(id.trim()); } } finally { reader.close(); } } catch (IOException ignored) { } } }
public void readExternal(Element parentNode) throws InvalidDataException { myDisabledHintsFiles.clear(); Element element = parentNode.getChild(DISABLE_HINTS_TAG); if (element != null) { for (Object o : element.getChildren(FILE_TAG)) { Element e = (Element) o; String url = e.getAttributeValue(URL_ATT); if (url != null) { VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url); if (file != null) { myDisabledHintsFiles.add(file); } } } } }
private static void addPatchedInfos( @NotNull HighlightInfo info, @NotNull PsiFile injectedPsi, @NotNull DocumentWindow documentWindow, @NotNull InjectedLanguageManager injectedLanguageManager, @Nullable TextRange fixedTextRange, @NotNull Collection<HighlightInfo> out) { ProperTextRange textRange = new ProperTextRange(info.startOffset, info.endOffset); List<TextRange> editables = injectedLanguageManager.intersectWithAllEditableFragments(injectedPsi, textRange); for (TextRange editable : editables) { TextRange hostRange = fixedTextRange == null ? documentWindow.injectedToHost(editable) : fixedTextRange; boolean isAfterEndOfLine = info.isAfterEndOfLine(); if (isAfterEndOfLine) { // convert injected afterEndOfLine to either host' afterEndOfLine or not-afterEndOfLine // highlight of the injected fragment boundary int hostEndOffset = hostRange.getEndOffset(); int lineNumber = documentWindow.getDelegate().getLineNumber(hostEndOffset); int hostLineEndOffset = documentWindow.getDelegate().getLineEndOffset(lineNumber); if (hostEndOffset < hostLineEndOffset) { // convert to non-afterEndOfLine isAfterEndOfLine = false; hostRange = new ProperTextRange(hostRange.getStartOffset(), hostEndOffset + 1); } } HighlightInfo patched = new HighlightInfo( info.forcedTextAttributes, info.forcedTextAttributesKey, info.type, hostRange.getStartOffset(), hostRange.getEndOffset(), info.getDescription(), info.getToolTip(), info.type.getSeverity(null), isAfterEndOfLine, null, false, 0, info.getProblemGroup(), info.getGutterIconRenderer()); patched.setHint(info.hasHint()); if (info.quickFixActionRanges != null) { for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) { TextRange quickfixTextRange = pair.getSecond(); List<TextRange> editableQF = injectedLanguageManager.intersectWithAllEditableFragments( injectedPsi, quickfixTextRange); for (TextRange editableRange : editableQF) { HighlightInfo.IntentionActionDescriptor descriptor = pair.getFirst(); if (patched.quickFixActionRanges == null) patched.quickFixActionRanges = new ArrayList<Pair<HighlightInfo.IntentionActionDescriptor, TextRange>>(); TextRange hostEditableRange = documentWindow.injectedToHost(editableRange); patched.quickFixActionRanges.add(Pair.create(descriptor, hostEditableRange)); } } } patched.setFromInjection(true); out.add(patched); } }
private boolean addInjectedPsiHighlights( @NotNull PsiFile injectedPsi, TextAttributes injectedAttributes, @NotNull Collection<HighlightInfo> outInfos, @NotNull ProgressIndicator progress, @NotNull InjectedLanguageManager injectedLanguageManager) { DocumentWindow documentWindow = (DocumentWindow) PsiDocumentManager.getInstance(myProject).getCachedDocument(injectedPsi); if (documentWindow == null) return true; Place places = InjectedLanguageUtil.getShreds(injectedPsi); for (PsiLanguageInjectionHost.Shred place : places) { PsiLanguageInjectionHost host = place.getHost(); if (host == null) continue; TextRange textRange = place.getRangeInsideHost().shiftRight(host.getTextRange().getStartOffset()); if (textRange.isEmpty()) continue; String desc = injectedPsi.getLanguage().getDisplayName() + ": " + injectedPsi.getText(); HighlightInfo.Builder builder = HighlightInfo.newHighlightInfo(HighlightInfoType.INJECTED_LANGUAGE_BACKGROUND) .range(textRange); if (injectedAttributes != null && InjectedLanguageUtil.isHighlightInjectionBackground(host)) { builder.textAttributes(injectedAttributes); } builder.unescapedToolTip(desc); HighlightInfo info = builder.createUnconditionally(); info.setFromInjection(true); outInfos.add(info); } HighlightInfoHolder holder = createInfoHolder(injectedPsi); runHighlightVisitorsForInjected(injectedPsi, holder, progress); for (int i = 0; i < holder.size(); i++) { HighlightInfo info = holder.get(i); final int startOffset = documentWindow.injectedToHost(info.startOffset); final TextRange fixedTextRange = getFixedTextRange(documentWindow, startOffset); addPatchedInfos( info, injectedPsi, documentWindow, injectedLanguageManager, fixedTextRange, outInfos); } int injectedStart = holder.size(); highlightInjectedSyntax(injectedPsi, holder); for (int i = injectedStart; i < holder.size(); i++) { HighlightInfo info = holder.get(i); final int startOffset = info.startOffset; final TextRange fixedTextRange = getFixedTextRange(documentWindow, startOffset); if (fixedTextRange == null) { info.setFromInjection(true); outInfos.add(info); } else { HighlightInfo patched = new HighlightInfo( info.forcedTextAttributes, info.forcedTextAttributesKey, info.type, fixedTextRange.getStartOffset(), fixedTextRange.getEndOffset(), info.getDescription(), info.getToolTip(), info.type.getSeverity(null), info.isAfterEndOfLine(), null, false, 0, info.getProblemGroup(), info.getGutterIconRenderer()); patched.setFromInjection(true); outInfos.add(patched); } } if (!isDumbMode()) { List<HighlightInfo> todos = new ArrayList<HighlightInfo>(); highlightTodos( injectedPsi, injectedPsi.getText(), 0, injectedPsi.getTextLength(), progress, myPriorityRange, todos, todos); for (HighlightInfo info : todos) { addPatchedInfos(info, injectedPsi, documentWindow, injectedLanguageManager, null, outInfos); } } advanceProgress(1); return true; }
@NotNull private Set<PsiFile> getInjectedPsiFiles( @NotNull final List<PsiElement> elements1, @NotNull final List<PsiElement> elements2, @NotNull final ProgressIndicator progress) { ApplicationManager.getApplication().assertReadAccessAllowed(); final Set<PsiFile> outInjected = new THashSet<PsiFile>(); List<DocumentWindow> injected = InjectedLanguageUtil.getCachedInjectedDocuments(myFile); final 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 || myRestrictRange.intersects(context.getTextRange()))) { hosts.add(context); } } InjectedLanguageManagerImpl injectedLanguageManager = InjectedLanguageManagerImpl.getInstanceImpl(myProject); Processor<PsiElement> collectInjectableProcessor = new CommonProcessors.CollectProcessor<PsiElement>(hosts); injectedLanguageManager.processInjectableElements(elements1, collectInjectableProcessor); injectedLanguageManager.processInjectableElements(elements2, collectInjectableProcessor); 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 (!JobLauncher.getInstance() .invokeConcurrentlyUnderProgress( new ArrayList<PsiElement>(hosts), progress, true, new Processor<PsiElement>() { @Override public boolean process(PsiElement element) { ApplicationManager.getApplication().assertReadAccessAllowed(); progress.checkCanceled(); InjectedLanguageUtil.enumerate(element, myFile, false, visitor); return true; } })) { throw new ProcessCanceledException(); } synchronized (outInjected) { return outInjected; } }
private void updateOutputItemsList( final String outputDir, final VirtualFile srcFile, VirtualFile sourceRoot, final String packagePrefix, final List<File> filesToRefresh, Map<String, Collection<TranslatingCompiler.OutputItem>> results, final GlobalSearchScope srcRootScope) throws CacheCorruptedException { CompositeDependencyCache dependencyCache = myCompileContext.getDependencyCache(); JavaDependencyCache child = dependencyCache.findChild(JavaDependencyCache.class); final Cache newCache = child.getNewClassesCache(); final Set<CompiledClass> paths = myFileNameToSourceMap.get(srcFile.getName()); if (paths == null || paths.isEmpty()) { return; } final String filePath = "/" + calcPackagePath(srcFile, sourceRoot, packagePrefix); for (final CompiledClass cc : paths) { myCompileContext.getProgressIndicator().checkCanceled(); if (LOG.isDebugEnabled()) { LOG.debug("Checking [pathToClass; relPathToSource] = " + cc); } boolean pathsEquals = FileUtil.pathsEqual(filePath, cc.relativePathToSource); if (!pathsEquals) { final String qName = child.resolve(cc.qName); if (qName != null) { pathsEquals = ApplicationManager.getApplication() .runReadAction( new Computable<Boolean>() { public Boolean compute() { final JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject); PsiClass psiClass = facade.findClass(qName, srcRootScope); if (psiClass == null) { final int dollarIndex = qName.indexOf("$"); if (dollarIndex >= 0) { final String topLevelClassName = qName.substring(0, dollarIndex); psiClass = facade.findClass(topLevelClassName, srcRootScope); } } if (psiClass != null) { final VirtualFile vFile = psiClass.getContainingFile().getVirtualFile(); return vFile != null && vFile.equals(srcFile); } return false; } }); } } if (pathsEquals) { final String outputPath = cc.pathToClass.replace(File.separatorChar, '/'); final Pair<String, String> realLocation = moveToRealLocation(outputDir, outputPath, srcFile, filesToRefresh); if (realLocation != null) { Collection<TranslatingCompiler.OutputItem> outputs = results.get(realLocation.getFirst()); if (outputs == null) { outputs = new ArrayList<TranslatingCompiler.OutputItem>(); results.put(realLocation.getFirst(), outputs); } outputs.add(new OutputItemImpl(realLocation.getSecond(), srcFile)); if (PACKAGE_ANNOTATION_FILE_NAME.equals(srcFile.getName())) { myProcessedPackageInfos.add(srcFile); } if (CompilerManager.MAKE_ENABLED) { newCache.setPath(cc.qName, realLocation.getSecond()); } if (LOG.isDebugEnabled()) { LOG.debug( "Added output item: [outputDir; outputPath; sourceFile] = [" + realLocation.getFirst() + "; " + realLocation.getSecond() + "; " + srcFile.getPresentableUrl() + "]"); } } else { myCompileContext.addMessage( CompilerMessageCategory.ERROR, "Failed to copy from temporary location to output directory: " + outputPath + " (see idea.log for details)", null, -1, -1); if (LOG.isDebugEnabled()) { LOG.debug("Failed to move to real location: " + outputPath + "; from " + outputDir); } } } } }