use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class ClassTransformer method addAmbiguousMember.
private void addAmbiguousMember(ClassDefinitionBuilder classBuilder, Interface model, String name) {
Declaration member = model.getMember(name, null, false);
Type satisfiedType = model.getType().getSupertype(model);
if (member instanceof Class) {
Class klass = (Class) member;
if (Strategy.generateInstantiator(member) && !klass.hasConstructors()) {
// instantiator method implementation
generateInstantiatorDelegate(classBuilder, satisfiedType, model, klass, null, model.getType(), false);
}
if (klass.hasConstructors()) {
for (Declaration m : klass.getMembers()) {
if (m instanceof Constructor && Strategy.generateInstantiator(m)) {
Constructor ctor = (Constructor) m;
generateInstantiatorDelegate(classBuilder, satisfiedType, model, klass, ctor, model.getType(), false);
}
}
}
} else if (member instanceof Function) {
Function method = (Function) member;
final TypedReference typedMember = satisfiedType.getTypedMember(method, Collections.<Type>emptyList());
java.util.List<java.util.List<Type>> producedTypeParameterBounds = producedTypeParameterBounds(typedMember, method);
final java.util.List<TypeParameter> typeParameters = method.getTypeParameters();
final java.util.List<Parameter> parameters = method.getFirstParameterList().getParameters();
for (Parameter param : parameters) {
if (Strategy.hasDefaultParameterOverload(param)) {
MethodDefinitionBuilder overload = new DefaultedArgumentMethodTyped(null, MethodDefinitionBuilder.method(this, method), typedMember, true).makeOverload(method.getFirstParameterList(), param, typeParameters);
overload.modifiers(PUBLIC | ABSTRACT);
classBuilder.method(overload);
}
}
final MethodDefinitionBuilder concreteMemberDelegate = makeDelegateToCompanion(null, typedMember, model.getType(), PUBLIC | ABSTRACT, method.getTypeParameters(), producedTypeParameterBounds, typedMember.getType(), naming.selector(method), method.getFirstParameterList().getParameters(), ((Function) member).getTypeErased(), null, DelegateType.OTHER, false);
classBuilder.method(concreteMemberDelegate);
} else if (member instanceof Value || member instanceof Setter) {
TypedDeclaration attr = (TypedDeclaration) member;
final TypedReference typedMember = satisfiedType.getTypedMember(attr, Collections.<Type>emptyList());
if (member instanceof Value) {
final MethodDefinitionBuilder getterDelegate = makeDelegateToCompanion(null, typedMember, model.getType(), PUBLIC | ABSTRACT, Collections.<TypeParameter>emptyList(), Collections.<java.util.List<Type>>emptyList(), typedMember.getType(), Naming.getGetterName(attr), Collections.<Parameter>emptyList(), attr.getTypeErased(), null, DelegateType.OTHER, false);
classBuilder.method(getterDelegate);
}
if (member instanceof Setter) {
final MethodDefinitionBuilder setterDelegate = makeDelegateToCompanion(null, typedMember, model.getType(), PUBLIC | ABSTRACT, Collections.<TypeParameter>emptyList(), Collections.<java.util.List<Type>>emptyList(), typeFact().getAnythingType(), Naming.getSetterName(attr), Collections.<Parameter>singletonList(((Setter) member).getParameter()), ((Setter) member).getTypeErased(), null, DelegateType.OTHER, false);
classBuilder.method(setterDelegate);
}
}
}
use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class ExpressionTransformer method makeJavaStaticInvocation.
JCExpression makeJavaStaticInvocation(CeylonTransformer gen, final Functional methodOrClass, Reference producedReference, final ParameterList parameterList) {
CallBuilder callBuilder = CallBuilder.instance(gen);
if (methodOrClass instanceof Function) {
callBuilder.invoke(gen.naming.makeName((Function) methodOrClass, Naming.NA_FQ | Naming.NA_WRAPPER_UNQUOTED));
} else if (methodOrClass instanceof Class) {
callBuilder.instantiate(gen.makeJavaType(((Class) methodOrClass).getType(), JT_RAW | JT_NO_PRIMITIVES));
}
ListBuffer<ExpressionAndType> reified = ListBuffer.lb();
DirectInvocation.addReifiedArguments(gen, producedReference, reified);
for (ExpressionAndType reifiedArgument : reified) {
callBuilder.argument(reifiedArgument.expression);
}
for (Parameter parameter : parameterList.getParameters()) {
callBuilder.argument(gen.naming.makeQuotedIdent(parameter.getName()));
}
JCExpression innerInvocation = callBuilder.build();
return innerInvocation;
}
use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class ExpressionTransformer method transform.
public JCExpression transform(Tree.Parameter param) {
// Transform the expression marking that we're inside a defaulted parameter for $this-handling
//needDollarThis = true;
JCExpression expr;
at(param);
if (Strategy.hasDefaultParameterValueMethod(param.getParameterModel())) {
Tree.SpecifierOrInitializerExpression spec = Decl.getDefaultArgument(param);
Scope container = param.getParameterModel().getModel().getContainer();
boolean classParameter = container instanceof ClassOrInterface;
ClassOrInterface oldWithinDefaultParameterExpression = withinDefaultParameterExpression;
if (classParameter)
withinDefaultParameterExpression((ClassOrInterface) container);
if (param instanceof Tree.FunctionalParameterDeclaration) {
Tree.FunctionalParameterDeclaration fpTree = (Tree.FunctionalParameterDeclaration) param;
Tree.SpecifierExpression lazy = (Tree.SpecifierExpression) spec;
Function fp = (Function) fpTree.getParameterModel().getModel();
expr = CallableBuilder.anonymous(gen(), param, (Function) fpTree.getTypedDeclaration().getDeclarationModel(), lazy.getExpression(), ((Tree.MethodDeclaration) fpTree.getTypedDeclaration()).getParameterLists(), getTypeForFunctionalParameter(fp), true).build();
} else {
expr = transformExpression(spec.getExpression(), CodegenUtil.getBoxingStrategy(param.getParameterModel().getModel()), param.getParameterModel().getType());
}
if (classParameter)
withinDefaultParameterExpression(oldWithinDefaultParameterExpression);
} else {
expr = makeErroneous(param, "compiler bug: no default parameter value method");
}
//needDollarThis = false;
return expr;
}
use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class ClassTransformer method addMissingUnrefinedMembers.
/**
* Recover from members not being refined in the class hierarchy
* by generating a stub method that throws.
*/
private void addMissingUnrefinedMembers(Node def, Class classModel, ClassDefinitionBuilder classBuilder) {
for (Reference unrefined : classModel.getUnimplementedFormals()) {
//classModel.getMember(memberName, null, false);
Declaration formalMember = unrefined.getDeclaration();
String errorMessage = "formal member '" + formalMember.getName() + "' of '" + ((TypeDeclaration) formalMember.getContainer()).getName() + "' not implemented in class hierarchy";
java.util.List<Type> params = new java.util.ArrayList<Type>();
if (formalMember instanceof Generic) {
for (TypeParameter tp : ((Generic) formalMember).getTypeParameters()) {
params.add(tp.getType());
}
}
if (formalMember instanceof Value) {
addRefinedThrowerAttribute(classBuilder, errorMessage, classModel, (Value) formalMember);
} else if (formalMember instanceof Function) {
addRefinedThrowerMethod(classBuilder, errorMessage, classModel, (Function) formalMember);
} else if (formalMember instanceof Class && formalMember.isClassMember()) {
addRefinedThrowerInstantiatorMethod(classBuilder, errorMessage, classModel, (Class) formalMember, unrefined);
}
// formal member class of interface handled in
// makeDelegateToCompanion()
}
}
use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class MethodDefinitionBuilder method getNonWideningParam.
public NonWideningParam getNonWideningParam(TypedReference typedRef, WideningRules wideningRules) {
TypedDeclaration nonWideningDecl = null;
int flags = 0;
Type nonWideningType;
FunctionOrValue mov = (FunctionOrValue) typedRef.getDeclaration();
if (Decl.isValue(mov)) {
TypedReference nonWideningTypedRef = gen.nonWideningTypeDecl(typedRef);
nonWideningType = gen.nonWideningType(typedRef, nonWideningTypedRef);
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();
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);
// 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;
}
}
}
// 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, nonWideningType, nonWideningDecl);
}
Aggregations