use of org.eclipse.ceylon.model.typechecker.model.Reference in project ceylon by eclipse.
the class ClassOrInterfaceImpl method addMethodIfCompatible.
@SuppressWarnings({ "hiding" })
private <Container, Type, Arguments extends Sequential<? extends Object>> void addMethodIfCompatible(@Ignore TypeDescriptor $reifiedContainer, @Ignore TypeDescriptor $reifiedType, @Ignore TypeDescriptor $reifiedArguments, ArrayList<ceylon.language.meta.model.Method<? super Container, ? extends Type, ? super Arguments>> members, FunctionDeclarationImpl decl, org.eclipse.ceylon.model.typechecker.model.Type qualifyingType, ClassOrInterfaceImpl<Container> containerMetamodel, org.eclipse.ceylon.model.typechecker.model.Type reifiedType, org.eclipse.ceylon.model.typechecker.model.Type reifiedArguments) {
// now the types
Reference producedReference = decl.declaration.appliedReference(qualifyingType, Collections.<org.eclipse.ceylon.model.typechecker.model.Type>emptyList());
org.eclipse.ceylon.model.typechecker.model.Type type = producedReference.getType();
if (!type.isSubtypeOf(reifiedType))
return;
org.eclipse.ceylon.model.typechecker.model.Type argumentsType = Metamodel.getProducedTypeForArguments(decl.declaration.getUnit(), (Functional) decl.declaration, producedReference);
if (!reifiedArguments.isSubtypeOf(argumentsType))
return;
// it's compatible!
members.add(decl.<Container, Type, Arguments>memberApply($reifiedContainer, $reifiedType, $reifiedArguments, containerMetamodel));
}
use of org.eclipse.ceylon.model.typechecker.model.Reference in project ceylon by eclipse.
the class ClassOrInterfaceDeclarationImpl method getAppliedClassOrInterface.
@SuppressWarnings("unchecked")
public <Container, Kind extends ceylon.language.meta.model.ClassOrInterface<? extends Object>> ceylon.language.meta.model.Member<Container, Kind> getAppliedClassOrInterface(@Ignore TypeDescriptor $reifiedContainer, @Ignore TypeDescriptor $reifiedKind, Sequential<? extends ceylon.language.meta.model.Type<?>> types, ceylon.language.meta.model.Type<? extends Object> container) {
List<org.eclipse.ceylon.model.typechecker.model.Type> producedTypes = Metamodel.getProducedTypes(types);
Type qualifyingType = Metamodel.getModel(container);
if (getStatic()) {
producedTypes.addAll(0, qualifyingType.getTypeArgumentList());
}
Metamodel.checkQualifyingType(qualifyingType, declaration);
Metamodel.checkTypeArguments(qualifyingType, declaration, producedTypes);
// find the proper qualifying type
Type memberQualifyingType = qualifyingType.getSupertype((TypeDeclaration) declaration.getContainer());
Reference producedReference = declaration.appliedReference(memberQualifyingType, producedTypes);
final Type appliedType = producedReference.getType();
return (Member<Container, Kind>) Metamodel.getAppliedMetamodel(appliedType);
}
use of org.eclipse.ceylon.model.typechecker.model.Reference in project ceylon by eclipse.
the class ExpressionTransformer method transform.
public JCExpression transform(Tree.InvocationExpression ce) {
JCExpression ret = checkForInvocationExpressionOptimisation(ce);
if (ret != null)
return ret;
Tree.Term primary = Decl.unwrapExpressionsUntilTerm(ce.getPrimary());
Declaration primaryDeclaration = null;
Reference producedReference = null;
if (primary instanceof Tree.MemberOrTypeExpression) {
producedReference = ((Tree.MemberOrTypeExpression) primary).getTarget();
primaryDeclaration = ((Tree.MemberOrTypeExpression) primary).getDeclaration();
}
Invocation invocation;
if (ce.getPositionalArgumentList() != null) {
if ((isIndirectInvocation(ce, true) || isWithinDefaultParameterExpression(primaryDeclaration.getContainer())) && !Decl.isJavaStaticOrInterfacePrimary(ce.getPrimary())) {
// indirect invocation
invocation = new IndirectInvocation(this, primary, primaryDeclaration, ce);
} else {
// direct invocation
java.util.List<Parameter> parameters = ((Functional) primaryDeclaration).getFirstParameterList().getParameters();
invocation = new PositionalInvocation(this, primary, primaryDeclaration, producedReference, ce, parameters);
}
} else if (ce.getNamedArgumentList() != null) {
invocation = new NamedArgumentInvocation(this, primary, primaryDeclaration, producedReference, ce);
} else {
return makeErroneous(ce, "no arguments");
}
return transformInvocation(invocation);
}
use of org.eclipse.ceylon.model.typechecker.model.Reference in project ceylon by eclipse.
the class ClassTransformer method concreteMembersFromSuperinterfaces.
/**
* Generates companion fields ($Foo$impl) and methods
*/
private void concreteMembersFromSuperinterfaces(final Class model, ClassDefinitionBuilder classBuilder, Type satisfiedType, Set<Interface> satisfiedInterfaces) {
satisfiedType = satisfiedType.resolveAliases();
Interface iface = (Interface) satisfiedType.getDeclaration();
if (satisfiedInterfaces.contains(iface) || iface.isIdentifiable()) {
return;
}
// then don't instantiate it...
if (hasImpl(iface)) {
// ... otherwise for each satisfied interface,
// instantiate an instance of the
// companion class in the constructor and assign it to a
// $Interface$impl field
transformInstantiateCompanions(classBuilder, model, iface, satisfiedType);
}
if (!ModelUtil.isCeylonDeclaration(iface)) {
// let's not try to implement CMI for Java interfaces
return;
}
// For each super interface
for (Declaration member : sortedMembers(iface.getMembers())) {
if (member instanceof Class) {
Class klass = (Class) member;
final Type typedMember = satisfiedType.getTypeMember(klass, Collections.<Type>emptyList());
if (Strategy.generateInstantiator(member) && !klass.hasConstructors() && !model.isFormal() && needsCompanionDelegate(model, typedMember) && model.getDirectMember(member.getName(), null, false) == null) {
// instantiator method implementation
generateInstantiatorDelegate(classBuilder, satisfiedType, iface, klass, null, model.getType(), !member.isFormal());
}
if (klass.hasConstructors()) {
for (Declaration m : klass.getMembers()) {
if (m instanceof Constructor && Strategy.generateInstantiator(m)) {
Constructor ctor = (Constructor) m;
generateInstantiatorDelegate(classBuilder, satisfiedType, iface, klass, ctor, model.getType(), true);
}
}
}
}
// type aliases are on the $impl class
if (member instanceof TypeAlias)
continue;
if (Strategy.onlyOnCompanion(member)) {
// (they're just private methods on the $impl)
continue;
}
if (member instanceof Function) {
Function method = (Function) member;
final TypedReference typedMember = satisfiedType.getTypedMember(method, typesOfTypeParameters(method.getTypeParameters()));
Declaration sub = (Declaration) model.getMember(method.getName(), getSignatureIfRequired(typedMember), false, true);
if (sub instanceof Function) /* && !sub.isAbstraction()*/
{
Function subMethod = (Function) sub;
if (subMethod.getParameterLists().isEmpty()) {
continue;
}
java.util.List<java.util.List<Type>> producedTypeParameterBounds = producedTypeParameterBounds(typedMember, subMethod);
// final TypedReference refinedTypedMember = model.getType().getTypedMember(subMethod, Collections.<Type>emptyList());
final java.util.List<TypeParameter> typeParameters = subMethod.getTypeParameters();
final java.util.List<Parameter> parameters = subMethod.getFirstParameterList().getParameters();
boolean hasOverloads = false;
if (!satisfiedInterfaces.contains((Interface) method.getContainer())) {
for (Parameter param : parameters) {
if (Strategy.hasDefaultParameterValueMethod(param) && CodegenUtil.getTopmostRefinedDeclaration(param.getModel()).getContainer().equals(member)) {
final TypedReference typedParameter = typedMember.getTypedParameter(param);
// If that method has a defaulted parameter,
// we need to generate a default value method
// which also delegates to the $impl
final MethodDefinitionBuilder defaultValueDelegate = makeDelegateToCompanion(iface, typedMember, model.getType(), modifierTransformation().defaultValueMethodBridge(), typeParameters, producedTypeParameterBounds, typedParameter.getFullType(), Naming.getDefaultedParamMethodName(method, param), parameters.subList(0, parameters.indexOf(param)), param.getModel().getTypeErased(), null, param);
classBuilder.method(defaultValueDelegate);
}
if (Strategy.hasDefaultParameterOverload(param)) {
if ((method.isDefault() || method.isShared() && !method.isFormal()) && Decl.equal(method, subMethod)) {
MethodDefinitionBuilder overload = new DefaultedArgumentMethodTyped(new DaoThis((Tree.AnyMethod) null, null), MethodDefinitionBuilder.method(this, subMethod), typedMember, true).makeOverload(subMethod.getFirstParameterList(), param, typeParameters);
classBuilder.method(overload);
}
hasOverloads = true;
}
}
}
// delegating to the $impl instance
if (needsCompanionDelegate(model, typedMember)) {
final MethodDefinitionBuilder concreteMemberDelegate = makeDelegateToCompanion(iface, typedMember, model.getType(), modifierTransformation().methodBridge(method), typeParameters, producedTypeParameterBounds, typedMember.getType(), naming.selector(method), method.getFirstParameterList().getParameters(), ((Function) member).getTypeErased(), null, null);
classBuilder.method(concreteMemberDelegate);
}
if (hasOverloads && (method.isDefault() || method.isShared() && !method.isFormal()) && Decl.equal(method, subMethod)) {
final MethodDefinitionBuilder canonicalMethod = makeDelegateToCompanion(iface, typedMember, model.getType(), modifierTransformation().canonicalMethodBridge(), subMethod.getTypeParameters(), producedTypeParameterBounds, typedMember.getType(), Naming.selector(method, Naming.NA_CANONICAL_METHOD), method.getFirstParameterList().getParameters(), ((Function) member).getTypeErased(), naming.selector(method), null);
classBuilder.method(canonicalMethod);
}
}
} else if (member instanceof Value || member instanceof Setter) {
TypedDeclaration attr = (TypedDeclaration) member;
final TypedReference typedMember = satisfiedType.getTypedMember(attr, null);
if (needsCompanionDelegate(model, typedMember)) {
Setter setter = (member instanceof Setter) ? (Setter) member : null;
if (member instanceof Value) {
Value getter = (Value) member;
if (member instanceof JavaBeanValue) {
setter = ((Value) member).getSetter();
}
final MethodDefinitionBuilder getterDelegate = makeDelegateToCompanion(iface, typedMember, model.getType(), modifierTransformation().getterBridge(getter), Collections.<TypeParameter>emptyList(), Collections.<java.util.List<Type>>emptyList(), typedMember.getType(), Naming.getGetterName(getter), Collections.<Parameter>emptyList(), getter.getTypeErased(), null, null);
classBuilder.method(getterDelegate);
}
if (setter != null) {
final MethodDefinitionBuilder setterDelegate = makeDelegateToCompanion(iface, satisfiedType.getTypedMember(setter, null), model.getType(), modifierTransformation().setterBridge(setter), Collections.<TypeParameter>emptyList(), Collections.<java.util.List<Type>>emptyList(), typeFact().getAnythingType(), Naming.getSetterName(attr), Collections.<Parameter>singletonList(setter.getParameter()), setter.getTypeErased(), null, null);
classBuilder.method(setterDelegate);
}
if (Decl.isValue(member) && ((Value) attr).isVariable()) {
// $impl to delegate to
throw new BugException("assertion failed: " + member.getQualifiedNameString() + " was unexpectedly a variable value");
}
}
} else {
Reference typedMember = member instanceof TypeDeclaration ? satisfiedType.getTypeMember((TypeDeclaration) member, Collections.<Type>emptyList()) : satisfiedType.getTypedMember((TypedDeclaration) member, Collections.<Type>emptyList());
if (needsCompanionDelegate(model, typedMember)) {
throw new BugException("unhandled concrete interface member " + member.getQualifiedNameString() + " " + member.getClass());
}
}
}
// Add $impl instances for the whole interface hierarchy
satisfiedInterfaces.add(iface);
for (Type sat : iface.getSatisfiedTypes()) {
sat = model.getType().getSupertype(sat.getDeclaration());
concreteMembersFromSuperinterfaces(model, classBuilder, sat, satisfiedInterfaces);
}
}
use of org.eclipse.ceylon.model.typechecker.model.Reference in project ceylon by eclipse.
the class NamedArgumentInvocation method addReifiedArguments.
@Override
protected void addReifiedArguments(ListBuffer<ExpressionAndType> result) {
Reference ref = gen.resolveAliasesForReifiedTypeArguments(producedReference);
if (!AbstractTransformer.supportsReified(ref.getDeclaration()))
return;
int tpCount = gen.getTypeParameters(ref).size();
for (int tpIndex = 0; tpIndex < tpCount; tpIndex++) {
result.append(new ExpressionAndType(reifiedTypeArgName(tpIndex).makeIdent(), gen.makeTypeDescriptorType()));
}
}
Aggregations