public void testTypingDoesNotInterfereWithDuplicates() throws Exception { SliceTreeStructure treeStructure = configureTree("DupSlice"); SliceNode root = (SliceNode) treeStructure.getRootElement(); List<SliceNode> nodes = new ArrayList<SliceNode>(); expandNodesTo(root, nodes); for (int i = 0; i < nodes.size() - 1; i++) { SliceNode node = nodes.get(i); assertNull(node.getDuplicate()); } SliceNode last = nodes.get(nodes.size() - 1); assertNotNull(last.getDuplicate()); type(" xx"); PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); backspace(); backspace(); PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); nodes.clear(); expandNodesTo(root, nodes); for (int i = 0; i < nodes.size() - 1; i++) { SliceNode node = nodes.get(i); assertNull(node.getDuplicate()); } assertNotNull(last.getDuplicate()); }
@Nullable public static JetElement getOutermostDescendantElement( @Nullable PsiElement root, boolean first, final @NotNull Predicate<JetElement> predicate) { if (!(root instanceof JetElement)) return null; final List<JetElement> results = Lists.newArrayList(); ((JetElement) root) .accept( new JetVisitorVoid() { @Override public void visitJetElement(@NotNull JetElement element) { if (predicate.apply(element)) { //noinspection unchecked results.add(element); } else { element.acceptChildren(this); } } }); if (results.isEmpty()) return null; return first ? results.get(0) : results.get(results.size() - 1); }
/** a = S & a = T imply S = T */ private void eqEq(List<PsiType> eqBounds) { for (int i = 0; i < eqBounds.size(); i++) { PsiType sBound = eqBounds.get(i); for (int j = i + 1; j < eqBounds.size(); j++) { final PsiType tBound = eqBounds.get(j); addConstraint(new TypeEqualityConstraint(tBound, sBound)); } } }
private static void logStats(Collection<PsiFile> otherFiles, long start) { long time = System.currentTimeMillis() - start; final Multiset<String> stats = HashMultiset.create(); for (PsiFile file : otherFiles) { stats.add( StringUtil.notNullize(file.getViewProvider().getVirtualFile().getExtension()) .toLowerCase()); } List<String> extensions = ContainerUtil.newArrayList(stats.elementSet()); Collections.sort( extensions, new Comparator<String>() { @Override public int compare(String o1, String o2) { return stats.count(o2) - stats.count(o1); } }); String message = "Search in " + otherFiles.size() + " files with unknown types took " + time + "ms.\n" + "Mapping their extensions to an existing file type (e.g. Plain Text) might speed up the search.\n" + "Most frequent non-indexed file extensions: "; for (int i = 0; i < Math.min(10, extensions.size()); i++) { String extension = extensions.get(i); message += extension + "(" + stats.count(extension) + ") "; } LOG.info(message); }
@Nullable private PsiDirectory chooseDirectory(final Project project, final PsiFile file) { PsiDirectory preferredDirectory = myWritableDirectoryList.isEmpty() ? null : myWritableDirectoryList.get(0); final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); final VirtualFile virtualFile = file.getVirtualFile(); assert virtualFile != null; final Module moduleForFile = fileIndex.getModuleForFile(virtualFile); if (myWritableDirectoryList.size() > 1 && !ApplicationManager.getApplication().isUnitTestMode()) { if (moduleForFile != null) { for (PsiDirectory directory : myWritableDirectoryList) { if (fileIndex.getModuleForFile(directory.getVirtualFile()) == moduleForFile) { preferredDirectory = directory; break; } } } return DirectoryChooserUtil.chooseDirectory( myWritableDirectoryList.toArray(new PsiDirectory[myWritableDirectoryList.size()]), preferredDirectory, project, new HashMap<PsiDirectory, String>()); } return preferredDirectory; }
@Override public UsageView showUsages( UsageInfo[] usages, UsageViewPresentation presentation, UsageViewManager manager, PsiElement[] elements) { final List<PsiElement> overridingMethods = new ArrayList<>(); final List<UsageInfo> others = new ArrayList<>(); for (UsageInfo usage : usages) { if (usage instanceof SafeDeleteOverridingMethodUsageInfo) { overridingMethods.add(((SafeDeleteOverridingMethodUsageInfo) usage).getOverridingMethod()); } else { others.add(usage); } } UsageTarget[] targets = new UsageTarget[elements.length + overridingMethods.size()]; for (int i = 0; i < targets.length; i++) { if (i < elements.length) { targets[i] = new PsiElement2UsageTargetAdapter(elements[i]); } else { targets[i] = new PsiElement2UsageTargetAdapter(overridingMethods.get(i - elements.length)); } } return manager.showUsages( targets, UsageInfoToUsageConverter.convert(elements, others.toArray(new UsageInfo[others.size()])), presentation); }
@NotNull public List<String> createConversions(@NotNull PsiCallExpression expression) { PsiExpressionList argumentList = expression.getArgumentList(); PsiExpression[] arguments = argumentList != null ? argumentList.getExpressions() : new PsiExpression[] {}; List<String> conversions = new LinkedList<String>(); //noinspection UnusedDeclaration for (PsiExpression a : arguments) { conversions.add(""); } PsiMethod resolve = expression.resolveMethod(); if (resolve != null) { List<PsiType> expectedTypes = new LinkedList<PsiType>(); List<PsiType> actualTypes = new LinkedList<PsiType>(); for (PsiParameter p : resolve.getParameterList().getParameters()) expectedTypes.add(p.getType()); for (PsiExpression e : arguments) actualTypes.add(e.getType()); if (conversions.size() == actualTypes.size() && actualTypes.size() == expectedTypes.size()) { for (int i = 0; i < actualTypes.size(); i++) conversions.set(i, createConversionForExpression(arguments[i], expectedTypes.get(i))); } } return conversions; }
public void updateThrowsList(PsiClassType exceptionType) { if (!getSuperMethods().isEmpty()) { for (RefMethod refSuper : getSuperMethods()) { ((RefMethodImpl) refSuper).updateThrowsList(exceptionType); } } else if (myUnThrownExceptions != null) { if (exceptionType == null) { myUnThrownExceptions = null; return; } PsiClass exceptionClass = exceptionType.resolve(); JavaPsiFacade facade = JavaPsiFacade.getInstance(myManager.getProject()); for (int i = myUnThrownExceptions.size() - 1; i >= 0; i--) { String exceptionFqn = myUnThrownExceptions.get(i); PsiClass classType = facade.findClass( exceptionFqn, GlobalSearchScope.allScope(getRefManager().getProject())); if (InheritanceUtil.isInheritorOrSelf(exceptionClass, classType, true) || InheritanceUtil.isInheritorOrSelf(classType, exceptionClass, true)) { myUnThrownExceptions.remove(i); } } if (myUnThrownExceptions.isEmpty()) myUnThrownExceptions = null; } }
@NotNull public UsageInfo[] findUsages() { myRenamers.clear(); ArrayList<UsageInfo> result = new ArrayList<UsageInfo>(); List<PsiElement> elements = new ArrayList<PsiElement>(myAllRenames.keySet()); //noinspection ForLoopReplaceableByForEach for (int i = 0; i < elements.size(); i++) { PsiElement element = elements.get(i); final String newName = myAllRenames.get(element); final UsageInfo[] usages = RenameUtil.findUsages( element, newName, mySearchInComments, mySearchTextOccurrences, myAllRenames); final List<UsageInfo> usagesList = Arrays.asList(usages); result.addAll(usagesList); for (AutomaticRenamerFactory factory : myRenamerFactories) { if (factory.isApplicable(element)) { myRenamers.add(factory.createRenamer(element, newName, usagesList)); } } for (AutomaticRenamerFactory factory : Extensions.getExtensions(AutomaticRenamerFactory.EP_NAME)) { if (factory.getOptionName() == null && factory.isApplicable(element)) { myRenamers.add(factory.createRenamer(element, newName, usagesList)); } } } UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]); usageInfos = UsageViewUtil.removeDuplicatedUsages(usageInfos); return usageInfos; }
@Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } DocumentFoldingInfo info = (DocumentFoldingInfo) o; if (myFile != null ? !myFile.equals(info.myFile) : info.myFile != null) { return false; } if (!myProject.equals(info.myProject) || !myPsiElements.equals(info.myPsiElements) || !mySerializedElements.equals(info.mySerializedElements)) { return false; } if (myRangeMarkers.size() != info.myRangeMarkers.size()) return false; for (int i = 0; i < myRangeMarkers.size(); i++) { RangeMarker marker = myRangeMarkers.get(i); RangeMarker other = info.myRangeMarkers.get(i); if (marker == other || !marker.isValid() || !other.isValid()) { continue; } if (!TextRange.areSegmentsEqual(marker, other)) return false; FoldingInfo fi = marker.getUserData(FOLDING_INFO_KEY); FoldingInfo ofi = other.getUserData(FOLDING_INFO_KEY); if (!Comparing.equal(fi, ofi)) return false; } return true; }
private <T> boolean findListToRemoveFrom( @NotNull String name, @NotNull final List<T> elements, final Convertor<T, AbstractUrl> convertor) { Collection<TreeItem<Pair<AbstractUrl, String>>> list = getFavoritesListRootUrls(name); if (elements.size() > 1) { final List<T> sublist = elements.subList(0, elements.size() - 1); for (T obj : sublist) { AbstractUrl objUrl = convertor.convert(obj); final TreeItem<Pair<AbstractUrl, String>> item = findNextItem(objUrl, list); if (item == null || item.getChildren() == null) return false; list = item.getChildren(); } } TreeItem<Pair<AbstractUrl, String>> found = null; AbstractUrl url = convertor.convert(elements.get(elements.size() - 1)); if (url == null) return false; for (TreeItem<Pair<AbstractUrl, String>> pair : list) { if (url.equals(pair.getData().getFirst())) { found = pair; break; } } if (found != null) { list.remove(found); fireListeners.rootsChanged(name); return true; } return false; }
@Override public void visitListOrMap(GrListOrMap listOrMap) { if (listOrMap.isMap()) return; final TypeConstraint[] constraints = calculateTypeConstraints(listOrMap); List<PsiType> result = new ArrayList<PsiType>(constraints.length); for (TypeConstraint constraint : constraints) { if (constraint instanceof SubtypeConstraint) { final PsiType type = constraint.getType(); final PsiType iterable = com.intellij.psi.util.PsiUtil.extractIterableTypeParameter(type, true); if (iterable != null) { result.add(iterable); } } } if (result.size() == 0) { myResult = TypeConstraint.EMPTY_ARRAY; } else { myResult = new TypeConstraint[result.size()]; for (int i = 0; i < result.size(); i++) { final PsiType type = result.get(i); if (type != null) { myResult[i] = SubtypeConstraint.create(type); } } } }
@NotNull private static PsiSubstitutor replaceVariables(Collection<InferenceVariable> inferenceVariables) { final List<InferenceVariable> targetVars = new ArrayList<InferenceVariable>(); PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; final InferenceVariable[] oldVars = inferenceVariables.toArray(new InferenceVariable[inferenceVariables.size()]); for (InferenceVariable variable : oldVars) { final InferenceVariable newVariable = new InferenceVariable( variable.getCallContext(), variable.getParameter(), variable.getName()); substitutor = substitutor.put( variable, JavaPsiFacade.getElementFactory(variable.getProject()).createType(newVariable)); targetVars.add(newVariable); if (variable.isThrownBound()) { newVariable.setThrownBound(); } } for (int i = 0; i < targetVars.size(); i++) { InferenceVariable var = targetVars.get(i); for (InferenceBound boundType : InferenceBound.values()) { for (PsiType bound : oldVars[i].getBounds(boundType)) { var.addBound(substitutor.substitute(bound), boundType, null); } } } return substitutor; }
@Override public void addEntryPoint(@NotNull RefElement newEntryPoint, boolean isPersistent) { if (!newEntryPoint.isValid()) return; if (isPersistent) { if (newEntryPoint instanceof RefMethod && ((RefMethod) newEntryPoint).isConstructor() || newEntryPoint instanceof RefClass) { final ClassPattern classPattern = new ClassPattern(); classPattern.pattern = new SmartRefElementPointerImpl(newEntryPoint, true).getFQName(); getPatterns().add(classPattern); final EntryPointsManager entryPointsManager = getInstance(newEntryPoint.getElement().getProject()); if (this != entryPointsManager) { entryPointsManager.addEntryPoint(newEntryPoint, true); } return; } } if (newEntryPoint instanceof RefClass) { RefClass refClass = (RefClass) newEntryPoint; if (refClass.isAnonymous()) { // Anonymous class cannot be an entry point. return; } List<RefMethod> refConstructors = refClass.getConstructors(); if (refConstructors.size() == 1) { addEntryPoint(refConstructors.get(0), isPersistent); } else if (refConstructors.size() > 1) { // Many constructors here. Need to ask user which ones are used for (RefMethod refConstructor : refConstructors) { addEntryPoint(refConstructor, isPersistent); } } } if (!isPersistent) { myTemporaryEntryPoints.add(newEntryPoint); ((RefElementImpl) newEntryPoint).setEntry(true); } else { if (myPersistentEntryPoints.get(newEntryPoint.getExternalName()) == null) { final SmartRefElementPointerImpl entry = new SmartRefElementPointerImpl(newEntryPoint, true); myPersistentEntryPoints.put(entry.getFQName(), entry); ((RefElementImpl) newEntryPoint).setEntry(true); ((RefElementImpl) newEntryPoint).setPermanentEntry(true); if (entry.isPersistent()) { // do save entry points final EntryPointsManager entryPointsManager = getInstance(newEntryPoint.getElement().getProject()); if (this != entryPointsManager) { entryPointsManager.addEntryPoint(newEntryPoint, true); } } } } }
@Nullable public String getHint(final QuickFix fix) { if (myQuickFixes != null) { final List<String> list = myQuickFixes.getKeysByValue(fix); if (list != null) { LOG.assertTrue(list.size() == 1); return list.get(0); } } return null; }
@Override public void generatePlaces() { final PatternCompiler<PsiElement> compiler = getCompiler(); List<String> patternString = getPatternString(this); InjectionPlace[] places = InjectionPlace.ARRAY_FACTORY.create(patternString.size()); for (int i = 0, patternStringSize = patternString.size(); i < patternStringSize; i++) { String text = patternString.get(i); places[i] = new InjectionPlace(compiler.createElementPattern(text, getDisplayName()), true); } setInjectionPlaces(places); }
public static ClassFilter[] readFilters(List<Element> children) throws InvalidDataException { if (ContainerUtil.isEmpty(children)) { return ClassFilter.EMPTY_ARRAY; } ClassFilter[] filters = new ClassFilter[children.size()]; for (int i = 0, size = children.size(); i < size; i++) { filters[i] = create(children.get(i)); } return filters; }
public void removeRootByIndexes(String name, List<Integer> elementsIndexes) { List<TreeItem<Pair<AbstractUrl, String>>> list = getFavoritesListRootUrls(name); assert list != null; for (Integer index : elementsIndexes.subList(0, elementsIndexes.size() - 1)) { assert index >= 0 && index < list.size(); final TreeItem<Pair<AbstractUrl, String>> item = list.get(index); list = item.getChildren(); } assert list != null && !list.isEmpty(); list.remove(elementsIndexes.get(elementsIndexes.size() - 1).intValue()); fireListeners.rootsChanged(name); }
private static boolean isOverrideObjectDirect(@NotNull PsiMethod method) { List<HierarchicalMethodSignature> superSignatures = method.getHierarchicalMethodSignature().getSuperSignatures(); if (superSignatures.size() == 1) { PsiClass containingClass = superSignatures.get(0).getMethod().getContainingClass(); String qualifiedName = containingClass != null ? containingClass.getQualifiedName() : ""; if (qualifiedName != null && qualifiedName.equals(JAVA_LANG_OBJECT)) { return true; } } return false; }
private static int appendRange(List<TextRange> result, int start, int length) { if (length > 0) { int lastIndex = result.size() - 1; TextRange lastRange = lastIndex >= 0 ? result.get(lastIndex) : null; if (lastRange != null && lastRange.getEndOffset() == start) { result.set(lastIndex, lastRange.grown(length)); } else { result.add(TextRange.from(start, length)); } } return start + length; }
public void testLeafExpressionsMoreComplex() throws Exception { SliceTreeStructure treeStructure = configureTree("Duplicate"); SliceNode root = (SliceNode) treeStructure.getRootElement(); Collection<PsiElement> leaves = SliceLeafAnalyzer.calcLeafExpressions(root, treeStructure, SliceLeafAnalyzer.createMap()); assertNotNull(leaves); assertEquals(2, leaves.size()); List<PsiElement> list = new ArrayList<PsiElement>(leaves); Collections.sort( list, new Comparator<PsiElement>() { @Override public int compare(PsiElement o1, PsiElement o2) { return o1.getText().compareTo(o2.getText()); } }); assertTrue(list.get(0) instanceof PsiLiteralExpression); assertEquals(false, ((PsiLiteral) list.get(0)).getValue()); assertTrue(list.get(1) instanceof PsiLiteralExpression); assertEquals(true, ((PsiLiteral) list.get(1)).getValue()); }
private static PyType getTypeByControlFlow( @NotNull String name, @NotNull TypeEvalContext context, @NotNull PyExpression anchor, @NotNull ScopeOwner scopeOwner) { PyAugAssignmentStatement augAssignment = PsiTreeUtil.getParentOfType(anchor, PyAugAssignmentStatement.class); try { final PyElement element = augAssignment != null ? augAssignment : anchor; final List<ReadWriteInstruction> defs = PyDefUseUtil.getLatestDefs(scopeOwner, name, element, true); if (!defs.isEmpty()) { PyType type = defs.get(0).getType(context, anchor); for (int i = 1; i < defs.size(); i++) { type = PyUnionType.union(type, defs.get(i).getType(context, anchor)); } return type; } } catch (PyDefUseUtil.InstructionNotFoundException ignored) { } return null; }
public String getPrefixByNamespace(String namespace) { final PsiElement parent = getParent(); BidirectionalMap<String, String> map = initNamespaceMaps(parent); if (map != null) { List<String> keysByValue = map.getKeysByValue(namespace); final String ns = keysByValue == null || keysByValue.isEmpty() ? null : keysByValue.get(0); if (ns != null) return ns; } if (parent instanceof XmlTag) return ((XmlTag) parent).getPrefixByNamespace(namespace); // The prefix 'xml' is by definition bound to the namespace name // http://www.w3.org/XML/1998/namespace. It MAY, but need not, be declared if (XmlUtil.XML_NAMESPACE_URI.equals(namespace)) return XML_NS_PREFIX; return null; }
public static NavigatablePsiElement getPackageReference(@NotNull JetFile file, int partIndex) { JetNamespaceHeader header = file.getNamespaceHeader(); if (header == null) { throw new IllegalArgumentException("Should be called only for files with namespace: " + file); } List<JetSimpleNameExpression> names = header.getNamespaceNames(); if (!(0 <= partIndex && partIndex < names.size())) { throw new IndexOutOfBoundsException( String.format( "%s index for file with header %s is out of range", partIndex, header.getText())); } return names.get(partIndex); }
@Nullable private InstructionImpl reduceAllNegationsIntoInstruction( GroovyPsiElement currentScope, List<? extends GotoInstruction> negations) { if (negations.size() > 1) { InstructionImpl instruction = addNode(new InstructionImpl(currentScope)); for (GotoInstruction negation : negations) { addEdge(negation, instruction); } return instruction; } else if (negations.size() == 1) { GotoInstruction instruction = negations.get(0); myHead = instruction; return instruction; } return null; }
@NotNull public List<String> createConversions( @NotNull PsiPolyadicExpression expression, PsiType expectedType) { PsiExpression[] arguments = expression.getOperands(); int length = arguments.length; List<String> conversions = new LinkedList<String>(); List<PsiType> expectedTypes = Collections.nCopies(length, expectedType); List<PsiType> actualTypes = new LinkedList<PsiType>(); for (PsiExpression e : arguments) actualTypes.add(e.getType()); assert actualTypes.size() == expectedTypes.size() : "The type list must have the same length"; for (int i = 0; i < actualTypes.size(); i++) conversions.add(i, createConversionForExpression(arguments[i], expectedTypes.get(i))); return conversions; }
public synchronized boolean editRoot( @NotNull String name, @NotNull List<Integer> elementsIndexes, final AbstractTreeNode newElement) { List<TreeItem<Pair<AbstractUrl, String>>> list = getFavoritesListRootUrls(name); assert list != null; for (Integer index : elementsIndexes.subList(0, elementsIndexes.size() - 1)) { assert index >= 0 && index < list.size(); final TreeItem<Pair<AbstractUrl, String>> item = list.get(index); list = item.getChildren(); } assert list != null && !list.isEmpty(); final Object value = newElement.getValue(); final AbstractUrl urlByElement = createUrlByElement(value, myProject); if (urlByElement == null) return false; list.set( elementsIndexes.get(elementsIndexes.size() - 1).intValue(), new TreeItem<Pair<AbstractUrl, String>>( Pair.create(urlByElement, newElement.getClass().getName()))); return true; }
private static void checkStructure(final SliceNode root, @NonNls String dataExpected) { List<SliceNode> actualNodes = new ArrayList<SliceNode>((Collection) root.getChildren()); Collections.sort(actualNodes, SliceTreeBuilder.SLICE_NODE_COMPARATOR); Object[] actualStrings = ContainerUtil.map2Array( actualNodes, new Function<SliceNode, Object>() { @Override public Object fun(SliceNode node) { return node.toString(); } }); String[] childrenExpected = dataExpected.length() == 0 ? ArrayUtil.EMPTY_STRING_ARRAY : dataExpected.split("\n"); String curChildren = ""; String curNode = null; int iactual = 0; for (int iexp = 0; iexp <= childrenExpected.length; iexp++) { String e = iexp == childrenExpected.length ? null : childrenExpected[iexp]; boolean isTopLevel = e == null || e.charAt(0) != ' '; if (isTopLevel) { if (curNode != null) { assertTrue(iactual < actualStrings.length); Object actual = actualStrings[iactual]; assertEquals(curNode, actual); checkStructure(actualNodes.get(iactual), curChildren); iactual++; } curNode = e; curChildren = ""; } else { curChildren += StringUtil.trimStart(e, " ") + "\n"; } } assertEquals(actualNodes.size(), iactual); }
public static boolean isImplicitlyUsed(@NotNull JetElement element) { PsiElement parent = element.getParent(); if (!(parent instanceof JetBlockExpression)) return true; JetBlockExpression block = (JetBlockExpression) parent; List<JetElement> statements = block.getStatements(); if (statements.get(statements.size() - 1) == element) { JetExpression expression = getDirectParentOfTypeForBlock(block, JetIfExpression.class); if (expression == null) { expression = getDirectParentOfTypeForBlock(block, JetWhenExpression.class); } if (expression == null) { expression = getDirectParentOfTypeForBlock(block, JetFunctionLiteral.class); } if (expression == null) { expression = getDirectParentOfTypeForBlock(block, JetTryExpression.class); } if (expression != null) { return isImplicitlyUsed(expression); } } return false; }
@Nullable public static String checkContract(PsiMethod method, String text) { List<MethodContract> contracts; try { contracts = ControlFlowAnalyzer.parseContract(text); } catch (ControlFlowAnalyzer.ParseException e) { return e.getMessage(); } int paramCount = method.getParameterList().getParametersCount(); for (int i = 0; i < contracts.size(); i++) { MethodContract contract = contracts.get(i); if (contract.arguments.length != paramCount) { return "Method takes " + paramCount + " parameters, while contract clause number " + (i + 1) + " expects " + contract.arguments.length; } } return null; }