LookupElement (final PsiType type, final CompletionParameters parameters) { if (!JavaCompletionUtil.hasAccessibleConstructor(type, parameters.getPosition())) return null; final PsiClass psiClass = PsiUtil.resolveClassInType(type); if (psiClass == null || psiClass.getName() == null) return null; PsiElement position = parameters.getPosition(); if ((parameters.getInvocationCount() < 2 || psiClass instanceof PsiCompiledElement) && HighlightClassUtil.checkCreateInnerClassFromStaticContext(position, null, psiClass) != null && !psiElement().afterLeaf(psiElement().withText(PsiKeyword.NEW).afterLeaf(".")).accepts(position)) { return null; } PsiType psiType = GenericsUtil.eliminateWildcards(type); if (JavaSmartCompletionContributor.AFTER_NEW.accepts(parameters.getOriginalPosition()) && PsiUtil.getLanguageLevel(parameters.getOriginalFile()).isAtLeast(LanguageLevel.JDK_1_7)) { final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(psiClass.getProject()); PsiClassType classType = (PsiClassType)type; if (psiClass.hasTypeParameters() && !classType.isRaw()) { final String erasedText = TypeConversionUtil.erasure(psiType).getCanonicalText(); String canonicalText = psiType.getCanonicalText(); if (canonicalText.contains("?extends") || canonicalText.contains("?super")) { LOG.error("Malformed canonical text: " + canonicalText + "; presentable text: " + psiType + " of " + psiType.getClass() + "; " + (psiType instanceof PsiClassReferenceType ? ((PsiClassReferenceType)psiType).getReference().getClass() : "")); return null; } try { boolean hasDefaultConstructor = PsiDiamondTypeImpl.hasDefaultConstructor(psiClass); boolean hasConstructorWithGenericsParameters = PsiDiamondTypeImpl.haveConstructorsGenericsParameters(psiClass); if (hasDefaultConstructor || !hasConstructorWithGenericsParameters) { String args; if (hasDefaultConstructor) { args = ""; } else { //just try to resolve to the first constructor PsiSubstitutor substitutor = classType.resolveGenerics().getSubstitutor(); PsiParameter[] constructorParams = psiClass.getConstructors()[0].getParameterList().getParameters(); args = StreamEx.of(constructorParams) .map(p -> p.getType()) .map(t -> t instanceof PsiEllipsisType ellipsisType ? ellipsisType.toArrayType() : t) .map(substitutor::substitute) .map(GenericsUtil::getVariableTypeByExpressionType) .map(paramType -> "(" + paramType.getCanonicalText() + ")" + PsiTypesUtil.getDefaultValueOfType(paramType)) .joining(","); } final PsiStatement statement = elementFactory .createStatementFromText(canonicalText + " v = new " + erasedText + "<>(" + args + ")", parameters.getPosition()); final PsiVariable declaredVar = (PsiVariable)((PsiDeclarationStatement)statement).getDeclaredElements()[0]; final PsiNewExpression initializer = (PsiNewExpression)declaredVar.getInitializer(); final PsiDiamondTypeImpl.DiamondInferenceResult inferenceResult = PsiDiamondTypeImpl.resolveInferredTypes(initializer); if (inferenceResult.getErrorMessage() == null && !psiClass.hasModifierProperty(PsiModifier.ABSTRACT) && areInferredTypesApplicable(inferenceResult.getTypes(), parameters.getPosition())) { assert initializer != null; psiType = Objects.requireNonNull(initializer.getType()); } } } catch (IncorrectOperationException ignore) {} } } final PsiTypeLookupItem item = PsiTypeLookupItem.createLookupItem(psiType, position).setShowPackage(); if (psiClass.isInterface() || psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) { item.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE); item.setIndicateAnonymous(true); } return LookupElementDecorator.withInsertHandler(item, myConstructorInsertHandler); }