public static PsiType getDefaultParameterizedType( PsiType type, PsiManager mgr ) { if( type.getArrayDimensions() > 0 ) { PsiType defType = getDefaultParameterizedType( ((PsiArrayType)type).getComponentType(), mgr ); if( !defType.equals( type ) ) { return new PsiArrayType( defType ); } return type; } if( type instanceof PsiIntersectionType ) { return makeDefaultParameterizedTypeForCompoundType( (PsiIntersectionType)type, mgr ); } if( type instanceof PsiDisjunctionType ) { return getDefaultParameterizedType( PsiTypesUtil.getLowestUpperBoundClassType( (PsiDisjunctionType)type ), mgr ); } if( !isGenericType( type ) && !isParameterizedType( type ) ) { return type; } type = ((PsiClassType)type).rawType(); return makeDefaultParameterizedType( type ); }
@Override public void tokenize(@NotNull PsiTypeElement element, TokenConsumer consumer) { final PsiType type = element.getType(); if (type instanceof PsiDisjunctionType) { tokenizeComplexType(element, consumer); return; } final PsiClass psiClass = PsiUtil.resolveClassInType(type); if (psiClass == null || psiClass.getContainingFile() == null || psiClass.getContainingFile().getVirtualFile() == null) { return; } final VirtualFile virtualFile = psiClass.getContainingFile().getVirtualFile(); final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(element.getProject()).getFileIndex(); final boolean isInSource = (virtualFile != null) && fileIndex.isInContent(virtualFile); if (isInSource) { consumer.consumeToken(element, element.getText(), true, 0, getRangeToCheck(element.getText(), psiClass.getName()), IdentifierSplitter.getInstance()); } }
@NotNull private List<DfaTypeValue> allCaughtTypes(PsiParameter param) { List<PsiType> psiTypes; PsiType type = param.getType(); if(type instanceof PsiDisjunctionType) { psiTypes = ((PsiDisjunctionType) type).getDisjunctions(); } else { psiTypes = Collections.singletonList(type); } List<DfaValue> result = psiTypes.stream().map(it -> myRunner.getFactory().createTypeValue(it, Nullness.NOT_NULL)).collect(Collectors.toList()); return ContainerUtil.<DfaValue, DfaTypeValue>mapNotNull(result, dfaValue -> dfaValue instanceof DfaTypeValue ? (DfaTypeValue) dfaValue : null); }
@Override public void tokenize(@NotNull PsiTypeElement element, TokenConsumer consumer) { final PsiType type = element.getType(); if (type instanceof PsiDisjunctionType) { tokenizeComplexType(element, consumer); return; } final PsiClass psiClass = PsiUtil.resolveClassInType(type); if (psiClass == null || psiClass.getContainingFile() == null || psiClass.getContainingFile().getVirtualFile() == null) { return; } final String name = psiClass.getName(); if (name == null) { return; } final VirtualFile virtualFile = psiClass.getContainingFile().getVirtualFile(); final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(element.getProject()).getFileIndex(); final boolean isInSource = (virtualFile != null) && fileIndex.isInContent(virtualFile); if (isInSource) { final String elementText = element.getText(); if (elementText.contains(name)) { consumer.consumeToken(element, elementText, true, 0, getRangeToCheck(elementText, name), IdentifierSplitter.getInstance()); } } }
private static PsiType solveType( PsiType genParamType, PsiType argType, TypeVarToTypeMap inferenceMap, boolean bReverse, PsiClassType tvType, PsiType type ) { // Solve the type. Either LUB or GLB. // // Infer the type as the intersection of the existing inferred type and this one. This is most relevant for // case where we infer a given type var from more than one type context e.g., a method call: // var l : String // var s : StringBuilder // var r = foo( l, s ) // here we must use the LUB of String and StringBuilder, which is CharSequence & Serializable // function foo<T>( t1: T, t2: T ) {} // // Also handle inferring a type from a structure type's methods: // PsiType lubType; if( bReverse ) { // Contravariant lubType = findGreatestLowerBound( type, argType ); } else { if( inferenceMap.isInferredForCovariance( tvType ) ) { // Covariant lubType = argType.equals( genParamType ) ? type : PsiTypesUtil.getLowestUpperBoundClassType( (PsiDisjunctionType)PsiDisjunctionType.createDisjunction( Arrays.asList( type, argType ), type( type ).getManager() ) ); } else { // Contravariant // This is the first type encountered in a return/covariant position, the prior type[s] are in contravariant positions, // therefore we can apply contravariance to maintain the return type's more specific type i.e., since the other type[s] // are all param types and are contravariant with tvType, we should keep the more specific type between them. Note if // the param type is more specific, tvType's variance is broken either way (both lub and glb produce a type that is not // call-compatible). lubType = findGreatestLowerBound( type, argType ); } // We have inferred tvType from a covariant position, so we infer using covariance in subsequent positions inferenceMap.setInferredForCovariance( tvType ); } return lubType; }