AnnotationHolderImpl.assertMyFile() very noisy when using languageInjector
One of my plugin's custom languages uses a MultiplePsiFilesPerDocumentFileViewProvider to allow custom language expressions inside of what are otherwise HTML files alongside custom tags/attributes defined by XSD. This has worked very well for several years, but recently I had an issue reported where code like the following:
<apex:outputPanel rendered="{!someExpression}">
...
</apex:outputPanel>
would yield an XSD validation error because rendered is of type xsd:boolean and the inner language expression, {!someExpression}, doesn't conform to its constraints.
I tried to resolve this using an inspection suppressor, but unfortunately that error doesn't seem to be coming from an inspection. Instead I added a languageInjector implementation which did resolve the issue. However, doing so did require me to accommodate for the language injection in a few places, e.g., using InjectedLanguageUtil.getTopLevelFile() to resolve the real containing file.
I think I have everything working well for the most part, but now I'm seeing quite a bit noise in idea.log in the form of:
2017-07-13 13:06:02,549 [50014328] ERROR - emon.impl.AnnotationHolderImpl - Annotation must be registered for an element inside 'FILE' which is in 'VirtualFileWindow in C:\dev\projects\myProject\src\pages\MyPage.page'.
Element passed: 'XmlToken:XML_COMMENT_CHARACTERS' is inside the 'HtmlFile:AddDiscount.page' which is in 'file://C:/dev/projects/myProject/src/pages/MyPage.page'
java.lang.Throwable
at com.intellij.openapi.diagnostic.Logger.error(Logger.java:132)
at com.intellij.codeInsight.daemon.impl.AnnotationHolderImpl.a(AnnotationHolderImpl.java:130)
at com.intellij.codeInsight.daemon.impl.AnnotationHolderImpl.createInfoAnnotation(AnnotationHolderImpl.java:112)
...
AnnotationHolderImpl.assertMyFile() is comparing the annotation session's file to the containing file for the element to be annotated. The former is coming back as a VirtualFileWindow so the two aren't matching. When I find usages of VirtualFileWindow, I see quite a few like the following (including many in InjectedLanguageUtil/ManagerImpl):
if (virtualFile instanceof VirtualFileWindow) {
virtualFile = ((VirtualFileWindow) virtualFile).getDelegate();
}
Should assertMyFile() be doing similar? Or should it resolve to the delegate even earlier for the file referenced in the session? Or is there something else my plugin should be doing to ensure that the real virtual file is the one that's used instead? I'm happy to make whatever changes are required to have this hang together properly, so if I've just missed something, please let me know.
Thanks in advance for any pointers!
Regards,
Scott
请先登录再写评论。
Unwrapping VirtualFileWindow is indeed done in places where one needs to determine the top-level file by an injected one, but assertMyFile isn't one of those places. Instead, your annotator should report errors for the same elements that are passed to it, this helps to avoid some highlighting blinking during editing, and this assertion about file mismatch.
Alternatively, you could still try to suppress XSD errors in a multi-root view provider by implementing com.intellij.codeInsight.daemon.impl.HighlightInfoFilter and analyzing the context of the given highlight info. Basic rule of thumb in this case is that if a highlight info is somewhere near the border of two languages, then it might be incorrect in such template file.
Thanks, Peter. That helps. I might investigate the latter and see if I can eliminate the need for injection in these attribute values since it would eliminate the potential ripple effect that I'm potentially just now beginning to see. Ideally I'd just leave it the way it's been for a couple of years and suppress that error, and it sounds like HighlightInfoFilter might give me just what I need there.
Much appreciated!