@Nullable public static List<ValueParameterDescriptor> getSubstitutedValueParameters( FunctionDescriptor substitutedDescriptor, @NotNull FunctionDescriptor functionDescriptor, @NotNull TypeSubstitutor substitutor) { List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(); List<ValueParameterDescriptor> unsubstitutedValueParameters = functionDescriptor.getValueParameters(); for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) { ValueParameterDescriptor unsubstitutedValueParameter = unsubstitutedValueParameters.get(i); // TODO : Lazy? JetType substitutedType = substitutor.substitute(unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE); JetType varargElementType = unsubstitutedValueParameter.getVarargElementType(); JetType substituteVarargElementType = varargElementType == null ? null : substitutor.substitute(varargElementType, Variance.IN_VARIANCE); if (substitutedType == null) return null; result.add( new ValueParameterDescriptorImpl( substitutedDescriptor, unsubstitutedValueParameter, unsubstitutedValueParameter.getAnnotations(), unsubstitutedValueParameter.isVar(), substitutedType, substituteVarargElementType)); } return result; }
private static String renderParameter( ValueParameterDescriptor descriptor, boolean named, BindingContext bindingContext) { StringBuilder builder = new StringBuilder(); if (named) builder.append("["); if (descriptor.getVarargElementType() != null) { builder.append("vararg "); } builder .append(descriptor.getName()) .append(": ") .append(DescriptorRenderer.TEXT.renderType(getActualParameterType(descriptor))); if (descriptor.hasDefaultValue()) { PsiElement element = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor); String defaultExpression = "?"; if (element instanceof JetParameter) { JetParameter parameter = (JetParameter) element; JetExpression defaultValue = parameter.getDefaultValue(); if (defaultValue != null) { if (defaultValue instanceof JetConstantExpression) { JetConstantExpression constantExpression = (JetConstantExpression) defaultValue; defaultExpression = constantExpression.getText(); if (defaultExpression.length() > 10) { if (defaultExpression.startsWith("\"")) defaultExpression = "\"...\""; else if (defaultExpression.startsWith("\'")) defaultExpression = "\'...\'"; else defaultExpression = defaultExpression.substring(0, 7) + "..."; } } } } builder.append(" = ").append(defaultExpression); } if (named) builder.append("]"); return builder.toString(); }
@NotNull public static SimpleFunctionDescriptor createSamAdapterFunction( @NotNull SimpleFunctionDescriptor original) { SimpleFunctionDescriptorImpl result = new SimpleFunctionDescriptorImpl( original.getContainingDeclaration(), original.getAnnotations(), original.getName(), CallableMemberDescriptor.Kind.SYNTHESIZED); TypeParameters typeParameters = recreateAndInitializeTypeParameters(original.getTypeParameters(), result); JetType returnTypeUnsubstituted = original.getReturnType(); assert returnTypeUnsubstituted != null : original; JetType returnType = typeParameters.substitutor.substitute(returnTypeUnsubstituted, Variance.OUT_VARIANCE); assert returnType != null : "couldn't substitute type: " + returnType + ", substitutor = " + typeParameters.substitutor; List<ValueParameterDescriptor> valueParameters = Lists.newArrayList(); for (ValueParameterDescriptor originalParam : original.getValueParameters()) { JetType originalType = originalParam.getType(); JetType newTypeUnsubstituted = isSamType(originalType) ? getFunctionTypeForSamType(originalType) : originalType; JetType newType = typeParameters.substitutor.substitute(newTypeUnsubstituted, Variance.IN_VARIANCE); assert newType != null : "couldn't substitute type: " + newTypeUnsubstituted + ", substitutor = " + typeParameters.substitutor; ValueParameterDescriptor newParam = new ValueParameterDescriptorImpl( result, originalParam.getIndex(), originalParam.getAnnotations(), originalParam.getName(), newType, false, null); valueParameters.add(newParam); } result.initialize( null, original.getExpectedThisObject(), typeParameters.descriptors, valueParameters, returnType, original.getModality(), original.getVisibility(), false); return result; }
public static void genNotNullAssertionsForParameters( @NotNull InstructionAdapter v, @NotNull GenerationState state, @NotNull FunctionDescriptor descriptor, @NotNull FrameMap frameMap) { if (!state.isGenerateNotNullParamAssertions()) return; // Private method is not accessible from other classes, no assertions needed if (getVisibilityAccessFlag(descriptor) == ACC_PRIVATE) return; for (ValueParameterDescriptor parameter : descriptor.getValueParameters()) { JetType type = parameter.getReturnType(); if (type == null || isNullableType(type)) continue; int index = frameMap.getIndex(parameter); Type asmType = state.getTypeMapper().mapReturnType(type); if (asmType.getSort() == Type.OBJECT || asmType.getSort() == Type.ARRAY) { v.load(index, asmType); v.visitLdcInsn(descriptor.getName().asString()); v.invokestatic( "jet/runtime/Intrinsics", "checkParameterIsNotNull", "(Ljava/lang/Object;Ljava/lang/String;)V"); } } }
private void processPrimaryConstructor( @NotNull TopDownAnalysisContext c, @NotNull MutableClassDescriptor classDescriptor, @NotNull JetClass klass) { // TODO : not all the parameters are real properties JetScope memberScope = classDescriptor.getScopeForClassHeaderResolution(); ConstructorDescriptor constructorDescriptor = descriptorResolver.resolvePrimaryConstructorDescriptor( memberScope, classDescriptor, klass, trace); if (constructorDescriptor != null) { List<ValueParameterDescriptor> valueParameterDescriptors = constructorDescriptor.getValueParameters(); List<JetParameter> primaryConstructorParameters = klass.getPrimaryConstructorParameters(); assert valueParameterDescriptors.size() == primaryConstructorParameters.size(); List<ValueParameterDescriptor> notProperties = new ArrayList<ValueParameterDescriptor>(); for (ValueParameterDescriptor valueParameterDescriptor : valueParameterDescriptors) { JetParameter parameter = primaryConstructorParameters.get(valueParameterDescriptor.getIndex()); if (parameter.getValOrVarNode() != null) { PropertyDescriptor propertyDescriptor = descriptorResolver.resolvePrimaryConstructorParameterToAProperty( classDescriptor, valueParameterDescriptor, memberScope, parameter, trace); classDescriptor.getBuilder().addPropertyDescriptor(propertyDescriptor); c.getPrimaryConstructorParameterProperties().put(parameter, propertyDescriptor); } else { notProperties.add(valueParameterDescriptor); } } if (classDescriptor.getKind() != ClassKind.TRAIT) { classDescriptor.setPrimaryConstructor(constructorDescriptor); classDescriptor.addConstructorParametersToInitializersScope(notProperties); } } }
public static boolean isSamAdapterNecessary(@NotNull SimpleFunctionDescriptor fun) { for (ValueParameterDescriptor param : fun.getValueParameters()) { if (isSamType(param.getType())) { return true; } } return false; }
@NotNull private VarargCheckResult checkVarargInSuperFunctions( @NotNull ValueParameterDescriptor originalParam) { boolean someSupersVararg = false; boolean someSupersNotVararg = false; for (FunctionDescriptor superFunction : superFunctions) { if (superFunction.getValueParameters().get(originalParam.getIndex()).getVarargElementType() != null) { someSupersVararg = true; } else { someSupersNotVararg = true; } } JetType originalVarargElementType = originalParam.getVarargElementType(); JetType originalType = originalParam.getType(); if (someSupersVararg && someSupersNotVararg) { reportError("Incompatible super methods: some have vararg parameter, some have not"); return new VarargCheckResult(originalType, originalVarargElementType != null); } KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance(); if (someSupersVararg && originalVarargElementType == null) { // convert to vararg assert isArrayType(originalType); if (builtIns.isPrimitiveArray(originalType)) { // replace IntArray? with IntArray return new VarargCheckResult(TypeUtils.makeNotNullable(originalType), true); } // replace Array<out Foo>? with Array<Foo> JetType varargElementType = builtIns.getArrayElementType(originalType); return new VarargCheckResult(builtIns.getArrayType(INVARIANT, varargElementType), true); } else if (someSupersNotVararg && originalVarargElementType != null) { // convert to non-vararg assert isArrayType(originalType); if (builtIns.isPrimitiveArray(originalType)) { // replace IntArray with IntArray? return new VarargCheckResult(TypeUtils.makeNullable(originalType), false); } // replace Array<Foo> with Array<out Foo>? return new VarargCheckResult( TypeUtils.makeNullable( builtIns.getArrayType(Variance.OUT_VARIANCE, originalVarargElementType)), false); } return new VarargCheckResult(originalType, originalVarargElementType != null); }
private List<ValueParameterDescriptor> createValueParameterDescriptors( ExpressionTypingContext context, JetFunctionLiteral functionLiteral, FunctionDescriptorImpl functionDescriptor, boolean functionTypeExpected) { List<ValueParameterDescriptor> valueParameterDescriptors = Lists.newArrayList(); List<JetParameter> declaredValueParameters = functionLiteral.getValueParameters(); List<ValueParameterDescriptor> expectedValueParameters = (functionTypeExpected) ? JetStandardClasses.getValueParameters(functionDescriptor, context.expectedType) : null; boolean hasDeclaredValueParameters = functionLiteral.getValueParameterList() != null; if (functionTypeExpected && !hasDeclaredValueParameters && expectedValueParameters.size() == 1) { ValueParameterDescriptor valueParameterDescriptor = expectedValueParameters.get(0); ValueParameterDescriptor it = new ValueParameterDescriptorImpl( functionDescriptor, 0, Collections.<AnnotationDescriptor>emptyList(), "it", false, valueParameterDescriptor.getOutType(), valueParameterDescriptor.hasDefaultValue(), valueParameterDescriptor.getVarargElementType()); valueParameterDescriptors.add(it); context.trace.record(AUTO_CREATED_IT, it); } else { for (int i = 0; i < declaredValueParameters.size(); i++) { JetParameter declaredParameter = declaredValueParameters.get(i); JetTypeReference typeReference = declaredParameter.getTypeReference(); JetType type; if (typeReference != null) { type = context.getTypeResolver().resolveType(context.scope, typeReference); } else { if (expectedValueParameters != null && i < expectedValueParameters.size()) { type = expectedValueParameters.get(i).getOutType(); } else { context.trace.report(CANNOT_INFER_PARAMETER_TYPE.on(declaredParameter)); type = ErrorUtils.createErrorType("Cannot be inferred"); } } ValueParameterDescriptor valueParameterDescriptor = context .getDescriptorResolver() .resolveValueParameterDescriptor(functionDescriptor, declaredParameter, i, type); valueParameterDescriptors.add(valueParameterDescriptor); } } return valueParameterDescriptors; }
@NotNull private List<ValueParameterDescriptor> copyValueParameters( @NotNull FunctionDescriptor descriptor) { List<ValueParameterDescriptor> valueParameters = descriptor.getValueParameters(); List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(valueParameters.size()); for (ValueParameterDescriptor valueParameter : valueParameters) { result.add(valueParameter.copy(this, valueParameter.getName())); } return result; }
protected void renderValueParameter( ValueParameterDescriptor parameterDescriptor, boolean isLast, StringBuilder builder) { if (parameterDescriptor.getIndex() == 0) { builder.append("("); } parameterDescriptor.accept(subVisitor, builder); if (!isLast) { builder.append(", "); } else { builder.append(")"); } }
@NotNull private List<JsExpression> translateArguments() { List<JsExpression> result = new ArrayList<JsExpression>(); ResolvedCall<?> resolvedCall = getResolvedCallForCallExpression(bindingContext(), expression); for (ValueParameterDescriptor parameterDescriptor : resolvedCall.getResultingDescriptor().getValueParameters()) { ResolvedValueArgument actualArgument = resolvedCall.getValueArgumentsByIndex().get(parameterDescriptor.getIndex()); result.addAll(translateSingleArgument(actualArgument, parameterDescriptor)); } return result; }
public ValueParameterDescriptorImpl( @NotNull DeclarationDescriptor containingDeclaration, @NotNull ValueParameterDescriptor original, @NotNull List<AnnotationDescriptor> annotations, @NotNull JetType outType, @Nullable JetType varargElementType) { super(containingDeclaration, annotations, original.getName(), outType); this.original = original; this.index = original.getIndex(); this.declaresDefaultValue = original.declaresDefaultValue(); this.varargElementType = varargElementType; }
@NotNull private static List<ValueParameterDescriptor> createValueParameterDescriptors( @NotNull ExpressionTypingContext context, @NotNull JetFunctionLiteral functionLiteral, @NotNull FunctionDescriptorImpl functionDescriptor, boolean functionTypeExpected) { List<ValueParameterDescriptor> valueParameterDescriptors = Lists.newArrayList(); List<JetParameter> declaredValueParameters = functionLiteral.getValueParameters(); List<ValueParameterDescriptor> expectedValueParameters = (functionTypeExpected) ? KotlinBuiltIns.getInstance() .getValueParameters(functionDescriptor, context.expectedType) : null; JetParameterList valueParameterList = functionLiteral.getValueParameterList(); boolean hasDeclaredValueParameters = valueParameterList != null; if (functionTypeExpected && !hasDeclaredValueParameters && expectedValueParameters.size() == 1) { ValueParameterDescriptor valueParameterDescriptor = expectedValueParameters.get(0); ValueParameterDescriptor it = new ValueParameterDescriptorImpl( functionDescriptor, 0, Collections.<AnnotationDescriptor>emptyList(), Name.identifier("it"), valueParameterDescriptor.getType(), valueParameterDescriptor.hasDefaultValue(), valueParameterDescriptor.getVarargElementType()); valueParameterDescriptors.add(it); context.trace.record(AUTO_CREATED_IT, it); } else { if (expectedValueParameters != null && declaredValueParameters.size() != expectedValueParameters.size()) { List<JetType> expectedParameterTypes = DescriptorUtils.getValueParametersTypes(expectedValueParameters); context.trace.report( EXPECTED_PARAMETERS_NUMBER_MISMATCH.on( functionLiteral, expectedParameterTypes.size(), expectedParameterTypes)); } for (int i = 0; i < declaredValueParameters.size(); i++) { ValueParameterDescriptor valueParameterDescriptor = createValueParameterDescriptor( context, functionDescriptor, declaredValueParameters, expectedValueParameters, i); valueParameterDescriptors.add(valueParameterDescriptor); } } return valueParameterDescriptors; }
@Nullable public static ValueParameterDescriptor getAnnotationParameterByName( @NotNull Name name, @NotNull ClassDescriptor annotationClass) { Collection<ConstructorDescriptor> constructors = annotationClass.getConstructors(); assert constructors.size() == 1 : "Annotation class descriptor must have only one constructor"; for (ValueParameterDescriptor parameter : constructors.iterator().next().getValueParameters()) { if (parameter.getName().equals(name)) { return parameter; } } return null; }
@NotNull private static JetType getFunctionTypeForSamType(@NotNull JetType samType) { FunctionDescriptor function = getAbstractMethodOfSamType(samType); JetType returnType = function.getReturnType(); assert returnType != null : "function is not initialized: " + function; List<JetType> parameterTypes = Lists.newArrayList(); for (ValueParameterDescriptor parameter : function.getValueParameters()) { parameterTypes.add(parameter.getType()); } JetType functionType = KotlinBuiltIns.getInstance() .getFunctionType( Collections.<AnnotationDescriptor>emptyList(), null, parameterTypes, returnType); return TypeUtils.makeNullableAsSpecified(functionType, samType.isNullable()); }
private void computeDefaultValuePresence() { if (hasDefaultValue != null) return; overriddenDescriptorsLocked = true; if (declaresDefaultValue) { hasDefaultValue = true; } else { for (ValueParameterDescriptor descriptor : overriddenDescriptors) { if (descriptor.hasDefaultValue()) { hasDefaultValue = true; return; } } hasDefaultValue = false; } }
private void checkDefaultParameterValues( List<JetParameter> valueParameters, List<ValueParameterDescriptor> valueParameterDescriptors, JetScope declaringScope) { for (int i = 0; i < valueParameters.size(); i++) { ValueParameterDescriptor valueParameterDescriptor = valueParameterDescriptors.get(i); if (valueParameterDescriptor.hasDefaultValue()) { JetParameter jetParameter = valueParameters.get(i); JetExpression defaultValue = jetParameter.getDefaultValue(); if (defaultValue != null) { expressionTypingServices.getType( declaringScope, defaultValue, valueParameterDescriptor.getType(), trace); } } } }
private static String renderParameter( ValueParameterDescriptor parameter, boolean named, BindingContext bindingContext) { StringBuilder builder = new StringBuilder(); if (named) builder.append("["); if (parameter.getVarargElementType() != null) { builder.append("vararg "); } builder .append(parameter.getName()) .append(": ") .append( DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(getActualParameterType(parameter))); if (parameter.hasDefaultValue()) { PsiElement parameterDeclaration = BindingContextUtils.descriptorToDeclaration(bindingContext, parameter); builder.append(" = ").append(getDefaultExpressionString(parameterDeclaration)); } if (named) builder.append("]"); return builder.toString(); }
/* VARIABLES */ private void renderValueParameter( @NotNull ValueParameterDescriptor valueParameter, @NotNull StringBuilder builder, boolean topLevel) { if (topLevel) { builder.append(renderKeyword("value-parameter")).append(" "); } if (verbose) { builder.append("/*").append(valueParameter.getIndex()).append("*/ "); } renderAnnotations(valueParameter, builder); renderVariable(valueParameter, builder, topLevel); boolean withDefaultValue = debugMode ? valueParameter.declaresDefaultValue() : valueParameter.hasDefaultValue(); if (withDefaultValue) { builder.append(" = ..."); } }
private void createComponentFunctions( @NotNull MutableClassDescriptor classDescriptor, @NotNull ConstructorDescriptor constructorDescriptor) { int parameterIndex = 0; for (ValueParameterDescriptor parameter : constructorDescriptor.getValueParameters()) { if (!parameter.getType().isError()) { PropertyDescriptor property = trace.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter); if (property != null) { ++parameterIndex; SimpleFunctionDescriptor functionDescriptor = DescriptorResolver.createComponentFunctionDescriptor( parameterIndex, property, parameter, classDescriptor, trace); classDescriptor.getBuilder().addFunctionDescriptor(functionDescriptor); } } } }
private void checkParameterAndReturnTypesForOverridingMethods( @NotNull List<ValueParameterDescriptor> valueParameters, @NotNull List<TypeParameterDescriptor> methodTypeParameters, @Nullable JetType returnType) { TypeSubstitutor substitutor = DescriptorResolverUtils.createSubstitutorForTypeParameters(originalToAltTypeParameters); for (ValueParameterDescriptor parameter : valueParameters) { int index = parameter.getIndex(); ValueParameterDescriptor altParameter = altValueParameters.get(index); JetType substituted = substitutor.substitute(parameter.getType(), Variance.INVARIANT); assert substituted != null; if (!TypeUtils.equalTypes(substituted, altParameter.getType())) { throw new AlternativeSignatureMismatchException( "Parameter type changed for method which overrides another: " + altParameter.getType() + ", was: " + parameter.getType()); } } // don't check receiver for (TypeParameterDescriptor parameter : methodTypeParameters) { int index = parameter.getIndex(); JetType substituted = substitutor.substitute(parameter.getUpperBoundsAsType(), Variance.INVARIANT); assert substituted != null; if (!TypeUtils.equalTypes(substituted, altTypeParameters.get(index).getUpperBoundsAsType())) { throw new AlternativeSignatureMismatchException( "Type parameter's upper bound changed for method which overrides another: " + altTypeParameters.get(index).getUpperBoundsAsType() + ", was: " + parameter.getUpperBoundsAsType()); } } if (returnType != null) { JetType substitutedReturnType = substitutor.substitute(returnType, Variance.INVARIANT); assert substitutedReturnType != null; if (!JetTypeChecker.INSTANCE.isSubtypeOf(altReturnType, substitutedReturnType)) { throw new AlternativeSignatureMismatchException( "Return type is changed to not subtype for method which overrides another: " + altReturnType + ", was: " + returnType); } } }
@NotNull private FunctionDescriptor standardFunction( ClassDescriptor classDescriptor, List<TypeProjection> typeArguments, String name, JetType... parameterType) { List<JetType> parameterTypeList = Arrays.asList(parameterType); // JetTypeInferrer.Services typeInferrerServices = // JetSemanticServices.createSemanticServices(getProject()).getTypeInferrerServices(new // BindingTraceContext()); CallResolver callResolver = new InjectorForTests(getProject()).getCallResolver(); OverloadResolutionResults<FunctionDescriptor> functions = callResolver.resolveExactSignature( classDescriptor.getMemberScope(typeArguments), ReceiverDescriptor.NO_RECEIVER, name, parameterTypeList); for (ResolvedCall<? extends FunctionDescriptor> resolvedCall : functions.getResultingCalls()) { List<ValueParameterDescriptor> unsubstitutedValueParameters = resolvedCall.getResultingDescriptor().getValueParameters(); for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) { ValueParameterDescriptor unsubstitutedValueParameter = unsubstitutedValueParameters.get(i); if (unsubstitutedValueParameter.getType().equals(parameterType[i])) { return resolvedCall.getResultingDescriptor(); } } } throw new IllegalArgumentException( "Not found: kotlin::" + classDescriptor.getName() + "." + name + "(" + parameterTypeList + ")"); }
@Nullable public static JetChangeSignatureDialog createDialog( @NotNull PsiElement element, PsiElement context, Project project, Editor editor) { if (!CommonRefactoringUtil.checkReadOnlyStatus(project, element)) return null; BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) element.getContainingFile()) .getBindingContext(); DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element); if (descriptor instanceof ClassDescriptor) { descriptor = ((ClassDescriptor) descriptor).getUnsubstitutedPrimaryConstructor(); } if (descriptor instanceof FunctionDescriptorImpl) { for (ValueParameterDescriptor parameter : ((FunctionDescriptor) descriptor).getValueParameters()) { if (parameter.getVarargElementType() != null) { String message = JetRefactoringBundle.message("error.cant.refactor.vararg.functions"); CommonRefactoringUtil.showErrorHint( project, editor, message, REFACTORING_NAME, HelpID.CHANGE_SIGNATURE); return null; } } return new JetChangeSignatureDialog( project, new JetFunctionPlatformDescriptorImpl((FunctionDescriptor) descriptor, element), context); } else { String message = RefactoringBundle.getCannotRefactorMessage( JetRefactoringBundle.message( "error.wrong.caret.position.function.or.constructor.name")); CommonRefactoringUtil.showErrorHint( project, editor, message, REFACTORING_NAME, HelpID.CHANGE_SIGNATURE); return null; } }
@Nullable private CompileTimeConstant<?> getCompileTimeConstFromArrayExpression( FqName annotationFqName, Name valueName, PsiArrayInitializerMemberValue value, PostponedTasks taskList) { PsiAnnotationMemberValue[] initializers = value.getInitializers(); List<CompileTimeConstant<?>> values = getCompileTimeConstantForArrayValues(annotationFqName, valueName, taskList, initializers); ClassDescriptor classDescriptor = classResolver.resolveClass(annotationFqName, DescriptorSearchRule.INCLUDE_KOTLIN, taskList); // TODO: nullability issues ValueParameterDescriptor valueParameterDescriptor = DescriptorResolverUtils.getValueParameterDescriptorForAnnotationParameter( valueName, classDescriptor); if (valueParameterDescriptor == null) { return null; } JetType expectedArrayType = valueParameterDescriptor.getType(); return new ArrayValue(values, expectedArrayType); }
public static boolean containsErrorType(@NotNull FunctionDescriptor function) { if (containsErrorType(function.getReturnType())) { return true; } ReceiverParameterDescriptor receiverParameter = function.getReceiverParameter(); if (receiverParameter != null && containsErrorType(receiverParameter.getType())) { return true; } for (ValueParameterDescriptor parameter : function.getValueParameters()) { if (containsErrorType(parameter.getType())) { return true; } } for (TypeParameterDescriptor parameter : function.getTypeParameters()) { for (JetType upperBound : parameter.getUpperBounds()) { if (containsErrorType(upperBound)) { return true; } } } return false; }
private JavaDescriptorResolver.ValueParameterDescriptors modifyValueParametersAccordingToSuperMethods( @NotNull JavaDescriptorResolver.ValueParameterDescriptors parameters // descriptors built by parameters resolver ) { // we are not processing receiver type specifically: // if this function comes from Kotlin, then we don't need to do it, if it doesn't, then it can't // have receiver List<ValueParameterDescriptor> resultParameters = Lists.newArrayList(); for (ValueParameterDescriptor originalParam : parameters.getDescriptors()) { final int index = originalParam.getIndex(); List<TypeAndVariance> typesFromSuperMethods = ContainerUtil.map( superFunctions, new Function<FunctionDescriptor, TypeAndVariance>() { @Override public TypeAndVariance fun(FunctionDescriptor superFunction) { return new TypeAndVariance( superFunction.getValueParameters().get(index).getType(), INVARIANT); } }); VarargCheckResult varargCheckResult = checkVarargInSuperFunctions(originalParam); JetType altType = modifyTypeAccordingToSuperMethods( varargCheckResult.parameterType, typesFromSuperMethods, MEMBER_SIGNATURE_CONTRAVARIANT); resultParameters.add( new ValueParameterDescriptorImpl( originalParam.getContainingDeclaration(), index, originalParam.getAnnotations(), originalParam.getName(), altType, originalParam.declaresDefaultValue(), varargCheckResult.isVararg ? KotlinBuiltIns.getInstance().getArrayElementType(altType) : null)); } JetType originalReceiverType = parameters.getReceiverType(); if (originalReceiverType != null) { JetType substituted = SignaturesUtil.createSubstitutorForFunctionTypeParameters(autoTypeParameterToModified) .substitute(originalReceiverType, INVARIANT); assert substituted != null; return new JavaDescriptorResolver.ValueParameterDescriptors(substituted, resultParameters); } else { return new JavaDescriptorResolver.ValueParameterDescriptors(null, resultParameters); } }
public void serialize(ValueParameterDescriptor valueParameter) { sb.append("/*"); sb.append(valueParameter.getIndex()); sb.append("*/ "); if (valueParameter.getVarargElementType() != null) { sb.append("vararg "); } sb.append(valueParameter.getName()); sb.append(": "); if (valueParameter.getVarargElementType() != null) { new TypeSerializer(sb).serialize(valueParameter.getVarargElementType()); } else { new TypeSerializer(sb).serialize(valueParameter.getType()); } if (valueParameter.hasDefaultValue()) { sb.append(" = ?"); } }
private static JetType getActualParameterType(ValueParameterDescriptor descriptor) { JetType paramType = descriptor.getType(); if (descriptor.getVarargElementType() != null) paramType = descriptor.getVarargElementType(); return paramType; }
@Override public JetType visitFunctionLiteralExpression( JetFunctionLiteralExpression expression, ExpressionTypingContext context) { JetFunctionLiteral functionLiteral = expression.getFunctionLiteral(); JetBlockExpression bodyExpression = functionLiteral.getBodyExpression(); if (bodyExpression == null) return null; JetType expectedType = context.expectedType; boolean functionTypeExpected = expectedType != TypeUtils.NO_EXPECTED_TYPE && JetStandardClasses.isFunctionType(expectedType); NamedFunctionDescriptorImpl functionDescriptor = createFunctionDescriptor(expression, context, functionTypeExpected); List<JetType> parameterTypes = Lists.newArrayList(); List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters(); for (ValueParameterDescriptor valueParameter : valueParameters) { parameterTypes.add(valueParameter.getOutType()); } ReceiverDescriptor receiverParameter = functionDescriptor.getReceiverParameter(); JetType receiver = receiverParameter != NO_RECEIVER ? receiverParameter.getType() : null; JetType returnType = TypeUtils.NO_EXPECTED_TYPE; JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope( context.scope, functionDescriptor, context.trace); JetTypeReference returnTypeRef = functionLiteral.getReturnTypeRef(); if (returnTypeRef != null) { returnType = context.getTypeResolver().resolveType(context.scope, returnTypeRef); context .getServices() .checkFunctionReturnType( expression, context .replaceScope(functionInnerScope) .replaceExpectedType(returnType) .replaceExpectedReturnType(returnType) .replaceDataFlowInfo(context.dataFlowInfo)); } else { if (functionTypeExpected) { returnType = JetStandardClasses.getReturnTypeFromFunctionType(expectedType); } returnType = context .getServices() .getBlockReturnedType( functionInnerScope, bodyExpression, CoercionStrategy.COERCION_TO_UNIT, context.replaceExpectedType(returnType).replaceExpectedReturnType(returnType)); } JetType safeReturnType = returnType == null ? ErrorUtils.createErrorType("<return type>") : returnType; functionDescriptor.setReturnType(safeReturnType); boolean hasDeclaredValueParameters = functionLiteral.getValueParameterList() != null; if (!hasDeclaredValueParameters && functionTypeExpected) { JetType expectedReturnType = JetStandardClasses.getReturnTypeFromFunctionType(expectedType); if (JetStandardClasses.isUnit(expectedReturnType)) { functionDescriptor.setReturnType(JetStandardClasses.getUnitType()); return DataFlowUtils.checkType( JetStandardClasses.getFunctionType( Collections.<AnnotationDescriptor>emptyList(), receiver, parameterTypes, JetStandardClasses.getUnitType()), expression, context); } } return DataFlowUtils.checkType( JetStandardClasses.getFunctionType( Collections.<AnnotationDescriptor>emptyList(), receiver, parameterTypes, safeReturnType), expression, context); }
@Override public void updateUI(Object descriptor, ParameterInfoUIContext context) { // todo: when we will have ability to pass Array as vararg, implement such feature here too? if (context == null || context.getParameterOwner() == null || !context.getParameterOwner().isValid()) { return; } PsiElement parameterOwner = context.getParameterOwner(); if (parameterOwner instanceof JetValueArgumentList) { JetValueArgumentList argumentList = (JetValueArgumentList) parameterOwner; if (descriptor instanceof FunctionDescriptor) { JetFile file = (JetFile) argumentList.getContainingFile(); BindingContext bindingContext = AnalyzeSingleFileUtil.getContextForSingleFile(file); FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor; StringBuilder builder = new StringBuilder(); List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters(); List<JetValueArgument> valueArguments = argumentList.getArguments(); int currentParameterIndex = context.getCurrentParameterIndex(); int boldStartOffset = -1; int boldEndOffset = -1; boolean isGrey = false; boolean isDeprecated = false; // todo: add deprecation check Color color = context.getDefaultParameterColor(); PsiElement parent = argumentList.getParent(); if (parent instanceof JetCallElement) { JetCallElement callExpression = (JetCallElement) parent; JetExpression calleeExpression = callExpression.getCalleeExpression(); JetSimpleNameExpression refExpression = null; if (calleeExpression instanceof JetSimpleNameExpression) { refExpression = (JetSimpleNameExpression) calleeExpression; } else if (calleeExpression instanceof JetConstructorCalleeExpression) { JetConstructorCalleeExpression constructorCalleeExpression = (JetConstructorCalleeExpression) calleeExpression; if (constructorCalleeExpression.getConstructorReferenceExpression() instanceof JetSimpleNameExpression) { refExpression = (JetSimpleNameExpression) constructorCalleeExpression.getConstructorReferenceExpression(); } } if (refExpression != null) { DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, refExpression); if (declarationDescriptor != null) { if (declarationDescriptor == functionDescriptor) { color = GREEN_BACKGROUND; } } } } boolean[] usedIndexes = new boolean[valueParameters.size()]; boolean namedMode = false; Arrays.fill(usedIndexes, false); if ((currentParameterIndex >= valueParameters.size() && (valueParameters.size() > 0 || currentParameterIndex > 0)) && (valueParameters.size() == 0 || valueParameters.get(valueParameters.size() - 1).getVarargElementType() == null)) { isGrey = true; } if (valueParameters.size() == 0) builder.append(CodeInsightBundle.message("parameter.info.no.parameters")); for (int i = 0; i < valueParameters.size(); ++i) { if (i != 0) builder.append(", "); boolean highlightParameter = i == currentParameterIndex || (!namedMode && i < currentParameterIndex && valueParameters.get(valueParameters.size() - 1).getVarargElementType() != null); if (highlightParameter) boldStartOffset = builder.length(); if (!namedMode) { if (valueArguments.size() > i) { JetValueArgument argument = valueArguments.get(i); if (argument.isNamed()) { namedMode = true; } else { ValueParameterDescriptor param = valueParameters.get(i); builder.append(renderParameter(param, false, bindingContext)); if (i < currentParameterIndex) { if (argument.getArgumentExpression() != null) { // check type JetType paramType = getActualParameterType(param); JetType exprType = bindingContext.get( BindingContext.EXPRESSION_TYPE, argument.getArgumentExpression()); if (exprType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(exprType, paramType)) isGrey = true; } else isGrey = true; } usedIndexes[i] = true; } } else { ValueParameterDescriptor param = valueParameters.get(i); builder.append(renderParameter(param, false, bindingContext)); } } if (namedMode) { boolean takeAnyArgument = true; if (valueArguments.size() > i) { JetValueArgument argument = valueArguments.get(i); if (argument.isNamed()) { for (int j = 0; j < valueParameters.size(); ++j) { JetSimpleNameExpression referenceExpression = argument.getArgumentName().getReferenceExpression(); ValueParameterDescriptor param = valueParameters.get(j); if (referenceExpression != null && !usedIndexes[j] && param.getName().equals(referenceExpression.getReferencedNameAsName())) { takeAnyArgument = false; usedIndexes[j] = true; builder.append(renderParameter(param, true, bindingContext)); if (i < currentParameterIndex) { if (argument.getArgumentExpression() != null) { // check type JetType paramType = getActualParameterType(param); JetType exprType = bindingContext.get( BindingContext.EXPRESSION_TYPE, argument.getArgumentExpression()); if (exprType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(exprType, paramType)) isGrey = true; } else isGrey = true; } break; } } } } if (takeAnyArgument) { if (i < currentParameterIndex) isGrey = true; for (int j = 0; j < valueParameters.size(); ++j) { ValueParameterDescriptor param = valueParameters.get(j); if (!usedIndexes[j]) { usedIndexes[j] = true; builder.append(renderParameter(param, true, bindingContext)); break; } } } } if (highlightParameter) boldEndOffset = builder.length(); } if (builder.toString().isEmpty()) context.setUIComponentEnabled(false); else context.setupUIComponentPresentation( builder.toString(), boldStartOffset, boldEndOffset, isGrey, isDeprecated, false, color); } else context.setUIComponentEnabled(false); } }