use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class ExpressionTransformer method transformMemberReference.
JCExpression transformMemberReference(Tree.QualifiedMemberOrTypeExpression expr, Tree.MemberOrTypeExpression primary) {
Declaration member = expr.getDeclaration();
Type qualifyingType = primary.getTypeModel();
Tree.TypeArguments typeArguments = expr.getTypeArguments();
boolean prevSyntheticClassBody = withinSyntheticClassBody(true);
try {
if (member.isStaticallyImportable()) {
if (member instanceof Function) {
Function method = (Function) member;
Reference producedReference = method.appliedReference(qualifyingType, typeArguments.getTypeModels());
return CallableBuilder.javaStaticMethodReference(gen(), expr.getTypeModel(), method, producedReference).build();
} else if (member instanceof FieldValue) {
return naming.makeName((TypedDeclaration) member, Naming.NA_FQ | Naming.NA_WRAPPER_UNQUOTED);
} else if (member instanceof Value) {
CallBuilder callBuilder = CallBuilder.instance(this);
JCExpression qualExpr = naming.makeTypeDeclarationExpression(null, (TypeDeclaration) member.getContainer(), DeclNameFlag.QUALIFIED);
callBuilder.invoke(naming.makeQualifiedName(qualExpr, (TypedDeclaration) member, Naming.NA_GETTER | Naming.NA_MEMBER));
return callBuilder.build();
} else if (member instanceof Class) {
Reference producedReference = expr.getTarget();
return CallableBuilder.javaStaticMethodReference(gen(), expr.getTypeModel(), (Class) member, producedReference).build();
}
}
if (member instanceof Value) {
if (expr.getStaticMethodReference() && Decl.isEnumeratedConstructor((Value) member)) {
CallBuilder callBuilder = CallBuilder.instance(this);
JCExpression qualExpr;
Class class1 = (Class) member.getContainer();
if (class1.isToplevel()) {
qualExpr = naming.makeTypeDeclarationExpression(null, (TypeDeclaration) member.getContainer(), DeclNameFlag.QUALIFIED);
callBuilder.invoke(naming.makeQualifiedName(qualExpr, (TypedDeclaration) member, Naming.NA_GETTER | Naming.NA_MEMBER));
} else if (class1.isMember()) {
// creates a Callable<Outer.Inner,[Outer]> that returns the enumeratedConstructor given an outer instance
if (primary instanceof Tree.QualifiedMemberOrTypeExpression && ((Tree.QualifiedMemberOrTypeExpression) primary).getPrimary() instanceof Tree.BaseTypeExpression)
return CallableBuilder.unboundValueMemberReference(gen(), expr, expr.getTypeModel(), ((TypedDeclaration) member)).build();
else {
qualExpr = primary instanceof Tree.QualifiedMemberOrTypeExpression ? transformExpression(((Tree.QualifiedMemberOrTypeExpression) primary).getPrimary()) : null;
callBuilder.invoke(naming.makeQualifiedName(qualExpr, (TypedDeclaration) member, Naming.NA_GETTER | Naming.NA_MEMBER));
}
} else {
callBuilder.fieldRead(naming.makeName((TypedDeclaration) member, Naming.NA_IDENT));
}
return callBuilder.build();
} else {
return CallableBuilder.unboundValueMemberReference(gen(), expr, expr.getTypeModel(), ((TypedDeclaration) member)).build();
}
} else if (Decl.isConstructor(member)) {
Reference producedReference = expr.getTarget();
return CallableBuilder.unboundFunctionalMemberReference(gen(), expr, expr.getTypeModel(), Decl.getConstructor(member), producedReference).build();
} else if (member instanceof Function) {
Function method = (Function) member;
if (!method.isParameter()) {
Reference producedReference = method.appliedReference(qualifyingType, typeArguments.getTypeModels());
return CallableBuilder.unboundFunctionalMemberReference(gen(), expr, expr.getTypeModel(), method, producedReference).build();
} else {
Reference producedReference = method.appliedReference(qualifyingType, typeArguments.getTypeModels());
return CallableBuilder.unboundFunctionalMemberReference(gen(), expr, expr.getTypeModel(), method, producedReference).build();
}
} else if (member instanceof Class) {
Reference producedReference = expr.getTarget();
return CallableBuilder.unboundFunctionalMemberReference(gen(), expr, expr.getTypeModel(), (Class) member, producedReference).build();
} else {
return makeErroneous(expr, "compiler bug: member reference of " + expr + " not supported yet");
}
} finally {
withinSyntheticClassBody(prevSyntheticClassBody);
}
}
use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class ExpressionTransformer method transform.
JCExpression transform(Tree.FunctionArgument functionArg, Type expectedType) {
Function model = functionArg.getDeclarationModel();
List<JCStatement> body;
boolean prevNoExpressionlessReturn = statementGen().noExpressionlessReturn;
boolean prevSyntheticClassBody = expressionGen().withinSyntheticClassBody(true);
try {
statementGen().noExpressionlessReturn = isAnything(model.getType());
if (functionArg.getBlock() != null) {
body = statementGen().transformBlock(functionArg.getBlock());
if (!functionArg.getBlock().getDefinitelyReturns()) {
if (isAnything(model.getType())) {
body = body.append(make().Return(makeNull()));
} else {
body = body.append(make().Return(makeErroneous(functionArg.getBlock(), "compiler bug: non-void method does not definitely return")));
}
}
} else {
Tree.Expression expr = functionArg.getExpression();
JCExpression transExpr = expressionGen().transformExpression(expr);
JCReturn returnStat = make().Return(transExpr);
body = List.<JCStatement>of(returnStat);
}
} finally {
expressionGen().withinSyntheticClassBody(prevSyntheticClassBody);
statementGen().noExpressionlessReturn = prevNoExpressionlessReturn;
}
//functionArg.getTypeModel();
Type callableType = model.getTypedReference().getFullType();
CallableBuilder callableBuilder = CallableBuilder.methodArgument(gen(), functionArg, model, callableType, Collections.singletonList(functionArg.getParameterLists().get(0)), classGen().transformMplBody(functionArg.getParameterLists(), model, body));
JCExpression result = callableBuilder.build();
result = applyErasureAndBoxing(result, callableType, true, BoxingStrategy.BOXED, expectedType);
return result;
}
use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class CodegenUtil method isContainerFunctionalParameter.
public static boolean isContainerFunctionalParameter(Declaration declaration) {
Scope containerScope = declaration.getContainer();
Declaration containerDeclaration;
if (containerScope instanceof Specification) {
containerDeclaration = ((Specification) containerScope).getDeclaration();
} else if (containerScope instanceof Declaration) {
containerDeclaration = (Declaration) containerScope;
} else {
throw BugException.unhandledCase(containerScope);
}
return containerDeclaration instanceof Function && ((Function) containerDeclaration).isParameter();
}
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, JCExpression lhs, JCExpression rhs) {
JCExpression result = null;
// FIXME: can this be anything else than a Tree.StaticMemberOrTypeExpression or Tree.ParameterizedExpression?
TypedDeclaration decl;
if (leftTerm instanceof Tree.StaticMemberOrTypeExpression) {
decl = (TypedDeclaration) ((Tree.StaticMemberOrTypeExpression) leftTerm).getDeclaration();
lhs = addInterfaceImplAccessorIfRequired(lhs, (Tree.StaticMemberOrTypeExpression) leftTerm, decl);
lhs = addThisOrObjectQualifierIfRequired(lhs, (Tree.StaticMemberOrTypeExpression) leftTerm, decl);
} else {
// instanceof Tree.ParameterizedExpression
decl = (TypedDeclaration) ((Tree.MemberOrTypeExpression) ((Tree.ParameterizedExpression) leftTerm).getPrimary()).getDeclaration();
}
boolean variable = decl.isVariable();
at(op);
String selector = naming.selector(decl, Naming.NA_SETTER);
if (decl.isToplevel()) {
// must use top level setter
lhs = naming.makeName(decl, Naming.NA_FQ | Naming.NA_WRAPPER);
} else if (Decl.isGetter(decl)) {
if (Decl.isTransient(decl) && !decl.isVariable()) {
JCExpression attr = gen().transformAttributeGetter(decl, rhs);
result = at(op).Assign(naming.makeQualifiedName(lhs, decl, Naming.NA_WRAPPER), attr);
} else {
// must use the setter
if (Decl.isLocal(decl)) {
lhs = naming.makeQualifiedName(lhs, decl, Naming.NA_WRAPPER | Naming.NA_SETTER);
} else if (decl.isStaticallyImportable()) {
lhs = naming.makeTypeDeclarationExpression(null, (TypeDeclaration) decl.getContainer(), DeclNameFlag.QUALIFIED);
}
}
} else if (decl instanceof Function && Decl.isDeferred(decl)) {
if (Decl.isLocal(decl)) {
// Deferred method initialization of a local function
// The Callable field has the same name as the method, so use NA_MEMBER
result = at(op).Assign(naming.makeQualifiedName(lhs, decl, Naming.NA_WRAPPER_UNQUOTED | Naming.NA_MEMBER), rhs);
} else {
// Deferred method initialization of a class function
result = at(op).Assign(naming.makeQualifiedName(lhs, decl, Naming.NA_MEMBER), rhs);
}
} else if ((variable || decl.isLate()) && (Decl.isClassAttribute(decl))) {
// must use the setter, nothing to do, unless it's a java field
if (Decl.isJavaField(decl)) {
if (decl.isStaticallyImportable()) {
// static field
result = at(op).Assign(naming.makeName(decl, Naming.NA_FQ | Naming.NA_WRAPPER_UNQUOTED), rhs);
} else {
// normal field
result = at(op).Assign(naming.makeQualifiedName(lhs, decl, Naming.NA_IDENT), rhs);
}
}
} else if (variable && (decl.isCaptured() || decl.isShared())) {
// must use the qualified setter
if (Decl.isBoxedVariable(decl)) {
result = at(op).Assign(naming.makeName(decl, Naming.NA_Q_LOCAL_INSTANCE | Naming.NA_MEMBER | Naming.NA_SETTER), rhs);
} else if (Decl.isLocalNotInitializer(decl)) {
lhs = naming.makeQualifiedName(lhs, decl, Naming.NA_WRAPPER);
} else if (isWithinSuperInvocation() && decl.isCaptured() && decl.isVariable()) {
lhs = naming.makeUnquotedIdent(Naming.getAliasedParameterName(((Value) decl).getInitializerParameter()));
result = at(op).Assign(lhs, rhs);
}
} else {
result = at(op).Assign(naming.makeQualifiedName(lhs, decl, Naming.NA_IDENT), rhs);
}
if (result == null) {
result = make().Apply(List.<JCTree.JCExpression>nil(), makeQualIdent(lhs, selector), List.<JCTree.JCExpression>of(rhs));
}
return result;
}
use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class ExpressionTransformer method transform.
private List<JCAnnotation> transform(Object useSite, OutputElement target, Tree.AnnotationList annotationList, EnumSet<OutputElement> outputs) {
if (annotationList == null) {
return List.nil();
}
if ((gen().disableAnnotations & CeylonTransformer.DISABLE_USER_ANNOS) != 0) {
return List.nil();
}
LinkedHashMap<Class, ListBuffer<JCAnnotation>> annotationSet = new LinkedHashMap<>();
if (annotationList != null) {
if (annotationList.getAnonymousAnnotation() != null && isNaturalTarget((Function) typeFact().getLanguageModuleDeclaration("doc"), useSite, target)) {
transformAnonymousAnnotation(annotationList.getAnonymousAnnotation(), annotationSet);
}
if (annotationList.getAnnotations() != null) {
for (Tree.Annotation annotation : annotationList.getAnnotations()) {
Function annoCtorDecl = ((Function) ((Tree.BaseMemberExpression) annotation.getPrimary()).getDeclaration());
EnumSet<OutputElement> possibleTargets = AnnotationUtil.interopAnnotationTargeting(outputs, annotation, false);
if ((isNaturalTarget(annoCtorDecl, useSite, target) && possibleTargets == null) || (possibleTargets != null && possibleTargets.equals(EnumSet.of(target)))) {
transformAnnotation(annotation, annotationSet);
}
}
}
}
ListBuffer<JCAnnotation> result = ListBuffer.lb();
for (Class annotationClass : annotationSet.keySet()) {
ListBuffer<JCAnnotation> annotations = annotationSet.get(annotationClass);
if (isSequencedAnnotation(annotationClass)) {
JCAnnotation wrapperAnnotation = make().Annotation(makeJavaType(annotationClass.getType(), JT_ANNOTATIONS), List.<JCExpression>of(make().NewArray(null, null, (List) annotations.toList())));
result.append(wrapperAnnotation);
} else {
if (annotations.size() > 1) {
makeErroneous(annotationList, "compiler bug: multiple occurances of non-sequenced annotation class " + annotationClass.getQualifiedNameString());
}
result.appendList(annotations);
}
}
// Special case: Generate a @java.lang.Deprecated() if Ceylon deprecated
if (annotationList != null) {
for (Tree.Annotation annotation : annotationList.getAnnotations()) {
if (isNaturalTarget((Function) typeFact().getLanguageModuleDeclaration("deprecated"), useSite, target) && isDeprecatedAnnotation(annotation.getPrimary())) {
result.append(make().Annotation(make().Type(syms().deprecatedType), List.<JCExpression>nil()));
}
}
}
return result.toList();
}
Aggregations