@Override public boolean isArray() { if (internalIsResolved()) { return resolvedTo.isArray(); } return false; }
@Override public boolean isArray() { for(LightweightTypeReference component: expose(components)) { if (component.isArray()) return true; } return false; }
protected void addComponentType(LightweightTypeReference reference, List<LightweightTypeReference> result) { if (reference.isArray()) { result.add(((ArrayTypeReference) reference).getComponentType()); } else { result.add(reference); } }
@Override public boolean isArray() { return this.getDelegate().isArray(); }
private boolean isArrayTypeMismatch(LightweightTypeReference receiverType, LightweightTypeReference parameterType) { if (receiverType.isArray()) { if (parameterType.isArray()) { LightweightTypeReference componentType = parameterType.getComponentType(); if (isArrayTypeMismatch(receiverType.getComponentType(), componentType)) { return true; } return false; } return true; } else { if (!parameterType.isArray() && parameterType.isPrimitive()) { return true; } } return false; }
@Override public LightweightTypeReference getComponentType() { if (components != null) { for(LightweightTypeReference component: components) { if (component.isArray()) return component.getComponentType(); } } return super.getComponentType(); }
protected Object wrapOrUnwrapArray(Object result, LightweightTypeReference expectedType) { if (expectedType.isArray() && !(result instanceof Object[])) { Class<?> arrayType; try { arrayType = getJavaType(expectedType.getComponentType().getType()); return Conversions.unwrapArray(result, arrayType); } catch (ClassNotFoundException e) { return result; } } else if (!expectedType.isArray() && expectedType.isSubtypeOf(Iterable.class)) { return Conversions.doWrapArray(result); } return result; }
protected LightweightTypeReference getCollectionElementType(XCollectionLiteral literal) { LightweightTypeReference type = getLightweightType(literal); if (type == null) throw new IllegalStateException(); if(type.isArray()) { LightweightTypeReference result = type.getComponentType(); if (result == null) throw new IllegalStateException(); return result; } else if(type.isSubtypeOf(Collection.class) && type.hasTypeArguments()) { return type.getTypeArguments().get(0).getInvariantBoundSubstitute(); } return type.getOwner().newReferenceToObject(); }
@Override /* @Nullable */ protected LightweightTypeReference getExpectedType() { JvmOperation operation = annotationValue.getOperation(); LightweightTypeReference result = getResolvedTypes().getActualType(operation); if (result != null && result.isArray()) { return result.getComponentType(); } return result; }
private boolean isArrayTypeMismatch(LightweightTypeReference rawReceiverType, JvmType rawParameterType) { if (rawReceiverType.isArray()) { LightweightTypeReference parameterTypeReference = rawReceiverType.getOwner().toPlainTypeReference(rawParameterType); if (parameterTypeReference.getSuperType(Iterable.class) == null && isArrayTypeMismatch(rawReceiverType, parameterTypeReference)) { return true; } } return false; }
protected boolean isMatchingFirstParameter(JvmOperation feature) { List<JvmFormalParameter> parameters = feature.getParameters(); JvmFormalParameter firstParameter = parameters.get(0); JvmTypeReference type = firstParameter.getParameterType(); if (type == null) return false; JvmType rawParameterType = type.getType(); if (rawParameterType == null || rawParameterType.eIsProxy()) return false; if (!(rawParameterType instanceof JvmTypeParameter)) { if (rawArgumentType.isResolved()) { // short circuit - limit extension scope entries to real candidates LightweightTypeReference parameterTypeReference = rawArgumentType.getOwner().toPlainTypeReference(rawParameterType); if (parameterTypeReference.isResolved() && !parameterTypeReference.isAssignableFrom(rawArgumentType)) { if (parameterTypeReference.isArray() && !rawArgumentType.isArray() && rawArgumentType.isSubtypeOf(Iterable.class)) { return true; } return false; } if (parameterTypeReference.isArray() && !rawArgumentType.isArray() && !rawArgumentType.isSubtypeOf(Iterable.class)) { return false; } } else if (isArrayTypeMismatch(rawArgumentType, rawParameterType)) { return false; } } return true; }
@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; }
@Override protected void resolveAgainstActualType(LightweightTypeReference declaredType, LightweightTypeReference actualType, final AbstractTypeComputationState state) { super.resolveAgainstActualType(declaredType, actualType, state); if (!isStatic() || ((actualType.hasTypeArguments() || actualType.isArray()) && getDeclaredTypeParameters().isEmpty())) { DeferredTypeParameterHintCollector collector = new DeferredTypeParameterHintCollector(state.getReferenceOwner()); collector.processPairedReferences(declaredType, actualType); } }
protected Object _doEvaluate(XListLiteral literal, IEvaluationContext context, CancelIndicator indicator) { IResolvedTypes resolveTypes = typeResolver.resolveTypes(literal); LightweightTypeReference type = resolveTypes.getActualType(literal); List<Object> list = newArrayList(); for(XExpression element: literal.getElements()) { if (indicator.isCanceled()) throw new InterpreterCanceledException(); list.add(internalEvaluate(element, context, indicator)); } if(type != null && type.isArray()) { try { LightweightTypeReference componentType = type.getComponentType(); return Conversions.unwrapArray(list, getJavaType(componentType.getType())); } catch (ClassNotFoundException e) { } } return Collections.unmodifiableList(list); }
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(); }
/** Replies if the given reference is referencing a final type. * * @param expressionTypeRef - the type reference to test. * @return <code>true</code> if the given type is final. */ public static 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(); }
public void acceptHint(LightweightBoundTypeArgument hint) { if (internalIsResolved()) { throw new IllegalStateException("Cannot add hints to a resolved reference"); } if (hint.getSource() == BoundTypeArgumentSource.EXPLICIT) { LightweightTypeReference reference = hint.getTypeReference(); if (!(reference instanceof ParameterizedTypeReference) && !reference.isArray() && !reference.isUnknown()) { throw new IllegalArgumentException("cannot set " + hint + " as explicit hint"); } if (!getAllHints().isEmpty()) { throw new IllegalStateException("Cannot set explicit hint if other hints are present: " + getAllHints()); } this.resolvedTo = reference; getOwner().acceptHint(getHandle(), new LightweightBoundTypeArgument(resolvedTo, BoundTypeArgumentSource.RESOLVED, this, hint.getDeclaredVariance(), hint.getActualVariance())); return; } getOwner().acceptHint(this.getHandle(), hint); }
@Check public void checkOperandTypesForTripleEquals(XBinaryOperation binaryOperation) { if(isTripleEqualsOperation(binaryOperation)){ LightweightTypeReference left = getActualType(binaryOperation.getLeftOperand()); LightweightTypeReference right = getActualType(binaryOperation.getRightOperand()); if(left.isArray() != right.isArray()) { if (left.isArray()) { if (right.isAny() || right.isType(Object.class) || right.isType(Serializable.class) || right.isType(Cloneable.class)) { return; } } else { if (left.isAny() || left.isType(Object.class) || left.isType(Serializable.class) || left.isType(Cloneable.class)) { return; } } error("Incompatible operand types " + left.getHumanReadableName() + " and " + right.getHumanReadableName(), null, INVALID_OPERAND_TYPES); } } }
protected void computeType(XListLiteral literal, JvmGenericType listType, ITypeExpectation expectation, ITypeComputationState state) { LightweightTypeReference elementTypeExpectation = null; final LightweightTypeReference expectedType = expectation.getExpectedType(); if(expectedType != null) { if(expectedType.isArray()) { computeArrayLiteralType(literal, expectedType, expectation, state); return; } elementTypeExpectation = getElementOrComponentType(expectedType, state); } List<LightweightTypeReference> listTypeCandidates = computeCollectionTypeCandidates(literal, listType, elementTypeExpectation, state); LightweightTypeReference commonListType = getCommonSuperType(listTypeCandidates, state); if (commonListType != null) { LightweightTypeReference commonElementType = getElementOrComponentType(commonListType, state); ITypeReferenceOwner owner = state.getReferenceOwner(); commonElementType = normalizeElementType(commonElementType, expectedType, owner); if (expectedType != null) { commonListType = createCollectionTypeReference(listType, commonElementType, expectedType, owner); } expectation.acceptActualType(commonListType, ConformanceFlags.UNCHECKED); refineElementTypeExpectation(literal, commonElementType, state); } else { setUnboundCollectionType(literal, listType, expectation, elementTypeExpectation, state); } }
@Check public void checkInstanceOf(XInstanceOfExpression instanceOfExpression) { LightweightTypeReference leftType = getActualType(instanceOfExpression.getExpression()); final LightweightTypeReference rightType = toLightweightTypeReference(instanceOfExpression.getType(), true); if (leftType == null || rightType == null || rightType.getType() == null || rightType.getType().eIsProxy()) { return; } if (containsTypeArgs(rightType)) { error("Cannot perform instanceof check against parameterized type " + getNameOfTypes(rightType), null, ValidationMessageAcceptor.INSIGNIFICANT_INDEX, INVALID_INSTANCEOF); return; } if (leftType.isAny() || leftType.isUnknown()) { return; // null / unknown is ok } if (rightType.isPrimitive()) { error("Cannot perform instanceof check against primitive type " + this.getNameOfTypes(rightType), null, ValidationMessageAcceptor.INSIGNIFICANT_INDEX, INVALID_INSTANCEOF); return; } if (leftType.isPrimitive() || rightType.isArray() && !(leftType.isArray() || leftType.isType(Object.class) || leftType.isType(Cloneable.class) || leftType.isType(Serializable.class)) || isFinal(rightType) && !memberOfTypeHierarchy(rightType, leftType) || isFinal(leftType) && !memberOfTypeHierarchy(leftType, rightType)) { error("Incompatible conditional operand types " + this.getNameOfTypes(leftType)+" and "+this.getNameOfTypes(rightType), null, ValidationMessageAcceptor.INSIGNIFICANT_INDEX, INVALID_INSTANCEOF); return; } if (!isIgnored(OBSOLETE_INSTANCEOF) && rightType.isAssignableFrom(leftType, new TypeConformanceComputationArgument(false, false, true, true, false, false))) { addIssueToState(OBSOLETE_INSTANCEOF, "The expression of type " + getNameOfTypes(leftType) + " is already of type " + canonicalName(rightType), null); } }