protected void renderTypeParameter( TypeParameterDescriptor descriptor, StringBuilder builder, boolean topLevel) { if (!descriptor.isReified()) { String variance = descriptor.getVariance().toString(); if (!variance.isEmpty()) { builder.append(renderKeyword(variance)).append(" "); } } else { builder.append(renderKeyword("reified")).append(" "); } renderName(descriptor, builder); if (descriptor.getUpperBounds().size() == 1) { JetType upperBound = descriptor.getUpperBounds().iterator().next(); if (upperBound != JetStandardClasses.getDefaultBound()) { builder.append(" : ").append(renderType(upperBound)); } } else if (topLevel) { boolean first = true; for (JetType upperBound : descriptor.getUpperBounds()) { if (upperBound.equals(JetStandardClasses.getDefaultBound())) { continue; } if (first) { builder.append(" : "); } else { builder.append(" & "); } builder.append(renderType(upperBound)); first = false; } } else { // rendered with "where" } }
private ClassDescriptor recordClassForFunction(FunctionDescriptor funDescriptor) { ClassDescriptor classDescriptor; int arity = funDescriptor.getValueParameters().size(); classDescriptor = new ClassDescriptorImpl( funDescriptor.getContainingDeclaration(), Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, Name.special("<closure>")); ((ClassDescriptorImpl) classDescriptor) .initialize( false, Collections.<TypeParameterDescriptor>emptyList(), Collections.singleton( (funDescriptor.getReceiverParameter().exists() ? JetStandardClasses.getReceiverFunction(arity) : JetStandardClasses.getFunction(arity)) .getDefaultType()), JetScope.EMPTY, Collections.<ConstructorDescriptor>emptySet(), null); assert PsiCodegenPredictor.checkPredictedClassNameForFun( bindingContext, funDescriptor, classDescriptor); bindingTrace.record(CLASS_FOR_FUNCTION, funDescriptor, classDescriptor); return classDescriptor; }
public void renderClassDescriptor( ClassDescriptor descriptor, StringBuilder builder, String keyword) { if (descriptor.getKind() != ClassKind.CLASS_OBJECT) { renderVisibility(descriptor.getVisibility(), builder); } if (descriptor.getKind() != ClassKind.TRAIT && descriptor.getKind() != ClassKind.OBJECT && descriptor.getKind() != ClassKind.CLASS_OBJECT) { renderModality(descriptor.getModality(), builder); } builder.append(renderKeyword(keyword)); if (descriptor.getKind() != ClassKind.CLASS_OBJECT) { builder.append(" "); renderName(descriptor, builder); renderTypeParameters(descriptor.getTypeConstructor().getParameters(), builder); } if (!descriptor.equals(JetStandardClasses.getNothing())) { Collection<? extends JetType> supertypes = descriptor.getTypeConstructor().getSupertypes(); if (supertypes.isEmpty() || supertypes.size() == 1 && JetStandardClasses.isAny(supertypes.iterator().next())) { } else { builder.append(" : "); for (Iterator<? extends JetType> iterator = supertypes.iterator(); iterator.hasNext(); ) { JetType supertype = iterator.next(); builder.append(renderType(supertype)); if (iterator.hasNext()) { builder.append(", "); } } } } }
private String renderType(JetType type, boolean shortNamesOnly) { if (type == null) { return escape("[NULL]"); } else if (ErrorUtils.isErrorType(type)) { return escape(type.toString()); } else if (JetStandardClasses.isUnit(type)) { return escape(JetStandardClasses.UNIT_ALIAS + (type.isNullable() ? "?" : "")); } else if (JetStandardClasses.isTupleType(type)) { return escape(renderTupleType(type, shortNamesOnly)); } else if (JetStandardClasses.isFunctionType(type)) { return escape(renderFunctionType(type, shortNamesOnly)); } else { return escape(renderDefaultType(type, shortNamesOnly)); } }
@Override public void visitClassType(String name, boolean nullable, boolean forceReal) { FqName ourName = new FqName( name.replace('/', '.').replace('$', '.') // TODO: not sure ); this.classDescriptor = null; if (!forceReal) { classDescriptor = javaSemanticServices .getTypeTransformer() .getKotlinAnalog(ourName, JavaTypeTransformer.TypeUsage.MEMBER_SIGNATURE_INVARIANT); } if (classDescriptor == null) { // TODO: this is the worst code in Kotlin project Matcher matcher = Pattern.compile("jet\\.Function(\\d+)").matcher(ourName.getFqName()); if (matcher.matches()) { classDescriptor = JetStandardClasses.getFunction(Integer.parseInt(matcher.group(1))); } } if (classDescriptor == null) { Matcher matcher = Pattern.compile("jet\\.Tuple(\\d+)").matcher(ourName.getFqName()); if (matcher.matches()) { classDescriptor = JetStandardClasses.getTuple(Integer.parseInt(matcher.group(1))); } } if (this.classDescriptor == null) { this.classDescriptor = javaDescriptorResolver.resolveClass(ourName, DescriptorSearchRule.INCLUDE_KOTLIN); } if (this.classDescriptor == null) { // TODO: report in to trace this.errorType = ErrorUtils.createErrorType("class not found by name: " + ourName); } this.nullable = nullable; this.typeArguments = new ArrayList<TypeProjection>(); }
private String renderFunctionType(JetType type, boolean shortNamesOnly) { StringBuilder sb = new StringBuilder(); JetType receiverType = JetStandardClasses.getReceiverType(type); if (receiverType != null) { sb.append(renderType(receiverType, shortNamesOnly)); sb.append("."); } sb.append("("); appendTypeProjections( sb, JetStandardClasses.getParameterTypeProjectionsFromFunctionType(type), shortNamesOnly); sb.append(") -> "); sb.append(renderType(JetStandardClasses.getReturnTypeFromFunctionType(type), shortNamesOnly)); if (type.isNullable()) { return "(" + sb + ")?"; } return sb.toString(); }
protected String renderTupleType(JetType type, boolean shortNamesOnly) { StringBuilder sb = new StringBuilder("#("); appendTypes(sb, JetStandardClasses.getTupleElementTypes(type), shortNamesOnly); sb.append(")"); if (type.isNullable()) { sb.append("?"); } return sb.toString(); }
public static SimpleFunctionDescriptor createInvoke(FunctionDescriptor fd) { int arity = fd.getValueParameters().size(); SimpleFunctionDescriptorImpl invokeDescriptor = new SimpleFunctionDescriptorImpl( fd.getExpectedThisObject().exists() ? JetStandardClasses.getReceiverFunction(arity) : JetStandardClasses.getFunction(arity), Collections.<AnnotationDescriptor>emptyList(), Name.identifier("invoke"), CallableMemberDescriptor.Kind.DECLARATION); invokeDescriptor.initialize( fd.getReceiverParameter().exists() ? fd.getReceiverParameter().getType() : null, fd.getExpectedThisObject(), Collections.<TypeParameterDescriptorImpl>emptyList(), fd.getValueParameters(), fd.getReturnType(), Modality.FINAL, Visibilities.PUBLIC, /*isInline = */ false); return invokeDescriptor; }
@NotNull public static JetType getDefaultType(IElementType constantType) { if (constantType == JetNodeTypes.INTEGER_CONSTANT) { return JetStandardLibrary.getInstance().getIntType(); } else if (constantType == JetNodeTypes.FLOAT_CONSTANT) { return JetStandardLibrary.getInstance().getDoubleType(); } else if (constantType == JetNodeTypes.BOOLEAN_CONSTANT) { return JetStandardLibrary.getInstance().getBooleanType(); } else if (constantType == JetNodeTypes.CHARACTER_CONSTANT) { return JetStandardLibrary.getInstance().getCharType(); } else if (constantType == JetNodeTypes.NULL) { return JetStandardClasses.getNullableNothingType(); } else { throw new IllegalArgumentException("Unsupported constant type: " + constantType); } }
public Map<String, JetType> getClassTypesMap() { if (classTypesMap == null) { classTypesMap = new HashMap<String, JetType>(); for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) { PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType(); classTypesMap.put( jvmPrimitiveType.getWrapper().getFqName().getFqName(), JetStandardLibrary.getInstance().getNullablePrimitiveJetType(primitiveType)); } classTypesMap.put("java.lang.Object", JetStandardClasses.getNullableAnyType()); classTypesMap.put( "java.lang.String", JetStandardLibrary.getInstance().getNullableStringType()); classTypesMap.put( "java.lang.CharSequence", JetStandardLibrary.getInstance().getNullableCharSequenceType()); classTypesMap.put( "java.lang.Throwable", JetStandardLibrary.getInstance().getNullableThrowableType()); } return classTypesMap; }
public Map<String, JetType> getPrimitiveTypesMap() { if (primitiveTypesMap == null) { primitiveTypesMap = new HashMap<String, JetType>(); for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) { PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType(); primitiveTypesMap.put( jvmPrimitiveType.getName(), JetStandardLibrary.getInstance().getPrimitiveJetType(primitiveType)); primitiveTypesMap.put( "[" + jvmPrimitiveType.getName(), JetStandardLibrary.getInstance().getPrimitiveArrayJetType(primitiveType)); primitiveTypesMap.put( jvmPrimitiveType.getWrapper().getFqName().getFqName(), JetStandardLibrary.getInstance().getNullablePrimitiveJetType(primitiveType)); } primitiveTypesMap.put("void", JetStandardClasses.getUnitType()); } return primitiveTypesMap; }
private JetType getPrimitiveType(char descriptor, boolean nullable) { if (!nullable) { for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) { if (jvmPrimitiveType.getJvmLetter() == descriptor) { return jetStandardLibrary.getPrimitiveJetType(jvmPrimitiveType.getPrimitiveType()); } } if (descriptor == 'V') { return JetStandardClasses.getUnitType(); } } else { for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) { if (jvmPrimitiveType.getJvmLetter() == descriptor) { return jetStandardLibrary.getNullablePrimitiveJetType( jvmPrimitiveType.getPrimitiveType()); } } if (descriptor == 'V') { throw new IllegalStateException("incorrect signature: nullable void"); } } throw new IllegalStateException("incorrect signature"); }
private void resolveSecondaryConstructorBody( JetSecondaryConstructor declaration, final ConstructorDescriptor descriptor) { if (!context.completeAnalysisNeeded(declaration)) return; MutableClassDescriptor classDescriptor = (MutableClassDescriptor) descriptor.getContainingDeclaration(); final JetScope scopeForSupertypeInitializers = FunctionDescriptorUtil.getFunctionInnerScope( classDescriptor.getScopeForSupertypeResolution(), descriptor, trace); // contains only constructor parameters final JetScope scopeForConstructorBody = FunctionDescriptorUtil.getFunctionInnerScope( classDescriptor.getScopeForInitializers(), descriptor, trace); // contains members & backing fields final DataFlowInfo dataFlowInfo = DataFlowInfo.EMPTY; // TODO: dataFlowInfo PsiElement nameElement = declaration.getNameNode().getPsi(); if (classDescriptor.getUnsubstitutedPrimaryConstructor() == null) { trace.report(SECONDARY_CONSTRUCTOR_BUT_NO_PRIMARY.on(nameElement)); } else { List<JetDelegationSpecifier> initializers = declaration.getInitializers(); if (initializers.isEmpty()) { trace.report(SECONDARY_CONSTRUCTOR_NO_INITIALIZER_LIST.on(nameElement)); } else { initializers .get(0) .accept( new JetVisitorVoid() { @Override public void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call) { JetTypeReference typeReference = call.getTypeReference(); if (typeReference != null) { callResolver.resolveFunctionCall( trace, scopeForSupertypeInitializers, CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, call), NO_EXPECTED_TYPE, dataFlowInfo); } } @Override public void visitDelegationToThisCall(JetDelegatorToThisCall call) { // TODO : check that there's no recursion in this() calls // TODO : check: if a this() call is present, no other initializers are allowed ClassDescriptor classDescriptor = descriptor.getContainingDeclaration(); callResolver.resolveFunctionCall( trace, scopeForSupertypeInitializers, CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, call), NO_EXPECTED_TYPE, dataFlowInfo); // call.getThisReference(), // classDescriptor, // classDescriptor.getDefaultType(), // call); // trace.getErrorHandler().genericError(call.getNode(), // "this-calls are not supported"); } @Override public void visitDelegationByExpressionSpecifier( JetDelegatorByExpressionSpecifier specifier) { trace.report(BY_IN_SECONDARY_CONSTRUCTOR.on(specifier)); } @Override public void visitDelegationToSuperClassSpecifier( JetDelegatorToSuperClass specifier) { trace.report(INITIALIZER_WITH_NO_ARGUMENTS.on(specifier)); } @Override public void visitDelegationSpecifier(JetDelegationSpecifier specifier) { throw new IllegalStateException(); } }); for (int i = 1, initializersSize = initializers.size(); i < initializersSize; i++) { JetDelegationSpecifier initializer = initializers.get(i); trace.report(MANY_CALLS_TO_THIS.on(initializer)); } } } JetExpression bodyExpression = declaration.getBodyExpression(); if (bodyExpression != null) { expressionTypingServices.checkFunctionReturnType( scopeForConstructorBody, declaration, descriptor, JetStandardClasses.getUnitType(), trace); } checkDefaultParameterValues( declaration.getValueParameters(), descriptor.getValueParameters(), scopeForConstructorBody); }