private void doTest(final String selection, String additionalPath) throws Exception { final String mainFxml = getTestName(true) + ".fxml"; if (additionalPath != null) { myFixture.configureByFiles(mainFxml, additionalPath); complete(); } else { configureByFile(mainFxml); } assertTrue(myItems.length > 0); LookupElement selectionElement = null; for (LookupElement item : myItems) { if (item.getLookupString().equals(selection)) { selectionElement = item; break; } } if (selection != null && selectionElement == null) { fail(selection + " is not suggested"); } if (selectionElement == null) { selectionElement = myItems[0]; } selectItem(selectionElement); checkResultByFile(getTestName(true) + "_after.fxml"); }
@Nullable Map<LookupElement, PrefixMatcher> retainMatchingItems( final String newPrefix, final LookupImpl lookup) { synchronized (lock) { LinkedHashMap<LookupElement, PrefixMatcher> map = new LinkedHashMap<LookupElement, PrefixMatcher>(); for (LookupElement item : myItems) { if (item.isValid()) { PrefixMatcher matcher = lookup.itemMatcher(item).cloneWithPrefix(newPrefix); if (matcher.prefixMatches(item)) { map.put(item, matcher); } } } if (map.size() != myItems.size()) { clearItems(); for (LookupElement newItem : map.keySet()) { addItem(newItem); } } return map; } }
private String getCaseCorrectedLookupString(LookupElement item) { String lookupString = item.getLookupString(); if (item.isCaseSensitive()) { return lookupString; } final String prefix = itemPattern(item); final int length = prefix.length(); if (length == 0 || !itemMatcher(item).prefixMatches(prefix)) return lookupString; boolean isAllLower = true; boolean isAllUpper = true; boolean sameCase = true; for (int i = 0; i < length && (isAllLower || isAllUpper || sameCase); i++) { final char c = prefix.charAt(i); boolean isLower = Character.isLowerCase(c); boolean isUpper = Character.isUpperCase(c); // do not take this kind of symbols into account ('_', '@', etc.) if (!isLower && !isUpper) continue; isAllLower = isAllLower && isLower; isAllUpper = isAllUpper && isUpper; sameCase = sameCase && isLower == Character.isLowerCase(lookupString.charAt(i)); } if (sameCase) return lookupString; if (isAllLower) return lookupString.toLowerCase(); if (isAllUpper) return StringUtil.toUpperCase(lookupString); return lookupString; }
private void assertCompletionContains( String completionText, PsiElement context, String[] expectedItems, String[] disallowedItems) { SmaliCodeFragmentFactory codeFragmentFactory = new SmaliCodeFragmentFactory(); JavaCodeFragment fragment = codeFragmentFactory.createCodeFragment( new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, completionText), context, getProject()); Editor editor = createEditor(fragment.getVirtualFile()); editor.getCaretModel().moveToOffset(completionText.length()); new CodeCompletionHandlerBase(CompletionType.BASIC).invokeCompletion(getProject(), editor); List<LookupElement> elements = LookupManager.getInstance(getProject()).getActiveLookup().getItems(); HashSet expectedSet = Sets.newHashSet(expectedItems); HashSet disallowedSet = Sets.newHashSet(disallowedItems); for (LookupElement element : elements) { expectedSet.remove(element.toString()); Assert.assertFalse(disallowedSet.contains(element.toString())); } Assert.assertTrue(expectedSet.size() == 0); }
@Nullable public static PsiReferenceExpression createMockReference( final PsiElement place, @NotNull PsiType qualifierType, LookupElement qualifierItem) { PsiElementFactory factory = JavaPsiFacade.getElementFactory(place.getProject()); if (qualifierItem.getObject() instanceof PsiClass) { final String qname = ((PsiClass) qualifierItem.getObject()).getQualifiedName(); if (qname == null) return null; final String text = qname + ".xxx"; try { final PsiExpression expr = factory.createExpressionFromText(text, place); if (expr instanceof PsiReferenceExpression) { return (PsiReferenceExpression) expr; } return null; // ignore ill-formed qualified names like "org.spark-project.jetty" that can't // be used from Java code anyway } catch (IncorrectOperationException e) { LOG.info(e); return null; } } return (PsiReferenceExpression) factory.createExpressionFromText( "xxx.xxx", JavaCompletionUtil.createContextWithXxxVariable(place, qualifierType)); }
public static void checkCompletionContains( JavaCodeInsightTestFixture fixture, String... expectedVariants) { LookupElement[] lookupElements = fixture.completeBasic(); Assert.assertNotNull(lookupElements); Set<String> missedVariants = CollectionFactory.hashSet(expectedVariants); for (LookupElement lookupElement : lookupElements) { String lookupString = lookupElement.getLookupString(); missedVariants.remove(lookupString); Object object = lookupElement.getObject(); if (object instanceof ResolveResult) { object = ((ResolveResult) object).getElement(); } if (object instanceof PsiMethod) { missedVariants.remove(lookupString + "()"); } else if (object instanceof PsiVariable) { missedVariants.remove('@' + lookupString); } else if (object instanceof NamedArgumentDescriptor) { missedVariants.remove(lookupString + ':'); } } if (missedVariants.size() > 0) { Assert.assertTrue("Some completion variants are missed " + missedVariants, false); } }
private boolean hideAutopopupIfMeaningless() { if (!myLookup.isLookupDisposed() && isAutopopupCompletion() && !myLookup.isSelectionTouched() && !myLookup.isCalculating()) { myLookup.refreshUi(true); final List<LookupElement> items = myLookup.getItems(); for (LookupElement item : items) { if (!myLookup.itemPattern(item).equals(item.getLookupString())) { return false; } if (item.isValid()) { final LookupElementPresentation presentation = new LookupElementPresentation(); item.renderElement(presentation); if (StringUtil.isNotEmpty(presentation.getTailText())) { return false; } } } myLookup.hideLookup(false); LOG.assertTrue(CompletionServiceImpl.getCompletionService().getCurrentCompletion() == null); CompletionServiceImpl.setCompletionPhase(new CompletionPhase.EmptyAutoPopup(this)); return true; } return false; }
static CharFilter.Result getLookupAction(final char charTyped, final LookupImpl lookup) { final CharFilter.Result filtersDecision = getFiltersDecision(charTyped, lookup); if (!Registry.is("ide.completion.allow.finishing.by.chars") && filtersDecision == CharFilter.Result.SELECT_ITEM_AND_FINISH_LOOKUP) { return CharFilter.Result.HIDE_LOOKUP; } final LookupElement currentItem = lookup.getCurrentItem(); if (currentItem != null && charTyped != ' ') { String postfix = lookup.getAdditionalPrefix() + charTyped; final PrefixMatcher matcher = lookup.itemMatcher(currentItem); for (String lookupString : currentItem.getAllLookupStrings()) { if (lookupString.startsWith(matcher.getPrefix() + postfix)) { return CharFilter.Result.ADD_TO_PREFIX; } } } if (filtersDecision != null) { return filtersDecision; } throw new AssertionError( "Typed char not handler by char filter: c=" + charTyped + "; prefix=" + currentItem + "; filters=" + Arrays.toString(getFilters())); }
@Nullable public static List<? extends PsiElement> getAllPsiElements(final LookupElement item) { List<PsiMethod> allMethods = getAllMethods(item); if (allMethods != null) return allMethods; if (item.getObject() instanceof PsiElement) return Collections.singletonList((PsiElement) item.getObject()); return null; }
private void markClassItemWrapped(@NotNull LookupElement classItem) { LookupElement delegate = classItem; while (true) { delegate.putUserData(WRAPPING_CONSTRUCTOR_CALL, this); if (!(delegate instanceof LookupElementDecorator)) break; delegate = ((LookupElementDecorator) delegate).getDelegate(); } }
public void testPointerSpecType() { myFixture.configureByText( "foo.go", "package main; type a struct{};" + "func main() {q1, q2:=&a{};q<caret>}"); myFixture.completeBasic(); LookupElement first = ArrayUtil.getFirstElement(myFixture.getLookupElements()); assertNotNull(first); LookupElementPresentation presentation = new LookupElementPresentation(); first.renderElement(presentation); assertEquals("*main.a", presentation.getTypeText()); }
@NotNull @Override public Comparable weigh(@NotNull LookupElement element) { final PsiTypeLookupItem lookupItem = element.as(PsiTypeLookupItem.CLASS_CONDITION_KEY); if (lookupItem != null) { return lookupItem.getBracketsCount() * 10 + (lookupItem.isAddArrayInitializer() ? 1 : 0); } if (element.as(CastingLookupElementDecorator.CLASS_CONDITION_KEY) != null) { return 239; } return 0; }
public static void emulateInsertion(LookupElement item, int offset, InsertionContext context) { setOffsets(context, offset, offset); final Editor editor = context.getEditor(); final Document document = editor.getDocument(); final String lookupString = item.getLookupString(); document.insertString(offset, lookupString); editor.getCaretModel().moveToOffset(context.getTailOffset()); PsiDocumentManager.getInstance(context.getProject()).commitDocument(document); item.handleInsert(context); }
@Override public AutoCompletionDecision handleAutoCompletionPossibility( @NotNull AutoCompletionContext context) { final CompletionParameters parameters = context.getParameters(); if (parameters.getCompletionType() != CompletionType.SMART && parameters.getCompletionType() != CompletionType.BASIC) { return null; } boolean needInsertBrace = false; boolean needInsertParenth = false; final LookupElement[] items = context.getItems(); if (items.length > 1) { String commonName = null; final ArrayList<PsiMethod> allMethods = new ArrayList<PsiMethod>(); for (LookupElement item : items) { Object o = item.getPsiElement(); if (item.getUserData(LookupItem.FORCE_SHOW_SIGNATURE_ATTR) != null || !(o instanceof PsiMethod)) { return AutoCompletionDecision.SHOW_LOOKUP; } final PsiMethod method = (PsiMethod) o; final JavaChainLookupElement chain = item.as(JavaChainLookupElement.CLASS_CONDITION_KEY); final String name = method.getName() + "#" + (chain == null ? "" : chain.getQualifier().getLookupString()); if (commonName != null && !commonName.equals(name)) { return AutoCompletionDecision.SHOW_LOOKUP; } if (hasOnlyClosureParams(method)) { needInsertBrace = true; } else { needInsertParenth = true; } if (needInsertBrace && needInsertParenth) { return AutoCompletionDecision.SHOW_LOOKUP; } commonName = name; allMethods.add(method); item.putUserData(JavaCompletionUtil.ALL_METHODS_ATTRIBUTE, allMethods); } return AutoCompletionDecision.insertItem( JavaMethodMergingContributor.findBestOverload(items)); } return super.handleAutoCompletionPossibility(context); }
public void testDimenUnitsCompletion1() throws Exception { final VirtualFile file = copyFileToProject(getTestName(true) + ".xml"); myFixture.configureFromExistingVirtualFile(file); myFixture.complete(CompletionType.BASIC); final List<String> lookupElementStrings = myFixture.getLookupElementStrings(); assertNotNull(lookupElementStrings); UsefulTestCase.assertSameElements( lookupElementStrings, "3dp", "3px", "3sp", "3pt", "3mm", "3in"); final PsiElement originalElement = myFixture.getFile().findElementAt(myFixture.getEditor().getCaretModel().getOffset()); assertNotNull(originalElement); final LookupEx lookup = myFixture.getLookup(); LookupElement dpElement = null; LookupElement pxElement = null; for (LookupElement element : lookup.getItems()) { if (element.getLookupString().endsWith("dp")) { dpElement = element; } else if (element.getLookupString().endsWith("px")) { pxElement = element; } } assertNotNull(dpElement); assertNotNull(pxElement); DocumentationProvider provider; PsiElement docTargetElement; lookup.setCurrentItem(dpElement); docTargetElement = DocumentationManager.getInstance(getProject()) .findTargetElement(myFixture.getEditor(), myFixture.getFile(), originalElement); assertNotNull(docTargetElement); provider = DocumentationManager.getProviderFromElement(docTargetElement); assertEquals( "<html><body><b>Density-independent Pixels</b> - an abstract unit that is based on the physical " + "density of the screen.</body></html>", provider.generateDoc(docTargetElement, originalElement)); lookup.setCurrentItem(pxElement); docTargetElement = DocumentationManager.getInstance(getProject()) .findTargetElement(myFixture.getEditor(), myFixture.getFile(), originalElement); assertNotNull(docTargetElement); provider = DocumentationManager.getProviderFromElement(docTargetElement); assertEquals( "<html><body><b>Pixels</b> - corresponds to actual pixels on the screen. Not recommended.</body></html>", provider.generateDoc(docTargetElement, originalElement)); }
private void addKeyword( Set<LookupElement> set, final TailType tailType, final Object comp, final PrefixMatcher matcher, final PsiFile file, final CompletionVariant variant) { for (final LookupElement item : set) { if (item.getObject().toString().equals(comp.toString())) { return; } } addLookupItem(set, tailType, comp, file, variant); }
public void testReadOnly() throws Exception { configureByFile(getTestName(true) + ".fxml"); assertTrue(myItems.length > 0); LookupElement selectionElement = null; for (LookupElement item : myItems) { if (item.getLookupString().equals("backgroundFills")) { selectionElement = item; break; } } if (selectionElement != null) { fail("Read only attribute was suggested"); } }
@Nullable public static PsiElement getTargetElement(LookupElement lookupElement) { PsiElement psiElement = lookupElement.getPsiElement(); if (psiElement != null) { return getOriginalElement(psiElement); } Object object = lookupElement.getObject(); if (object instanceof LookupValueWithPsiElement) { final PsiElement element = ((LookupValueWithPsiElement) object).getElement(); if (element != null) return getOriginalElement(element); } return null; }
@NotNull @Override public Comparable weigh(@NotNull LookupElement item) { return item.getObject() instanceof PsiClass && !myAcceptClasses ? ExpectedTypeMatching.normal : getExpectedTypeMatching(item, myExpectedTypes); }
@NotNull @Override public String getLookupString() { return maybeAddParentheses(myQualifier.getLookupString()) + "." + getDelegate().getLookupString(); }
public void addSparedChars( CompletionProgressIndicator indicator, LookupElement item, InsertionContext context, char completionChar) { String textInserted; if (context.getStartOffset() >= 0 && context.getTailOffset() >= context.getStartOffset()) { textInserted = context .getDocument() .getText() .substring(context.getStartOffset(), context.getTailOffset()); } else { textInserted = item.getLookupString(); } String withoutSpaces = StringUtil.replace( textInserted, new String[] {" ", "\t", "\n"}, new String[] {"", "", ""}); int spared = withoutSpaces.length() - indicator.getLookup().itemPattern(item).length(); if (!LookupEvent.isSpecialCompletionChar(completionChar) && withoutSpaces.contains(String.valueOf(completionChar))) { spared--; } if (spared > 0) { mySpared += spared; } }
@Nullable private Object getQualifierObject() { Object qObject = myQualifier.getObject(); if (qObject instanceof ResolveResult) { qObject = ((ResolveResult) qObject).getElement(); } return qObject; }
@Override public boolean isStartMatch(LookupElement element) { if (super.isStartMatch(element)) { return true; } if (element.isCaseSensitive()) { return false; } return ContainerUtil.or( element.getAllLookupStrings(), new Condition<String>() { @Override public boolean value(String s) { return myCaseInsensitiveMatcher.isStartMatch(s); } }); }
public void testOnlyCssAsStylesheets() throws Exception { myFixture.addFileToProject("my.fxml", ""); myFixture.addFileToProject("my.png", ""); myFixture.addFileToProject("sample.css", ".root{}"); configureByFile(getTestName(true) + ".fxml"); assertTrue(myItems.length == 1); LookupElement selectionElement = null; for (LookupElement item : myItems) { if (item.getLookupString().equals("sample.css")) { selectionElement = item; break; } } if (selectionElement == null) { fail("sample.css was not found"); } }
private static void suggestChainedCalls( CompletionParameters parameters, CompletionResultSet result, PsiElement position) { PsiElement parent = position.getParent(); if (!(parent instanceof PsiJavaCodeReferenceElement) || parent.getParent() instanceof PsiImportStatementBase) { return; } PsiElement qualifier = ((PsiJavaCodeReferenceElement) parent).getQualifier(); if (!(qualifier instanceof PsiJavaCodeReferenceElement) || ((PsiJavaCodeReferenceElement) qualifier).isQualified()) { return; } PsiElement target = ((PsiJavaCodeReferenceElement) qualifier).resolve(); if (target != null && !(target instanceof PsiPackage)) { return; } PsiFile file = position.getContainingFile(); if (file instanceof PsiJavaCodeReferenceCodeFragment) { return; } String fullPrefix = parent .getText() .substring(0, parameters.getOffset() - parent.getTextRange().getStartOffset()); CompletionResultSet qualifiedCollector = result.withPrefixMatcher(fullPrefix); ElementFilter filter = JavaCompletionContributor.getReferenceFilter(position); for (LookupElement base : suggestQualifierItems(parameters, (PsiJavaCodeReferenceElement) qualifier, filter)) { PsiType type = JavaCompletionUtil.getLookupElementType(base); if (type != null && !PsiType.VOID.equals(type)) { PsiReferenceExpression ref = ReferenceExpressionCompletionContributor.createMockReference(position, type, base); if (ref != null) { for (final LookupElement item : JavaSmartCompletionContributor.completeReference( position, ref, filter, true, true, parameters, result.getPrefixMatcher())) { qualifiedCollector.addElement( JavaCompletionUtil.highlightIfNeeded( null, new JavaChainLookupElement(base, item), item.getObject(), position)); } } } } }
@NotNull @Override public Comparable weigh(@NotNull LookupElement element) { final Object object = element.getObject(); if (object instanceof PsiField) return -2; if (object instanceof PsiMethod && PropertyUtil.isSimplePropertyGetter((PsiMethod) object)) return -1; return 0; }
@NotNull @Override public Comparable weigh(@NotNull LookupElement element) { if (element.getObject() instanceof PsiEnumConstant) return -2; if (!(myParameters.getOriginalFile() instanceof PsiJavaFile)) return -1; if (PsiKeyword.TRUE.equals(element.getLookupString()) || PsiKeyword.FALSE.equals(element.getLookupString())) { boolean inReturn = PsiTreeUtil.getParentOfType( myParameters.getPosition(), PsiReturnStatement.class, false, PsiMember.class) != null; return inReturn ? -2 : 0; } return -1; }
@NotNull @Override public Comparable weigh(@NotNull LookupElement element) { final Object object = element.getObject(); if (object instanceof PsiMethod) { PsiType type = ((PsiMethod) object).getReturnType(); final JavaMethodCallElement callItem = element.as(JavaMethodCallElement.CLASS_CONDITION_KEY); if (callItem != null) { type = callItem.getSubstitutor().substitute(type); } if (type instanceof PsiClassType && ((PsiClassType) type).resolve() instanceof PsiTypeParameter) return 1; } return 0; }
@Override public void renderElement(LookupElementPresentation presentation) { super.renderElement(presentation); final LookupElementPresentation qualifierPresentation = new LookupElementPresentation(); myQualifier.renderElement(qualifierPresentation); String name = maybeAddParentheses(qualifierPresentation.getItemText()); final String qualifierText = myQualifier.as(CastingLookupElementDecorator.CLASS_CONDITION_KEY) != null ? "(" + name + ")" : name; presentation.setItemText(qualifierText + "." + presentation.getItemText()); if (myQualifier instanceof LookupItem && getQualifierObject() instanceof PsiClass) { String locationString = JavaPsiClassReferenceElement.getLocationString((LookupItem) myQualifier); presentation.setTailText(StringUtil.notNullize(presentation.getTailText()) + locationString); } }
private static int getItemToSelect( LookupImpl lookup, List<LookupElement> items, boolean onExplicitAction, @Nullable LookupElement mostRelevant) { if (items.isEmpty() || lookup.getFocusDegree() == LookupImpl.FocusDegree.UNFOCUSED) { return 0; } if (lookup.isSelectionTouched() || !onExplicitAction) { final LookupElement lastSelection = lookup.getCurrentItem(); int old = ContainerUtil.indexOfIdentity(items, lastSelection); if (old >= 0) { return old; } Object selectedValue = ((LookupImpl) lookup).getList().getSelectedValue(); if (selectedValue instanceof EmptyLookupItem && ((EmptyLookupItem) selectedValue).isLoading()) { int index = ((LookupImpl) lookup).getList().getSelectedIndex(); if (index >= 0 && index < items.size()) { return index; } } for (int i = 0; i < items.size(); i++) { String invariant = PRESENTATION_INVARIANT.get(items.get(i)); if (invariant != null && invariant.equals(PRESENTATION_INVARIANT.get(lastSelection))) { return i; } } } String selectedText = lookup.getEditor().getSelectionModel().getSelectedText(); for (int i = 0; i < items.size(); i++) { LookupElement item = items.get(i); if (isPrefixItem(lookup, item, true) && !isLiveTemplate(item) || item.getLookupString().equals(selectedText)) { return i; } } return Math.max(0, ContainerUtil.indexOfIdentity(items, mostRelevant)); }