diff options
Diffstat (limited to 'platform/lang-impl/src/com/intellij/find/findUsages')
8 files changed, 83 insertions, 65 deletions
diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/AbstractFindUsagesDialog.java b/platform/lang-impl/src/com/intellij/find/findUsages/AbstractFindUsagesDialog.java index d1bae2c48f57..ee76d0ee4cc2 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/AbstractFindUsagesDialog.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/AbstractFindUsagesDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -143,6 +143,7 @@ public abstract class AbstractFindUsagesDialog extends DialogWrapper { return panel; } + @NotNull public final FindUsagesOptions calcFindUsagesOptions() { calcFindUsagesOptions(myFindUsagesOptions); return myFindUsagesOptions; diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java b/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java index a38dcced6135..fe47fb8558a6 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,14 +42,14 @@ public class CommonFindUsagesDialog extends AbstractFindUsagesDialog { boolean toShowInNewTab, boolean mustOpenInNewTab, boolean isSingleFile, - FindUsagesHandler handler) { + @NotNull FindUsagesHandler handler) { super(project, findUsagesOptions, toShowInNewTab, mustOpenInNewTab, isSingleFile, isTextSearch(element, isSingleFile, handler), !isSingleFile && !element.getManager().isInProject(element)); myPsiElement = element; init(); } - private static boolean isTextSearch(PsiElement element, boolean isSingleFile, FindUsagesHandler handler) { + private static boolean isTextSearch(@NotNull PsiElement element, boolean isSingleFile, @NotNull FindUsagesHandler handler) { return FindUsagesUtil.isSearchForTextOccurrencesAvailable(element, isSingleFile, handler); } diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java index 5152fa8f863b..a9291cf612ba 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,8 +47,10 @@ import java.util.Collections; */ public abstract class FindUsagesHandler { // return this handler if you want to cancel the search + @NotNull public static final FindUsagesHandler NULL_HANDLER = new FindUsagesHandler(PsiUtilCore.NULL_PSI_ELEMENT){}; + @NotNull private final PsiElement myPsiElement; protected FindUsagesHandler(@NotNull PsiElement psiElement) { @@ -81,7 +83,8 @@ public abstract class FindUsagesHandler { return PsiElement.EMPTY_ARRAY; } - public static FindUsagesOptions createFindUsagesOptions(final Project project, @Nullable final DataContext dataContext) { + @NotNull + public static FindUsagesOptions createFindUsagesOptions(@NotNull Project project, @Nullable final DataContext dataContext) { FindUsagesOptions findUsagesOptions = new FindUsagesOptions(project, dataContext); findUsagesOptions.isUsages = true; findUsagesOptions.isSearchForTextOccurrences = true; @@ -92,6 +95,7 @@ public abstract class FindUsagesHandler { public FindUsagesOptions getFindUsagesOptions() { return getFindUsagesOptions(null); } + @NotNull public FindUsagesOptions getFindUsagesOptions(@Nullable final DataContext dataContext) { FindUsagesOptions options = createFindUsagesOptions(getProject(), dataContext); @@ -185,7 +189,7 @@ public abstract class FindUsagesHandler { } @Nullable - protected Collection<String> getStringsToSearch(final PsiElement element) { + protected Collection<String> getStringsToSearch(@NotNull final PsiElement element) { if (element instanceof PsiNamedElement) { return ApplicationManager.getApplication().runReadAction(new Computable<Collection<String>>() { @Override @@ -202,6 +206,7 @@ public abstract class FindUsagesHandler { return false; } + @NotNull public Collection<PsiReference> findReferencesToHighlight(@NotNull PsiElement target, @NotNull SearchScope searchScope) { return ReferencesSearch.search(target, searchScope, false).findAll(); } diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java index 6fe9d9799cba..d3978780e535 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java @@ -91,8 +91,7 @@ public class FindUsagesManager implements JDOMExternalizable { private final com.intellij.usages.UsageViewManager myAnotherManager; private boolean myToOpenInNewTab = true; - - private PsiElement2UsageTargetComposite myLastSearchInFileData; + private PsiElement2UsageTargetComposite myLastSearchInFileData; // EDT only private final UsageHistory myHistory = new UsageHistory(); public FindUsagesManager(@NotNull Project project, @NotNull com.intellij.usages.UsageViewManager anotherManager) { @@ -118,6 +117,7 @@ public class FindUsagesManager implements JDOMExternalizable { } public void clearFindingNextUsageInFile() { + ApplicationManager.getApplication().assertIsDispatchThread(); myLastSearchInFileData = null; } @@ -140,6 +140,8 @@ public class FindUsagesManager implements JDOMExternalizable { } private boolean findUsageInFile(@NotNull FileEditor editor, @NotNull FileSearchScope direction) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (myLastSearchInFileData == null) return false; PsiElement[] primaryElements = myLastSearchInFileData.getPrimaryElements(); PsiElement[] secondaryElements = myLastSearchInFileData.getSecondaryElements(); @@ -164,7 +166,11 @@ public class FindUsagesManager implements JDOMExternalizable { } - private void initLastSearchElement(@NotNull FindUsagesOptions findUsagesOptions, @NotNull PsiElement[] primaryElements,@NotNull PsiElement[] secondaryElements) { + private void initLastSearchElement(@NotNull FindUsagesOptions findUsagesOptions, + @NotNull PsiElement[] primaryElements, + @NotNull PsiElement[] secondaryElements) { + ApplicationManager.getApplication().assertIsDispatchThread(); + myLastSearchInFileData = new PsiElement2UsageTargetComposite(primaryElements, secondaryElements, findUsagesOptions); } @@ -199,8 +205,8 @@ public class FindUsagesManager implements JDOMExternalizable { return null; } - public void findUsages(@NotNull PsiElement psiElement, final PsiFile scopeFile, final FileEditor editor, boolean showDialog) { - FindUsagesHandler handler = getNewFindUsagesHandler(psiElement, false); + public void findUsages(@NotNull PsiElement psiElement, final PsiFile scopeFile, final FileEditor editor, boolean showDialog, @Nullable("null means default (stored in options)") SearchScope searchScope) { + FindUsagesHandler handler = getFindUsagesHandler(psiElement, false); if (handler == null) return; boolean singleFile = scopeFile != null; @@ -216,8 +222,8 @@ public class FindUsagesManager implements JDOMExternalizable { setOpenInNewTab(dialog.isShowInSeparateWindow()); FindUsagesOptions findUsagesOptions = dialog.calcFindUsagesOptions(); - if (!showDialog) { - findUsagesOptions.searchScope = GlobalSearchScope.projectScope(myProject); + if (searchScope != null) { + findUsagesOptions.searchScope = searchScope; } clearFindingNextUsageInFile(); @@ -229,15 +235,15 @@ public class FindUsagesManager implements JDOMExternalizable { @NotNull FindUsagesOptions findUsagesOptions, PsiFile scopeFile, FileEditor editor) { - FindUsagesHandler handler = getNewFindUsagesHandler(psiElement, false); + FindUsagesHandler handler = getFindUsagesHandler(psiElement, false); if (handler == null) return; startFindUsages(findUsagesOptions, handler, scopeFile, editor); } - void startFindUsages(@NotNull FindUsagesOptions findUsagesOptions, - @NotNull FindUsagesHandler handler, - PsiFile scopeFile, - FileEditor editor) { + private void startFindUsages(@NotNull FindUsagesOptions findUsagesOptions, + @NotNull FindUsagesHandler handler, + PsiFile scopeFile, + FileEditor editor) { boolean singleFile = scopeFile != null; clearFindingNextUsageInFile(); @@ -247,9 +253,8 @@ public class FindUsagesManager implements JDOMExternalizable { PsiElement[] secondaryElements = handler.getSecondaryElements(); checkNotNull(secondaryElements, handler, "getSecondaryElements()"); if (singleFile) { - findUsagesOptions = findUsagesOptions.clone(); editor.putUserData(KEY_START_USAGE_AGAIN, null); - findUsagesInEditor(primaryElements, secondaryElements, handler, scopeFile, FileSearchScope.FROM_START, findUsagesOptions, editor); + findUsagesInEditor(primaryElements, secondaryElements, handler, scopeFile, FileSearchScope.FROM_START, findUsagesOptions.clone(), editor); } else { boolean skipResultsWithOneUsage = FindSettings.getInstance().isSkipResultsWithOneUsage(); @@ -257,7 +262,7 @@ public class FindUsagesManager implements JDOMExternalizable { } } - public void showSettingsAndFindUsages(@NotNull NavigationItem[] targets) { + public static void showSettingsAndFindUsages(@NotNull NavigationItem[] targets) { if (targets.length == 0) return; NavigationItem target = targets[0]; if (!(target instanceof ConfigurableUsageTarget)) return; @@ -276,16 +281,13 @@ public class FindUsagesManager implements JDOMExternalizable { @NotNull - public static ProgressIndicator startProcessUsages(@NotNull FindUsagesHandler handler, + public static ProgressIndicator startProcessUsages(@NotNull final FindUsagesHandler handler, @NotNull final PsiElement[] primaryElements, @NotNull final PsiElement[] secondaryElements, @NotNull final Processor<Usage> processor, - @NotNull FindUsagesOptions findUsagesOptions, + @NotNull final FindUsagesOptions findUsagesOptions, @NotNull final Runnable onComplete) { - final UsageSearcher usageSearcher = createUsageSearcher(primaryElements, secondaryElements, handler, findUsagesOptions, null); - final ProgressIndicatorBase indicator = new ProgressIndicatorBase(); - dropResolveCacheRegularly(indicator, handler.getProject()); ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { @Override public void run() { @@ -293,6 +295,7 @@ public class FindUsagesManager implements JDOMExternalizable { ProgressManager.getInstance().runProcess(new Runnable() { @Override public void run() { + final UsageSearcher usageSearcher = createUsageSearcher(primaryElements, secondaryElements, handler, findUsagesOptions, null); usageSearcher.generate(processor); } }, indicator); @@ -339,6 +342,14 @@ public class FindUsagesManager implements JDOMExternalizable { return new UsageSearcher() { @Override public void generate(@NotNull final Processor<Usage> processor) { + Project project = ApplicationManager.getApplication().runReadAction(new Computable<Project>() { + @Override + public Project compute() { + return scopeFile != null ? scopeFile.getProject() : primaryElements[0].getProject(); + } + }); + dropResolveCacheRegularly(ProgressManager.getInstance().getProgressIndicator(), project); + if (scopeFile != null) { optionsClone.searchScope = new LocalSearchScope(scopeFile); } @@ -357,7 +368,10 @@ public class FindUsagesManager implements JDOMExternalizable { final Iterable<PsiElement> elements = ContainerUtil.concat(primaryElements, secondaryElements); optionsClone.fastTrack = new SearchRequestCollector(new SearchSession()); - + if (optionsClone.searchScope instanceof GlobalSearchScope) { + // we will search in project scope always but warn if some usage is out of scope + optionsClone.searchScope = optionsClone.searchScope.union(GlobalSearchScope.projectScope(project)); + } try { for (final PsiElement element : elements) { ApplicationManager.getApplication().runReadAction(new Runnable() { @@ -380,12 +394,6 @@ public class FindUsagesManager implements JDOMExternalizable { } } - Project project = ApplicationManager.getApplication().runReadAction(new Computable<Project>() { - @Override - public Project compute() { - return scopeFile != null ? scopeFile.getProject() : primaryElements[0].getProject(); - } - }); PsiSearchHelper.SERVICE.getInstance(project) .processRequests(optionsClone.fastTrack, new Processor<PsiReference>() { @Override @@ -426,24 +434,21 @@ public class FindUsagesManager implements JDOMExternalizable { @NotNull final FindUsagesHandler handler, @NotNull final FindUsagesOptions findUsagesOptions, final boolean toSkipUsagePanelWhenOneUsage) { - if (primaryElements.length == 0) { throw new AssertionError(handler + " " + findUsagesOptions); } Iterable<PsiElement> allElements = ContainerUtil.concat(primaryElements, secondaryElements); - final UsageTarget[] targets = convertToUsageTargets(allElements, findUsagesOptions); + final PsiElement2UsageTargetAdapter[] targets = convertToUsageTargets(allElements, findUsagesOptions); myAnotherManager.searchAndShowUsages(targets, new Factory<UsageSearcher>() { @Override public UsageSearcher create() { - dropResolveCacheRegularly(ProgressManager.getInstance().getProgressIndicator(), myProject); return createUsageSearcher(primaryElements, secondaryElements, handler, findUsagesOptions, null); } }, !toSkipUsagePanelWhenOneUsage, true, createPresentation(primaryElements[0], findUsagesOptions, shouldOpenInNewTab()), null); - myHistory.add((ConfigurableUsageTarget)targets[0]); - //addToHistory(allElements, findUsagesOptions); + myHistory.add(targets[0]); } - private static void dropResolveCacheRegularly(ProgressIndicator indicator, final Project project) { + private static void dropResolveCacheRegularly(ProgressIndicator indicator, @NotNull final Project project) { if (indicator instanceof ProgressIndicatorEx) { ((ProgressIndicatorEx)indicator).addStateDelegate(new ProgressIndicatorBase() { volatile long lastCleared = System.currentTimeMillis(); @@ -468,14 +473,12 @@ public class FindUsagesManager implements JDOMExternalizable { @NotNull FindUsagesOptions options, boolean toOpenInNewTab) { UsageViewPresentation presentation = new UsageViewPresentation(); - String scopeString = options.searchScope == null ? null : options.searchScope.getDisplayName(); + String scopeString = options.searchScope.getDisplayName(); presentation.setScopeText(scopeString); String usagesString = generateUsagesString(options); presentation.setUsagesString(usagesString); - String title = scopeString == null - ? FindBundle.message("find.usages.of.element.panel.title", usagesString, UsageViewUtil.getLongName(psiElement)) - : FindBundle.message("find.usages.of.element.in.scope.panel.title", usagesString, UsageViewUtil.getLongName(psiElement), - scopeString); + String title = FindBundle.message("find.usages.of.element.in.scope.panel.title", usagesString, UsageViewUtil.getLongName(psiElement), + scopeString); presentation.setTabText(title); presentation.setTabName(FindBundle.message("find.usages.of.element.tab.name", usagesString, UsageViewUtil.getShortName(psiElement))); presentation.setTargetsNodeText(StringUtil.capitalize(UsageViewUtil.getType(psiElement))); diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesOptions.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesOptions.java index 39727af430e1..38d3d161fc91 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesOptions.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesOptions.java @@ -21,7 +21,6 @@ import com.intellij.find.FindSettings; import com.intellij.ide.util.scopeChooser.ScopeChooserCombo; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.psi.search.ProjectScope; import com.intellij.psi.search.SearchRequestCollector; import com.intellij.psi.search.SearchScope; @@ -31,7 +30,8 @@ import org.jetbrains.annotations.Nullable; import java.util.List; -public class FindUsagesOptions extends UserDataHolderBase implements Cloneable { +public class FindUsagesOptions implements Cloneable { + @NotNull public SearchScope searchScope; public boolean isSearchForTextOccurrences = true; @@ -46,15 +46,17 @@ public class FindUsagesOptions extends UserDataHolderBase implements Cloneable { public FindUsagesOptions(@NotNull Project project, @Nullable final DataContext dataContext) { String defaultScopeName = FindSettings.getInstance().getDefaultScopeName(); List<SearchScope> predefined = ScopeChooserCombo.getPredefinedScopes(project, dataContext, true, false, false, false); + SearchScope resultScope = null; for (SearchScope scope : predefined) { if (scope.getDisplayName().equals(defaultScopeName)) { - searchScope = scope; + resultScope = scope; break; } } - if (searchScope == null) { - searchScope = ProjectScope.getProjectScope(project); + if (resultScope == null) { + resultScope = ProjectScope.getProjectScope(project); } + searchScope = resultScope; } public FindUsagesOptions(@NotNull SearchScope searchScope) { @@ -63,9 +65,15 @@ public class FindUsagesOptions extends UserDataHolderBase implements Cloneable { @Override public FindUsagesOptions clone() { - return (FindUsagesOptions)super.clone(); + try { + return (FindUsagesOptions)super.clone(); + } + catch (CloneNotSupportedException e) { + throw new RuntimeException(e); + } } + @Override public boolean equals(final Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; @@ -74,13 +82,12 @@ public class FindUsagesOptions extends UserDataHolderBase implements Cloneable { if (isSearchForTextOccurrences != that.isSearchForTextOccurrences) return false; if (isUsages != that.isUsages) return false; - if (searchScope != null ? !searchScope.equals(that.searchScope) : that.searchScope != null) return false; - - return true; + return searchScope.equals(that.searchScope); } + @Override public int hashCode() { - int result = searchScope == null ? 0 : searchScope.hashCode(); + int result = searchScope.hashCode(); result = 31 * result + (isSearchForTextOccurrences ? 1 : 0); result = 31 * result + (isUsages ? 1 : 0); return result; diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesUtil.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesUtil.java index 02c98d83a82c..1521f72e0d61 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesUtil.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,13 @@ package com.intellij.find.findUsages; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class FindUsagesUtil { private FindUsagesUtil() { } - public static boolean isSearchForTextOccurrencesAvailable(@NotNull PsiElement element, boolean isSingleFile, FindUsagesHandler handler) { + public static boolean isSearchForTextOccurrencesAvailable(@NotNull PsiElement element, boolean isSingleFile, @Nullable FindUsagesHandler handler) { return !isSingleFile && handler != null && handler.isSearchForTextOccurencesAvailable(element, isSingleFile); } } diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetAdapter.java b/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetAdapter.java index e5119f26d088..5e4c59dfd572 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetAdapter.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetAdapter.java @@ -40,7 +40,6 @@ import com.intellij.psi.meta.PsiMetaData; import com.intellij.psi.meta.PsiMetaOwner; import com.intellij.psi.meta.PsiPresentableMetaData; import com.intellij.psi.search.LocalSearchScope; -import com.intellij.psi.search.ProjectScope; import com.intellij.psi.search.SearchScope; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.ui.ComputableIcon; @@ -116,6 +115,7 @@ public class PsiElement2UsageTargetAdapter return getElement(); } + @Override public String toString() { return getPresentableText(); } @@ -198,6 +198,9 @@ public class PsiElement2UsageTargetAdapter sink.put(UsageView.USAGE_INFO_KEY, new UsageInfo(element)); } } + else if (key == UsageView.USAGE_SCOPE) { + sink.put(UsageView.USAGE_SCOPE, myOptions.searchScope); + } } @Override @@ -209,24 +212,22 @@ public class PsiElement2UsageTargetAdapter @Override public String getLongDescriptiveName() { SearchScope searchScope = myOptions.searchScope; - String scopeString = searchScope == null ? null : searchScope.getDisplayName(); + String scopeString = searchScope.getDisplayName(); PsiElement psiElement = getElement(); return psiElement == null ? UsageViewBundle.message("node.invalid") : FindBundle.message("recent.find.usages.action.popup", StringUtil.capitalize(UsageViewUtil.getType(psiElement)), DescriptiveNameUtil.getDescriptiveName(psiElement), - scopeString == null - ? ProjectScope.getAllScope(psiElement.getProject()).getDisplayName() - : scopeString + scopeString ); } @Override public void showSettings() { - FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(myPointer.getProject())).getFindUsagesManager(); PsiElement element = getElement(); if (element != null) { - findUsagesManager.findUsages(element, null, null, true); + FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(myPointer.getProject())).getFindUsagesManager(); + findUsagesManager.findUsages(element, null, null, true, null); } } diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetComposite.java b/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetComposite.java index a16050a08b07..a44208095e02 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetComposite.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetComposite.java @@ -43,7 +43,7 @@ public class PsiElement2UsageTargetComposite extends PsiElement2UsageTargetAdapt PsiElement element = getElement(); if (element == null) return; FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(element.getProject())).getFindUsagesManager(); - FindUsagesHandler handler = findUsagesManager.getNewFindUsagesHandler(element, false); + FindUsagesHandler handler = findUsagesManager.getFindUsagesHandler(element, false); boolean skipResultsWithOneUsage = FindSettings.getInstance().isSkipResultsWithOneUsage(); findUsagesManager.findUsages(myDescriptor.getPrimaryElements(), myDescriptor.getAdditionalElements(), handler, myOptions, skipResultsWithOneUsage); } |