/** * 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(); }
protected List<LightweightTypeReference> replacePrimitivesAndRemoveAnyReferences(List<LightweightTypeReference> types) { List<LightweightTypeReference> result = Lists.newArrayList(); for(LightweightTypeReference type: types) { if (!(type.isAny())) result.add(type.getWrapperTypeIfPrimitive()); } return result; }
@Override public boolean isAny() { if (internalIsResolved()) { return resolvedTo.isAny(); } return false; }
protected boolean containsPrimitiveOrAnyReferences(List<LightweightTypeReference> types) { for(LightweightTypeReference type: types) { if (type.isPrimitive() || type.isAny()) return true; } return false; }
protected String referenceToString(LightweightTypeReference reference) { if (reference == null) { return "[null]"; } if (reference.isAny()) { return "Object"; } return reference.getHumanReadableName(); }
@Override public boolean isAny() { for(LightweightTypeReference component: expose(components)) { if (component.isAny()) return true; } return false; }
@Override public boolean isAnyType() { return this.getDelegate().isAny(); }
public ArrayTypeReference(ITypeReferenceOwner owner, LightweightTypeReference component) { super(owner); this.component = Preconditions.checkNotNull(component, "component"); // TODO decide about the following constraint which prevents (Number & Serializable)[] // if (!(component.getType() instanceof JvmComponentType)) { // throw new IllegalArgumentException("Cannot create array reference from non-component type " + component.getIdentifier()); // } if (component.isAny()) { throw new IllegalArgumentException("component is invalid: type <any> is not allowed"); } if (component.isWildcard()) { throw new IllegalArgumentException("component is invalid: " + component); } if (!component.isOwnedBy(owner)) { throw new IllegalArgumentException("component is not valid in current context"); } }
/** * Creates a list of collection type references from the element types of a collection literal. */ protected List<LightweightTypeReference> computeCollectionTypeCandidates(XCollectionLiteral literal, JvmGenericType collectionType, LightweightTypeReference elementTypeExpectation, ITypeComputationState state) { List<XExpression> elements = literal.getElements(); if(!elements.isEmpty()) { List<LightweightTypeReference> elementTypes = Lists.newArrayListWithCapacity(elements.size()); for(XExpression element: elements) { ITypeComputationResult elementType = computeTypes(element, elementTypeExpectation, state); LightweightTypeReference actualType = elementType.getActualExpressionType(); if(actualType != null && !actualType.isAny()) { ParameterizedTypeReference collectionTypeCandidate = state.getReferenceOwner().newParameterizedTypeReference(collectionType); collectionTypeCandidate.addTypeArgument(actualType.getWrapperTypeIfPrimitive()); elementTypes.add(collectionTypeCandidate); } } return elementTypes; } return Collections.emptyList(); }
protected void resolveAgainstActualType(LightweightTypeReference declaredType, LightweightTypeReference actualType, final AbstractTypeComputationState state) { if (!actualType.isAny()) { // TODO this(..) and super(..) for generic types List<JvmTypeParameter> typeParameters = getDeclaredTypeParameters(); if (!typeParameters.isEmpty()) { // TODO actualType -(hint for)-> declared type == inferred // declared type -(hint for)-> actual type == expected TypeArgumentFromComputedTypeCollector.resolveAgainstActualType( declaredType, actualType, typeParameters, getTypeParameterMapping(), BoundTypeArgumentSource.EXPECTATION, state.getReferenceOwner()); } } }
@Override public LightweightTypeReference doVisitGenericArrayTypeReference(JvmGenericArrayTypeReference reference) { JvmTypeReference originalComponentType = reference.getComponentType(); LightweightTypeReference lightweightComponentType = null; if (originalComponentType != null) { lightweightComponentType = visit(originalComponentType); if (lightweightComponentType.isAny()) return lightweightComponentType; } else { lightweightComponentType = getObjectReference(); } return owner.newArrayTypeReference(lightweightComponentType); }
protected int isConformantMergeResult(LightweightMergedBoundTypeArgument mergeResult, LightweightTypeReference right, int flags) { LightweightTypeReference mergeResultReference = mergeResult.getTypeReference(); if (right.isWildcard() && mergeResultReference.isWildcard()) { if (right.getLowerBoundSubstitute().isAny()) { LightweightTypeReference lowerBoundMergeResult = mergeResultReference.getLowerBoundSubstitute(); if (!lowerBoundMergeResult.isAny()) { mergeResultReference = lowerBoundMergeResult; } } else { flags = flags | AS_TYPE_ARGUMENT; } } else if (mergeResultReference.isWildcard()) { flags = flags | AS_TYPE_ARGUMENT; } return isConformant(mergeResultReference, right, flags); }
@Override public void addExtensionsToCurrentScope(List<? extends JvmIdentifiableElement> extensionProviders) { if (extensionProviders.isEmpty()) return; if (extensionProviders.size() == 1) { addExtensionToCurrentScope(extensionProviders.get(0)); return; } Map<XExpression, LightweightTypeReference> prototypeToType = Maps2.newLinkedHashMapWithExpectedSize(extensionProviders.size()); for(JvmIdentifiableElement extensionProvider: extensionProviders) { LightweightTypeReference knownType = getResolvedTypes().getActualType(extensionProvider); if (knownType != null && !knownType.isAny() && !knownType.isUnknown()) { XFeatureCall prototype = getResolver().getXbaseFactory().createXFeatureCall(); prototype.setFeature(extensionProvider); prototypeToType.put(prototype, knownType); } } if (!prototypeToType.isEmpty()) featureScopeSession = featureScopeSession.addToExtensionScope(prototypeToType); }
@Override public void addExtensionToCurrentScope(JvmIdentifiableElement extensionProvider) { LightweightTypeReference knownType = getResolvedTypes().getActualType(extensionProvider); if (knownType != null && !knownType.isAny() && !knownType.isUnknown()) { XFeatureCall prototype = getResolver().getXbaseFactory().createXFeatureCall(); prototype.setFeature(extensionProvider); featureScopeSession = featureScopeSession.addToExtensionScope(Collections.<XExpression, LightweightTypeReference>singletonMap(prototype, knownType)); } }
protected FunctionTypeReference processExpressionType(FunctionTypeReference incompleteClosureType, ITypeComputationResult expressionResult) { LightweightTypeReference expressionResultType = expressionResult.getReturnType(); if (expressionResultType == null || !expressionResultType.isPrimitiveVoid()) { FunctionTypeReference result = getFunctionTypeReference(false); LightweightTypeReference expectedReturnType = result.getTypeArguments().get(result.getTypeArguments().size() - 1); if (expressionResultType != null && !expressionResultType.isAny()) { result.setReturnType(expressionResultType); deferredBindTypeArgument(expectedReturnType, expressionResultType, BoundTypeArgumentSource.INFERRED); } else { LightweightTypeReference objectTypeReference = incompleteClosureType.getOwner().newReferenceToObject(); result.setReturnType(objectTypeReference); deferredBindTypeArgument(expectedReturnType, objectTypeReference, BoundTypeArgumentSource.INFERRED); } List<LightweightTypeReference> incompleteParameterTypes = incompleteClosureType.getParameterTypes(); for(int i = 0; i < incompleteParameterTypes.size(); i++) { result.addParameterType(incompleteParameterTypes.get(i)); } List<LightweightTypeReference> incompleteTypeArguments = incompleteClosureType.getTypeArguments(); List<LightweightTypeReference> resultTypeArguments = result.getTypeArguments(); for(int i = 0; i < incompleteTypeArguments.size(); i++) { deferredBindTypeArgument(resultTypeArguments.get(i), incompleteTypeArguments.get(i), BoundTypeArgumentSource.INFERRED); } return result; } else { incompleteClosureType.setReturnType(expressionResultType); return incompleteClosureType; } }
protected AbstractDiagnostic createTypeDiagnostic(XExpression expression, LightweightTypeReference actualType, LightweightTypeReference expectedType) { if (!expectedType.isAny()) { String actualName = actualType.getSimpleName(); String expectedName = expectedType.getSimpleName(); if (actualName.equals(expectedName)) { if (expectedType.isAssignableFrom(actualType)) { return null; } } if (expression.eContainingFeature() == XbasePackage.Literals.XABSTRACT_FEATURE_CALL__IMPLICIT_FIRST_ARGUMENT) { return new EObjectDiagnosticImpl(Severity.ERROR, IssueCodes.INCOMPATIBLE_TYPES, String.format( "Type mismatch: cannot convert implicit first argument from %s to %s", actualType.getHumanReadableName(), expectedType.getHumanReadableName()), expression, null, -1, null); } else { return new EObjectDiagnosticImpl(Severity.ERROR, IssueCodes.INCOMPATIBLE_TYPES, String.format( "Type mismatch: cannot convert from %s to %s", actualType.getHumanReadableName(), expectedType.getHumanReadableName()), expression, null, -1, null); } } else { return new EObjectDiagnosticImpl(Severity.ERROR, IssueCodes.INCOMPATIBLE_TYPES, String.format( "Type mismatch: type %s is not applicable at this location", actualType.getHumanReadableName()), expression, null, -1, null); } }
@Override /* @Nullable */ protected LightweightMergedBoundTypeArgument getBoundTypeArgument(JvmTypeParameter typeParameter, ConstraintVisitingInfo info) { LightweightMergedBoundTypeArgument result = super.getBoundTypeArgument(typeParameter, info); if (result != null) { LightweightTypeReference typeReference = result.getTypeReference(); if (result.getVariance() == VarianceInfo.INVARIANT) { if (typeReference.isWildcard() && typeReference.getLowerBoundSubstitute().isAny() && typeReference.getUpperBoundSubstitute().isType(Object.class)) { // assume unbound wildcard - use the constraints of the respective type parameter if (!typeParameter.getConstraints().isEmpty()) { JvmTypeConstraint constraint = typeParameter.getConstraints().get(0); if (constraint instanceof JvmUpperBound) { LightweightTypeReference reference = getOwner().toLightweightTypeReference(constraint.getTypeReference()); return new LightweightMergedBoundTypeArgument(reference, VarianceInfo.OUT); } } } } if (declaratorParameterMapping.containsKey(typeParameter) && typeReference.isWildcard()) { wasCapturedWildcard = true; } } return result; }
@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 _computeTypes(XSynchronizedExpression expr, ITypeComputationState state) { ITypeComputationState paramState = state.withExpectation(state.getReferenceOwner().newReferenceToObject()); ITypeComputationResult paramType = paramState.computeTypes(expr.getParam()); LightweightTypeReference actualParamType = paramType.getActualExpressionType(); if (actualParamType != null && (actualParamType.isPrimitive() || actualParamType.isAny())) { state.addDiagnostic(new EObjectDiagnosticImpl( Severity.ERROR, IssueCodes.INCOMPATIBLE_TYPES, actualParamType.getHumanReadableName() + " is not a valid type's argument for the synchronized expression.", expr.getParam(), null, -1, new String[] { })); } state.computeTypes(expr.getExpression()); }
protected LightweightTypeReference appendVariableTypeAndName(XVariableDeclaration varDeclaration, ITreeAppendable appendable) { if (!varDeclaration.isWriteable()) { appendable.append("final "); } LightweightTypeReference type = null; if (varDeclaration.getType() != null) { serialize(varDeclaration.getType(), varDeclaration, appendable); type = getLightweightType((JvmIdentifiableElement) varDeclaration); } else { type = getLightweightType(varDeclaration.getRight()); if (type.isAny()) { type = getTypeForVariableDeclaration(varDeclaration.getRight()); } appendable.append(type); } appendable.append(" "); appendable.append(appendable.declareVariable(varDeclaration, makeJavaIdentifier(varDeclaration.getName()))); return type; }