use of org.eclipse.ceylon.model.typechecker.model.TypedReference in project ceylon by eclipse.
the class ExpressionTransformer method transformExpression.
//
// Any sort of expression
JCExpression transformExpression(final TypedDeclaration declaration, final Tree.Term expr) {
// make sure we use the best declaration for boxing and type
TypedReference typedRef = getTypedReference(declaration);
TypedReference nonWideningTypedRef = nonWideningTypeDecl(typedRef);
Type nonWideningType = nonWideningType(typedRef, nonWideningTypedRef);
// the non-widening type of the innermost callable
if (declaration instanceof Functional && Decl.isMpl((Functional) declaration)) {
for (int i = ((Functional) declaration).getParameterLists().size(); i > 1; i--) {
nonWideningType = getReturnTypeOfCallable(nonWideningType);
}
}
// respect the refining definition of optionality
nonWideningType = propagateOptionality(declaration.getType(), nonWideningType);
BoxingStrategy boxing = CodegenUtil.getBoxingStrategy(nonWideningTypedRef.getDeclaration());
int flags = 0;
if (declaration.hasUncheckedNullType() || declaration == coercedFunctionalInterfaceNeedsNoNullChecks)
flags = ExpressionTransformer.EXPR_TARGET_ACCEPTS_NULL;
if (CodegenUtil.downcastForSmall(expr, declaration))
flags |= ExpressionTransformer.EXPR_UNSAFE_PRIMITIVE_TYPECAST_OK;
return transformExpression(expr, boxing, nonWideningType, flags);
}
use of org.eclipse.ceylon.model.typechecker.model.TypedReference in project ceylon by eclipse.
the class ExpressionTransformer method transformCallableBridge.
public JCExpression transformCallableBridge(Tree.StaticMemberOrTypeExpression expr, Value functional, Type expectedType) {
ParameterList paramList = new ParameterList();
// expr is a SAM
// expectedType is a Callable
TypedReference samRef = checkForFunctionalInterface(expr.getTypeModel());
TypedDeclaration samDecl = samRef.getDeclaration();
if (samDecl instanceof Value) {
Parameter param = new Parameter();
Value paramModel = new Value();
param.setModel(paramModel);
param.setName("arg0");
paramModel.setName("arg0");
paramModel.setType(samRef.getType());
paramModel.setUnboxed(samDecl.getUnboxed());
// FIXME: other stuff like erasure?
paramList.getParameters().add(param);
} else {
int i = 0;
for (Parameter samParam : ((Function) samDecl).getFirstParameterList().getParameters()) {
TypedReference typedSamParam = samRef.getTypedParameter(samParam);
Parameter param = new Parameter();
Value paramModel = new Value();
param.setModel(paramModel);
param.setName("arg" + i);
paramModel.setName("arg" + i);
paramModel.setType(typedSamParam.getFullType());
// FIXME: other stuff like erasure?
paramModel.setUnboxed(typedSamParam.getDeclaration().getUnboxed());
paramList.getParameters().add(param);
i++;
}
}
// FIXME: this is cheating we should be assembling it from the SAM type
Type callableType = expectedType.getSupertype(typeFact().getCallableDeclaration());
return CallableBuilder.methodReference(gen(), expr, paramList, expectedType, callableType, false);
}
use of org.eclipse.ceylon.model.typechecker.model.TypedReference in project ceylon by eclipse.
the class MethodDefinitionBuilder method getNonWideningParam.
public NonWideningParam getNonWideningParam(TypedReference typedRef, WideningRules wideningRules) {
TypedDeclaration nonWideningDecl = null;
int flags = 0;
long modifiers = 0;
Type nonWideningType;
FunctionOrValue mov = (FunctionOrValue) typedRef.getDeclaration();
if (Decl.isValue(mov)) {
TypedReference nonWideningTypedRef = gen.nonWideningTypeDecl(typedRef);
nonWideningType = gen.nonWideningType(typedRef, nonWideningTypedRef).resolveAliases();
nonWideningDecl = nonWideningTypedRef.getDeclaration();
} else {
// Stef: So here's the thing. I know this is wrong for Function where we should do getFullType(), BUT
// lots of methods call this and then feed the output into AT.makeJavaType(TypedDeclaration typeDecl, Type type, int flags)
// which adds the Callable type, so if we fix it here we have to remove it from there and there's lots of callers of that
// function which rely on its behaviour and frankly I've had enough of this refactoring, so a few callers of this function
// have to add the Callable back. It sucks, yeah, but so far it works, which is amazing enough that I don't want to touch it
// any more. More ambitious/courageous people are welcome to fix this properly.
nonWideningType = typedRef.getType().resolveAliases();
nonWideningDecl = mov;
}
if (!CodegenUtil.isUnBoxed(nonWideningDecl))
flags |= AbstractTransformer.JT_NO_PRIMITIVES;
// make sure we don't accidentally narrow value parameters that would be erased in the topmost declaration
if (wideningRules != WideningRules.NONE && mov instanceof Value) {
TypedDeclaration refinedParameter = (TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(mov);
if (refinedParameter != null && refinedParameter instanceof Value && ((Value) refinedParameter).getInitializerParameter() != null && gen.isJavaVariadic(((Value) refinedParameter).getInitializerParameter())) {
modifiers |= Flags.VARARGS;
}
// mixin bridge methods have the same rules as when refining stuff except they are their own refined decl
if (wideningRules == WideningRules.FOR_MIXIN || !Decl.equal(refinedParameter, mov)) {
Type refinedParameterType;
// in the refined parameter type
if (refinedParameter instanceof Function)
refinedParameterType = refinedParameter.appliedTypedReference(null, Collections.<Type>emptyList()).getFullType();
else
refinedParameterType = refinedParameter.getType();
// if the supertype method itself got erased to Object, we can't do better than this
if (gen.willEraseToObject(refinedParameterType) && !gen.willEraseToBestBounds(mov))
nonWideningType = gen.typeFact().getObjectType();
else if (CodegenUtil.isRaw(refinedParameter)) {
flags |= AbstractTransformer.JT_RAW;
} else {
flags |= AbstractTransformer.JT_NARROWED;
}
if ((flags & AbstractTransformer.JT_RAW) == 0 && !Decl.equal(refinedParameter, mov) && implementsRawParameter(mov)) {
flags |= AbstractTransformer.JT_RAW;
}
}
}
// keep in sync with gen.willEraseToBestBounds()
if (wideningRules != WideningRules.NONE && (gen.typeFact().isUnion(nonWideningType) || gen.typeFact().isIntersection(nonWideningType))) {
final Type refinedType = ((TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(nonWideningDecl)).getType();
if (refinedType.isTypeParameter() && !refinedType.getSatisfiedTypes().isEmpty()) {
nonWideningType = refinedType.getSatisfiedTypes().get(0);
// Could be parameterized, and type param won't be in scope, so have to go raw
flags |= AbstractTransformer.JT_RAW;
}
}
// this is to be done on the parameter's containing method, to see if that method must have raw parameters
if (mov.isParameter() && mov.getContainer() instanceof Declaration && gen.rawParameters((Declaration) mov.getContainer())) {
flags |= AbstractTransformer.JT_RAW;
}
return new NonWideningParam(flags, modifiers, nonWideningType, nonWideningDecl);
}
use of org.eclipse.ceylon.model.typechecker.model.TypedReference in project ceylon by eclipse.
the class MethodDefinitionBuilder method resultTypeNonWidening.
public MethodDefinitionBuilder resultTypeNonWidening(Type currentType, TypedReference typedRef, Type returnType, int flags) {
TypedReference nonWideningTypedRef = gen.nonWideningTypeDecl(typedRef, currentType);
returnType = gen.nonWideningType(typedRef, nonWideningTypedRef);
return resultType(makeResultType(nonWideningTypedRef.getDeclaration(), returnType, flags), typedRef.getDeclaration());
}
use of org.eclipse.ceylon.model.typechecker.model.TypedReference in project ceylon by eclipse.
the class NamedArgumentInvocation method bindAttributeArgument.
private void bindAttributeArgument(Tree.AttributeArgument attrArg, Parameter declaredParam, Naming.SyntheticName argName) {
ListBuffer<JCStatement> statements;
final Value model = attrArg.getDeclarationModel();
final String name = model.getName();
String className = Naming.getAttrClassName(model, 0);
final List<JCTree> attrClass = gen.gen().transformAttribute(model, name, className, null, attrArg.getBlock(), attrArg.getSpecifierExpression(), null, null);
TypedReference typedRef = gen.getTypedReference(model);
TypedReference nonWideningTypedRef = gen.nonWideningTypeDecl(typedRef);
Type nonWideningType = gen.nonWideningType(typedRef, nonWideningTypedRef);
Type type = parameterType(declaredParam, model.getType(), 0);
final BoxingStrategy boxType = getNamedParameterBoxingStrategy(declaredParam);
JCExpression initValue = gen.make().Apply(null, gen.makeSelect(gen.makeUnquotedIdent(className), Naming.getGetterName(model)), List.<JCExpression>nil());
initValue = gen.expressionGen().applyErasureAndBoxing(initValue, nonWideningType, !CodegenUtil.isUnBoxed(nonWideningTypedRef.getDeclaration()), boxType, type);
JCTree.JCVariableDecl var = gen.make().VarDef(gen.make().Modifiers(FINAL, List.<JCAnnotation>nil()), argName.asName(), gen.makeJavaType(type, boxType == BoxingStrategy.BOXED ? JT_NO_PRIMITIVES : 0), initValue);
statements = toStmts(attrArg, attrClass).append(var);
bind(declaredParam, argName, gen.makeJavaType(type, boxType == BoxingStrategy.BOXED ? JT_NO_PRIMITIVES : 0), statements.toList());
}
Aggregations