Should useScope include a declaration?

Answered

What scope should I return from getUseScope for a function parameter in my custom language plugin? Should it be a whole function or just a function body? Javadoc says: Returns the scope in which references to this element are searched but I'm not sure.
Context:
I have LocalSearchScope(myFunctionBodyPsiElement) as the return value and renaming and other features worked fine until I implemented inplace renaming which doesn't work and fails with a negative offset at com.intellij.codeInsight.template.TemplateBuilderImpl.initTemplate(TemplateBuilderImpl.java:212) . Returning LocalSearchScope(myFunctionPsiElement) works BTW.
Should useScope include the declaration too?

0
4 comments

I'd suggest whole function as parameters in some languages can be used in function signature (default values)

Anna

0

It's not my case. I have a simple function with a single parameter (without any default value) and the parameter is used only inside the function body.

0

I'll provide some details below.

NOTE: I use 2020.3 version but the code is the same in the latest IDEA version.

The code:

function identity(value) {
    return value
}

The stack trace:

java.lang.Throwable: file: JavaScript file container: RangeMarker(25,45) 448 markers: [[value]18, 23], [[value]38, 43]
    at com.intellij.openapi.diagnostic.Logger.error(Logger.java:159)
    at com.intellij.codeInsight.template.TemplateBuilderImpl.initTemplate(TemplateBuilderImpl.java:212)
    at com.intellij.codeInsight.template.TemplateBuilderImpl.buildTemplate(TemplateBuilderImpl.java:202)
    at com.intellij.codeInsight.template.TemplateBuilderImpl.buildInlineTemplate(TemplateBuilderImpl.java:179)
    at com.intellij.refactoring.rename.inplace.InplaceRefactoring.startTemplate(InplaceRefactoring.java:403)
    at com.intellij.refactoring.rename.inplace.InplaceRefactoring.lambda$buildTemplateAndStart$0(InplaceRefactoring.java:359)
    at com.intellij.openapi.command.WriteCommandAction$BuilderImpl$1.run(WriteCommandAction.java:112)
    at com.intellij.openapi.application.RunResult.run(RunResult.java:35)
    at com.intellij.openapi.command.WriteCommandAction.lambda$performWriteCommandAction$1(WriteCommandAction.java:253)
    at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:1000)
    at com.intellij.openapi.command.WriteCommandAction.lambda$performWriteCommandAction$2(WriteCommandAction.java:252)
    at com.intellij.openapi.command.WriteCommandAction.lambda$doExecuteCommand$4(WriteCommandAction.java:310)
    at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:220)
    at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:187)
    at com.intellij.openapi.command.WriteCommandAction.doExecuteCommand(WriteCommandAction.java:312)
    at com.intellij.openapi.command.WriteCommandAction.performWriteCommandAction(WriteCommandAction.java:251)
    at com.intellij.openapi.command.WriteCommandAction.execute(WriteCommandAction.java:232)
    at com.intellij.openapi.command.WriteCommandAction$BuilderImpl.run(WriteCommandAction.java:114)
    at com.intellij.refactoring.rename.inplace.InplaceRefactoring.buildTemplateAndStart(InplaceRefactoring.java:359)
    at com.intellij.refactoring.rename.inplace.VariableInplaceRenamer.buildTemplateAndStart(VariableInplaceRenamer.java:115)
    at com.intellij.refactoring.rename.inplace.InplaceRefactoring.performInplaceRefactoring(InplaceRefactoring.java:210)
    at com.intellij.refactoring.rename.inplace.VariableInplaceRenamer.performInplaceRename(VariableInplaceRenamer.java:90)
    at com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler.doRename(VariableInplaceRenameHandler.java:120)
    at com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler.invoke(VariableInplaceRenameHandler.java:77)
    at com.intellij.refactoring.actions.BaseRefactoringAction.performRefactoringAction(BaseRefactoringAction.java:156)
    at com.intellij.refactoring.rename.RenameHandler2Renamer.performRename(RenameHandler2Renamer.java:36)
    at com.intellij.refactoring.actions.RenameElementAction.actionPerformed(RenameElementAction.java:67)
    at com.intellij.openapi.actionSystem.ex.ActionUtil.performActionDumbAware(ActionUtil.java:281)
    at com.intellij.openapi.actionSystem.impl.ActionMenuItem$ActionTransmitter.lambda$actionPerformed$0(ActionMenuItem.java:310)
    at com.intellij.openapi.wm.impl.FocusManagerImpl.runOnOwnContext(FocusManagerImpl.java:286)
    at com.intellij.openapi.wm.impl.IdeFocusManagerImpl.runOnOwnContext(IdeFocusManagerImpl.java:77)
    at com.intellij.openapi.actionSystem.impl.ActionMenuItem$ActionTransmitter.actionPerformed(ActionMenuItem.java:299)
    at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
    at com.intellij.openapi.actionSystem.impl.ActionMenuItem.lambda$fireActionPerformed$0(ActionMenuItem.java:110)
    at com.intellij.openapi.application.TransactionGuardImpl.performUserActivity(TransactionGuardImpl.java:95)
    at com.intellij.openapi.actionSystem.impl.ActionMenuItem.fireActionPerformed(ActionMenuItem.java:110)
    at com.intellij.ui.plaf.beg.BegMenuItemUI.doClick(BegMenuItemUI.java:514)
    at com.intellij.ui.plaf.beg.BegMenuItemUI$MyMouseInputHandler.mouseReleased(BegMenuItemUI.java:544)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6652)
    at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3345)
    at java.desktop/java.awt.Component.processEvent(Component.java:6417)
    at java.desktop/java.awt.Container.processEvent(Container.java:2263)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5027)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4859)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4859)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:778)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:727)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:751)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:749)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:748)
    at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:976)
    at com.intellij.ide.IdeEventQueue.dispatchMouseEvent(IdeEventQueue.java:911)
    at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:840)
    at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$8(IdeEventQueue.java:454)
    at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:773)
    at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$9(IdeEventQueue.java:453)
    at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:822)
    at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:507)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

RangeMarker(25, 45) represents the function body other markers are the parameter and it's usage in the function body. The function body element was obtained via 'InplaceRefactoring#checkLocalScope' method that looks like:


protected PsiElement checkLocalScope() {
    final SearchScope searchScope = PsiSearchHelper.getInstance(myElementToRename.getProject()).getUseScope(myElementToRename);
    if (searchScope instanceof LocalSearchScope) {
      final PsiElement[] elements = getElements((LocalSearchScope)searchScope);
      return PsiTreeUtil.findCommonParent(elements);
    }

    return null;
  }

So for LocalSearchScope with single element it just returns this element.

In other words inplace renaming of 'value' parameter fails becuase it's declaration (in parameters) is out of scope of the function body that was returned as useScope of that parameter.

I see 3 reasons of such behavior:

- The statement 'Returns the scope in which references to this element are searched.' in javadoc of 'PsiElement#getUseScope' method is missleading and should include declaration as well.

- Method 'InplaceRefactoring#checkLocalScope' doesn't work right and should take declaration into account.

- I just use InplaceRefactoring wrong and should customize it. Maybe `VariableInplaceRenamer` shouldn't be used at all in my case.

 

0

I'd say that probably `InplaceRefactoring` should have explicitly added declaration itself to the scope. But given that for all "non-local declarations" the scope already contains declaration, I'd avoid changes in the platform and return slightly bigger scope in your case.

0

Please sign in to leave a comment.