public static boolean proveArrayTypeDistinct(Project project, PsiArrayType type, PsiType bound) { final JavaPsiFacade facade = JavaPsiFacade.getInstance(project); final GlobalSearchScope searchScope = GlobalSearchScope.allScope(project); final Set<PsiClass> possibleClasses = new HashSet<PsiClass>(); possibleClasses.add(facade.findClass(CommonClassNames.JAVA_IO_SERIALIZABLE, searchScope)); possibleClasses.add(facade.findClass(CommonClassNames.JAVA_LANG_CLONEABLE, searchScope)); possibleClasses.add(facade.findClass(CommonClassNames.JAVA_LANG_OBJECT, searchScope)); if (type.getArrayDimensions() == bound.getArrayDimensions()) { final PsiType componentType = type.getComponentType(); final PsiType boundComponentType = ((PsiArrayType) bound).getComponentType(); if (boundComponentType instanceof PsiClassType && componentType instanceof PsiClassType) { return proveExtendsBoundsDistinct( boundComponentType, componentType, ((PsiClassType) boundComponentType).resolve(), ((PsiClassType) componentType).resolve()); } else { return !bound.equals(type); } } else if (bound.getArrayDimensions() + 1 == type.getArrayDimensions() && bound.getDeepComponentType() instanceof PsiClassType) { return !possibleClasses.contains(((PsiClassType) bound.getDeepComponentType()).resolve()); } else if (bound.getArrayDimensions() == type.getArrayDimensions() + 1 && type.getDeepComponentType() instanceof PsiClassType) { return !possibleClasses.contains(((PsiClassType) type.getDeepComponentType()).resolve()); } else if (bound instanceof PsiClassType) { return !possibleClasses.contains(((PsiClassType) bound).resolve()); } else if (bound instanceof PsiWildcardType) { final PsiType boundBound = ((PsiWildcardType) bound).getBound(); return boundBound != null && !boundBound.equals(type); } return true; }
private int substituteToTypeParameters( PsiTypeElement typeElement, PsiTypeElement inplaceTypeElement, PsiType[] paramVals, PsiTypeParameter[] params, TemplateBuilder builder, PsiSubstitutor rawingSubstitutor, boolean toplevel) { PsiType type = inplaceTypeElement.getType(); List<PsiType> types = new ArrayList<>(); for (int i = 0; i < paramVals.length; i++) { PsiType val = paramVals[i]; if (val == null) return SUBSTITUTED_NONE; if (type.equals(val)) { types.add(myFactory.createType(params[i])); } } if (!types.isEmpty()) { Project project = typeElement.getProject(); PsiType substituted = rawingSubstitutor.substitute(type); if (!CommonClassNames.JAVA_LANG_OBJECT.equals(substituted.getCanonicalText()) && (toplevel || substituted.equals(type))) { types.add(substituted); } builder.replaceElement( typeElement, new TypeExpression(project, types.toArray(PsiType.createArray(types.size())))); return toplevel ? SUBSTITUTED_IN_REF : SUBSTITUTED_IN_PARAMETERS; } boolean substituted = false; PsiJavaCodeReferenceElement ref = typeElement.getInnermostComponentReferenceElement(); PsiJavaCodeReferenceElement inplaceRef = inplaceTypeElement.getInnermostComponentReferenceElement(); if (ref != null) { LOG.assertTrue(inplaceRef != null); PsiTypeElement[] innerTypeElements = ref.getParameterList().getTypeParameterElements(); PsiTypeElement[] inplaceInnerTypeElements = inplaceRef.getParameterList().getTypeParameterElements(); for (int i = 0; i < innerTypeElements.length; i++) { substituted |= substituteToTypeParameters( innerTypeElements[i], inplaceInnerTypeElements[i], paramVals, params, builder, rawingSubstitutor, false) != SUBSTITUTED_NONE; } } return substituted ? SUBSTITUTED_IN_PARAMETERS : SUBSTITUTED_NONE; }
public static String[] getParameterString(ExtractInfoHelper helper, boolean useCanonicalText) { int i = 0; ParameterInfo[] infos = helper.getParameterInfos(); int number = 0; for (ParameterInfo info : infos) { if (info.passAsParameter()) number++; } ArrayList<String> params = new ArrayList<String>(); for (ParameterInfo info : infos) { if (info.passAsParameter()) { PsiType paramType = info.getType(); final PsiPrimitiveType unboxed = PsiPrimitiveType.getUnboxedType(paramType); if (unboxed != null) paramType = unboxed; String paramTypeText; if (paramType == null || paramType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) || paramType.equals(PsiType.NULL)) { paramTypeText = ""; } else { paramTypeText = (useCanonicalText ? paramType.getCanonicalText() : paramType.getPresentableText()) + " "; } params.add(paramTypeText + info.getName() + (i < number - 1 ? ", " : "")); i++; } } return ArrayUtil.toStringArray(params); }
private String[] suggestVariableNameByType( PsiType type, final VariableKind variableKind, boolean correctKeywords) { String longTypeName = getLongTypeName(type); CodeStyleSettings.TypeToNameMap map = getMapByVariableKind(variableKind); if (map != null && longTypeName != null) { if (type.equals(PsiType.NULL)) { longTypeName = CommonClassNames.JAVA_LANG_OBJECT; } String name = map.nameByType(longTypeName); if (name != null && isIdentifier(name)) { return new String[] {name}; } } Collection<String> suggestions = new LinkedHashSet<String>(); suggestNamesForCollectionInheritors(type, variableKind, suggestions, correctKeywords); suggestNamesFromGenericParameters(type, variableKind, suggestions, correctKeywords); String typeName = normalizeTypeName(getTypeName(type)); if (typeName != null) { ContainerUtil.addAll( suggestions, getSuggestionsByName( typeName, variableKind, type instanceof PsiArrayType, correctKeywords)); } return ArrayUtil.toStringArray(suggestions); }
public static boolean areSignaturesEqualLightweight( @NotNull MethodSignature sig1, @NotNull MethodSignature sig2) { final boolean isConstructor1 = sig1.isConstructor(); final boolean isConstructor2 = sig2.isConstructor(); if (isConstructor1 != isConstructor2) return false; if (!isConstructor1 || !(sig1 instanceof HierarchicalMethodSignature || sig2 instanceof HierarchicalMethodSignature)) { final String name1 = sig1.getName(); final String name2 = sig2.getName(); if (!name1.equals(name2)) return false; } final PsiType[] parameterTypes1 = sig1.getParameterTypes(); final PsiType[] parameterTypes2 = sig2.getParameterTypes(); if (parameterTypes1.length != parameterTypes2.length) return false; // optimization: check for really different types in method parameters for (int i = 0; i < parameterTypes1.length; i++) { final PsiType type1 = parameterTypes1[i]; final PsiType type2 = parameterTypes2[i]; if (type1 instanceof PsiPrimitiveType != type2 instanceof PsiPrimitiveType) return false; if (type1 instanceof PsiPrimitiveType && !type1.equals(type2)) return false; } return true; }
private List<PsiType> matchingTypeParameters( PsiType[] paramVals, PsiTypeParameter[] params, ExpectedTypeInfo info) { PsiType type = info.getType(); int kind = info.getKind(); List<PsiType> result = new ArrayList<>(); for (int i = 0; i < paramVals.length; i++) { PsiType val = paramVals[i]; if (val != null) { switch (kind) { case ExpectedTypeInfo.TYPE_STRICTLY: if (val.equals(type)) result.add(myFactory.createType(params[i])); break; case ExpectedTypeInfo.TYPE_OR_SUBTYPE: if (type.isAssignableFrom(val)) result.add(myFactory.createType(params[i])); break; case ExpectedTypeInfo.TYPE_OR_SUPERTYPE: if (val.isAssignableFrom(type)) result.add(myFactory.createType(params[i])); break; } } } return result; }
@Override protected void addCompletions( @NotNull final CompletionParameters parameters, final ProcessingContext processingContext, @NotNull final CompletionResultSet resultSet) { final PsiElement context = parameters.getPosition(); final Pair<PsiClass, Integer> pair = getTypeParameterInfo(context); if (pair == null) return; PsiExpression expression = PsiTreeUtil.getContextOfType(context, PsiExpression.class, true); if (expression != null) { ExpectedTypeInfo[] types = ExpectedTypesProvider.getExpectedTypes(expression, true, false, false); if (types.length > 0) { for (ExpectedTypeInfo info : types) { PsiType type = info.getType(); if (type instanceof PsiClassType && !type.equals(expression.getType())) { fillExpectedTypeArgs( resultSet, context, pair.first, pair.second, ((PsiClassType) type).resolveGenerics(), mySmart ? info.getTailType() : TailType.NONE); } } return; } } if (mySmart) { addInheritors(parameters, resultSet, pair.first, pair.second); } }
public static boolean canBeMigrated(final PsiElement e) { if (e == null) { return false; } final PsiElement element = normalizeElement(e); if (!element.getManager().isInProject(element)) { return false; } final PsiType type = TypeMigrationLabeler.getElementType(element); if (type != null) { final PsiType elemenType = type instanceof PsiArrayType ? type.getDeepComponentType() : type; if (elemenType instanceof PsiPrimitiveType) { return !elemenType.equals(PsiType.VOID); } final PsiClass aClass = ((PsiClassType) elemenType).resolve(); return aClass != null /* && !aClass.hasTypeParameters()*/; } return false; }
private static boolean isReturnTypeIsMoreSpecificThan( @NotNull HierarchicalMethodSignature thisSig, @NotNull HierarchicalMethodSignature thatSig) { PsiType thisRet = thisSig.getSubstitutor().substitute(thisSig.getMethod().getReturnType()); PsiType thatRet = thatSig.getSubstitutor().substitute(thatSig.getMethod().getReturnType()); return thatRet != null && thisRet != null && !thatRet.equals(thisRet) && TypeConversionUtil.isAssignable(thatRet, thisRet, false); }
private static boolean typesAreEquivalent(@Nullable PsiType type1, @Nullable PsiType type2) { if (type1 == null) { return type2 == null; } if (type2 == null) { return false; } return type1.equals(type2); }
private boolean typesAgree(@NotNull PsiType type1, @NotNull PsiType type2) { if (argumentsSupplied() && type1 instanceof PsiArrayType && !(type2 instanceof PsiArrayType)) { type1 = ((PsiArrayType) type1).getComponentType(); } return argumentsSupplied() ? // resolve, otherwise same_name_variants TypesUtil.isAssignableWithoutConversions(type1, type2, myPlace) : type1.equals(type2); }
@NotNull @Override public MyResult weigh(@NotNull LookupElement item) { final Object object = item.getObject(); if (object instanceof PsiClass) { if (object instanceof PsiTypeParameter) return MyResult.typeParameter; if (myTypeParameter != null && object.equals( PsiUtil.resolveClassInType( TypeConversionUtil.typeParameterErasure(myTypeParameter)))) { return MyResult.exactlyExpected; } } if (myExpectedTypes == null) return MyResult.normal; PsiType itemType = JavaCompletionUtil.getLookupElementType(item); if (itemType == null || !itemType.isValid()) return MyResult.normal; if (object instanceof PsiClass) { for (final ExpectedTypeInfo info : myExpectedTypes) { if (TypeConversionUtil.erasure(info.getType().getDeepComponentType()) .equals(TypeConversionUtil.erasure(itemType))) { return AbstractExpectedTypeSkipper.skips(item, myLocation) ? MyResult.expectedNoSelect : MyResult.exactlyExpected; } } } for (final ExpectedTypeInfo expectedInfo : myExpectedTypes) { final PsiType defaultType = expectedInfo.getDefaultType(); final PsiType expectedType = expectedInfo.getType(); if (!expectedType.isValid()) { return MyResult.normal; } if (defaultType != expectedType) { if (defaultType.equals(itemType)) { return MyResult.exactlyDefault; } if (defaultType.isAssignableFrom(itemType)) { return MyResult.ofDefaultType; } } if (PsiType.VOID.equals(itemType) && PsiType.VOID.equals(expectedType)) { return MyResult.exactlyExpected; } } return MyResult.normal; }
@Nullable public static PsiMethod findPropertyGetterWithType( String propertyName, boolean isStatic, PsiType type, Iterator<PsiMethod> methods) { while (methods.hasNext()) { PsiMethod method = methods.next(); if (method.hasModifierProperty(PsiModifier.STATIC) != isStatic) continue; if (isSimplePropertyGetter(method)) { if (getPropertyNameByGetter(method).equals(propertyName)) { if (type.equals(method.getReturnType())) return method; } } } return null; }
@Override @Nullable public PsiType fun(final PsiMethodCallExpression call) { PsiReferenceExpression methodExpression = call.getMethodExpression(); PsiType theOnly = null; final JavaResolveResult[] results = methodExpression.multiResolve(false); LanguageLevel languageLevel = PsiUtil.getLanguageLevel(call); final PsiElement callParent = PsiUtil.skipParenthesizedExprUp(call.getParent()); final PsiExpressionList parentArgList; if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) { parentArgList = callParent instanceof PsiConditionalExpression && !PsiPolyExpressionUtil.isPolyExpression((PsiExpression) callParent) ? null : PsiTreeUtil.getParentOfType(call, PsiExpressionList.class); } else { parentArgList = null; } final MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(parentArgList); final boolean genericMethodCall = properties != null && properties.getInfo().isToInferApplicability(); for (int i = 0; i < results.length; i++) { final JavaResolveResult candidateInfo = results[i]; if (genericMethodCall && PsiPolyExpressionUtil.isMethodCallPolyExpression( call, (PsiMethod) candidateInfo.getElement())) { if (callParent instanceof PsiAssignmentExpression) { return null; } LOG.error("poly expression evaluation during overload resolution"); } final PsiType type = getResultType(call, methodExpression, candidateInfo, languageLevel); if (type == null) { return null; } if (i == 0) { theOnly = type; } else if (!theOnly.equals(type)) { return null; } } return PsiClassImplUtil.correctType(theOnly, call.getResolveScope()); }
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; PsiTypeItem that = (PsiTypeItem) o; if (myType == null) { if (that.myType != null) return false; } else { if (!myType.equals(that.myType)) return false; } return true; }
private void suggestNamesForCollectionInheritors( final PsiType type, final VariableKind variableKind, final Collection<String> suggestions, final boolean correctKeywords) { PsiType componentType = PsiUtil.extractIterableTypeParameter(type, false); if (componentType == null || componentType.equals(type)) { return; } String typeName = normalizeTypeName(getTypeName(componentType)); if (typeName != null) { ContainerUtil.addAll( suggestions, getSuggestionsByName(typeName, variableKind, true, correctKeywords)); } }
private static AllowedValues getAllowedValuesFromMagic( @NotNull PsiModifierListOwner element, @NotNull PsiType type, PsiAnnotation magic) { if (magic == null) return null; PsiAnnotationMemberValue[] allowedValues; final boolean canBeOred; if (TypeConversionUtil.getTypeRank(type) <= TypeConversionUtil.LONG_RANK) { PsiAnnotationMemberValue intValues = magic.findAttributeValue("intValues"); allowedValues = intValues instanceof PsiArrayInitializerMemberValue ? ((PsiArrayInitializerMemberValue) intValues).getInitializers() : PsiAnnotationMemberValue.EMPTY_ARRAY; if (allowedValues.length == 0) { PsiAnnotationMemberValue orValue = magic.findAttributeValue("flags"); allowedValues = orValue instanceof PsiArrayInitializerMemberValue ? ((PsiArrayInitializerMemberValue) orValue).getInitializers() : PsiAnnotationMemberValue.EMPTY_ARRAY; canBeOred = true; } else { canBeOred = false; } } else if (type.equals( PsiType.getJavaLangString( element.getManager(), GlobalSearchScope.allScope(element.getProject())))) { PsiAnnotationMemberValue strValuesAttr = magic.findAttributeValue("stringValues"); allowedValues = strValuesAttr instanceof PsiArrayInitializerMemberValue ? ((PsiArrayInitializerMemberValue) strValuesAttr).getInitializers() : PsiAnnotationMemberValue.EMPTY_ARRAY; canBeOred = false; } else { return null; // other types not supported } if (allowedValues.length != 0) { return new AllowedValues(allowedValues, canBeOred); } // last resort: try valuesFromClass PsiAnnotationMemberValue[] values = readFromClass("valuesFromClass", magic, type); boolean ored = false; if (values == null) { values = readFromClass("flagsFromClass", magic, type); ored = true; } if (values == null) return null; return new AllowedValues(values, ored); }
@Nullable private static String doCheckRepeatableAnnotation(@NotNull PsiAnnotation annotation) { PsiAnnotationOwner owner = annotation.getOwner(); if (!(owner instanceof PsiModifierList)) return null; PsiElement target = ((PsiModifierList) owner).getParent(); if (!(target instanceof PsiClass) || !((PsiClass) target).isAnnotationType()) return null; PsiClass container = getRepeatableContainer(annotation); if (container == null) return null; PsiMethod[] methods = container.findMethodsByName("value", false); if (methods.length == 0) { return JavaErrorMessages.message( "annotation.container.no.value", container.getQualifiedName()); } if (methods.length == 1) { PsiType expected = new PsiImmediateClassType((PsiClass) target, PsiSubstitutor.EMPTY).createArrayType(); if (!expected.equals(methods[0].getReturnType())) { return JavaErrorMessages.message( "annotation.container.bad.type", container.getQualifiedName(), JavaHighlightUtil.formatType(expected)); } } RetentionPolicy targetPolicy = getRetentionPolicy((PsiClass) target); if (targetPolicy != null) { RetentionPolicy containerPolicy = getRetentionPolicy(container); if (containerPolicy != null && targetPolicy.compareTo(containerPolicy) > 0) { return JavaErrorMessages.message( "annotation.container.low.retention", container.getQualifiedName(), containerPolicy); } } Set<PsiAnnotation.TargetType> repeatableTargets = PsiImplUtil.getAnnotationTargets((PsiClass) target); if (repeatableTargets != null) { Set<PsiAnnotation.TargetType> containerTargets = PsiImplUtil.getAnnotationTargets(container); if (containerTargets != null && !repeatableTargets.containsAll(containerTargets)) { return JavaErrorMessages.message( "annotation.container.wide.target", container.getQualifiedName()); } } return null; }
@Nullable public static PsiField findPropertyFieldWithType( Project project, String propertyName, boolean isStatic, PsiType type, Iterator<PsiField> fields) { while (fields.hasNext()) { PsiField field = fields.next(); if (field.hasModifierProperty(PsiModifier.STATIC) != isStatic) continue; if (propertyName.equals(suggestPropertyName(project, field))) { if (type.equals(field.getType())) return field; } } return null; }
@Nullable private PsiMethod[] getChangeRoots(final PsiMethod method, @NotNull PsiType returnType) { if (!myFixWholeHierarchy) return new PsiMethod[] {method}; final PsiMethod[] methods = method.findDeepestSuperMethods(); if (methods.length > 0) { for (PsiMethod psiMethod : methods) { if (returnType.equals(psiMethod.getReturnType())) { return new PsiMethod[] {method}; } } return methods; } // no - only base return new PsiMethod[] {method}; }
public boolean satisfiedBy(PsiElement element) { if (!(element instanceof PsiSwitchStatement)) { return false; } final PsiSwitchStatement switchStatement = (PsiSwitchStatement) element; final PsiCodeBlock body = switchStatement.getBody(); if (body == null) { return false; } final PsiExpression expression = switchStatement.getExpression(); if (expression == null) { return false; } final PsiType type = expression.getType(); if (!(type instanceof PsiClassType)) { return false; } final PsiClass enumClass = ((PsiClassType) type).resolve(); if (enumClass == null || !enumClass.isEnum()) { return false; } final PsiField[] fields = enumClass.getFields(); final Set<String> enumElements = new HashSet<String>(fields.length); for (final PsiField field : fields) { final PsiType fieldType = field.getType(); if (fieldType.equals(type)) { final String fieldName = field.getName(); enumElements.add(fieldName); } } final PsiStatement[] statements = body.getStatements(); for (PsiStatement statement : statements) { if (statement instanceof PsiSwitchLabelStatement) { final PsiSwitchLabelStatement labelStatement = (PsiSwitchLabelStatement) statement; final PsiExpression value = labelStatement.getCaseValue(); if (value != null) { final String valueText = value.getText(); enumElements.remove(valueText); } } } if (enumElements.isEmpty()) { return false; } return !ErrorUtil.containsError(element); }
private void updateRefMethod( PsiElement psiResolved, RefElement refResolved, PsiElement refExpression, final PsiElement psiFrom, final RefElement refFrom) { PsiMethod psiMethod = (PsiMethod) psiResolved; RefMethodImpl refMethod = (RefMethodImpl) refResolved; PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(refExpression, PsiMethodCallExpression.class); if (call != null) { PsiType returnType = psiMethod.getReturnType(); if (!psiMethod.isConstructor() && returnType != PsiType.VOID) { if (!(call.getParent() instanceof PsiExpressionStatement)) { refMethod.setReturnValueUsed(true); } addTypeReference(psiFrom, returnType, refFrom.getRefManager()); } PsiExpressionList argumentList = call.getArgumentList(); if (argumentList.getExpressions().length > 0) { refMethod.updateParameterValues(argumentList.getExpressions()); } final PsiExpression psiExpression = call.getMethodExpression().getQualifierExpression(); if (psiExpression != null) { final PsiType usedType = psiExpression.getType(); if (usedType != null) { final String fqName = psiMethod.getContainingClass().getQualifiedName(); if (fqName != null) { final PsiClassType methodOwnerType = JavaPsiFacade.getInstance(call.getProject()) .getElementFactory() .createTypeByFQClassName( fqName, GlobalSearchScope.allScope(psiMethod.getProject())); if (!usedType.equals(methodOwnerType)) { refMethod.setCalledOnSubClass(true); } } } } } }
private boolean isIteratorNext( PsiElement element, String iteratorName, PsiType contentType) { if (element == null) { return false; } if (element instanceof PsiTypeCastExpression) { final PsiTypeCastExpression castExpression = (PsiTypeCastExpression)element; final PsiType type = castExpression.getType(); if (type == null) { return false; } if (!type.equals(contentType)) { return false; } final PsiExpression operand = castExpression.getOperand(); return isIteratorNext(operand, iteratorName, contentType); } if (!(element instanceof PsiMethodCallExpression)) { return false; } final PsiMethodCallExpression callExpression = (PsiMethodCallExpression)element; final PsiExpressionList argumentList = callExpression.getArgumentList(); final PsiExpression[] args = argumentList.getExpressions(); if (args.length != 0) { return false; } final PsiReferenceExpression reference = callExpression.getMethodExpression(); final PsiExpression qualifier = reference.getQualifierExpression(); if (qualifier == null) { return false; } if (!iteratorName.equals(qualifier.getText())) { return false; } final String referenceName = reference.getReferenceName(); return HardcodedMethodConstants.NEXT.equals(referenceName); }
private void checkExpression(@NotNull PsiExpression expression) { if (expression.getParent() instanceof PsiParenthesizedExpression) { return; } final PsiType expressionType = expression.getType(); if (expressionType == null || expressionType.equals(PsiType.VOID) || !TypeConversionUtil.isPrimitiveAndNotNull(expressionType)) { return; } final PsiPrimitiveType primitiveType = (PsiPrimitiveType) expressionType; final PsiClassType boxedType = primitiveType.getBoxedType(expression); if (boxedType == null) { return; } final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, false); if (expectedType == null || ClassUtils.isPrimitive(expectedType)) { return; } if (!expectedType.isAssignableFrom(boxedType)) { // JLS 5.2 Assignment Conversion // check if a narrowing primitive conversion is applicable if (!(expectedType instanceof PsiClassType) || !PsiUtil.isConstantExpression(expression)) { return; } final PsiClassType classType = (PsiClassType) expectedType; final String className = classType.getCanonicalText(); if (!convertableBoxedClassNames.contains(className)) { return; } if (!PsiType.BYTE.equals(expressionType) && !PsiType.CHAR.equals(expressionType) && !PsiType.SHORT.equals(expressionType) && !PsiType.INT.equals(expressionType)) { return; } } if (ignoreAddedToCollection && isAddedToCollection(expression)) { return; } registerError(expression); }
private boolean isListElementDeclaration( PsiStatement statement, PsiVariable listVariable, String indexName, PsiType type) { if (!(statement instanceof PsiDeclarationStatement)) { return false; } final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement) statement; final PsiElement[] declaredElements = declarationStatement.getDeclaredElements(); if (declaredElements.length != 1) { return false; } final PsiElement declaredElement = declaredElements[0]; if (!(declaredElement instanceof PsiVariable)) { return false; } final PsiVariable variable = (PsiVariable) declaredElement; final PsiExpression initializer = variable.getInitializer(); if (!isListGetLookup(initializer, indexName, listVariable)) { return false; } return type != null && type.equals(variable.getType()); }
private static boolean forEachStatementsAreEquivalent( @NotNull PsiForeachStatement statement1, @NotNull PsiForeachStatement statement2) { final PsiExpression value1 = statement1.getIteratedValue(); final PsiExpression value2 = statement2.getIteratedValue(); if (!expressionsAreEquivalent(value1, value2)) { return false; } final PsiParameter parameter1 = statement1.getIterationParameter(); final PsiParameter parameter2 = statement1.getIterationParameter(); final String name1 = parameter1.getName(); final String name2 = parameter2.getName(); if (!name1.equals(name2)) { return false; } final PsiType type1 = parameter1.getType(); if (!type1.equals(parameter2.getType())) { return false; } final PsiStatement body1 = statement1.getBody(); final PsiStatement body2 = statement2.getBody(); return statementsAreEquivalent(body1, body2); }
private static boolean compareParamTypes( @NotNull PsiManager manager, @NotNull PsiType type1, @NotNull PsiType type2) { if (type1 instanceof PsiArrayType) { return type2 instanceof PsiArrayType && compareParamTypes( manager, ((PsiArrayType) type1).getComponentType(), ((PsiArrayType) type2).getComponentType()); } if (!(type1 instanceof PsiClassType) || !(type2 instanceof PsiClassType)) { return type1.equals(type2); } PsiClass class1 = ((PsiClassType) type1).resolve(); PsiClass class2 = ((PsiClassType) type2).resolve(); if (class1 instanceof PsiTypeParameter && class2 instanceof PsiTypeParameter) { return Comparing.equal(class1.getName(), class2.getName()) && ((PsiTypeParameter) class1).getIndex() == ((PsiTypeParameter) class2).getIndex(); } return manager.areElementsEquivalent(class1, class2); }
private String[] suggestVariableNameByType( final PsiType type, final VariableKind variableKind, final boolean correctKeywords, boolean skipIndices) { String longTypeName = skipIndices ? type.getCanonicalText() : getLongTypeName(type); CodeStyleSettings.TypeToNameMap map = getMapByVariableKind(variableKind); if (map != null && longTypeName != null) { if (type.equals(PsiType.NULL)) { longTypeName = CommonClassNames.JAVA_LANG_OBJECT; } String name = map.nameByType(longTypeName); if (name != null && isIdentifier(name)) { return new String[] {name}; } } final Collection<String> suggestions = new LinkedHashSet<String>(); final PsiClass psiClass = !skipIndices && type instanceof PsiClassType ? ((PsiClassType) type).resolve() : null; if (!skipIndices) { suggestNamesForCollectionInheritors(type, variableKind, suggestions, correctKeywords); if (psiClass != null && CommonClassNames.JAVA_UTIL_OPTIONAL.equals(psiClass.getQualifiedName()) && ((PsiClassType) type).getParameterCount() == 1) { PsiType optionalContent = ((PsiClassType) type).getParameters()[0]; Collections.addAll( suggestions, suggestVariableNameByType(optionalContent, variableKind, correctKeywords, false)); } suggestNamesFromGenericParameters(type, variableKind, suggestions, correctKeywords); } String typeName = getTypeName(type, !skipIndices); if (typeName != null) { typeName = normalizeTypeName(typeName); ContainerUtil.addAll( suggestions, getSuggestionsByName( typeName, variableKind, type instanceof PsiArrayType, correctKeywords)); } if (psiClass != null && psiClass.getContainingClass() != null) { InheritanceUtil.processSupers( psiClass, false, new Processor<PsiClass>() { @Override public boolean process(PsiClass superClass) { if (PsiTreeUtil.isAncestor(superClass, psiClass, true)) { ContainerUtil.addAll( suggestions, getSuggestionsByName( superClass.getName(), variableKind, false, correctKeywords)); } return false; } }); } return ArrayUtil.toStringArray(suggestions); }
@Nullable private String createCollectionIterationText(@NotNull PsiForStatement forStatement) throws IncorrectOperationException { final PsiStatement body = forStatement.getBody(); final PsiStatement firstStatement = getFirstStatement(body); final PsiStatement initialization = forStatement.getInitialization(); if (!(initialization instanceof PsiDeclarationStatement)) { return null; } final PsiDeclarationStatement declaration = (PsiDeclarationStatement) initialization; final PsiElement declaredIterator = declaration.getDeclaredElements()[0]; if (!(declaredIterator instanceof PsiVariable)) { return null; } final PsiVariable iteratorVariable = (PsiVariable) declaredIterator; final PsiMethodCallExpression initializer = (PsiMethodCallExpression) iteratorVariable.getInitializer(); if (initializer == null) { return null; } final PsiType iteratorType = initializer.getType(); if (iteratorType == null) { return null; } final PsiType iteratorContentType = extractContentTypeFromType(iteratorType); final PsiType iteratorVariableType = iteratorVariable.getType(); final PsiType contentType; final PsiClassType javaLangObject = TypeUtils.getObjectType(forStatement); if (iteratorContentType == null) { final PsiType iteratorVariableContentType = extractContentTypeFromType(iteratorVariableType); if (iteratorVariableContentType == null) { contentType = javaLangObject; } else { contentType = iteratorVariableContentType; } } else { contentType = iteratorContentType; } final PsiReferenceExpression methodExpression = initializer.getMethodExpression(); final PsiExpression collection = methodExpression.getQualifierExpression(); final String iteratorName = iteratorVariable.getName(); final boolean isDeclaration = isIteratorNextDeclaration(firstStatement, iteratorName, contentType); final PsiStatement statementToSkip; @NonNls final String finalString; final String contentVariableName; if (isDeclaration) { final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement) firstStatement; assert declarationStatement != null; final PsiElement[] declaredElements = declarationStatement.getDeclaredElements(); final PsiElement declaredElement = declaredElements[0]; if (!(declaredElement instanceof PsiVariable)) { return null; } final PsiVariable variable = (PsiVariable) declaredElement; contentVariableName = variable.getName(); statementToSkip = declarationStatement; if (variable.hasModifierProperty(PsiModifier.FINAL)) { finalString = "final "; } else { finalString = ""; } } else { if (collection instanceof PsiReferenceExpression) { final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) collection; final String collectionName = referenceExpression.getReferenceName(); contentVariableName = createNewVariableName(forStatement, contentType, collectionName); } else { contentVariableName = createNewVariableName(forStatement, contentType, null); } final Project project = forStatement.getProject(); final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project); if (codeStyleSettings.GENERATE_FINAL_LOCALS) { finalString = "final "; } else { finalString = ""; } statementToSkip = null; } final String contentTypeString = contentType.getCanonicalText(); @NonNls final StringBuilder out = new StringBuilder(); out.append("for("); out.append(finalString); out.append(contentTypeString); out.append(' '); out.append(contentVariableName); out.append(": "); if (!contentType.equals(javaLangObject)) { @NonNls final String iterableTypeString = "java.lang.Iterable<" + contentTypeString + '>'; if (iteratorContentType == null) { out.append('('); out.append(iterableTypeString); out.append(')'); } } if (collection == null) { out.append("this"); } else { out.append(collection.getText()); } out.append(')'); replaceIteratorNext( body, contentVariableName, iteratorName, statementToSkip, out, contentType); return out.toString(); }
@Override public void visitTypeCastExpression(@NotNull PsiTypeCastExpression expression) { super.visitTypeCastExpression(expression); final PsiExpression operand = expression.getOperand(); if (operand == null) { return; } final PsiType operandType = operand.getType(); if (operandType == null) { return; } final PsiType type = expression.getType(); if (type == null) { return; } final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, true); if (expectedType == null) { return; } if (expectedType.equals(type)) { return; } final PsiClass resolved = PsiUtil.resolveClassInType(expectedType); if (resolved != null && !resolved.isPhysical()) { return; } if (expectedType.isAssignableFrom(operandType)) { // then it's redundant, and caught by the built-in exception return; } if (isTypeParameter(expectedType)) { return; } if (expectedType instanceof PsiArrayType) { final PsiArrayType arrayType = (PsiArrayType) expectedType; final PsiType componentType = arrayType.getDeepComponentType(); if (isTypeParameter(componentType)) { return; } } if (type instanceof PsiPrimitiveType || expectedType instanceof PsiPrimitiveType) { return; } if (PsiPrimitiveType.getUnboxedType(type) != null || PsiPrimitiveType.getUnboxedType(expectedType) != null) { return; } if (expectedType instanceof PsiClassType) { final PsiClassType expectedClassType = (PsiClassType) expectedType; final PsiClassType expectedRawType = expectedClassType.rawType(); if (type.equals(expectedRawType)) { return; } if (type instanceof PsiClassType) { final PsiClassType classType = (PsiClassType) type; final PsiClassType rawType = classType.rawType(); if (rawType.equals(expectedRawType)) { return; } } if (type instanceof PsiArrayType) { return; } } if (ignoreInMatchingInstanceof && InstanceOfUtils.hasAgreeingInstanceof(expression)) { return; } final PsiTypeElement castTypeElement = expression.getCastType(); if (castTypeElement == null) { return; } registerError(castTypeElement, expectedType); }