use of com.redhat.ceylon.model.typechecker.model.Parameter in project ceylon-compiler by ceylon.
the class ClassTransformer method refineMethod.
private Function refineMethod(Scope container, TypedReference pr, ClassOrInterface classModel, Function formalMethod, Unit unit) {
Function refined = new Function();
refined.setActual(true);
refined.setShared(formalMethod.isShared());
refined.setContainer(container);
// in case there are subclasses
refined.setDefault(true);
refined.setDeferred(false);
refined.setDeprecated(formalMethod.isDeprecated());
refined.setName(formalMethod.getName());
refined.setRefinedDeclaration(formalMethod.getRefinedDeclaration());
refined.setScope(container);
refined.setType(pr.getType());
refined.setUnit(unit);
refined.setUnboxed(formalMethod.getUnboxed());
refined.setUntrustedType(formalMethod.getUntrustedType());
refined.setTypeErased(formalMethod.getTypeErased());
ArrayList<TypeParameter> refinedTp = new ArrayList<TypeParameter>();
;
for (TypeParameter formalTp : formalMethod.getTypeParameters()) {
refinedTp.add(formalTp);
}
refined.setTypeParameters(refinedTp);
for (ParameterList formalPl : formalMethod.getParameterLists()) {
ParameterList refinedPl = new ParameterList();
for (Parameter formalP : formalPl.getParameters()) {
Parameter refinedP = new Parameter();
refinedP.setAtLeastOne(formalP.isAtLeastOne());
refinedP.setDeclaration(refined);
refinedP.setDefaulted(formalP.isDefaulted());
refinedP.setDeclaredAnything(formalP.isDeclaredAnything());
refinedP.setHidden(formalP.isHidden());
refinedP.setSequenced(formalP.isSequenced());
refinedP.setName(formalP.getName());
final TypedReference typedParameter = pr.getTypedParameter(formalP);
FunctionOrValue paramModel;
if (formalP.getModel() instanceof Value) {
Value paramValueModel = refineValue((Value) formalP.getModel(), typedParameter, refined, classModel.getUnit());
paramValueModel.setInitializerParameter(refinedP);
paramModel = paramValueModel;
} else {
Function paramFunctionModel = refineMethod(refined, typedParameter, classModel, (Function) formalP.getModel(), unit);
paramFunctionModel.setInitializerParameter(refinedP);
paramModel = paramFunctionModel;
}
refinedP.setModel(paramModel);
refinedPl.getParameters().add(refinedP);
}
refined.addParameterList(refinedPl);
}
return refined;
}
use of com.redhat.ceylon.model.typechecker.model.Parameter 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.Parameter in project ceylon-compiler by ceylon.
the class ClassTransformer method transformAnnotationClass.
/**
* Transforms an annotation class into a Java annotation type.
* <pre>
* annotation class Foo(String s, Integer i=1) {}
* </pre>
* is transformed into
* <pre>
* @Retention(RetentionPolicy.RUNTIME)
* @interface Foo$annotation$ {
* String s();
* long i() default 1;
* }
* </pre>
* If the annotation class is a subtype of SequencedAnnotation a wrapper
* annotation is also generated:
* <pre>
* @Retention(RetentionPolicy.RUNTIME)
* @interface Foo$annotations${
* Foo$annotation$[] value();
* }
* </pre>
*/
private List<JCTree> transformAnnotationClass(Tree.AnyClass def) {
Class klass = (Class) def.getDeclarationModel();
String annotationName = Naming.suffixName(Suffix.$annotation$, klass.getName());
ClassDefinitionBuilder annoBuilder = ClassDefinitionBuilder.klass(this, annotationName, null, false);
// annotations are never explicitly final in Java
annoBuilder.modifiers(Flags.ANNOTATION | Flags.INTERFACE | (transformClassDeclFlags(klass) & ~FINAL));
annoBuilder.getInitBuilder().modifiers(transformClassDeclFlags(klass) & ~FINAL);
annoBuilder.annotations(makeAtRetention(RetentionPolicy.RUNTIME));
annoBuilder.annotations(makeAtIgnore());
annoBuilder.annotations(expressionGen().transformAnnotations(OutputElement.ANNOTATION_TYPE, def));
for (Tree.Parameter p : def.getParameterList().getParameters()) {
Parameter parameterModel = p.getParameterModel();
annoBuilder.method(makeAnnotationMethod(p));
}
List<JCTree> result;
if (isSequencedAnnotation(klass)) {
result = annoBuilder.annotations(makeAtAnnotationTarget(EnumSet.noneOf(AnnotationTarget.class))).build();
String wrapperName = Naming.suffixName(Suffix.$annotations$, klass.getName());
ClassDefinitionBuilder sequencedBuilder = ClassDefinitionBuilder.klass(this, wrapperName, null, false);
// annotations are never explicitely final in Java
sequencedBuilder.modifiers(Flags.ANNOTATION | Flags.INTERFACE | (transformClassDeclFlags(klass) & ~FINAL));
sequencedBuilder.annotations(makeAtRetention(RetentionPolicy.RUNTIME));
MethodDefinitionBuilder mdb = MethodDefinitionBuilder.systemMethod(this, naming.getSequencedAnnotationMethodName());
mdb.annotationFlags(Annotations.MODEL_AND_USER);
mdb.modifiers(PUBLIC | ABSTRACT);
mdb.resultType(null, make().TypeArray(makeJavaType(klass.getType(), JT_ANNOTATION)));
mdb.noBody();
ClassDefinitionBuilder sequencedAnnotation = sequencedBuilder.method(mdb);
sequencedAnnotation.annotations(transformAnnotationConstraints(klass));
sequencedAnnotation.annotations(makeAtIgnore());
result = result.appendList(sequencedAnnotation.build());
} else {
result = annoBuilder.annotations(transformAnnotationConstraints(klass)).build();
}
return result;
}
use of com.redhat.ceylon.model.typechecker.model.Parameter in project ceylon-compiler by ceylon.
the class ExpressionTransformer method transformArgumentsForSimpleInvocation.
private List<ExpressionAndType> transformArgumentsForSimpleInvocation(SimpleInvocation invocation, CallBuilder callBuilder) {
final Constructor superConstructor = invocation.getConstructor();
CtorDelegation constructorDelegation;
if (invocation instanceof SuperInvocation) {
constructorDelegation = ((SuperInvocation) invocation).getDelegation();
} else {
constructorDelegation = null;
}
List<ExpressionAndType> result = List.<ExpressionAndType>nil();
if (!(invocation instanceof SuperInvocation) || !((SuperInvocation) invocation).isDelegationDelegation()) {
int numArguments = invocation.getNumArguments();
if (invocation.getNumParameters() == 0) {
// skip transforming arguments
// (Usually, numArguments would already be null, but it's possible to call a
// parameterless function with a *[] argument - see #1593.)
numArguments = 0;
}
boolean wrapIntoArray = false;
ListBuffer<JCExpression> arrayWrap = new ListBuffer<JCExpression>();
for (int argIndex = 0; argIndex < numArguments; argIndex++) {
BoxingStrategy boxingStrategy = invocation.getParameterBoxingStrategy(argIndex);
Type parameterType = invocation.getParameterType(argIndex);
// to avoid ambiguity of foo(1,2) for foo(int...) and foo(Object...) methods
if (!wrapIntoArray && invocation.isParameterSequenced(argIndex) && invocation.isJavaMethod() && boxingStrategy == BoxingStrategy.UNBOXED && willEraseToPrimitive(typeFact().getDefiniteType(parameterType)) && !invocation.isSpread())
wrapIntoArray = true;
ExpressionAndType exprAndType;
if (invocation.isArgumentSpread(argIndex)) {
if (!invocation.isParameterSequenced(argIndex)) {
result = transformSpreadTupleArgument(invocation, callBuilder, result, argIndex);
break;
}
if (invocation.isJavaMethod()) {
// if it's a java method we need a special wrapping
exprAndType = transformSpreadArgument(invocation, numArguments, argIndex, boxingStrategy, parameterType);
argIndex = numArguments;
} else {
Type argType = invocation.getArgumentType(argIndex);
if (argType.getSupertype(typeFact().getSequentialDeclaration()) != null) {
exprAndType = transformArgument(invocation, argIndex, boxingStrategy);
} else if (argType.getSupertype(typeFact().getIterableDeclaration()) != null) {
exprAndType = transformArgument(invocation, argIndex, boxingStrategy);
JCExpression sequential = iterableToSequential(exprAndType.expression);
if (invocation.isParameterVariadicPlus(argIndex)) {
Type iteratedType = typeFact().getIteratedType(argType);
sequential = utilInvocation().castSequentialToSequence(sequential, iteratedType);
}
exprAndType = new ExpressionAndType(sequential, exprAndType.type);
} else {
exprAndType = new ExpressionAndType(makeErroneous(invocation.getNode(), "compiler bug: unexpected spread argument"), makeErroneous(invocation.getNode(), "compiler bug: unexpected spread argument"));
}
}
} else if (!invocation.isParameterSequenced(argIndex) || // if it's sequenced, Java and there's no spread at all, pass it along
(invocation.isParameterSequenced(argIndex) && invocation.isJavaMethod() && !invocation.isSpread())) {
exprAndType = transformArgument(invocation, argIndex, boxingStrategy);
// This is not required for primitive arrays since they are not Object[]
if (numArguments == 1 && invocation.isIndirect()) {
Type argumentType = invocation.getArgumentType(0);
if (isJavaObjectArray(argumentType) || isNull(argumentType)) {
exprAndType = new ExpressionAndType(make().TypeCast(makeJavaType(typeFact().getObjectType()), exprAndType.expression), exprAndType.type);
}
} else if (invocation.isParameterSequenced(argIndex) && invocation.isJavaMethod() && !invocation.isSpread()) {
// in fact, the very same problem happens when passing null or object arrays to a java variadic method
Type argumentType = invocation.getArgumentType(argIndex);
if (isJavaObjectArray(argumentType) || isNull(argumentType)) {
// remove any ambiguity
exprAndType = new ExpressionAndType(make().TypeCast(makeJavaType(parameterType), exprAndType.expression), exprAndType.type);
}
}
} else {
// we must have a sequenced param
if (invocation.isSpread()) {
exprAndType = transformSpreadArgument(invocation, numArguments, argIndex, boxingStrategy, parameterType);
argIndex = numArguments;
} else {
exprAndType = transformVariadicArgument(invocation, numArguments, argIndex, parameterType);
argIndex = numArguments;
}
}
if (!wrapIntoArray) {
if (argIndex == 0 && invocation.isCallable() && !invocation.isArgumentSpread(numArguments - 1)) {
exprAndType = new ExpressionAndType(make().TypeCast(make().Type(syms().objectType), exprAndType.expression), make().Type(syms().objectType));
}
result = result.append(exprAndType);
} else {
arrayWrap.append(exprAndType.expression);
}
}
if (invocation.isIndirect() && invocation.isParameterSequenced(numArguments) && !invocation.isArgumentSpread(numArguments - 1) && ((IndirectInvocation) invocation).getNumParameters() > numArguments) {
// Calling convention for indirect variadic invocation's requires
// explicit variadic argument (can't use the overloading trick)
result = result.append(new ExpressionAndType(makeEmptyAsSequential(true), make().Erroneous()));
}
if (wrapIntoArray) {
// must have at least one arg, so take the last one
Type parameterType = invocation.getParameterType(numArguments - 1);
JCExpression arrayType = makeJavaType(parameterType, JT_RAW);
JCNewArray arrayExpr = make().NewArray(arrayType, List.<JCExpression>nil(), arrayWrap.toList());
JCExpression arrayTypeExpr = make().TypeArray(makeJavaType(parameterType, JT_RAW));
result = result.append(new ExpressionAndType(arrayExpr, arrayTypeExpr));
}
} else {
for (Parameter p : constructorDelegation.getConstructor().getParameterList().getParameters()) {
result = result.append(new ExpressionAndType(naming.makeName(p.getModel(), Naming.NA_IDENT | Naming.NA_ALIASED), null));
}
}
boolean concreteDelegation = invocation instanceof SuperInvocation && ((SuperInvocation) invocation).getDelegation().isConcreteSelfDelegation();
if (superConstructor == null && concreteDelegation) {
Constructor delegateTo = ((SuperInvocation) invocation).getDelegation().getConstructor();
result = result.prepend(new ExpressionAndType(naming.makeNamedConstructorName(delegateTo, true), naming.makeNamedConstructorType(delegateTo, true)));
} else if (superConstructor != null && constructorDelegation != null && constructorDelegation.isSelfDelegation()) {
result = result.prepend(new ExpressionAndType(naming.makeNamedConstructorName(superConstructor, concreteDelegation), naming.makeNamedConstructorType(superConstructor, concreteDelegation)));
} else if (superConstructor != null && !Decl.isDefaultConstructor(superConstructor)) {
result = result.prepend(new ExpressionAndType(naming.makeNamedConstructorName(superConstructor, concreteDelegation), naming.makeNamedConstructorType(superConstructor, concreteDelegation)));
}
return result;
}
use of com.redhat.ceylon.model.typechecker.model.Parameter 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;
}
Aggregations