From cd339fbb1bf8dd051c9c28c5d5040be098f0d840 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 23 Mar 2011 16:04:36 +0300 Subject: [PATCH] Property resolution --- .../jetbrains/jet/lang/psi/JetProperty.java | 4 ++ .../lang/resolve/ClassDescriptorResolver.java | 7 ++- .../jet/lang/resolve/OverloadResolver.java | 10 +-- .../jet/lang/resolve/SubstitutingScope.java | 22 ++++++- .../resolve/java/JavaClassMembersScope.java | 4 +- .../resolve/java/JavaDescriptorResolver.java | 3 +- .../lang/types/DeclarationDescriptorImpl.java | 1 + .../jetbrains/jet/lang/types/ErrorType.java | 4 +- .../lang/types/FunctionDescriptorUtil.java | 2 +- .../jet/lang/types/JetStandardClasses.java | 2 +- .../jet/lang/types/JetTypeInferrer.java | 6 +- ...LazySubstitutedPropertyDescriptorImpl.java | 61 ------------------- .../jet/lang/types/PropertyDescriptor.java | 7 ++- .../lang/types/PropertyDescriptorImpl.java | 25 ++++++-- .../types/ValueParameterDescriptorImpl.java | 11 +++- .../jetbrains/jet/resolve/DescriptorUtil.java | 2 +- .../resolve/ResolveOfInfixExpressions.jet | 2 +- .../jetbrains/jet/resolve/JetResolveTest.java | 2 +- .../jet/types/JetTypeCheckerTest.java | 4 +- 19 files changed, 89 insertions(+), 90 deletions(-) delete mode 100644 idea/src/org/jetbrains/jet/lang/types/LazySubstitutedPropertyDescriptorImpl.java diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetProperty.java b/idea/src/org/jetbrains/jet/lang/psi/JetProperty.java index a224040c26b..b4843927b94 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetProperty.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetProperty.java @@ -24,6 +24,10 @@ public class JetProperty extends JetNamedDeclaration { visitor.visitProperty(this); } + public boolean isVar() { + return getNode().findChildByType(JetTokens.VAR_KEYWORD) != null; + } + @Nullable public JetTypeReference getReceiverTypeRef() { ASTNode node = getNode().getFirstChildNode(); diff --git a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java index 570e7a6d2f7..163122ab009 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java @@ -193,9 +193,10 @@ public class ClassDescriptorResolver { JetParameter valueParameter = valueParameters.get(i); JetTypeReference typeReference = valueParameter.getTypeReference(); + String name = valueParameter.getName(); JetType type; if (typeReference == null) { - semanticServices.getErrorHandler().genericError(valueParameter.getNode(), "A type annotation is required on a value parameter " + valueParameter.getName()); + semanticServices.getErrorHandler().genericError(valueParameter.getNode(), "A type annotation is required on a value parameter"); type = ErrorType.createErrorType("Type annotation was missing"); } else { type = typeResolver.resolveType(parameterScope, typeReference); @@ -204,7 +205,7 @@ public class ClassDescriptorResolver { functionDescriptor, i, AttributeResolver.INSTANCE.resolveAttributes(valueParameter.getModifierList()), - valueParameter.getName(), + name == null ? "" : name, type, valueParameter.getDefaultValue() != null, false // TODO : varargs @@ -280,6 +281,7 @@ public class ClassDescriptorResolver { containingDeclaration, AttributeResolver.INSTANCE.resolveAttributes(parameter.getModifierList()), parameter.getName(), + type, // TODO type); } @@ -305,6 +307,7 @@ public class ClassDescriptorResolver { containingDeclaration, AttributeResolver.INSTANCE.resolveAttributes(property.getModifierList()), property.getName(), + property.isVar() ? type : null, type); } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java index 24c8ecc2143..b4493a81cb2 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java @@ -61,7 +61,7 @@ public class OverloadResolver { // possibly an array/list/etc passed as a whole vararg for (int i = 0, positionedValueArgumentTypesSize = positionedValueArgumentTypes.size(); i < positionedValueArgumentTypesSize; i++) { JetType argumentType = positionedValueArgumentTypes.get(i); - JetType parameterType = parameters.get(i).getType(); + JetType parameterType = parameters.get(i).getOutType(); // TODO : handle vararg cases here if (!typeChecker.isConvertibleTo(argumentType, parameterType)) { continue descLoop; @@ -72,12 +72,12 @@ public class OverloadResolver { int nonVarargs = parameters.size() - 1; for (int i = 0; i < nonVarargs; i++) { JetType argumentType = positionedValueArgumentTypes.get(i); - JetType parameterType = parameters.get(i).getType(); + JetType parameterType = parameters.get(i).getOutType(); if (!typeChecker.isConvertibleTo(argumentType, parameterType)) { continue descLoop; } } - JetType varArgType = parameters.get(nonVarargs).getType(); + JetType varArgType = parameters.get(nonVarargs).getOutType(); for (int i = nonVarargs, args = positionedValueArgumentTypes.size(); i < args; i++) { JetType argumentType = positionedValueArgumentTypes.get(i); if (!typeChecker.isConvertibleTo(argumentType, varArgType)) { @@ -137,8 +137,8 @@ public class OverloadResolver { int fSize = fParams.size(); if (fSize != gParams.size()) return false; for (int i = 0; i < fSize; i++) { - JetType fParamType = fParams.get(i).getType(); - JetType gParamType = gParams.get(i).getType(); + JetType fParamType = fParams.get(i).getOutType(); + JetType gParamType = gParams.get(i).getOutType(); // TODO : maybe isSubtypeOf is sufficient? if (!typeChecker.isConvertibleTo(fParamType, gParamType)) { diff --git a/idea/src/org/jetbrains/jet/lang/resolve/SubstitutingScope.java b/idea/src/org/jetbrains/jet/lang/resolve/SubstitutingScope.java index 39cf3b549d6..e3ba9f6a0aa 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/SubstitutingScope.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/SubstitutingScope.java @@ -1,6 +1,7 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.types.*; import java.util.Map; @@ -24,7 +25,26 @@ public class SubstitutingScope implements JetScope { if (property == null || substitutionContext.isEmpty()) { return property; } - return new LazySubstitutedPropertyDescriptorImpl(property, substitutionContext); + + JetType inType = substitute(property.getInType(), Variance.IN_VARIANCE); + JetType outType = substitute(property.getOutType(), Variance.OUT_VARIANCE); + if (inType == null && outType == null) { + return null; // TODO : tell the user that the property was projected out + } + return new PropertyDescriptorImpl( + property.getContainingDeclaration(), + property.getAttributes(), // TODO + property.getName(), + inType, + outType + ); + } + + @Nullable + private JetType substitute(@Nullable JetType originalType, @NotNull Variance variance) { + if (originalType == null) return null; + + return TypeSubstitutor.INSTANCE.substitute(substitutionContext, originalType, variance); } @Override diff --git a/idea/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java b/idea/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java index 627bf9a68a6..76f7bfc07c0 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java @@ -49,11 +49,13 @@ public class JavaClassMembersScope implements JetScope { return null; } + JetType type = semanticServices.getTypeTransformer().transform(field.getType()); PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorImpl( containingDeclaration, Collections.emptyList(), field.getName(), - semanticServices.getTypeTransformer().transform(field.getType())); + field.hasModifierProperty(PsiModifier.FINAL) ? null : type, + type); semanticServices.getTrace().recordDeclarationResolution(field, propertyDescriptor); return propertyDescriptor; } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index eb7ffea1b81..85119b43225 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -157,11 +157,12 @@ public class JavaDescriptorResolver { List result = new ArrayList(); for (int i = 0, parametersLength = parameters.length; i < parametersLength; i++) { PsiParameter parameter = parameters[i]; + String name = parameter.getName(); result.add(new ValueParameterDescriptorImpl( containingDeclaration, i, Collections.emptyList(), // TODO - parameter.getName(), + name == null ? "p" + i : name, semanticServices.getTypeTransformer().transform(parameter.getType()), false, parameter.isVarArgs() diff --git a/idea/src/org/jetbrains/jet/lang/types/DeclarationDescriptorImpl.java b/idea/src/org/jetbrains/jet/lang/types/DeclarationDescriptorImpl.java index 6ac45aa8c92..bddb033b8b0 100644 --- a/idea/src/org/jetbrains/jet/lang/types/DeclarationDescriptorImpl.java +++ b/idea/src/org/jetbrains/jet/lang/types/DeclarationDescriptorImpl.java @@ -20,6 +20,7 @@ public abstract class DeclarationDescriptorImpl extends AnnotatedImpl implements this.containingDeclaration = containingDeclaration; } + @NotNull @Override public String getName() { return name; diff --git a/idea/src/org/jetbrains/jet/lang/types/ErrorType.java b/idea/src/org/jetbrains/jet/lang/types/ErrorType.java index 54a9d2dbaa1..17679c5f6f0 100644 --- a/idea/src/org/jetbrains/jet/lang/types/ErrorType.java +++ b/idea/src/org/jetbrains/jet/lang/types/ErrorType.java @@ -86,7 +86,9 @@ public class ErrorType { return ERROR_SCOPE; } - private static final PropertyDescriptor ERROR_PROPERTY = new PropertyDescriptorImpl(ERROR_CLASS, Collections.emptyList(), "", createErrorType("")); + private static final JetType ERROR_PROPERTY_TYPE = createErrorType(""); + private static final PropertyDescriptor ERROR_PROPERTY = new PropertyDescriptorImpl( + ERROR_CLASS, Collections.emptyList(), "", ERROR_PROPERTY_TYPE, ERROR_PROPERTY_TYPE); private static FunctionDescriptor createErrorFunction(List typeParameters, List positionedValueArgumentTypes) { FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(ERROR_CLASS, Collections.emptyList(), ""); diff --git a/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorUtil.java b/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorUtil.java index 8128fc66f58..1ff52c1f332 100644 --- a/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorUtil.java +++ b/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorUtil.java @@ -61,7 +61,7 @@ public class FunctionDescriptorUtil { for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) { ValueParameterDescriptor unsubstitutedValueParameter = unsubstitutedValueParameters.get(i); // TODO : Lazy? - JetType substitutedType = TypeSubstitutor.INSTANCE.substitute(substitutionContext, unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE); + JetType substitutedType = TypeSubstitutor.INSTANCE.substitute(substitutionContext, unsubstitutedValueParameter.getOutType(), Variance.IN_VARIANCE); if (substitutedType == null) return null; result.add(new ValueParameterDescriptorImpl( substitutedDescriptor, diff --git a/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java b/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java index 67239a5cf63..7860065a1fb 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java @@ -289,7 +289,7 @@ public class JetStandardClasses { private static List toTypes(List labeledEntries) { List result = new ArrayList(); for (ValueParameterDescriptor entry : labeledEntries) { - result.add(entry.getType()); + result.add(entry.getOutType()); } return result; } diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index a721e2c1bb5..92ed1abf9d8 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -334,7 +334,7 @@ public class JetTypeInferrer { PropertyDescriptor property = scope.getProperty(referencedName); if (property != null) { trace.recordReferenceResolution(expression, property); - result = property.getType(); + result = property.getOutType(); return; } else { NamespaceDescriptor namespace = scope.getNamespace(referencedName); @@ -377,7 +377,7 @@ public class JetTypeInferrer { } PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolvePropertyDescriptor(functionDescriptor, scope, parameter); parameterDescriptors.put(parameter.getName(), propertyDescriptor); - parameterTypes.add(propertyDescriptor.getType()); + parameterTypes.add(propertyDescriptor.getOutType()); } JetType returnType; if (returnTypeRef != null) { @@ -642,7 +642,7 @@ public class JetTypeInferrer { PropertyDescriptor propertyDescriptor; if (typeReference != null) { propertyDescriptor = semanticServices.getClassDescriptorResolver(trace).resolvePropertyDescriptor(scope.getContainingDeclaration(), scope, loopParameter); - JetType actualParameterType = propertyDescriptor.getType(); + JetType actualParameterType = propertyDescriptor.getOutType(); if (expectedParameterType != null && !semanticServices.getTypeChecker().isSubtypeOf(expectedParameterType, actualParameterType)) { semanticServices.getErrorHandler().genericError(typeReference.getNode(), "The loop iterates over values of type " + expectedParameterType + " but the parameter is declared to be " + actualParameterType); diff --git a/idea/src/org/jetbrains/jet/lang/types/LazySubstitutedPropertyDescriptorImpl.java b/idea/src/org/jetbrains/jet/lang/types/LazySubstitutedPropertyDescriptorImpl.java deleted file mode 100644 index 57ef5254149..00000000000 --- a/idea/src/org/jetbrains/jet/lang/types/LazySubstitutedPropertyDescriptorImpl.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.jetbrains.jet.lang.types; - -import org.jetbrains.annotations.NotNull; - -import java.util.List; -import java.util.Map; - -/** - * @author abreslav - */ -public class LazySubstitutedPropertyDescriptorImpl implements PropertyDescriptor { - private final PropertyDescriptor propertyDescriptor; - private final Map substitutionContext; - private JetType propertyType = null; - - public LazySubstitutedPropertyDescriptorImpl(@NotNull PropertyDescriptor propertyDescriptor, @NotNull Map substitutionContext) { - this.propertyDescriptor = propertyDescriptor; - this.substitutionContext = substitutionContext; - } - - @Override - public JetType getType() { - if (propertyType == null) { - propertyType = TypeSubstitutor.INSTANCE.safeSubstitute(substitutionContext, propertyDescriptor.getType(), Variance.OUT_VARIANCE); - } - return propertyType; - } - - @Override - public List getAttributes() { - // TODO : Substitute, lazily - return propertyDescriptor.getAttributes(); - } - - @Override - public String getName() { - return propertyDescriptor.getName(); - } - - @NotNull - @Override - public DeclarationDescriptor getOriginal() { - return propertyDescriptor.getOriginal(); - } - - @NotNull - @Override - public DeclarationDescriptor getContainingDeclaration() { - return propertyDescriptor.getContainingDeclaration(); - } - - @Override - public R accept(DeclarationDescriptorVisitor visitor, D data) { - return visitor.visitPropertyDescriptor(this, data); - } - - @Override - public void acceptVoid(DeclarationDescriptorVisitor visitor) { - accept(visitor, null); - } -} diff --git a/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptor.java index 143a9ba2cdd..4acbd9028bd 100644 --- a/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptor.java @@ -1,12 +1,17 @@ package org.jetbrains.jet.lang.types; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author abreslav */ public interface PropertyDescriptor extends DeclarationDescriptor { - JetType getType(); + @Nullable + JetType getOutType(); + + @Nullable + JetType getInType(); @Override @NotNull diff --git a/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptorImpl.java b/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptorImpl.java index 46c52a4957d..3a2ec60813a 100644 --- a/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptorImpl.java +++ b/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptorImpl.java @@ -1,6 +1,7 @@ package org.jetbrains.jet.lang.types; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -8,16 +9,30 @@ import java.util.List; * @author abreslav */ public class PropertyDescriptorImpl extends DeclarationDescriptorImpl implements PropertyDescriptor { - private JetType type; + private final JetType inType; + private final JetType outType; - public PropertyDescriptorImpl(@NotNull DeclarationDescriptor containingDeclaration, List attributes, String name, JetType type) { + public PropertyDescriptorImpl( + @NotNull DeclarationDescriptor containingDeclaration, + @NotNull List attributes, + @NotNull String name, + @Nullable JetType inType, + @Nullable JetType outType) { super(containingDeclaration, attributes, name); - this.type = type; + assert (inType != null) || (outType != null); + + this.inType = inType; + this.outType = outType; } @Override - public JetType getType() { - return type; + public JetType getOutType() { + return outType; + } + + @Override + public JetType getInType() { + return inType; } @Override diff --git a/idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptorImpl.java b/idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptorImpl.java index 43e753489fe..bcdc79fbd58 100644 --- a/idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptorImpl.java +++ b/idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptorImpl.java @@ -12,8 +12,15 @@ public class ValueParameterDescriptorImpl extends PropertyDescriptorImpl impleme private final boolean isVararg; private final int index; - public ValueParameterDescriptorImpl(@NotNull DeclarationDescriptor containingDeclaration, int index, List attributes, String name, JetType type, boolean hasDefaultValue, boolean isVararg) { - super(containingDeclaration, attributes, name, type); + public ValueParameterDescriptorImpl( + @NotNull DeclarationDescriptor containingDeclaration, + int index, + @NotNull List attributes, + @NotNull String name, + @NotNull JetType type, + boolean hasDefaultValue, + boolean isVararg) { + super(containingDeclaration, attributes, name, type, type); // TODO : writable? this.index = index; this.hasDefaultValue = hasDefaultValue; this.isVararg = isVararg; diff --git a/idea/src/org/jetbrains/jet/resolve/DescriptorUtil.java b/idea/src/org/jetbrains/jet/resolve/DescriptorUtil.java index 5f71466b40a..fe771a90582 100644 --- a/idea/src/org/jetbrains/jet/resolve/DescriptorUtil.java +++ b/idea/src/org/jetbrains/jet/resolve/DescriptorUtil.java @@ -15,7 +15,7 @@ public class DescriptorUtil { new DeclarationDescriptorVisitor() { @Override public Void visitPropertyDescriptor(PropertyDescriptor descriptor, StringBuilder builder) { - JetType type = descriptor.getType(); + JetType type = descriptor.getOutType(); builder.append(renderName(descriptor)).append(" : ").append(type); return super.visitPropertyDescriptor(descriptor, builder); } diff --git a/idea/testData/resolve/ResolveOfInfixExpressions.jet b/idea/testData/resolve/ResolveOfInfixExpressions.jet index 27626af2cf7..32bc20bbdde 100644 --- a/idea/testData/resolve/ResolveOfInfixExpressions.jet +++ b/idea/testData/resolve/ResolveOfInfixExpressions.jet @@ -36,7 +36,7 @@ import util.* } ~Foo~class Foo { - ~set1~fun set(i : Int, val : String) {} + ~set1~fun set(i : Int, val1 : String) {} ~get1~fun get(i : Int) : Int {} ~get2~fun get(i : Int, j : Int) : String {} ~get3~fun get(i : Object) : Any {return i } diff --git a/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java b/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java index 13b7adcd82f..02a36dcd496 100644 --- a/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java +++ b/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java @@ -99,7 +99,7 @@ public class JetResolveTest extends ExtensibleResolveTestCase { List unsubstitutedValueParameters = function.getUnsubstitutedValueParameters(); for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) { ValueParameterDescriptor unsubstitutedValueParameter = unsubstitutedValueParameters.get(i); - if (unsubstitutedValueParameter.getType().equals(parameterType[i])) { + if (unsubstitutedValueParameter.getOutType().equals(parameterType[i])) { return function; } } diff --git a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java index cc02fb4c00b..8ffddb7550b 100644 --- a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java +++ b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java @@ -333,7 +333,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase { assertType("new Props().p", "Int"); assertType("new Props().p.p", "Int"); - assertErrorType("new Props().p"); + assertErrorType("(return : Props).p"); } public void testOverloads() throws Exception { @@ -449,7 +449,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase { private void assertErrorType(String expression) { Project project = getProject(); JetExpression jetExpression = JetChangeUtil.createExpression(project, expression); - JetType type = semanticServices.getTypeInferrer(BindingTrace.DUMMY).getType(classDefinitions.BASIC_SCOPE, jetExpression, false); + JetType type = semanticServices.getTypeInferrer(BindingTrace.DUMMY).safeGetType(classDefinitions.BASIC_SCOPE, jetExpression, false); assertTrue("Error type expected but " + type + " returned", ErrorType.isErrorType(type)); }