diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index f841f0a4311..288a75f7482 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -619,6 +619,11 @@ public class JetTypeMapper { signatureVisitor.writeInterfaceBoundEnd(); } } + if (jetType.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) { + signatureVisitor.writeInterfaceBound(); + mapType(jetType, signatureVisitor); + signatureVisitor.writeInterfaceBoundEnd(); + } } signatureVisitor.writeFormalTypeParameterEnd(); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 46dd32c5894..66dfe604e63 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -166,8 +166,17 @@ public class JavaDescriptorResolver { ); classDescriptor.setName(name); + class OuterClassTypeVariableResolver implements TypeVariableResolver { + + @NotNull + @Override + public TypeParameterDescriptor getTypeVariable(@NotNull String name) { + throw new IllegalStateException("not implemented"); // TODO + } + } + List supertypes = new ArrayList(); - List typeParameters = resolveClassTypeParameters(psiClass, classDescriptor); + List typeParameters = resolveClassTypeParameters(psiClass, classDescriptor, new OuterClassTypeVariableResolver()); classDescriptor.setTypeConstructor(new TypeConstructorImpl( classDescriptor, Collections.emptyList(), // TODO @@ -225,7 +234,10 @@ public class JavaDescriptorResolver { classDescriptor, Collections.emptyList(), // TODO false); - ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters()); + ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(constructorDescriptor, + constructor.getParameterList().getParameters(), + new TypeParameterListTypeVariableResolver(typeParameters) // TODO: outer too + ); if (valueParameterDescriptors.receiverType != null) { throw new IllegalStateException(); } @@ -242,14 +254,14 @@ public class JavaDescriptorResolver { return classDescriptor; } - private List resolveClassTypeParameters(PsiClass psiClass, JavaClassDescriptor classDescriptor) { + private List resolveClassTypeParameters(PsiClass psiClass, JavaClassDescriptor classDescriptor, TypeVariableResolver typeVariableResolver) { for (PsiAnnotation annotation : psiClass.getModifierList().getAnnotations()) { if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_CLASS.getFqName())) { PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_CLASS_SIGNATURE); if (attributeValue != null) { String typeParametersString = (String) attributeValue.getValue(); if (typeParametersString != null) { - return resolveClassTypeParametersFromJetSignature(typeParametersString, psiClass, classDescriptor); + return resolveClassTypeParametersFromJetSignature(typeParametersString, psiClass, classDescriptor, typeVariableResolver); } } } @@ -290,14 +302,20 @@ public class JavaDescriptorResolver { private final PsiTypeParameterListOwner psiOwner; private final String name; private final TypeInfoVariance variance; + private final TypeVariableResolver typeVariableResolver; protected JetSignatureTypeParameterVisitor(DeclarationDescriptor containingDeclaration, PsiTypeParameterListOwner psiOwner, - String name, TypeInfoVariance variance) + String name, TypeInfoVariance variance, TypeVariableResolver typeVariableResolver) { + if (name.isEmpty()) { + throw new IllegalStateException(); + } + this.containingDeclaration = containingDeclaration; this.psiOwner = psiOwner; this.name = name; this.variance = variance; + this.typeVariableResolver = typeVariableResolver; } int index = 0; @@ -307,7 +325,7 @@ public class JavaDescriptorResolver { @Override public JetSignatureVisitor visitClassBound() { - return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) { + return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableResolver) { @Override protected void done(@NotNull JetType jetType) { if (isJavaLangObject(jetType)) { @@ -320,7 +338,7 @@ public class JavaDescriptorResolver { @Override public JetSignatureVisitor visitInterfaceBound() { - return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) { + return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableResolver) { @Override protected void done(@NotNull JetType jetType) { upperBounds.add(jetType); @@ -348,12 +366,28 @@ public class JavaDescriptorResolver { /** * @see #resolveMethodTypeParametersFromJetSignature(String, FunctionDescriptor) */ - private List resolveClassTypeParametersFromJetSignature(String jetSignature, final PsiClass clazz, final JavaClassDescriptor classDescriptor) { + private List resolveClassTypeParametersFromJetSignature(String jetSignature, final PsiClass clazz, + final JavaClassDescriptor classDescriptor, final TypeVariableResolver outerClassTypeVariableResolver) { final List r = new ArrayList(); + + class MyTypeVariableResolver implements TypeVariableResolver { + + @NotNull + @Override + public TypeParameterDescriptor getTypeVariable(@NotNull String name) { + for (TypeParameterDescriptor typeParameter : r) { + if (typeParameter.getName().equals(name)) { + return typeParameter; + } + } + return outerClassTypeVariableResolver.getTypeVariable(name); + } + } + new JetSignatureReader(jetSignature).accept(new JetSignatureExceptionsAdapter() { @Override public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) { - return new JetSignatureTypeParameterVisitor(classDescriptor, clazz, name, variance) { + return new JetSignatureTypeParameterVisitor(classDescriptor, clazz, name, variance, new MyTypeVariableResolver()) { @Override protected void done(TypeParameterDescriptor typeParameterDescriptor) { r.add(typeParameterDescriptor); @@ -548,12 +582,13 @@ public class JavaDescriptorResolver { } } - public ValueParameterDescriptors resolveParameterDescriptors(DeclarationDescriptor containingDeclaration, PsiParameter[] parameters) { + public ValueParameterDescriptors resolveParameterDescriptors(DeclarationDescriptor containingDeclaration, + PsiParameter[] parameters, TypeVariableResolver typeVariableResolver) { List result = new ArrayList(); JetType receiverType = null; for (int i = 0, parametersLength = parameters.length; i < parametersLength; i++) { PsiParameter parameter = parameters[i]; - JvmMethodParameterMeaning meaning = resolveParameterDescriptor(containingDeclaration, i, parameter); + JvmMethodParameterMeaning meaning = resolveParameterDescriptor(containingDeclaration, i, parameter, typeVariableResolver); if (meaning.kind == JvmMethodParameterKind.TYPE_INFO) { // TODO } else if (meaning.kind == JvmMethodParameterKind.REGULAR) { @@ -601,7 +636,8 @@ public class JavaDescriptorResolver { } @NotNull - private JvmMethodParameterMeaning resolveParameterDescriptor(DeclarationDescriptor containingDeclaration, int i, PsiParameter parameter) { + private JvmMethodParameterMeaning resolveParameterDescriptor(DeclarationDescriptor containingDeclaration, int i, + PsiParameter parameter, TypeVariableResolver typeVariableResolver) { PsiType psiType = parameter.getType(); JetType varargElementType; @@ -663,7 +699,7 @@ public class JavaDescriptorResolver { JetType outType; if (typeFromAnnotation != null && typeFromAnnotation.length() > 0) { - outType = semanticServices.getTypeTransformer().transformToType(typeFromAnnotation); + outType = semanticServices.getTypeTransformer().transformToType(typeFromAnnotation, typeVariableResolver); } else { outType = semanticServices.getTypeTransformer().transformToType(psiType); } @@ -750,6 +786,26 @@ public class JavaDescriptorResolver { return typeSubstitutor; } + private static class TypeParameterListTypeVariableResolver implements TypeVariableResolver { + + private final List typeParameters; + + private TypeParameterListTypeVariableResolver(List typeParameters) { + this.typeParameters = typeParameters; + } + + @NotNull + @Override + public TypeParameterDescriptor getTypeVariable(@NotNull String name) { + for (TypeParameterDescriptor typeParameter : typeParameters) { + if (typeParameter.getName().equals(name)) { + return typeParameter; + } + } + throw new IllegalStateException("unresolver variable: " + name); // TODO: report properly + } + } + @Nullable public FunctionDescriptor resolveMethodToFunctionDescriptor(DeclarationDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, PsiMethod method) { PsiType returnType = method.getReturnType(); @@ -763,7 +819,17 @@ public class JavaDescriptorResolver { } return functionDescriptor; } - DeclarationDescriptor classDescriptor = method.hasModifierProperty(PsiModifier.STATIC) ? resolveNamespace(method.getContainingClass()) : resolveClass(method.getContainingClass()); + DeclarationDescriptor classDescriptor; + final List classTypeParameters; + if (method.hasModifierProperty(PsiModifier.STATIC)) { + classDescriptor = resolveNamespace(method.getContainingClass()); + classTypeParameters = Collections.emptyList(); + } + else { + ClassDescriptor classClassDescriptor = resolveClass(method.getContainingClass()); + classDescriptor = classClassDescriptor; + classTypeParameters = classClassDescriptor.getTypeConstructor().getParameters(); + } if (classDescriptor == null) { return null; } @@ -774,14 +840,39 @@ public class JavaDescriptorResolver { method.getName() ); methodDescriptorCache.put(method, functionDescriptorImpl); - List typeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl); - ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(functionDescriptorImpl, parameters); + + // TODO: add outer classes + TypeParameterListTypeVariableResolver typeVariableResolverForParameters = new TypeParameterListTypeVariableResolver(classTypeParameters); + + final List methodTypeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl, typeVariableResolverForParameters); + + class MethodTypeVariableResolver implements TypeVariableResolver { + + @NotNull + @Override + public TypeParameterDescriptor getTypeVariable(@NotNull String name) { + for (TypeParameterDescriptor typeParameter : methodTypeParameters) { + if (typeParameter.getName().equals(name)) { + return typeParameter; + } + } + for (TypeParameterDescriptor typeParameter : classTypeParameters) { + if (typeParameter.getName().equals(name)) { + return typeParameter; + } + } + throw new IllegalStateException("unresolver variable: " + name); // TODO: report properly + } + } + + + ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(functionDescriptorImpl, parameters, new MethodTypeVariableResolver()); functionDescriptorImpl.initialize( valueParameterDescriptors.receiverType, DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor), - typeParameters, + methodTypeParameters, valueParameterDescriptors.descriptors, - makeReturnType(returnType, method), + makeReturnType(returnType, method, new MethodTypeVariableResolver()), Modality.convertFromFlags(method.hasModifierProperty(PsiModifier.ABSTRACT), !method.hasModifierProperty(PsiModifier.FINAL)), resolveVisibilityFromPsiModifiers(method) ); @@ -793,14 +884,14 @@ public class JavaDescriptorResolver { return substitutedFunctionDescriptor; } - private List resolveMethodTypeParameters(PsiMethod method, FunctionDescriptorImpl functionDescriptorImpl) { + private List resolveMethodTypeParameters(PsiMethod method, FunctionDescriptorImpl functionDescriptorImpl, TypeVariableResolver classTypeVariableResolver) { for (PsiAnnotation annotation : method.getModifierList().getAnnotations()) { if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_METHOD.getFqName())) { PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD); if (attributeValue != null) { String typeParametersString = (String) attributeValue.getValue(); if (typeParametersString != null) { - List r = resolveMethodTypeParametersFromJetSignature(typeParametersString, method, functionDescriptorImpl); + List r = resolveMethodTypeParametersFromJetSignature(typeParametersString, method, functionDescriptorImpl, classTypeVariableResolver); initializeTypeParameters(method); return r; } @@ -816,13 +907,30 @@ public class JavaDescriptorResolver { /** * @see #resolveClassTypeParametersFromJetSignature(String, com.intellij.psi.PsiClass, JavaClassDescriptor) */ - private List resolveMethodTypeParametersFromJetSignature(String jetSignature, final PsiMethod method, final FunctionDescriptor functionDescriptor) { + private List resolveMethodTypeParametersFromJetSignature(String jetSignature, final PsiMethod method, + final FunctionDescriptor functionDescriptor, final TypeVariableResolver classTypeVariableResolver) + { final List r = new ArrayList(); + + class MyTypeVariableResolver implements TypeVariableResolver { + + @NotNull + @Override + public TypeParameterDescriptor getTypeVariable(@NotNull String name) { + for (TypeParameterDescriptor typeParameter : r) { + if (typeParameter.getName().equals(name)) { + return typeParameter; + } + } + return classTypeVariableResolver.getTypeVariable(name); + } + } + new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(new JetSignatureExceptionsAdapter() { @Override public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) { - return new JetSignatureTypeParameterVisitor(functionDescriptor, method, name, variance) { + return new JetSignatureTypeParameterVisitor(functionDescriptor, method, name, variance, new MyTypeVariableResolver()) { @Override protected void done(TypeParameterDescriptor typeParameterDescriptor) { r.add(typeParameterDescriptor); @@ -834,7 +942,7 @@ public class JavaDescriptorResolver { return r; } - private JetType makeReturnType(PsiType returnType, PsiMethod method) { + private JetType makeReturnType(PsiType returnType, PsiMethod method, TypeVariableResolver typeVariableResolver) { boolean changeNullable = false; boolean nullable = true; @@ -859,7 +967,7 @@ public class JavaDescriptorResolver { } JetType transformedType; if (returnTypeFromAnnotation != null && returnTypeFromAnnotation.length() > 0) { - transformedType = semanticServices.getTypeTransformer().transformToType(returnTypeFromAnnotation); + transformedType = semanticServices.getTypeTransformer().transformToType(returnTypeFromAnnotation, typeVariableResolver); } else { transformedType = semanticServices.getTypeTransformer().transformToType(returnType); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java index fde7a02232c..40a6c60b35d 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java @@ -59,9 +59,9 @@ public class JavaTypeTransformer { } @NotNull - public JetType transformToType(@NotNull String kotlinSignature) { + public JetType transformToType(@NotNull String kotlinSignature, TypeVariableResolver typeVariableResolver) { final JetType[] r = new JetType[1]; - JetTypeJetSignatureReader reader = new JetTypeJetSignatureReader(resolver, standardLibrary) { + JetTypeJetSignatureReader reader = new JetTypeJetSignatureReader(resolver, standardLibrary, typeVariableResolver) { @Override protected void done(@NotNull JetType jetType) { r[0] = jetType; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java index ec5b1b2a7ee..520da450766 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java @@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.resolve.java; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetStandardClasses; @@ -25,10 +26,12 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd private final JavaDescriptorResolver javaDescriptorResolver; private final JetStandardLibrary jetStandardLibrary; + private final TypeVariableResolver typeVariableResolver; - public JetTypeJetSignatureReader(JavaDescriptorResolver javaDescriptorResolver, JetStandardLibrary jetStandardLibrary) { + public JetTypeJetSignatureReader(JavaDescriptorResolver javaDescriptorResolver, JetStandardLibrary jetStandardLibrary, TypeVariableResolver typeVariableResolver) { this.javaDescriptorResolver = javaDescriptorResolver; this.jetStandardLibrary = jetStandardLibrary; + this.typeVariableResolver = typeVariableResolver; } @@ -111,7 +114,7 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd @Override public JetSignatureVisitor visitTypeArgument(final char wildcard) { - return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary) { + return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary, typeVariableResolver) { @Override protected void done(@NotNull JetType jetType) { @@ -122,7 +125,7 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd @Override public JetSignatureVisitor visitArrayType(final boolean nullable) { - return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary) { + return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary, typeVariableResolver) { @Override protected void done(@NotNull JetType jetType) { JetType arrayType = TypeUtils.makeNullableAsSpecified(jetStandardLibrary.getArrayType(jetType), nullable); @@ -133,8 +136,8 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd @Override public void visitTypeVariable(String name, boolean nullable) { - // TODO: need a way to get type TypeParameterDescriptor by name - throw new IllegalStateException(); + JetType r = TypeUtils.makeNullableAsSpecified(typeVariableResolver.getTypeVariable(name).getDefaultType(), nullable); + done(r); } @Override diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableResolver.java new file mode 100644 index 00000000000..9f391218d72 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableResolver.java @@ -0,0 +1,12 @@ +package org.jetbrains.jet.lang.resolve.java; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; + +/** + * @author Stepan Koltsov + */ +public interface TypeVariableResolver { + @NotNull + TypeParameterDescriptor getTypeVariable(@NotNull String name); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java index 7f6ce8305d4..3f4b049f685 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -280,7 +280,7 @@ public interface Errors { ParameterizedDiagnosticFactory1 UNSAFE_CALL = ParameterizedDiagnosticFactory1.create(ERROR, "Only safe calls (?.) are allowed on a nullable receiver of type {0}"); SimpleDiagnosticFactory AMBIGUOUS_LABEL = SimpleDiagnosticFactory.create(ERROR, "Ambiguous label"); ParameterizedDiagnosticFactory1 UNSUPPORTED = ParameterizedDiagnosticFactory1.create(ERROR, "Unsupported [{0}]"); - PsiElementOnlyDiagnosticFactory1 UNNECESSARY_SAFE_CALL = PsiElementOnlyDiagnosticFactory1.create(WARNING, "Unnecessary safe call on a non-null receiver of type {0}"); + ParameterizedDiagnosticFactory1 UNNECESSARY_SAFE_CALL = ParameterizedDiagnosticFactory1.create(WARNING, "Unnecessary safe call on a non-null receiver of type {0}"); ParameterizedDiagnosticFactory2 NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER = new ParameterizedDiagnosticFactory2(ERROR, "{0} does not refer to a type parameter of {1}") { @Override protected String makeMessageForA(@NotNull JetTypeConstraint jetTypeConstraint) { diff --git a/compiler/testData/readClass/class/ClassParamReferencesParam.kt b/compiler/testData/readClass/class/ClassParamReferencesParam.kt new file mode 100644 index 00000000000..b33ee9488b6 --- /dev/null +++ b/compiler/testData/readClass/class/ClassParamReferencesParam.kt @@ -0,0 +1,3 @@ +package test + +class ClassParamReferencesParam diff --git a/compiler/testData/readClass/class/ClassParamReferencesParam2.kt b/compiler/testData/readClass/class/ClassParamReferencesParam2.kt new file mode 100644 index 00000000000..6d1879d65ed --- /dev/null +++ b/compiler/testData/readClass/class/ClassParamReferencesParam2.kt @@ -0,0 +1,3 @@ +package test + +class ClassParamReferencesParam diff --git a/compiler/testData/readClass/class/ClassTwoParams.kt b/compiler/testData/readClass/class/ClassTwoParams.kt new file mode 100644 index 00000000000..63df442512e --- /dev/null +++ b/compiler/testData/readClass/class/ClassTwoParams.kt @@ -0,0 +1,3 @@ +package test + +class ClassTwoParams diff --git a/compiler/testData/readClass/class/ClassTwoParams2.kt b/compiler/testData/readClass/class/ClassTwoParams2.kt new file mode 100644 index 00000000000..f3b2e9fff2a --- /dev/null +++ b/compiler/testData/readClass/class/ClassTwoParams2.kt @@ -0,0 +1,3 @@ +package test + +class ClassTwoParams diff --git a/compiler/testData/readClass/classFun/ClassInParamUsedInFun.kt b/compiler/testData/readClass/classFun/ClassInParamUsedInFun.kt new file mode 100644 index 00000000000..cf911c50801 --- /dev/null +++ b/compiler/testData/readClass/classFun/ClassInParamUsedInFun.kt @@ -0,0 +1,5 @@ +package test + +class ClassParamUsedInFun { + fun f(t: T) = 1 +} diff --git a/compiler/testData/readClass/classFun/ClassParamUsedInFun.kt b/compiler/testData/readClass/classFun/ClassParamUsedInFun.kt new file mode 100644 index 00000000000..361a543acde --- /dev/null +++ b/compiler/testData/readClass/classFun/ClassParamUsedInFun.kt @@ -0,0 +1,5 @@ +package test + +class ClassParamUsedInFun { + fun f(t: T) = 1 +} diff --git a/compiler/testData/readClass/fun/FunGenericParam.kt b/compiler/testData/readClass/fun/genericWithTypeVariables/FunGenericParam.kt similarity index 100% rename from compiler/testData/readClass/fun/FunGenericParam.kt rename to compiler/testData/readClass/fun/genericWithTypeVariables/FunGenericParam.kt diff --git a/compiler/testData/readClass/fun/FunInParam.kt b/compiler/testData/readClass/fun/genericWithTypeVariables/FunInParam.kt similarity index 100% rename from compiler/testData/readClass/fun/FunInParam.kt rename to compiler/testData/readClass/fun/genericWithTypeVariables/FunInParam.kt diff --git a/compiler/testData/readClass/fun/FunOutParam.kt b/compiler/testData/readClass/fun/genericWithTypeVariables/FunOutParam.kt similarity index 100% rename from compiler/testData/readClass/fun/FunOutParam.kt rename to compiler/testData/readClass/fun/genericWithTypeVariables/FunOutParam.kt diff --git a/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamParam.kt b/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamParam.kt new file mode 100644 index 00000000000..a696c85f92c --- /dev/null +++ b/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamParam.kt @@ -0,0 +1,3 @@ +package test + +fun

funParamParam(a: Int, b: P) = 1 diff --git a/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamReferencesParam.kt b/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamReferencesParam.kt new file mode 100644 index 00000000000..85ff1201f1c --- /dev/null +++ b/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamReferencesParam.kt @@ -0,0 +1,3 @@ +package test + +fun funParamReferencesParam() = 1 diff --git a/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamReferencesParam2.kt b/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamReferencesParam2.kt new file mode 100644 index 00000000000..df8c64e1ec0 --- /dev/null +++ b/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamReferencesParam2.kt @@ -0,0 +1,3 @@ +package test + +fun funParamReferencesParam() = 1 diff --git a/compiler/testData/readClass/fun/FunParamUpperClassBound.kt b/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamUpperClassBound.kt similarity index 100% rename from compiler/testData/readClass/fun/FunParamUpperClassBound.kt rename to compiler/testData/readClass/fun/genericWithTypeVariables/FunParamUpperClassBound.kt diff --git a/compiler/testData/readClass/fun/FunParamUpperClassInterfaceBound.kt b/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamUpperClassInterfaceBound.kt similarity index 100% rename from compiler/testData/readClass/fun/FunParamUpperClassInterfaceBound.kt rename to compiler/testData/readClass/fun/genericWithTypeVariables/FunParamUpperClassInterfaceBound.kt diff --git a/compiler/testData/readClass/fun/FunParamUpperInterfaceBound.kt b/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamUpperInterfaceBound.kt similarity index 100% rename from compiler/testData/readClass/fun/FunParamUpperInterfaceBound.kt rename to compiler/testData/readClass/fun/genericWithTypeVariables/FunParamUpperInterfaceBound.kt diff --git a/compiler/testData/readClass/fun/FunParamUpperInterfaceClassBound.kt b/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamUpperInterfaceClassBound.kt similarity index 100% rename from compiler/testData/readClass/fun/FunParamUpperInterfaceClassBound.kt rename to compiler/testData/readClass/fun/genericWithTypeVariables/FunParamUpperInterfaceClassBound.kt diff --git a/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamVaragParam.kt b/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamVaragParam.kt new file mode 100644 index 00000000000..3b3eaac310d --- /dev/null +++ b/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamVaragParam.kt @@ -0,0 +1,3 @@ +package test + +fun

funParamVarargParam(a: Int, vararg b: P) = 1 diff --git a/compiler/testData/readClass/fun/genericWithTypeVariables/FunTwoTypeParams.kt b/compiler/testData/readClass/fun/genericWithTypeVariables/FunTwoTypeParams.kt new file mode 100644 index 00000000000..283a4b9f140 --- /dev/null +++ b/compiler/testData/readClass/fun/genericWithTypeVariables/FunTwoTypeParams.kt @@ -0,0 +1,3 @@ +package test + +fun funTwoTypeParams() = 1 diff --git a/compiler/testData/readClass/fun/genericWithTypeVariables/FunTwoTypeParams2.kt b/compiler/testData/readClass/fun/genericWithTypeVariables/FunTwoTypeParams2.kt new file mode 100644 index 00000000000..ef12cb5917b --- /dev/null +++ b/compiler/testData/readClass/fun/genericWithTypeVariables/FunTwoTypeParams2.kt @@ -0,0 +1,3 @@ +package test + +fun funTwoTypeParams() = 1 diff --git a/compiler/testData/readClass/fun/FunClassParamNotNull.kt b/compiler/testData/readClass/fun/genericWithoutTypeVariables/FunClassParamNotNull.kt similarity index 100% rename from compiler/testData/readClass/fun/FunClassParamNotNull.kt rename to compiler/testData/readClass/fun/genericWithoutTypeVariables/FunClassParamNotNull.kt diff --git a/compiler/testData/readClass/fun/FunClassParamNullable.kt b/compiler/testData/readClass/fun/genericWithoutTypeVariables/FunClassParamNullable.kt similarity index 100% rename from compiler/testData/readClass/fun/FunClassParamNullable.kt rename to compiler/testData/readClass/fun/genericWithoutTypeVariables/FunClassParamNullable.kt diff --git a/compiler/testData/readClass/fun/FunParamNullable.kt b/compiler/testData/readClass/fun/genericWithoutTypeVariables/FunParamNullable.kt similarity index 100% rename from compiler/testData/readClass/fun/FunParamNullable.kt rename to compiler/testData/readClass/fun/genericWithoutTypeVariables/FunParamNullable.kt diff --git a/compiler/testData/readClass/fun/ReturnTypeClassParamNotNull.kt b/compiler/testData/readClass/fun/genericWithoutTypeVariables/ReturnTypeClassParamNotNull.kt similarity index 100% rename from compiler/testData/readClass/fun/ReturnTypeClassParamNotNull.kt rename to compiler/testData/readClass/fun/genericWithoutTypeVariables/ReturnTypeClassParamNotNull.kt diff --git a/compiler/testData/readClass/fun/ReturnTypeClassParamNullable.kt b/compiler/testData/readClass/fun/genericWithoutTypeVariables/ReturnTypeClassParamNullable.kt similarity index 100% rename from compiler/testData/readClass/fun/ReturnTypeClassParamNullable.kt rename to compiler/testData/readClass/fun/genericWithoutTypeVariables/ReturnTypeClassParamNullable.kt diff --git a/compiler/testData/readClass/fun/ClassFun.kt b/compiler/testData/readClass/fun/nonGeneric/ClassFun.kt similarity index 100% rename from compiler/testData/readClass/fun/ClassFun.kt rename to compiler/testData/readClass/fun/nonGeneric/ClassFun.kt diff --git a/compiler/testData/readClass/fun/ExtFun.kt b/compiler/testData/readClass/fun/nonGeneric/ExtFun.kt similarity index 100% rename from compiler/testData/readClass/fun/ExtFun.kt rename to compiler/testData/readClass/fun/nonGeneric/ExtFun.kt diff --git a/compiler/testData/readClass/fun/ExtFunInClass.kt b/compiler/testData/readClass/fun/nonGeneric/ExtFunInClass.kt similarity index 100% rename from compiler/testData/readClass/fun/ExtFunInClass.kt rename to compiler/testData/readClass/fun/nonGeneric/ExtFunInClass.kt diff --git a/compiler/testData/readClass/fun/FunDefaultArg.kt b/compiler/testData/readClass/fun/nonGeneric/FunDefaultArg.kt similarity index 100% rename from compiler/testData/readClass/fun/FunDefaultArg.kt rename to compiler/testData/readClass/fun/nonGeneric/FunDefaultArg.kt diff --git a/compiler/testData/readClass/fun/FunParamNotNull.kt b/compiler/testData/readClass/fun/nonGeneric/FunParamNotNull.kt similarity index 100% rename from compiler/testData/readClass/fun/FunParamNotNull.kt rename to compiler/testData/readClass/fun/nonGeneric/FunParamNotNull.kt diff --git a/compiler/testData/readClass/fun/FunVarargCharSequence.kt b/compiler/testData/readClass/fun/nonGeneric/FunVarargCharSequence.kt similarity index 100% rename from compiler/testData/readClass/fun/FunVarargCharSequence.kt rename to compiler/testData/readClass/fun/nonGeneric/FunVarargCharSequence.kt diff --git a/compiler/testData/readClass/fun/FunVarargInt.kt b/compiler/testData/readClass/fun/nonGeneric/FunVarargInt.kt similarity index 100% rename from compiler/testData/readClass/fun/FunVarargInt.kt rename to compiler/testData/readClass/fun/nonGeneric/FunVarargInt.kt diff --git a/compiler/testData/readClass/fun/ModifierAbstract.kt b/compiler/testData/readClass/fun/nonGeneric/ModifierAbstract.kt similarity index 100% rename from compiler/testData/readClass/fun/ModifierAbstract.kt rename to compiler/testData/readClass/fun/nonGeneric/ModifierAbstract.kt diff --git a/compiler/testData/readClass/fun/ModifierOpen.kt b/compiler/testData/readClass/fun/nonGeneric/ModifierOpen.kt similarity index 100% rename from compiler/testData/readClass/fun/ModifierOpen.kt rename to compiler/testData/readClass/fun/nonGeneric/ModifierOpen.kt diff --git a/compiler/testData/readClass/fun/NsFun.kt b/compiler/testData/readClass/fun/nonGeneric/NsFun.kt similarity index 100% rename from compiler/testData/readClass/fun/NsFun.kt rename to compiler/testData/readClass/fun/nonGeneric/NsFun.kt diff --git a/compiler/testData/readClass/fun/ReturnTypeNotNull.kt b/compiler/testData/readClass/fun/nonGeneric/ReturnTypeNotNull.kt similarity index 100% rename from compiler/testData/readClass/fun/ReturnTypeNotNull.kt rename to compiler/testData/readClass/fun/nonGeneric/ReturnTypeNotNull.kt diff --git a/compiler/testData/readClass/fun/ReturnTypeNullable.kt b/compiler/testData/readClass/fun/nonGeneric/ReturnTypeNullable.kt similarity index 100% rename from compiler/testData/readClass/fun/ReturnTypeNullable.kt rename to compiler/testData/readClass/fun/nonGeneric/ReturnTypeNullable.kt diff --git a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java index 0235ea39226..d7e988b9052 100644 --- a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java +++ b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java @@ -403,7 +403,7 @@ public class ReadClassDataTest extends UsefulTestCase { List list = new ArrayList(); for (JetType upper : param.getUpperBounds()) { StringBuilder sb = new StringBuilder(); - new Serializer(sb).serialize(upper); + new ValueParameterSerializer(sb).serialize(upper); list.add(sb.toString()); } Collections.sort(list); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java index 7f3cb3abd63..54a4248003e 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java @@ -87,7 +87,6 @@ public class QuickFixes { add(Errors.USELESS_ELVIS, RemoveRightPartOfBinaryExpressionFix.createRemoveElvisOperatorFactory()); - add(Errors.UNNECESSARY_SAFE_CALL, ReplaceSafeCallWithDotCall.createFactory()); JetIntentionActionFactory removeRedundantModifierFactory = RemoveModifierFix.createRemoveModifierFromListFactory(true); add(Errors.REDUNDANT_MODIFIER, removeRedundantModifierFactory); @@ -109,7 +108,7 @@ public class QuickFixes { add(Errors.GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY, removeModifierFactory); add(Errors.REDUNDANT_MODIFIER_IN_GETTER, removeRedundantModifierFactory); add(Errors.ILLEGAL_MODIFIER, removeModifierFactory); - + add(Errors.PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE, AddReturnTypeFix.createFactory()); JetIntentionActionFactory changeToBackingFieldFactory = ChangeToBackingFieldFix.createFactory(); @@ -127,6 +126,7 @@ public class QuickFixes { actionMap.put(Errors.VAL_WITH_SETTER, changeVariableMutabilityFix); actionMap.put(Errors.VAL_REASSIGNMENT, changeVariableMutabilityFix); - actionMap.put(Errors.UNSAFE_CALL, new ReplaceDotCallWithSafeCall()); + actionMap.put(Errors.UNNECESSARY_SAFE_CALL, new ReplaceCallFix(false)); + actionMap.put(Errors.UNSAFE_CALL, new ReplaceCallFix(true)); } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ReplaceCallFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ReplaceCallFix.java new file mode 100644 index 00000000000..aa7a0b3d512 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ReplaceCallFix.java @@ -0,0 +1,68 @@ +package org.jetbrains.jet.plugin.quickfix; + +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.plugin.JetBundle; + +/** + * @author svtk + */ +public class ReplaceCallFix implements IntentionAction { + private final boolean toSafe; + + public ReplaceCallFix(boolean toSafe) { + this.toSafe = toSafe; + } + + + @NotNull + @Override + public String getText() { + return toSafe ? JetBundle.message("replace.with.safe.call") : JetBundle.message("replace.with.dot.call"); + } + + @NotNull + @Override + public String getFamilyName() { + return toSafe ? JetBundle.message("replace.with.safe.call") : JetBundle.message("replace.with.dot.call"); + } + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + if (file instanceof JetFile) { + return getCallExpression(editor, (JetFile) file) != null; + } + return false; + } + + private JetQualifiedExpression getCallExpression(@NotNull Editor editor, @NotNull JetFile file) { + final PsiElement elementAtCaret = file.findElementAt(editor.getCaretModel().getOffset()); + return PsiTreeUtil.getParentOfType(elementAtCaret, toSafe ? JetDotQualifiedExpression.class : JetSafeQualifiedExpression.class); + } + + @Override + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + JetQualifiedExpression callExpression = getCallExpression(editor, (JetFile) file); + assert callExpression != null; + + JetExpression selector = callExpression.getSelectorExpression(); + if (selector != null) { + JetQualifiedExpression newElement = (JetQualifiedExpression) JetPsiFactory.createExpression( + project, callExpression.getReceiverExpression().getText() + (toSafe ? "?." : ".") + selector.getText()); + + callExpression.replace(newElement); + } + } + + @Override + public boolean startInWriteAction() { + return true; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ReplaceDotCallWithSafeCall.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ReplaceDotCallWithSafeCall.java deleted file mode 100644 index 0ddd2731c6f..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ReplaceDotCallWithSafeCall.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.jetbrains.jet.plugin.quickfix; - -import com.intellij.codeInsight.intention.IntentionAction; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.IncorrectOperationException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.plugin.JetBundle; - -/** - * @author ignatov - */ -@SuppressWarnings("IntentionDescriptionNotFoundInspection") -public class ReplaceDotCallWithSafeCall implements IntentionAction { - public ReplaceDotCallWithSafeCall() { - } - - @NotNull - @Override - public String getText() { - return JetBundle.message("replace.with.safe.call"); - } - - @NotNull - @Override - public String getFamilyName() { - return JetBundle.message("replace.with.safe.call"); - } - - @Override - public boolean isAvailable(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { - if (file instanceof JetFile) { - return getDotCallExpression(editor, (JetFile) file) != null; - } - return false; - } - - private static JetDotQualifiedExpression getDotCallExpression(@NotNull Editor editor, @NotNull JetFile file) { - final PsiElement elementAtCaret = file.findElementAt(editor.getCaretModel().getOffset()); - return PsiTreeUtil.getParentOfType(elementAtCaret, JetDotQualifiedExpression.class); - } - - @Override - public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - JetDotQualifiedExpression dotCallExpression = getDotCallExpression(editor, (JetFile) file); - assert dotCallExpression != null; - - JetExpression selector = dotCallExpression.getSelectorExpression(); - if (selector != null) { - JetSafeQualifiedExpression newElement = (JetSafeQualifiedExpression) JetPsiFactory.createExpression( - project, dotCallExpression.getReceiverExpression().getText() + "?." + selector.getText()); - - dotCallExpression.replace(newElement); - } - } - - @Override - public boolean startInWriteAction() { - return true; - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ReplaceSafeCallWithDotCall.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ReplaceSafeCallWithDotCall.java deleted file mode 100644 index c6a18316996..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ReplaceSafeCallWithDotCall.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.jetbrains.jet.plugin.quickfix; - -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiFile; -import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; -import com.intellij.util.IncorrectOperationException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement; -import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.plugin.JetBundle; - -/** - * @author svtk - */ -public class ReplaceSafeCallWithDotCall extends JetIntentionAction { - - public ReplaceSafeCallWithDotCall(@NotNull JetElement element) { - super(element); - } - - @NotNull - @Override - public String getText() { - return JetBundle.message("replace.with.dot.call"); - } - - @NotNull - @Override - public String getFamilyName() { - return JetBundle.message("replace.with.dot.call"); - } - - @Override - public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - if (element instanceof JetSafeQualifiedExpression) { - JetSafeQualifiedExpression safeQualifiedExpression = (JetSafeQualifiedExpression) element; - JetDotQualifiedExpression newElement = (JetDotQualifiedExpression) JetPsiFactory.createExpression(project, "x.foo"); - - CodeEditUtil.replaceChild(newElement.getNode(), newElement.getSelectorExpression().getNode(), safeQualifiedExpression.getSelectorExpression().getNode()); - CodeEditUtil.replaceChild(newElement.getNode(), newElement.getReceiverExpression().getNode(), safeQualifiedExpression.getReceiverExpression().getNode()); - - element.replace(newElement); - } - } - - public static JetIntentionActionFactory createFactory() { - return new JetIntentionActionFactory() { - @Override - public JetIntentionAction createAction(DiagnosticWithPsiElement diagnostic) { - assert diagnostic.getPsiElement() instanceof JetElement; - return new ReplaceSafeCallWithDotCall((JetElement) diagnostic.getPsiElement()); - } - }; - } -} diff --git a/idea/testData/quickfix/expressions/afterUnnecessarySafeCall1.kt b/idea/testData/quickfix/expressions/afterUnnecessarySafeCall1.kt index 55d3d6c64f3..6c1ad9fe270 100644 --- a/idea/testData/quickfix/expressions/afterUnnecessarySafeCall1.kt +++ b/idea/testData/quickfix/expressions/afterUnnecessarySafeCall1.kt @@ -1,4 +1,4 @@ // "Replace with dot call" "true" fun foo(a: Any) { - a.equals(0) + a.equals(0) } diff --git a/stdlib/ktSrc/JavaIterablesSpecial.kt b/stdlib/ktSrc/JavaIterablesSpecial.kt index 2e30749f216..3a564fabeb8 100644 --- a/stdlib/ktSrc/JavaIterablesSpecial.kt +++ b/stdlib/ktSrc/JavaIterablesSpecial.kt @@ -82,4 +82,4 @@ fun java.lang.Iterable.contains(item : T) : Boolean { } return false -} \ No newline at end of file +} diff --git a/stdlib/ktSrc/System.kt b/stdlib/ktSrc/System.kt index 3d7b443991d..2d62972afbe 100644 --- a/stdlib/ktSrc/System.kt +++ b/stdlib/ktSrc/System.kt @@ -16,4 +16,4 @@ fun measureTimeNano(block: () -> Unit) : Long { val start = System.nanoTime() block() return System.nanoTime() - start -} \ No newline at end of file +} diff --git a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureReader.java b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureReader.java index 44112938959..900ec35d2e0 100644 --- a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureReader.java +++ b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureReader.java @@ -63,7 +63,11 @@ public class JetSignatureReader { if (end < 0) { throw new IllegalStateException(); } - JetSignatureVisitor parameterVisitor = v.visitFormalTypeParameter(signature.substring(pos, end), variance); + String typeParameterName = signature.substring(pos, end); + if (typeParameterName.isEmpty()) { + throw new IllegalStateException("incorrect signature: " + signature); + } + JetSignatureVisitor parameterVisitor = v.visitFormalTypeParameter(typeParameterName, variance); pos = end + 1; c = signature.charAt(pos); @@ -71,12 +75,14 @@ public class JetSignatureReader { pos = parseType(signature, pos, parameterVisitor.visitClassBound()); } - while ((c = signature.charAt(pos++)) == ':') { + while ((c = signature.charAt(pos)) == ':') { + ++pos; pos = parseType(signature, pos, parameterVisitor.visitInterfaceBound()); } parameterVisitor.visitFormalTypeParameterEnd(); } while (c != '>'); + ++pos; } else { pos = 0; }