PsiTypeElement (@NotNull PsiTypeElement typeElement, ExpectedTypeInfo @NotNull [] infos, @Nullable PsiElement context, @NotNull PsiClass targetClass) { LOG.assertTrue(typeElement.isValid()); if (typeElement.isPhysical()) { ApplicationManager.getApplication().assertWriteAccessAllowed(); } GlobalSearchScope scope = typeElement.getResolveScope(); if (infos.length == 1 && mySubstitutor != PsiSubstitutor.EMPTY) { ExpectedTypeInfo info = infos[0]; final PsiType expectedType = info.getType(); final List<PsiTypeParameter> matchedParameters = matchingTypeParameters(mySubstitutor, expectedType, info.getKind()); if (!matchedParameters.isEmpty()) { final List<PsiType> types = new SmartList<>(map(matchedParameters, it -> myFactory.createType(it))); ContainerUtil.addAll(types, ExpectedTypesProvider.processExpectedTypes(infos, new MyTypeVisitor(myManager, scope), myProject)); myBuilder.replaceElement(typeElement, new TypeExpression(myProject, types)); return typeElement; } typeElement = replaceTypeElement(typeElement, info.getType()); PsiSubstitutor rawingSubstitutor = getRawingSubstitutor(myProject, context, targetClass); int substitionResult = hasNullSubstitutions(mySubstitutor) ? SUBSTITUTED_NONE : substituteToTypeParameters(typeElement, expectedType, rawingSubstitutor, true); if (substitionResult == SUBSTITUTED_IN_PARAMETERS) { PsiJavaCodeReferenceElement refElement = typeElement.getInnermostComponentReferenceElement(); LOG.assertTrue(refElement != null); PsiElement qualifier = refElement.getQualifier(); if (qualifier != null) { // Consider type element `java.util.List<java.lang.String>`. // At this point there is a template on `java.lang.String` type element already. // // We need java.util.List element to put the second template on, // but there is no such element, because type element consists of: // - qualifier `java.util` // - dot // - reference name element `List` // - reference type parameters `<java.lang.String>` // // Removing the qualifier also removes the dot, so in the end we get `List<java.lang.String>` // and we are safe to put the template on the reference name element `List`. // // Actual shortening or using of FQNs is then handled by com.intellij.codeInsight.template.impl.ShortenFQNamesProcessor. qualifier.delete(); } PsiElement referenceNameElement = refElement.getReferenceNameElement(); LOG.assertTrue(referenceNameElement != null); PsiClassType defaultType = getComponentType(info.getDefaultType()); LOG.assertTrue(defaultType != null); PsiClassType rawDefaultType = defaultType.rawType(); ExpectedTypeInfo info1 = ExpectedTypesProvider.createInfo(rawDefaultType, TYPE_STRICTLY, rawDefaultType, info.getTailType()); MyTypeVisitor visitor = new MyTypeVisitor(myManager, scope); PsiType[] types = ExpectedTypesProvider.processExpectedTypes(new ExpectedTypeInfo[]{info1}, visitor, myProject); myBuilder.replaceElement(referenceNameElement, new TypeExpression(myProject, types)); return typeElement; } else if (substitionResult != SUBSTITUTED_NONE) { return typeElement; } } PsiType[] types = infos.length == 0 ? new PsiType[]{typeElement.getType()} : ExpectedTypesProvider.processExpectedTypes(infos, new MyTypeVisitor(myManager, scope), myProject); myBuilder.replaceElement(typeElement, new TypeExpression(myProject, types)); return typeElement; }