Closed tomblachut closed 4 years ago
@tomblachut I believe it must be fixed after implementing https://github.com/tomblachut/svelte-intellij/pull/146 with proper scopes.
This is actually unrelated to stores, I could clarify it more.
Any declaration used only in template will be marked as unused, e.g. imported functions. But if you e.g. console.log
them inside script tag, they will be marked as used.
@tomblachut I will take a look. Actually we definitely had the same problem in vue files but it works now without re-writing ES6UnusedImportsInspection
Ok. So now I can explain. There are two cases:
{name}
. In this case, we need to fix the search scope for such references
e.g. add something like
if (effectiveSearchScope is LocalSearchScope) {
effectiveSearchScope.scope.forEach {
if (it is JSEmbeddedContent) {
queryParameters.optimizer.searchWord(
identifier,
LocalSearchScope(it.containingFile),
UsageSearchContext.IN_CODE,
true,
element,
SubstituteReferenceProcessor(element, identifier)
)
}
}
}
{$name}
. In this case, the hack above doesn't work because ES6UnusedImportsHelper
compares the reference name and the actual name in
com.intellij.lang.typescript.imports.ES6UnusedImportsHelper#isReferenceCanBeResolvedToSpecifier
so for the second case, I believe the best solution is to fix parser and provide name
as the reference name instead of $name
(also after the change you can remove the code related to val usageText = "\$$identifier"
search).
Unfortunately the solution with re-writing ES6UnusedImportsInspection
won't work well because we use ES6UnusedImportsHelper
directly in import optimizer so even if the error is suppressed the optimizer still will remove the import.
Another solution would be re-write ES6UnusedImportsHelper
but the changes will be available only in WS 2020.3
:(
fix parser
seems complicated. But OTOH we could split $ and name tokens so they highlight separately, right? That would be huge.
I've went through JS parsing to some extent before and didn't find way to change it in an elegant way, but today I noticed JavaScriptParser#buildTokenElement
.
For each call to this.myJavaScriptParser.buildTokenElement(JSElementTypes.REFERENCE_EXPRESSION)
we could replace (marker.collapse
) this token with some lazy element with two tokens inside, right? Preferably JSCallLikeExpression
because $
is actually a call, i.e. it takes a type and returns an inner one
Will need to also change (highlighting) lexer, for GlobalSearchScope to work, right?
@tomblachut actually you can use a custom reference expression similar to VueJSFilterReferenceExpressionImpl
but with changed getReferenceName()
method.
oh nice
@anstarovoyt Your suggestion with custom SvelteJSReferenceExpression
works great, I just need to refine types evaluation. I'm gonna break my code into 2 PRs and redo #146 because as you've said weird reference search is no longer needed.
Bonus points for fixed rename refactoring and '$' not being treated as part of reference
@tomblachut sounds good!
There is a similar issue where imports used in use:action
only are marked as unused
@unlocomqx this is related to directives support, they're not references yet, so import mechanism can't find them
Import statement must not be marked as unused in following example
It happens because
ES6UnusedImportsHelper#isUnusedSpecifier
->ES6UnusedImportsHelper#getLocalReferencesQuery
createsLocalSearchScope
containing only script tag, it should becontainingFile
in case of Svelte.My first dumb idea is to copy whole
ES6UnusedImportsInspection
and change necessary lines, but this will be hard to maintain.@anstarovoyt I'd appreciate your input here, thanks.