use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class ExpressionTransformer method transformAssignment.
private JCExpression transformAssignment(Node op, Tree.Term leftTerm, Tree.Term rightTerm) {
// Remember and disable inStatement for RHS
boolean tmpInStatement = inStatement;
inStatement = false;
// FIXME: can this be anything else than a Tree.MemberOrTypeExpression or Tree.ParameterizedExpression?
final JCExpression rhs;
BoxingStrategy boxing;
if (leftTerm instanceof Tree.MemberOrTypeExpression) {
TypedDeclaration decl = (TypedDeclaration) ((Tree.MemberOrTypeExpression) leftTerm).getDeclaration();
boxing = CodegenUtil.getBoxingStrategy(decl);
if (decl instanceof Value) {
Value val = (Value) decl;
if (val.getSetter() != null && val.getSetter().getUnboxed() != null) {
boxing = CodegenUtil.getBoxingStrategy(val.getSetter());
}
}
Type targetType = tmpInStatement ? leftTerm.getTypeModel() : rightTerm.getTypeModel();
// if we're dealing with widening do not trust the type of the declaration and get the real type
if (CodegenUtil.hasUntrustedType(decl)) {
TypedReference typedRef = (TypedReference) ((Tree.MemberOrTypeExpression) leftTerm).getTarget();
TypedReference nonWideningTypedRef = nonWideningTypeDecl(typedRef);
targetType = nonWideningType(typedRef, nonWideningTypedRef);
}
rhs = transformExpression(rightTerm, boxing, targetType, decl.hasUncheckedNullType() ? EXPR_TARGET_ACCEPTS_NULL : 0);
} else {
// instanceof Tree.ParameterizedExpression
boxing = CodegenUtil.getBoxingStrategy(leftTerm);
Tree.ParameterizedExpression paramExpr = (Tree.ParameterizedExpression) leftTerm;
FunctionOrValue decl = (FunctionOrValue) ((Tree.MemberOrTypeExpression) paramExpr.getPrimary()).getDeclaration();
CallableBuilder callableBuilder = CallableBuilder.anonymous(gen(), paramExpr, decl, (Tree.Expression) rightTerm, paramExpr.getParameterLists(), paramExpr.getPrimary().getTypeModel(), decl instanceof Function ? !((Function) decl).isDeferred() : false);
rhs = callableBuilder.build();
}
if (tmpInStatement) {
return transformAssignment(op, leftTerm, rhs);
} else {
Type valueType = rightTerm.getTypeModel();
if (isNull(valueType))
valueType = leftTerm.getTypeModel();
return transformAssignAndReturnOperation(op, leftTerm, boxing == BoxingStrategy.BOXED, leftTerm.getTypeModel(), valueType, new AssignAndReturnOperationFactory() {
@Override
public JCExpression getNewValue(JCExpression previousValue) {
return rhs;
}
});
}
}
use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class InterfaceVisitor method visit.
@Override
public void visit(Tree.AnyMethod that) {
Function model = that.getDeclarationModel();
// locals and toplevels get a type generated for them
if (!model.isMember() && !model.isToplevel()) {
Set<String> old = localCompanionClasses;
localCompanionClasses = new HashSet<String>();
super.visit(that);
localCompanionClasses = old;
} else {
super.visit(that);
}
}
use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class ExpressionTransformer method transform.
public JCTree transform(Tree.MemberLiteral expr) {
at(expr);
Declaration declaration = expr.getDeclaration();
if (declaration == null)
return makeErroneous(expr, "compiler bug: missing declaration");
if (declaration.isToplevel()) {
return makeTopLevelValueOrFunctionLiteral(expr);
} else if (expr.getWantsDeclaration()) {
return makeMemberValueOrFunctionDeclarationLiteral(expr, declaration);
} else {
// get its produced ref
Reference producedReference = expr.getTarget();
// it's a member we get from its container type
Type containerType = producedReference.getQualifyingType();
// if we have no container type it means we have an object member
boolean objectMember = containerType.getDeclaration().isAnonymous();
JCExpression memberCall;
if (objectMember) {
// We don't care about the type args for the cast, nor for the reified container expr, because
// we take the real reified container type from the container instance, and that one has the type
// arguments
containerType = ((Class) declaration.getContainer()).getType();
}
JCExpression typeCall = makeTypeLiteralCall(containerType, false, expr.getTypeModel());
// make sure we cast it to ClassOrInterface
String metatypeName;
if (Decl.isConstructor(declaration)) {
if (Decl.getConstructedClass(declaration).isToplevel()) {
metatypeName = "Class";
} else {
metatypeName = "MemberClass";
}
} else {
metatypeName = "ClassOrInterface";
}
TypeDeclaration classOrInterfaceDeclaration = (TypeDeclaration) typeFact().getLanguageModuleModelDeclaration(metatypeName);
JCExpression classOrInterfaceTypeExpr = makeJavaType(classOrInterfaceDeclaration.appliedReference(null, Arrays.asList(containerType)).getType());
typeCall = make().TypeCast(classOrInterfaceTypeExpr, typeCall);
// we will need a TD for the container
// Note that we don't use Basic for the container for object members, because that's not how we represent
// anonymous types.
JCExpression reifiedContainerExpr = makeReifiedTypeArgument(containerType);
// make a raw call and cast
if (Decl.isConstructor(declaration)) {
Type callableType = producedReference.getFullType();
/*JCExpression reifiedArgumentsExpr;
if (Decl.isEnumeratedConstructor(Decl.getConstructor(declaration))) {
reifiedArgumentsExpr = makeReifiedTypeArgument(typeFact().getCallableTuple(callableType.getQualifyingType()));
} else {
reifiedArgumentsExpr = makeReifiedTypeArgument(typeFact().getCallableTuple(callableType));
}*/
JCExpression reifiedArguments;
if (Decl.isEnumeratedConstructor(Decl.getConstructor(declaration))) {
reifiedArguments = makeReifiedTypeArgument(typeFact().getNothingType());
} else {
reifiedArguments = makeReifiedTypeArgument(typeFact().getCallableTuple(callableType));
}
List<JCExpression> arguments = List.of(reifiedArguments, ceylonLiteral(declaration.getName()));
JCExpression classModel = makeSelect(typeCall, "getDeclaredConstructor");
memberCall = make().Apply(null, classModel, arguments);
} else if (declaration instanceof Function) {
// we need to get types for each type argument
JCExpression closedTypesExpr = null;
if (expr.getTypeArgumentList() != null) {
java.util.List<Type> typeModels = expr.getTypeArgumentList().getTypeModels();
if (typeModels != null) {
closedTypesExpr = getClosedTypesSequential(typeModels);
}
}
// we also need type descriptors for ret and args
Type callableType = producedReference.getFullType();
JCExpression reifiedReturnTypeExpr = makeReifiedTypeArgument(typeFact().getCallableReturnType(callableType));
JCExpression reifiedArgumentsExpr = makeReifiedTypeArgument(typeFact().getCallableTuple(callableType));
List<JCExpression> arguments;
if (closedTypesExpr != null)
arguments = List.of(reifiedContainerExpr, reifiedReturnTypeExpr, reifiedArgumentsExpr, ceylonLiteral(declaration.getName()), closedTypesExpr);
else
arguments = List.of(reifiedContainerExpr, reifiedReturnTypeExpr, reifiedArgumentsExpr, ceylonLiteral(declaration.getName()));
memberCall = make().Apply(null, makeSelect(typeCall, "getMethod"), arguments);
} else if (declaration instanceof Value) {
JCExpression reifiedGetExpr = makeReifiedTypeArgument(producedReference.getType());
String getterName = "getAttribute";
Type ptype;
if (!((Value) declaration).isVariable())
ptype = typeFact().getNothingType();
else
ptype = producedReference.getType();
JCExpression reifiedSetExpr = makeReifiedTypeArgument(ptype);
memberCall = make().Apply(null, makeSelect(typeCall, getterName), List.of(reifiedContainerExpr, reifiedGetExpr, reifiedSetExpr, ceylonLiteral(declaration.getName())));
} else {
return makeErroneous(expr, "Unsupported member type: " + declaration);
}
// if(objectMember){
// // now get the instance and bind it
// // I don't think we need any expected type since objects can't be erased
// JCExpression object = transformExpression(expr.getObjectExpression());
// // reset the location after we transformed the expression
// memberCall = at(expr).Apply(null, makeSelect(memberCall, "bind"), List.of(object));
// }
// cast the member call because we invoke it with no Java generics
memberCall = make().TypeCast(makeJavaType(expr.getTypeModel(), JT_RAW | JT_NO_PRIMITIVES), memberCall);
memberCall = make().TypeCast(makeJavaType(expr.getTypeModel(), JT_NO_PRIMITIVES), memberCall);
return memberCall;
}
}
use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class ExpressionTransformer method isNaturalTarget.
/**
* Whether an annotation (with the given {@code annotationCtorDecl}
* annotation constructor) used on the given declaration ({@code useSite})
* should be added to the Java annotations of the given generated program
* elements ({@code target})
* @param annotationCtorDecl
* @param useSite
* @param target
* @return
*/
private boolean isNaturalTarget(// use site is either a Declaration, or a Package, or a Module,
Function annotationCtorDecl, // module imports
Object useSite, OutputElement target) {
EnumSet<AnnotationTarget> interopTargets;
if (annotationCtorDecl instanceof AnnotationProxyMethod) {
AnnotationProxyMethod annotationProxyMethod = (AnnotationProxyMethod) annotationCtorDecl;
if (annotationProxyMethod.getAnnotationTarget() == target) {
// Foo__WHATEVER, so honour the WHATEVER
return true;
}
interopTargets = annotationProxyMethod.getProxyClass().getAnnotationTarget();
} else {
interopTargets = null;
}
if (useSite instanceof Declaration) {
if (ModelUtil.isConstructor((Declaration) useSite)) {
if (useSite instanceof Functional) {
return target == OutputElement.CONSTRUCTOR;
} else if (useSite instanceof Value) {
return target == OutputElement.GETTER;
}
} else if (useSite instanceof Class) {
if (((Class) useSite).getParameterList() != null && interopTargets != null && interopTargets.contains(AnnotationTarget.CONSTRUCTOR) && !interopTargets.contains(AnnotationTarget.TYPE)) {
return target == OutputElement.CONSTRUCTOR;
}
return target == OutputElement.TYPE;
} else if (useSite instanceof Interface) {
return target == OutputElement.TYPE;
} else if (useSite instanceof Value) {
Value value = (Value) useSite;
TypeDeclaration decltype = typeFact().getValueDeclarationType().getDeclaration();
if (value.isParameter() && !value.isShared() && !(value.isCaptured() && value.isMember())) {
return target == OutputElement.PARAMETER;
} else if (annotationCtorDecl instanceof AnnotationProxyMethod) {
if (value.isLate() || value.isVariable()) {
return target == OutputElement.SETTER;
} else if (!value.isTransient()) {
return target == OutputElement.FIELD;
} else {
return target == OutputElement.GETTER;
}
} else {
return target == OutputElement.GETTER;
}
} else if (useSite instanceof Setter) {
return target == OutputElement.SETTER;
} else if (useSite instanceof Function) {
return target == OutputElement.METHOD;
} else if (useSite instanceof Constructor) {
return target == OutputElement.CONSTRUCTOR;
} else if (useSite instanceof TypeAlias) {
return target == OutputElement.TYPE;
}
} else if (useSite instanceof Package) {
return target == OutputElement.TYPE;
} else if (useSite instanceof Module) {
return target == OutputElement.TYPE;
} else if (useSite instanceof Tree.ImportModule) {
return target == OutputElement.FIELD;
}
throw new RuntimeException("" + useSite);
}
Aggregations