protected void enhanceFunctionType(FunctionTypeReference reference, FunctionTypeReference result, Visiting visiting) { for(LightweightTypeReference parameterType: reference.getParameterTypes()) { result.addParameterType(visitTypeArgument(parameterType, visiting, true)); } for(LightweightTypeReference typeArgument: reference.getTypeArguments()) { result.addTypeArgument(visitTypeArgument(typeArgument, visiting)); } LightweightTypeReference returnType = reference.getReturnType(); if (returnType != null) { result.setReturnType(visitTypeArgument(returnType, visiting)); } }
protected int doIsConformant(FunctionTypeReference left, FunctionTypeReference right, int flags) { if (left.getType() == right.getType()) { return flags | SUCCESS; } if ((flags & ALLOW_FUNCTION_CONVERSION) == 0) return flags; // function types can be converted to native function types which will be raw assignable if their // number of parameters matches and the function type kind if (left.getParameterTypes().size() == right.getParameterTypes().size()) { LightweightTypeReference leftReturnType = left.getReturnType(); LightweightTypeReference rightReturnType = right.getReturnType(); if (leftReturnType == rightReturnType) { return flags | SUCCESS; } if (leftReturnType != null && rightReturnType != null && leftReturnType.isPrimitiveVoid() == rightReturnType.isPrimitiveVoid()) { return flags | SUCCESS; } } return flags; }
@Override protected FunctionTypeReference doCopyInto(ITypeReferenceOwner owner) { FunctionTypeReference result = new FunctionTypeReference(owner, getType()); copyTypeArguments(result, owner); return result; }
protected void prepareResultType() { resultClosureType = expectedClosureType.getOwner().newFunctionTypeReference(expectedClosureType.getType()); for (LightweightTypeReference argument : expectedClosureType.getTypeArguments()) { resultClosureType.addTypeArgument(argument); } }
@Override protected void doVisitFunctionTypeReference(FunctionTypeReference reference, StringBuilder param) { param.append("("); List<LightweightTypeReference> parameterTypes = reference.getParameterTypes(); for(int i = 0; i < parameterTypes.size(); i++) { if (i != 0) { param.append(", "); } parameterTypes.get(i).accept(this, param); } param.append(")=>"); if (reference.getReturnType() != null) { reference.getReturnType().accept(this, param); } else { param.append("./."); } }
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; } }
@Override public LightweightTypeReference doVisitFunctionTypeReference(XFunctionTypeRef reference) { JvmTypeReference equivalent = reference.getEquivalent(); if (equivalent == null) { return super.doVisitFunctionTypeReference(reference); } FunctionTypeReference result; // constructors used below to avoid subsequent checks for isInner which was supposed to be done by // the computation of the equivalent if (equivalent.eClass() == TypesPackage.Literals.JVM_INNER_TYPE_REFERENCE) { JvmParameterizedTypeReference outer = ((JvmInnerTypeReference) equivalent).getOuter(); LightweightTypeReference outerEquivalent = outer.accept(this); result = new InnerFunctionTypeReference(owner, outerEquivalent, reference.getType()); } else { result = new FunctionTypeReference(owner, reference.getType()); } if (equivalent instanceof JvmParameterizedTypeReference) { for(JvmTypeReference argument: ((JvmParameterizedTypeReference)equivalent).getArguments()) { result.addTypeArgument(visit(argument)); } } for(JvmTypeReference parameter: reference.getParamTypes()) { result.addParameterType(visit(parameter)); } if (reference.getReturnType() != null) { result.setReturnType(visit(reference.getReturnType())); } return result; }
protected ITypeComputationState assignParameters(ITypeAssigner typeAssigner) { List<LightweightTypeReference> operationParameterTypes = expectedClosureType.getParameterTypes(); XClosure closure = getClosure(); List<JvmFormalParameter> closureParameters; LightweightTypeReference returnType = expectedClosureType.getReturnType(); if (returnType.getKind() == LightweightTypeReference.KIND_UNBOUND_TYPE_REFERENCE) { skippedHandle = ((UnboundTypeReference) returnType).getHandle(); resultClosureType.addParameterType(closureParameterType); if (validParameterTypes && !closureParameterType.isAssignableFrom(operationParameterType)) { validParameterTypes = false; resultClosureType.addParameterType(partiallyResolved); LightweightTypeReference lightweight = typeAssigner.toLightweightTypeReference(parameterType); typeAssigner.assignType(closureParameter, lightweight); resultClosureType.addParameterType(lightweight); } else { LightweightTypeReference objectType = typeAssigner.toLightweightTypeReference(getServices().getTypeReferences().getTypeForName(Object.class, closureParameter)); typeAssigner.assignType(closureParameter, objectType); resultClosureType.addParameterType(objectType);
if (functionTypeReference == null) throw new IllegalStateException("Expected type does not seem to be a SAM type"); appendable.append(functionTypeReference.toInstanceTypeReference()); appendable.append("() {"); appendable.increaseIndentation().increaseIndentation(); appendable.newLine().append("public "); LightweightTypeReference returnType = functionTypeReference.getReturnType(); if (returnType == null) throw new IllegalStateException("Could not find return type"); JvmFormalParameter p = params.get(i); final String name = p.getName(); appendable.append(functionTypeReference.getParameterTypes().get(i)); appendable.append(" ").append(name);
@Override protected LightweightTypeReference doVisitFunctionTypeReference(FunctionTypeReference reference, Visiting visiting) { if (reference.isResolved() && reference.isOwnedBy(getOwner())) return reference; FunctionTypeReference result = getOwner().newFunctionTypeReference(reference.getType()); enhanceFunctionType(reference, result, visiting); return result; }
protected void initClosureType(FunctionTypeReference result, boolean isProcedure) { ITypeReferenceOwner owner = result.getOwner(); TypeParameterByUnboundSubstitutor substitutor = new TypeParameterByUnboundSubstitutor(Collections.<JvmTypeParameter, LightweightMergedBoundTypeArgument>emptyMap(), owner) { @Override protected UnboundTypeReference createUnboundTypeReference(JvmTypeParameter type) { UnboundTypeReference result = getExpectation().createUnboundTypeReference(getClosure(), type); return result; } }; JvmGenericType type = (JvmGenericType) result.getType(); List<JvmTypeParameter> typeParameters = type.getTypeParameters(); int max = type.getTypeParameters().size(); if (!isProcedure) max--; for(int i = 0; i < max; i++) { JvmTypeParameter typeParameter = typeParameters.get(i); LightweightTypeReference parameterType = owner.newParameterizedTypeReference(typeParameter); LightweightTypeReference substituted = substitutor.substitute(parameterType); result.addTypeArgument(substituted); } if (!isProcedure) { JvmTypeParameter typeParameter = typeParameters.get(max); LightweightTypeReference parameterType = owner.toLightweightTypeReference(typeParameter); LightweightTypeReference substituted = substitutor.substitute(parameterType); result.addTypeArgument(substituted); } }
@Override public JvmTypeReference toTypeReference() { XFunctionTypeRef result = getOwner().getServices().getXtypeFactory().createXFunctionTypeRef(); result.setType(getType()); result.setEquivalent(getEquivalentTypeReference()); if (parameterTypes != null) { for(LightweightTypeReference parameterType: parameterTypes) { result.getParamTypes().add(parameterType.toTypeReference()); } } if (returnType != null) { result.setReturnType(returnType.toTypeReference()); } return result; }
private FunctionTypeReference createFunctionTypeRef( ITypeReferenceOwner owner, LightweightTypeReference functionType, List<LightweightTypeReference> parameterTypes, /* @Nullable */ LightweightTypeReference returnType, /* @Nullable */ LightweightTypeReference outer) { JvmType type = functionType.getType(); if (type == null) throw new IllegalArgumentException("type may not be null"); FunctionTypeReference result; if (outer == null) { result = owner.newFunctionTypeReference(type); } else { result = owner.newFunctionTypeReference(outer, type); } if (functionType instanceof ParameterizedTypeReference) { for(LightweightTypeReference typeArgument: ((ParameterizedTypeReference) functionType).getTypeArguments()) { result.addTypeArgument(typeArgument.copyInto(owner)); } } for(LightweightTypeReference parameterType: parameterTypes) { result.addParameterType(parameterType.copyInto(owner)); } if (returnType != null) { result.setReturnType(returnType.copyInto(owner)); } return result; }
final FunctionTypeReference fctRef = closureType0.tryConvertToFunctionTypeReference(true); if (fctRef != null) { closureType = Utils.toLightweightTypeReference(fctRef.getType(), this.typeServices).getRawTypeReference(); final FunctionTypeReference fctRef = returnType.tryConvertToFunctionTypeReference(true); if (fctRef != null) { returnType = fctRef.getReturnType(); } else { returnType = null;
@Override public String getJavaIdentifier() { return getAsStringNoFunctionType(getType().getIdentifier(), JavaIdentifierFunction.INSTANCE); }
protected FunctionTypeReference getAsFunctionOrNull(ParameterizedTypeReference typeReference) { if (typeReference.isRawType()) return null; FunctionTypeReference functionType = new FunctionTypeReference(typeReference.getOwner(), typeReference.getType()); List<LightweightTypeReference> allTypeArguments = typeReference.getTypeArguments(); if (!tryAssignTypeArguments(allTypeArguments.subList(0, allTypeArguments.size() - 1), functionType)) return null; LightweightTypeReference lastTypeArgument = allTypeArguments.get(allTypeArguments.size() - 1); functionType.addTypeArgument(lastTypeArgument); LightweightTypeReference returnType = lastTypeArgument.getUpperBoundSubstitute(); functionType.setReturnType(returnType); return functionType; }
LightweightTypeReference expressionResultType = expressionResult.getReturnType(); if (expressionResultType == null || expressionResultType instanceof AnyTypeReference) { LightweightTypeReference returnType = expectedClosureType.getReturnType(); if (returnType == null) throw new IllegalStateException("return type shall not be null"); resultClosureType.setReturnType(returnType); if (validParameterTypes && returnType.isPrimitiveVoid()) { return ConformanceFlags.INCOMPATIBLE; LightweightTypeReference expectedReturnType = expectedClosureType.getReturnType(); if (expectedReturnType == null) throw new IllegalStateException("expected return type may not be null"); if (!expressionResultType.isPrimitiveVoid()) { if (expectedReturnType.isPrimitiveVoid()) { resultClosureType.setReturnType(expectedReturnType); if (isImplicitReturn(expressionResult)) { return ConformanceFlags.NONE; resultClosureType.setReturnType(expressionResultType); if (validParameterTypes && isImplicitReturn(expressionResult)) { return ConformanceFlags.LAMBDA_VOID_COMPATIBLE; resultClosureType.setReturnType(expressionResultType); } else if (expectedReturnType.isPrimitiveVoid()) { resultClosureType.setReturnType(expectedReturnType); return ConformanceFlags.INCOMPATIBLE; } else { resultClosureType.setReturnType(expectedReturnType); return ConformanceFlags.LAMBDA_RAW_COMPATIBLE;
@Override protected void copyTypeArguments(ParameterizedTypeReference result, ITypeReferenceOwner owner) { super.copyTypeArguments(result, owner); FunctionTypeReference casted = (FunctionTypeReference) result; if (parameterTypes != null && !parameterTypes.isEmpty()) { for(LightweightTypeReference typeArgument: parameterTypes) { casted.addParameterType(typeArgument.copyInto(owner)); } } if (returnType != null) { casted.setReturnType(returnType.copyInto(owner)); } }
LightweightTypeReference expectedReturnType = expectedClosureType.getReturnType(); if (expectedReturnType == null) { throw new IllegalStateException("expected return type may not be null"); if (resultClosureType.getReturnType() == null) throw new IllegalStateException("Closure has no return type assigned"); if (!validParameterTypes || flags == ConformanceFlags.INCOMPATIBLE) {