@Override public final String toString() { return getSimpleName(); }
@Override public String getIdentifier() { return component.getIdentifier() + "[]"; }
@Override public boolean isImmutable(LightweightTypeReference type) { assert type != null; final LightweightTypeReference ref = type.getPrimitiveIfWrapperType(); if (ref.isArray()) { return false; } if (ref.isPrimitive() || ref.isPrimitiveVoid()) { return true; } for (final Class<?> jvmType : IMMUTABLE_TYPES) { if (type.isSubtypeOf(jvmType)) { return true; } } return false; }
/** * Primitive {@code void}, {@link AnyTypeReference any} and {@link UnknownTypeReference unknown} * types are not valid hints for {@link UnboundTypeReference#acceptHint(LightweightBoundTypeArgument) unbound references}. */ public boolean isValidHint() { return !isAny() && !isPrimitiveVoid(); }
/** * Implements fall-back strategy. If the expected type of a collection literal does not match the actual type, but the expected element * types would match the actual element type, the collection literal will be successfully typed according to the expectation. */ protected boolean matchesExpectation(LightweightTypeReference elementType, LightweightTypeReference expectation) { return expectation != null && expectation.isResolved() && !expectation.isWildcard() && expectation.isAssignableFrom(elementType); }
protected String referenceToString(LightweightTypeReference reference) { if (reference == null) { return "[null]"; } if (reference.isAny()) { return "Object"; } return reference.getHumanReadableName(); }
ITypeComputationState state) { LightweightTypeReference expectation = operation == null || operation.eIsProxy() ? null : state.getReferenceOwner().toLightweightTypeReference(operation.getReturnType()); if (expectation != null && expectation.isArray()) { LightweightTypeReference componentType = expectation.getComponentType(); if (componentType == null) { throw new IllegalStateException("Array without component type: " + expectation.getIdentifier()); ITypeComputationState expectationState = addEnumImportsIfNecessary(state, actualExpectation, componentType.getType()); expectationState.withinScope(annotation); if (value == null) { if (resultType != null && !actualExpectation.isAssignableFrom(resultType)) { if (value instanceof XListLiteral) { state.withNonVoidExpectation().computeTypes(value); } else { ITypeComputationState expectationState = addEnumImportsIfNecessary(state, expectation, expectation.getType()); expectationState.withinScope(annotation); if (value == null) { if (valueResultType != null && !expectation.isAssignableFrom(valueResultType)) { if (value instanceof XListLiteral) { ArrayTypeReference array = valueResultType.tryConvertToArray(); if (array != null) { LightweightTypeReference primitiveComponentType = array.getComponentType().getPrimitiveIfWrapperType(); state.addDiagnostic(new EObjectDiagnosticImpl( Severity.ERROR, IssueCodes.INCOMPATIBLE_TYPES, "Type mismatch: cannot convert from " + primitiveComponentType + "[] to " + expectation.getHumanReadableName(),
protected void doConversion(final LightweightTypeReference left, final LightweightTypeReference right, final ITreeAppendable appendable, XExpression context, final Later expression) { if(left.isPrimitive() && !right.isPrimitive()) { if (right.isAny()) { convertWrapperToPrimitive(left, left, context, appendable, expression); } else { convertWrapperToPrimitive(right, right.getPrimitiveIfWrapperType(), context, appendable, expression); } else if (right.isPrimitive() && !left.isPrimitive()) { convertPrimitiveToWrapper(right, right.getWrapperTypeIfPrimitive(), appendable, expression); } else if (right.isMultiType()) { convertMultiType(left, (CompoundTypeReference) right, context, appendable, expression); } else if (right.isArray() && !left.isArray() && left.isSubtypeOf(Iterable.class)) { convertArrayToList(left, appendable, context, expression); } else if (isJavaConformant(left, right)) { expression.exec(appendable); } else if (left.isArray() && !right.isArray() && right.isSubtypeOf(Iterable.class)) { convertListToArray(left, appendable, expression); } else if ((isFunction(left) && isFunction(right) || isProcedure(left) && isProcedure(right)) && left.getType() == right.getType()) { doCastConversion(left, appendable, expression); } else if (isFunction(right) || (isFunction(left) && findImplementingOperation(right) != null)) {
public void collectSynonymTypes(/* @Nullable */ LightweightTypeReference type, /* @NonNull */ Acceptor acceptor) { if (type == null || type.isPrimitiveVoid() || type.isType(Void.class)) { return; } if (type.isWrapper()) { if (!acceptor.accept(type.getPrimitiveIfWrapperType(), ConformanceFlags.CHECKED_SUCCESS | ConformanceFlags.UNBOXING)) { return; } // a primitive type is never an array or list collectCustomSynonymTypes(type, acceptor); return; } else if (type.isPrimitive()) { if (!acceptor.accept(type.getWrapperTypeIfPrimitive(), ConformanceFlags.CHECKED_SUCCESS | ConformanceFlags.BOXING)) { return; } // a primitive type is never an array or list collectCustomSynonymTypes(type, acceptor); return; } if (addArrayAndListSynonyms(type, acceptor)) { collectCustomSynonymTypes(type, acceptor); } }
@Check public void checkReturnTypeOfCheckConstraints(CheckConstraint checkConstraint) { XExpression xExpression = checkConstraint.getExpression(); if (xExpression != null) { final IResolvedTypes resolvedType = typeResolver.resolveTypes(xExpression); LightweightTypeReference type = resolvedType.getReturnType(xExpression); if (type.getPrimitiveIfWrapperType().getPrimitiveKind() != Primitive.Boolean) { error("Check expressions must return boolean instead of " + type.getSimpleName(), checkConstraint, PatternLanguagePackage.Literals.CHECK_CONSTRAINT__EXPRESSION, IssueCodes.CHECK_MUST_BE_BOOLEAN); } } }
if (type.isArray()) { LightweightTypeReference listType = type.tryConvertToListType(); if (listType != null) { LightweightTypeReference componentType = type.getComponentType(); if (componentType == null) { throw new IllegalStateException("Component type of an array may not be null"); if (componentType.isPrimitive()) { if (!acceptor.accept(listType, ConformanceFlags.CHECKED_SUCCESS | ConformanceFlags.DEMAND_CONVERSION | ConformanceFlags.BOXING)) { return false; ArrayTypeReference arrayType = type.tryConvertToArray(); if (arrayType != null) { LightweightTypeReference componentType = arrayType.getComponentType(); LightweightTypeReference primitiveComponentType = componentType.getPrimitiveIfWrapperType(); if (primitiveComponentType != componentType) { ArrayTypeReference primitiveArray = type.getOwner().newArrayTypeReference(primitiveComponentType); if (!acceptor.accept(primitiveArray, ConformanceFlags.CHECKED_SUCCESS | ConformanceFlags.DEMAND_CONVERSION | ConformanceFlags.UNBOXING)) { return false;
protected boolean isFinal(LightweightTypeReference expressionTypeRef) { if (expressionTypeRef.isArray()) { return isFinal(expressionTypeRef.getComponentType()); } if (expressionTypeRef.isPrimitive()) return true; return expressionTypeRef.getType() instanceof JvmDeclaredType && ((JvmDeclaredType) expressionTypeRef.getType()).isFinal(); }
protected LightweightTypeReference getAndEnhanceIterableOrArrayFromComponent(LightweightTypeReference parameterType, JvmGenericType iterableType, final CompoundTypeReference compoundResult) { if (parameterType.isUnknown()) { compoundResult.addComponent(parameterType); return parameterType; LightweightTypeReference iterableOrArray = null; LightweightTypeReference addAsArrayComponentAndIterable = null; if (parameterType.isPrimitive()) { iterableOrArray = owner.newArrayTypeReference(parameterType); compoundResult.addComponent(iterableOrArray); addAsArrayComponentAndIterable = parameterType.getWrapperTypeIfPrimitive(); } else if (parameterType.isAny()) { addAsArrayComponentAndIterable = parameterType.getOwner().newReferenceToObject(); } else { addAsArrayComponentAndIterable = parameterType; if (iterableOrArray == null) { iterableOrArray = reference; LightweightTypeReference potentialPrimitive = addAsArrayComponentAndIterable.getPrimitiveIfWrapperType(); if (potentialPrimitive != addAsArrayComponentAndIterable) { compoundResult.addComponent(owner.newArrayTypeReference(potentialPrimitive));
protected String getDefaultValueLiteral(XExpression expr) { LightweightTypeReference type = getTypeForVariableDeclaration(expr); if (type.isPrimitive()) { if (type.getPrimitiveKind() == Primitives.Primitive.Boolean) { return "false"; } else { return "(" + type.getSimpleName() + ") 0"; } } return "null"; }
@Override protected void addHint(UnboundTypeReference typeParameter, LightweightTypeReference reference) { LightweightTypeReference wrapped = reference.getWrapperTypeIfPrimitive(); typeParameter.acceptHint(wrapped, BoundTypeArgumentSource.RESOLVED, getOrigin(), getExpectedVariance(), getActualVariance()); LightweightTypeReference typeParameterReference = reference.getOwner().newParameterizedTypeReference(typeParameter.getTypeParameter()); if (validParameterTypes && !typeParameterReference.getRawTypeReference().isAssignableFrom(reference)) { validParameterTypes = false; } } }.processPairedReferences(operationParameterType, closureParameterType);
@Override public boolean isType(Class<?> clazz) { Class<?> clazzComponentType = clazz.getComponentType(); if (clazzComponentType != null) { return component.isType(clazzComponentType); } return false; }
/** * Determines if this type reference denotes the same or a supertype of * the given {@code reference}. */ public boolean isAssignableFrom(LightweightTypeReference reference) { return isAssignableFrom(reference, TypeConformanceComputationArgument.DEFAULT); }
@Override public IResolvedOperation getAsBottom() { JvmOperation operation = getDeclaration(); JvmDeclaredType declaringType = operation.getDeclaringType(); List<LightweightTypeReference> superTypes = getContextType().getAllSuperTypes(); for(LightweightTypeReference superType: superTypes) { if (superType.getType() == declaringType) { return new BottomResolvedOperation(operation, superType, getBottom().getOverrideTester()); } } throw new IllegalStateException(String.format("Could not find declaring type of method %s in hierarchy of %s", operation.getIdentifier(), getContextType().getIdentifier())); }
@Check public void checkJUnitMethodReturnType(XtendFunction function) { JvmOperation operation = associations.getDirectlyInferredOperation(function); /* * Active annotations could also change the return type. * Checking that the JvmOperation really has a JUnit annotation. */ if(hasJUnitAnnotation(operation)) { LightweightTypeReference actualType = determineReturnType(operation); if(actualType !=null && !actualType.isUnknown() && !actualType.isPrimitiveVoid()) { String message = String.format("JUnit method %s() must be void but is %s.", function.getName(), actualType.getHumanReadableName()); EAttribute location = XTEND_FUNCTION__NAME; error(message, function, location, INVALID_RETURN_TYPE_IN_CASE_OF_JUNIT_ANNOTATION); } } }
/** Replies if the given type is an interface. * * @param type - the type to test. * @return <code>true</code> if the given type is an interface. */ public static boolean isInterface(LightweightTypeReference type) { return type.getType() instanceof JvmGenericType && ((JvmGenericType) type.getType()).isInterface(); }