private PsiElement findExtensionMethodNavigationElement( PsiClass extClass, PsiMethod plantedMethod ) { PsiMethod[] found = extClass.findMethodsByName( plantedMethod.getName(), false ); outer: for( PsiMethod m : found ) { PsiParameter[] extParams = m.getParameterList().getParameters(); PsiParameter[] plantedParams = plantedMethod.getParameterList().getParameters(); if( extParams.length - 1 == plantedParams.length ) { for( int i = 1; i < extParams.length; i++ ) { PsiParameter extParam = extParams[i]; PsiParameter plantedParam = plantedParams[i - 1]; PsiType extErased = TypeConversionUtil.erasure( extParam.getType() ); PsiType plantedErased = TypeConversionUtil.erasure( plantedParam.getType() ); if( !extErased.toString().equals( plantedErased.toString() ) ) { continue outer; } } return m.getNavigationElement(); } } return null; }
private static boolean isAssignable( boolean structural, boolean covariant, PsiType to, PsiType from ) { if( to.equals( from ) ) { return true; } if( structural ) { return TypeConversionUtil.isAssignable( to, from ) || arePrimitiveTypesAssignable( to, from ) || isStructurallyAssignable( to, from, structural ) || TypeConversionUtil.boxingConversionApplicable( to, from ); } if( covariant ) { TypeConversionUtil.isAssignable( to, from ); } return false; }
@Nullable private static PsiType getCollectionComponentType(PsiType type, Project project) { if (!(type instanceof PsiClassType)) return null; PsiClassType classType = (PsiClassType) type; PsiClassType.ClassResolveResult result = classType.resolveGenerics(); PsiClass clazz = result.getElement(); if (clazz == null) return null; JavaPsiFacade facade = JavaPsiFacade.getInstance(project); @SuppressWarnings({"ConstantConditions"}) PsiClass collectionClass = facade.findClass("java.util.Collection", type.getResolveScope()); if (collectionClass == null || collectionClass.getTypeParameters().length != 1) return null; PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(collectionClass, clazz, result.getSubstitutor()); if (substitutor == null) return null; PsiType componentType = substitutor.substitute(collectionClass.getTypeParameters()[0]); return componentType instanceof PsiIntersectionType ? null : componentType; }
public static TypeConversionDescriptor wrapWithNewExpression(PsiType to, PsiType from, @Nullable PsiExpression expression, PsiElement context) { final String typeText = PsiDiamondTypeUtil.getCollapsedType(to, context); final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(to); final PsiClass atomicClass = resolveResult.getElement(); LOG.assertTrue(atomicClass != null); final PsiTypeParameter[] typeParameters = atomicClass.getTypeParameters(); if (typeParameters.length == 1) { final PsiType initial = resolveResult.getSubstitutor().substitute(typeParameters[0]); final PsiPrimitiveType unboxedInitialType = PsiPrimitiveType.getUnboxedType(initial); if (unboxedInitialType != null) { LOG.assertTrue(initial != null); if (from instanceof PsiPrimitiveType) { final PsiClassType boxedFromType = ((PsiPrimitiveType)from).getBoxedType(atomicClass); LOG.assertTrue(boxedFromType != null); if (!TypeConversionUtil.isAssignable(initial, boxedFromType)) { return new TypeConversionDescriptor("$val$", "new " + typeText + "((" + unboxedInitialType.getCanonicalText() + ")$val$)", expression); } } } } return new TypeConversionDescriptor("$val$", "new " + typeText + "($val$)", expression); }
private static String getHandlerSignature(JavaFxEventHandlerReference ref) { final XmlAttributeValue element = ref.getElement(); String canonicalText = JavaFxCommonClassNames.JAVAFX_EVENT; final PsiElement parent = element.getParent(); if (parent instanceof XmlAttribute) { final XmlAttribute xmlAttribute = (XmlAttribute)parent; final Project project = element.getProject(); final PsiField handlerField = ref.myCurrentTagClass.findFieldByName(xmlAttribute.getName(), true); if (handlerField != null) { final PsiClassType classType = JavaFxPsiUtil.getPropertyClassType(handlerField); if (classType != null) { final PsiClass eventHandlerClass = JavaPsiFacade.getInstance(project).findClass(JavaFxCommonClassNames.JAVAFX_EVENT_EVENT_HANDLER, GlobalSearchScope.allScope(project)); final PsiTypeParameter[] typeParameters = eventHandlerClass != null ? eventHandlerClass.getTypeParameters() : null; if (typeParameters != null && typeParameters.length == 1) { final PsiTypeParameter typeParameter = typeParameters[0]; final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(eventHandlerClass, classType); final PsiType eventType = substitutor.substitute(typeParameter); if (eventType != null) { canonicalText = eventType.getCanonicalText(); } } } } } return "public void " + element.getValue().substring(1) + "(" + canonicalText + " e)"; }
@NonNls @Nullable public TypeConversionDescriptorBase findConversion(final PsiType from, final PsiType to, final PsiMember member, final PsiExpression context, final boolean isCovariantPosition, final TypeMigrationLabeler labeler) { final TypeConversionDescriptorBase conversion = findConversion(from, to, member, context, labeler); if (conversion != null) return conversion; if (isCovariantPosition) { if (to instanceof PsiEllipsisType) { if (TypeConversionUtil.isAssignable(((PsiEllipsisType)to).getComponentType(), from)) return new TypeConversionDescriptorBase(); } if (TypeConversionUtil.isAssignable(to, from)) return new TypeConversionDescriptorBase(); } return !isCovariantPosition && TypeConversionUtil.isAssignable(from, to) ? new TypeConversionDescriptorBase() : null; }
@Override @Nullable public ResolvedClass getTypeClass() { if (!TypeConversionUtil.isPrimitiveAndNotNull(myType)) { GlobalSearchScope resolveScope = myType.getResolveScope(); if (resolveScope != null && resolveScope.getProject() != null) { ApplicationManager.getApplication().assertReadAccessAllowed(); PsiClass aClass = JavaPsiFacade.getInstance(resolveScope.getProject()).findClass(getSignature(), resolveScope); if (aClass != null) { return new ResolvedPsiClass(aClass); } } } return null; }
@Nullable private static PsiType inferGenericArgType(@NotNull GrClosureSignature signature, @NotNull PsiType targetType, int genericIndex, int param) { if (targetType instanceof PsiClassType) { final PsiClassType.ClassResolveResult result = ((PsiClassType)targetType).resolveGenerics(); final PsiClass psiClass = result.getElement(); if (psiClass != null) { final PsiSubstitutor substitutor = result.getSubstitutor(); final PsiType baseType = signature.getParameters()[param].getType(); final PsiClass baseClass = PsiUtil.resolveClassInClassTypeOnly(baseType); if (baseClass != null && InheritanceUtil.isInheritorOrSelf(psiClass, baseClass, true)) { final PsiTypeParameter[] typeParameters = baseClass.getTypeParameters(); if (genericIndex < typeParameters.length) { final PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(baseClass, psiClass, substitutor); return superClassSubstitutor.substitute(typeParameters[genericIndex]); } } } } return null; }
static VariablesProcessor findVariablesOfType(final PsiDeclarationStatement declaration, final PsiType type) { VariablesProcessor proc = new VariablesProcessor(false) { @Override protected boolean check(PsiVariable var, ResolveState state) { for (PsiElement element : declaration.getDeclaredElements()) { if (element == var) return false; } return TypeConversionUtil.isAssignable(var.getType(), type); } }; PsiElement scope = declaration; while (scope != null) { if (scope instanceof PsiFile || scope instanceof PsiMethod || scope instanceof PsiLambdaExpression || scope instanceof PsiClassInitializer) break; scope = scope.getParent(); } if (scope == null) return proc; PsiScopesUtil.treeWalkUp(proc, declaration, scope); return proc; }
@SuppressWarnings({"HardCodedStringLiteral"}) private static void appendJVMSignature(JVMNameBuffer buffer , PsiType type){ if (type == null) { return; } final PsiType psiType = TypeConversionUtil.erasure(type); if (psiType instanceof PsiArrayType) { buffer.append(new JVMRawText("[")); appendJVMSignature(buffer, ((PsiArrayType) psiType).getComponentType()); } else if (psiType instanceof PsiClassType) { final JVMName jvmName = getJVMQualifiedName(psiType); appendJvmClassQualifiedName(buffer, jvmName); } else if (psiType instanceof PsiPrimitiveType) { buffer.append(getPrimitiveSignature(psiType.getCanonicalText())); } else { LOG.error("unknown type " + type.getCanonicalText()); } }
private boolean applyUnboxedRelation(DfaVariableValue dfaLeft, DfaValue dfaRight, boolean negated) { PsiType type = dfaLeft.getVariableType(); if (!TypeConversionUtil.isPrimitiveWrapper(type)) { return true; } if (negated) { // from the fact "wrappers are not the same" it does not follow that "unboxed values are not equal" return true; } DfaBoxedValue.Factory boxedFactory = myFactory.getBoxedFactory(); DfaValue unboxedLeft = boxedFactory.createUnboxed(dfaLeft); DfaValue unboxedRight = boxedFactory.createUnboxed(dfaRight); return applyRelation(unboxedLeft, unboxedRight, false) && checkCompareWithBooleanLiteral(unboxedLeft, unboxedRight, false); }
@NotNull public DfaConstValue createFromValue(Object value, final PsiType type, @Nullable PsiVariable constant) { if (value == Boolean.TRUE) return dfaTrue; if (value == Boolean.FALSE) return dfaFalse; if (TypeConversionUtil.isNumericType(type) && !TypeConversionUtil.isFloatOrDoubleType(type)) { value = TypeConversionUtil.computeCastTo(value, PsiType.LONG); } if (value instanceof Double || value instanceof Float) { double doubleValue = ((Number)value).doubleValue(); if (doubleValue == -0.0) doubleValue = +0.0; value = new Double(doubleValue); } DfaConstValue instance = myValues.get(value); if (instance == null) { instance = new DfaConstValue(value, myFactory, constant); myValues.put(value, instance); } return instance; }
public static void register(HighlightInfo highlightInfo, PsiExpression expression, @NotNull PsiType lType) { if (lType != PsiType.NULL && expression instanceof PsiConditionalExpression) { final PsiExpression thenExpression = ((PsiConditionalExpression)expression).getThenExpression(); final PsiExpression elseExpression = ((PsiConditionalExpression)expression).getElseExpression(); if (thenExpression != null && elseExpression != null) { final PsiType thenType = thenExpression.getType(); final PsiType elseType = elseExpression.getType(); if (thenType != null && elseType != null) { final boolean thenAssignable = TypeConversionUtil.isAssignable(lType, thenType); final boolean elseAssignable = TypeConversionUtil.isAssignable(lType, elseType); if (!thenAssignable && thenExpression instanceof PsiMethodCallExpression) { inferTypeArgs(highlightInfo, lType, thenExpression); } if (!elseAssignable && elseExpression instanceof PsiMethodCallExpression) { inferTypeArgs(highlightInfo, lType, elseExpression); } } } } }
@Override public boolean isMemberEnabled(GrMemberInfo member) { PsiClass currentSuperClass = getSuperClass(); if(currentSuperClass == null) return true; if (myMemberInfoStorage.getDuplicatedMemberInfos(currentSuperClass).contains(member)) return false; if (myMemberInfoStorage.getExtending(currentSuperClass).contains(member.getMember())) return false; if (!currentSuperClass.isInterface()) return true; PsiElement element = member.getMember(); if (element instanceof PsiClass && ((PsiClass) element).isInterface()) return true; if (element instanceof PsiField) { return ((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC); } if (element instanceof PsiMethod) { if (currentSuperClass.isInterface()) { final PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(currentSuperClass, myClass, PsiSubstitutor.EMPTY); final MethodSignature signature = ((PsiMethod)element).getSignature(superSubstitutor); final PsiMethod superClassMethod = MethodSignatureUtil.findMethodBySignature(currentSuperClass, signature, false); if (superClassMethod != null) return false; } return !((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC); } return true; }
private static boolean appendJvmSignature(@NonNull StringBuilder buffer, @Nullable PsiType type) { if (type == null) { return false; } final PsiType psiType = TypeConversionUtil.erasure(type); if (psiType instanceof PsiArrayType) { buffer.append('['); appendJvmSignature(buffer, ((PsiArrayType)psiType).getComponentType()); } else if (psiType instanceof PsiClassType) { PsiClass resolved = ((PsiClassType)psiType).resolve(); if (resolved == null) { return false; } if (!appendJvmTypeName(buffer, resolved)) { return false; } } else if (psiType instanceof PsiPrimitiveType) { buffer.append(JVMNameUtil.getPrimitiveSignature(psiType.getCanonicalText())); } else { return false; } return true; }
@Nullable private static PsiType getBroaderType(PsiType currentType, PsiType castType) { if (currentType != null) { if (castType != null) { if (TypeConversionUtil.isAssignable(castType, currentType)) { return castType; } else if (!TypeConversionUtil.isAssignable(currentType, castType)) { for (PsiType superType : castType.getSuperTypes()) { if (TypeConversionUtil.isAssignable(superType, currentType)) { return superType; } } return null; } } } else { return castType; } return currentType; }
private static void addInheritors(CompletionParameters parameters, final CompletionResultSet resultSet, final PsiClass referencedClass, final int parameterIndex) { final List<PsiClassType> typeList = Collections.singletonList((PsiClassType)TypeConversionUtil.typeParameterErasure( referencedClass.getTypeParameters()[parameterIndex])); JavaInheritorsGetter.processInheritors(parameters, typeList, resultSet.getPrefixMatcher(), new Consumer<PsiType>() { @Override public void consume(final PsiType type) { final PsiClass psiClass = PsiUtil.resolveClassInType(type); if (psiClass == null) return; resultSet.addElement(TailTypeDecorator.withTail(new JavaPsiClassReferenceElement(psiClass), getTail(parameterIndex == referencedClass.getTypeParameters().length - 1))); } }); }
@Override public String getConflictMessage() { if (!TypeConversionUtil.isAssignable(myOriginalType, myTargetClassType)) { final String conflict = "No consistent substitution found for " + getElement().getText() + ". Expected \'" + myOriginalType.getPresentableText() + "\' but found \'" + myTargetClassType.getPresentableText() + "\'."; if (myConflict == null) { myConflict = conflict; } else { myConflict += "\n" + conflict; } } return myConflict; }
@Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { if (!myArrayAccessExpression.isValid()) return false; if (!TypeConversionUtil.areTypesAssignmentCompatible(PsiType.INT, myArrayAccessExpression.getIndexExpression())) { return false; } final PsiElement parent = myArrayAccessExpression.getParent(); if (parent instanceof PsiAssignmentExpression) { final PsiExpression lExpression = ((PsiAssignmentExpression)parent).getLExpression(); if (lExpression.equals(myArrayAccessExpression) && !(parent.getParent() instanceof PsiExpressionStatement)) { return false; } } final PsiExpression arrayExpression = myArrayAccessExpression.getArrayExpression(); final PsiType type = arrayExpression.getType(); final PsiType listType = createUtilListType(project); if (type == null || listType == null) return false; return listType.isAssignableFrom(type); }
@Override public boolean isAvailable(@NotNull Project project, @NotNull PsiFile file, @NotNull PsiElement startElement, @NotNull PsiElement endElement) { final PsiMethod myMethod = (PsiMethod)startElement; PsiType myReturnType = myReturnTypePointer.getType(); return myMethod.isValid() && myMethod.getManager().isInProject(myMethod) && myReturnType != null && myReturnType.isValid() && !TypeConversionUtil.isNullType(myReturnType) && myMethod.getReturnType() != null && !Comparing.equal(myReturnType, myMethod.getReturnType()); }
@Override public boolean isMemberEnabled(MemberInfo member) { final PsiClass currentSuperClass = getSuperClass(); if(currentSuperClass == null) return true; if (myMemberInfoStorage.getDuplicatedMemberInfos(currentSuperClass).contains(member)) return false; if (myMemberInfoStorage.getExtending(currentSuperClass).contains(member.getMember())) return false; final boolean isInterface = currentSuperClass.isInterface(); if (!isInterface) return true; PsiElement element = member.getMember(); if (element instanceof PsiClass && ((PsiClass) element).isInterface()) return true; if (element instanceof PsiField) { return ((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC); } if (element instanceof PsiMethod) { final PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(currentSuperClass, myClass, PsiSubstitutor.EMPTY); final MethodSignature signature = ((PsiMethod) element).getSignature(superSubstitutor); final PsiMethod superClassMethod = MethodSignatureUtil.findMethodBySignature(currentSuperClass, signature, false); if (superClassMethod != null && !PsiUtil.isLanguageLevel8OrHigher(currentSuperClass)) return false; return !((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC) || PsiUtil.isLanguageLevel8OrHigher(currentSuperClass); } return true; }
@Nullable private static PsiType getTypeFromMapAccess(@NotNull GrReferenceExpressionImpl ref) { //map access GrExpression qualifier = ref.getQualifierExpression(); if (qualifier != null) { PsiType qType = qualifier.getNominalType(); if (qType instanceof PsiClassType) { PsiClassType.ClassResolveResult qResult = ((PsiClassType)qType).resolveGenerics(); PsiClass clazz = qResult.getElement(); if (clazz != null) { PsiClass mapClass = JavaPsiFacade.getInstance(ref.getProject()).findClass(CommonClassNames.JAVA_UTIL_MAP, ref.getResolveScope()); if (mapClass != null && mapClass.getTypeParameters().length == 2) { PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(mapClass, clazz, qResult.getSubstitutor()); if (substitutor != null) { PsiType substituted = substitutor.substitute(mapClass.getTypeParameters()[1]); if (substituted != null) { return PsiImplUtil.normalizeWildcardTypeByPosition(substituted, ref); } } } } } } return null; }
private void getExpectedArgumentsTypesForNewExpression(@NotNull final PsiNewExpression newExpr, @NotNull final PsiExpressionList list) { PsiType newType = newExpr.getType(); if (newType instanceof PsiClassType) { JavaResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(newType); PsiClass newClass = (PsiClass)resolveResult.getElement(); final PsiSubstitutor substitutor; if (newClass instanceof PsiAnonymousClass) { final PsiAnonymousClass anonymous = (PsiAnonymousClass)newClass; newClass = anonymous.getBaseClassType().resolve(); if (newClass == null) return; substitutor = TypeConversionUtil.getSuperClassSubstitutor(newClass, anonymous, PsiSubstitutor.EMPTY); } else if (newClass != null) { substitutor = resolveResult.getSubstitutor(); } else { return; } getExpectedTypesForConstructorCall(newClass, list, substitutor); } }
protected static void chooseAndImplement(PsiClass psiClass, Project project, @NotNull PsiClass targetClass, Editor editor) { boolean hasNonTrivialConstructor = false; final PsiMethod[] constructors = psiClass.getConstructors(); for (PsiMethod constructor : constructors) { if (constructor.getParameterList().getParametersCount() > 0) { hasNonTrivialConstructor = true; break; } } if (hasNonTrivialConstructor) { final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(psiClass, targetClass, PsiSubstitutor.EMPTY); final List<PsiMethodMember> baseConstructors = new ArrayList<PsiMethodMember>(); for (PsiMethod baseConstr : constructors) { if (PsiUtil.isAccessible(project, baseConstr, targetClass, targetClass)) { baseConstructors.add(new PsiMethodMember(baseConstr, substitutor)); } } final int offset = editor.getCaretModel().getOffset(); CreateConstructorMatchingSuperFix.chooseConstructor2Delegate(project, editor, substitutor, baseConstructors, constructors, targetClass); editor.getCaretModel().moveToOffset(offset); } OverrideImplementUtil.chooseAndImplementMethods(project, editor, targetClass); }
private static LightMethodBuilder mirrorMethod(PsiClass typeDefinition, PsiMethod method, PsiClass baseClass, PsiSubstitutor substitutor) { final LightMethodBuilder builder = new LightMethodBuilder(method.getManager(), method.getName()); substitutor = substitutor.putAll(TypeConversionUtil.getSuperClassSubstitutor(baseClass, typeDefinition, PsiSubstitutor.EMPTY)); for (PsiParameter parameter : method.getParameterList().getParameters()) { builder.addParameter(StringUtil.notNullize(parameter.getName()), substitutor.substitute(parameter.getType())); } builder.setMethodReturnType(substitutor.substitute(method.getReturnType())); for (String modifier : STUB_MODIFIERS) { if (method.hasModifierProperty(modifier)) { builder.addModifier(modifier); } } return builder; }
@Override public void visitPolyadicExpression(PsiPolyadicExpression expression) { super.visitPolyadicExpression(expression); final IElementType tokenType = expression.getOperationTokenType(); if (ComparisonUtils.isComparisonOperation(tokenType)) { return; } final PsiExpression[] operands = expression.getOperands(); PsiType leftType = operands[0].getType(); for (int i = 1; i < operands.length; i++) { final PsiExpression operand = operands[i]; final PsiType rightType = operand.getType(); final PsiType expressionType = TypeConversionUtil.calcTypeForBinaryExpression(leftType, rightType, tokenType, true); if (TypeUtils.isJavaLangString(expressionType)) { return; } if (PsiType.CHAR.equals(rightType)) { registerError(operand, operand); } if (PsiType.CHAR.equals(leftType) && i == 1) { registerError(operands[0], operands[0]); } leftType = rightType; } }
@Override public void visitReturnStatement(PsiReturnStatement statement) { // has to change method return type corresponding to new value type super.visitReturnStatement(statement); final PsiElement method = PsiTreeUtil.getParentOfType(statement, PsiMethod.class, PsiLambdaExpression.class); final PsiExpression value = statement.getReturnValue(); if (method != null && value != null) { if (method instanceof PsiLambdaExpression) { //todo [IDEA-133097] return; } final PsiType returnType = ((PsiMethod)method).getReturnType(); final PsiType valueType = myTypeEvaluator.evaluateType(value); if (returnType != null && valueType != null) { if (!myLabeler.addMigrationRoot(method, valueType, myStatement, TypeConversionUtil.isAssignable(returnType, valueType), true) && TypeMigrationLabeler.typeContainsTypeParameters(returnType)) { myLabeler.markFailedConversion(Pair.create(returnType, valueType), value); } } } }
private void checkExpression(PsiExpression expression) { if (expression.getParent() instanceof PsiParenthesizedExpression) { return; } final PsiType expressionType = expression.getType(); if (!TypeConversionUtil.isAssignableFromPrimitiveWrapper(expressionType)) { return; } final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, false, true); if (!TypeConversionUtil.isPrimitiveAndNotNull(expectedType)) { return; } if (!(expression.getParent() instanceof PsiTypeCastExpression)) { final PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(expressionType); if (unboxedType == null || !expectedType.isAssignableFrom(unboxedType)) { return; } } registerError(expression, expression); }
private boolean isFieldMissingNullAnnotation(PsiField field, PsiType type) { return reportFields && field.isPhysical() && !(field instanceof PsiEnumConstant) && !TypeConversionUtil.isPrimitiveAndNotNull(type) && shouldCheckField(field) && !hasAnnotation(field); }
private boolean shouldInlineParameterName(int paramIndex) { PsiExpression argument = myCallArguments[paramIndex]; if (isLiteralExpression(argument) && argument.getType() != null) { PsiParameter parameter = myParameters[paramIndex]; String paramName = parameter.getName(); if (paramName != null && paramName.length() >= MIN_NAME_LENGTH_THRESHOLD) { return TypeConversionUtil.isAssignable(parameter.getType(), argument.getType()); } } return false; }
private JavaResolveResult advancedResolveImpl(@NotNull PsiFile containingFile) { PsiTypeElement[] typeElements = myRefParameterList == null ? PsiTypeElement.EMPTY_ARRAY : myRefParameterList.getTypeParameterElements(); PsiElement resolve = resolveElement(containingFile); if (resolve == null) return null; if (resolve instanceof PsiClass) { Map<PsiTypeParameter, PsiType> substitutionMap = new HashMap<PsiTypeParameter, PsiType>(); int index = 0; for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable((PsiClass)resolve)) { if (index >= typeElements.length) { PsiTypeParameterListOwner parameterOwner = parameter.getOwner(); if (parameterOwner == resolve) { substitutionMap.put(parameter, null); } else if (parameterOwner instanceof PsiClass) { PsiElement containingClass = myParent; while ((containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class, true)) != null) { PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getClassSubstitutor((PsiClass)parameterOwner, (PsiClass)containingClass, PsiSubstitutor.EMPTY); if (superClassSubstitutor != null) { substitutionMap.put(parameter, superClassSubstitutor.substitute(parameter)); break; } } } } else { substitutionMap.put(parameter, typeElements[index].getType()); } index++; } collectOuterClassTypeArgs((PsiClass)resolve, myCanonicalText, substitutionMap); return new CandidateInfo(resolve, PsiSubstitutorImpl.createSubstitutor(substitutionMap)); } else { return new CandidateInfo(resolve, PsiSubstitutor.EMPTY); } }
private static boolean isAddressed(List<PsiType> expectedThrownTypes, PsiType thrownType) { for (PsiType expectedThrownType : expectedThrownTypes) { if (TypeConversionUtil.isAssignable(TypeConversionUtil.erasure(thrownType), expectedThrownType)) { return true; } } return false; }
@Nullable public <T extends PsiExpression> PsiType getType(@NotNull T expr, @NotNull Function<T, PsiType> f) { final boolean isOverloadCheck = MethodCandidateInfo.isOverloadCheck(); PsiType type = isOverloadCheck ? null : myCalculatedTypes.get(expr); if (type == null) { final RecursionGuard.StackStamp dStackStamp = PsiDiamondType.ourDiamondGuard.markStack(); type = f.fun(expr); if (!dStackStamp.mayCacheNow() || isOverloadCheck) { return type; } if (type == null) type = TypeConversionUtil.NULL_TYPE; myCalculatedTypes.put(expr, type); if (type instanceof PsiClassReferenceType) { // convert reference-based class type to the PsiImmediateClassType, since the reference may become invalid PsiClassType.ClassResolveResult result = ((PsiClassReferenceType)type).resolveGenerics(); PsiClass psiClass = result.getElement(); type = psiClass == null ? type // for type with unresolved reference, leave it in the cache // for clients still might be able to retrieve its getCanonicalText() from the reference text : new PsiImmediateClassType(psiClass, result.getSubstitutor(), ((PsiClassReferenceType)type).getLanguageLevel(), type.getAnnotations()); } } if (!type.isValid()) { if (expr.isValid()) { PsiJavaCodeReferenceElement refInside = type instanceof PsiClassReferenceType ? ((PsiClassReferenceType)type).getReference() : null; @NonNls String typeinfo = type + " (" + type.getClass() + ")" + (refInside == null ? "" : "; ref inside: "+refInside + " ("+refInside.getClass()+") valid:"+refInside.isValid()); LOG.error("Type is invalid: " + typeinfo + "; expr: '" + expr + "' (" + expr.getClass() + ") is valid"); } else { LOG.error("Expression: '"+expr+"' is invalid, must not be used for getType()"); } } return type == TypeConversionUtil.NULL_TYPE ? null : type; }
@Override public void visitReferenceExpression(PsiReferenceExpression expression) { super.visitReferenceExpression(expression); if (expression instanceof PsiMethodReferenceExpression) { final PsiMethodReferenceExpression methodReferenceExpression = (PsiMethodReferenceExpression)expression; if (methodReferenceExpression.isConstructor()) { return; } final PsiElement referenceNameElement = methodReferenceExpression.getReferenceNameElement(); if (referenceNameElement == null) { return; } final PsiElement target = methodReferenceExpression.resolve(); if (!(target instanceof PsiMethod)) { return; } final PsiMethod method = (PsiMethod)target; final PsiType returnType = method.getReturnType(); if (returnType == null || returnType.equals(PsiType.VOID) || !TypeConversionUtil.isPrimitiveAndNotNull(returnType)) { return; } final PsiPrimitiveType primitiveType = (PsiPrimitiveType)returnType; final PsiClassType boxedType = primitiveType.getBoxedType(expression); if (boxedType == null) { return; } final PsiType functionalInterfaceReturnType = LambdaUtil.getFunctionalInterfaceReturnType(methodReferenceExpression); if (functionalInterfaceReturnType == null || ClassUtils.isPrimitive(functionalInterfaceReturnType) || !functionalInterfaceReturnType.isAssignableFrom(boxedType)) { return; } registerError(referenceNameElement); } else { checkExpression(expression); } }
@Nullable("null if ref is not 'super' reference") public static GroovyResolveResult[] resolveSuperExpression(@NotNull GrReferenceExpression ref) { GrExpression qualifier = ref.getQualifier(); if (qualifier == null) { final PsiElement parent = ref.getParent(); if (parent instanceof GrConstructorInvocation) { return ((GrConstructorInvocation)parent).multiResolve(false); } PsiClass aClass = PsiUtil.getContextClass(ref); if (aClass != null) { return getSuperClass(aClass); } } else if (qualifier instanceof GrReferenceExpression) { GroovyResolveResult result = ((GrReferenceExpression)qualifier).advancedResolve(); PsiElement resolved = result.getElement(); if (resolved instanceof PsiClass) { PsiClass superClass = (PsiClass)resolved; GrTypeDefinition scopeClass = PsiTreeUtil.getParentOfType(ref, GrTypeDefinition.class, true); if (scopeClass != null && GrTraitUtil.isTrait(superClass) && scopeClass.isInheritor(superClass, false)) { PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, scopeClass, PsiSubstitutor.EMPTY); return new GroovyResolveResultImpl[]{new GroovyResolveResultImpl(superClass, null, null, superClassSubstitutor, true, true)}; } if (PsiUtil.hasEnclosingInstanceInScope(superClass, ref, false)) { return getSuperClass(superClass); } } } return null; }
private static PsiType doGetType(PsiBinaryExpressionImpl param) { PsiExpression lOperand = param.getLOperand(); PsiExpression rOperand = param.getROperand(); if (rOperand == null) return null; PsiType rType = rOperand.getType(); IElementType sign = param.getOperationTokenType(); // optimization: if we can calculate type based on right type only PsiType type = TypeConversionUtil.calcTypeForBinaryExpression(null, rType, sign, false); if (type != TypeConversionUtil.NULL_TYPE) return type; PsiType lType = lOperand.getType(); return TypeConversionUtil.calcTypeForBinaryExpression(lType, rType, sign, true); }
private static boolean arrayCreationSignature(MethodSignature signature) { final PsiType[] parameterTypes = signature.getParameterTypes(); if (parameterTypes.length == 1 && parameterTypes[0] != null && TypeConversionUtil.isAssignable(PsiType.INT, parameterTypes[0])) { return true; } return false; }
@Nullable private PsiAnnotation findNullabilityAnnotationWithDefault(@NotNull PsiModifierListOwner owner, boolean checkBases, boolean nullable) { PsiAnnotation annotation = findPlainNullabilityAnnotation(owner, checkBases); if (annotation != null) { String qName = annotation.getQualifiedName(); if (qName == null) return null; List<String> contradictory = nullable ? getNotNulls() : getNullables(); if (contradictory.contains(qName)) return null; return annotation; } PsiType type = getOwnerType(owner); if (type == null || TypeConversionUtil.isPrimitiveAndNotNull(type)) return null; // even if javax.annotation.Nullable is not configured, it should still take precedence over ByDefault annotations if (AnnotationUtil.isAnnotated(owner, nullable ? Arrays.asList(DEFAULT_NOT_NULLS) : Arrays.asList(DEFAULT_NULLABLES), checkBases, false)) { return null; } if (!nullable && hasHardcodedContracts(owner)) { return null; } return findNullabilityDefaultInHierarchy(owner, nullable); }
@Override public void visitAssignmentExpression(PsiAssignmentExpression expression) { final PsiExpression rExpression = expression.getRExpression(); if(rExpression == null) { throwExpressionInvalid(expression); } rExpression.accept(this); Evaluator rEvaluator = myResult; final PsiExpression lExpression = expression.getLExpression(); final PsiType lType = lExpression.getType(); if(lType == null) { throwEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", lExpression.getText())); } IElementType assignmentType = expression.getOperationTokenType(); PsiType rType = rExpression.getType(); if(!TypeConversionUtil.areTypesAssignmentCompatible(lType, rExpression) && rType != null) { throwEvaluateException(DebuggerBundle.message("evaluation.error.incompatible.types", expression.getOperationSign().getText())); } lExpression.accept(this); Evaluator lEvaluator = myResult; rEvaluator = handleAssignmentBoxingAndPrimitiveTypeConversions(lType, rType, rEvaluator); if (assignmentType != JavaTokenType.EQ) { IElementType opType = TypeConversionUtil.convertEQtoOperation(assignmentType); final PsiType typeForBinOp = TypeConversionUtil.calcTypeForBinaryExpression(lType, rType, opType, true); if (typeForBinOp == null || rType == null) { throwEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", expression.getText())); } rEvaluator = createBinaryEvaluator(lEvaluator, lType, rEvaluator, rType, opType, typeForBinOp); } myResult = new AssignmentEvaluator(lEvaluator, rEvaluator); }
@Override public void visitPolyadicExpression(PsiPolyadicExpression wideExpression) { if (LOG.isDebugEnabled()) { LOG.debug("visitPolyadicExpression " + wideExpression); } PsiExpression[] operands = wideExpression.getOperands(); operands[0].accept(this); Evaluator result = myResult; PsiType lType = operands[0].getType(); for (int i = 1; i < operands.length; i++) { PsiExpression expression = operands[i]; if (expression == null) { throwExpressionInvalid(wideExpression); } expression.accept(this); Evaluator rResult = myResult; IElementType opType = wideExpression.getOperationTokenType(); PsiType rType = expression.getType(); if (rType == null) { throwEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", expression.getText())); } final PsiType typeForBinOp = TypeConversionUtil.calcTypeForBinaryExpression(lType, rType, opType, true); if (typeForBinOp == null) { throwEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", wideExpression.getText())); } myResult = createBinaryEvaluator(result, lType, rResult, rType, opType, typeForBinOp); lType = typeForBinOp; result = myResult; } }