use of com.redhat.ceylon.model.typechecker.model.Declaration 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.Declaration in project ceylon-compiler by ceylon.
the class ExpressionTransformer method checkForByteLiterals.
private JCExpression checkForByteLiterals(Tree.InvocationExpression ce) {
// same test as in BoxingVisitor.isByteLiteral()
if (ce.getPrimary() instanceof Tree.BaseTypeExpression && ce.getPositionalArgumentList() != null) {
java.util.List<Tree.PositionalArgument> positionalArguments = ce.getPositionalArgumentList().getPositionalArguments();
if (positionalArguments.size() == 1) {
PositionalArgument argument = positionalArguments.get(0);
if (argument instanceof Tree.ListedArgument && ((Tree.ListedArgument) argument).getExpression() != null) {
Term term = ((Tree.ListedArgument) argument).getExpression().getTerm();
boolean negative = false;
if (term instanceof Tree.NegativeOp) {
negative = true;
term = ((Tree.NegativeOp) term).getTerm();
}
if (term instanceof Tree.NaturalLiteral) {
Declaration decl = ((Tree.BaseTypeExpression) ce.getPrimary()).getDeclaration();
if (decl instanceof Class) {
String name = decl.getQualifiedNameString();
if (name.equals("ceylon.language::Byte")) {
at(ce);
try {
long value = literalValue((Tree.NaturalLiteral) term);
if (negative)
value = -value;
// assignment, not for method calls, so it's simpler to always cast
return make().TypeCast(syms().byteType, make().Literal(value));
} catch (ErroneousException e) {
// replaced with a throw.
return e.makeErroneous(this);
}
}
}
}
}
}
}
return null;
}
use of com.redhat.ceylon.model.typechecker.model.Declaration in project ceylon-compiler by ceylon.
the class ClassTransformer method makeAttributeForValueParameter.
private void makeAttributeForValueParameter(ClassDefinitionBuilder classBuilder, Tree.Parameter parameterTree, Tree.TypedDeclaration memberTree) {
Parameter decl = parameterTree.getParameterModel();
if (!(decl.getModel() instanceof Value)) {
return;
}
final Value value = (Value) decl.getModel();
if (decl.getDeclaration() instanceof Constructor) {
classBuilder.field(PUBLIC | FINAL, decl.getName(), makeJavaType(decl.getType()), null, false, expressionGen().transformAnnotations(OutputElement.FIELD, memberTree));
classBuilder.getInitBuilder().init(make().Exec(make().Assign(naming.makeQualIdent(naming.makeThis(), decl.getName()), naming.makeName(value, Naming.NA_IDENT))));
} else if (parameterTree instanceof Tree.ValueParameterDeclaration && (value.isShared() || value.isCaptured())) {
makeFieldForParameter(classBuilder, decl, memberTree);
AttributeDefinitionBuilder adb = AttributeDefinitionBuilder.getter(this, decl.getName(), decl.getModel());
adb.modifiers(classGen().transformAttributeGetSetDeclFlags(decl.getModel(), false));
adb.userAnnotations(expressionGen().transformAnnotations(OutputElement.GETTER, memberTree));
classBuilder.attribute(adb);
if (value.isVariable()) {
AttributeDefinitionBuilder setter = AttributeDefinitionBuilder.setter(this, decl.getName(), decl.getModel());
setter.modifiers(classGen().transformAttributeGetSetDeclFlags(decl.getModel(), false));
//setter.userAnnotations(expressionGen().transform(AnnotationTarget.SETTER, memberTree.getAnnotationList()));
classBuilder.attribute(setter);
}
} else if (decl.isHidden() && // TODO Isn't this always true here? We know this is a parameter to a Class
(decl.getDeclaration() instanceof TypeDeclaration)) {
Declaration member = CodegenUtil.findMethodOrValueForParam(decl);
if (Strategy.createField(decl, (Value) member)) {
// The field itself is created by when we transform the AttributeDeclaration
// but it has to be initialized here so all the fields are initialized in parameter order
JCExpression parameterExpr = makeUnquotedIdent(Naming.getAliasedParameterName(decl));
TypedReference typedRef = getTypedReference(value);
TypedReference nonWideningTypedRef = nonWideningTypeDecl(typedRef);
Type paramType = nonWideningType(typedRef, nonWideningTypedRef);
if (!paramType.isExactly(decl.getType())) {
// The parameter type follows normal erasure rules, not affected by inheritance
// but the attribute respects non-widening rules, so we may need to cast
// the parameter to the field type (see #1728)
parameterExpr = make().TypeCast(classGen().transformClassParameterType(decl), parameterExpr);
}
classBuilder.getInitBuilder().init(make().Exec(make().Assign(naming.makeQualifiedName(naming.makeThis(), value, Naming.NA_IDENT), parameterExpr)));
}
}
}
use of com.redhat.ceylon.model.typechecker.model.Declaration 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.Declaration in project ceylon-compiler by ceylon.
the class ExpressionTransformer method transformQualifiedInstantiation.
private JCExpression transformQualifiedInstantiation(Invocation invocation, CallBuilder callBuilder, TransformedInvocationPrimary transformedPrimary) {
Tree.QualifiedTypeExpression qte = (Tree.QualifiedTypeExpression) invocation.getPrimary();
Declaration declaration = qte.getDeclaration();
invocation.location(callBuilder);
if (Decl.isJavaStaticOrInterfacePrimary(invocation.getPrimary())) {
callBuilder.instantiate(transformedPrimary.expr);
} else if (!Strategy.generateInstantiator(declaration)) {
if (Decl.isConstructorPrimary(invocation.getPrimary())) {
if (Decl.getConstructedClass(invocation.getPrimaryDeclaration()).isMember()) /*&& invocation.getPrimary() instanceof Tree.QualifiedTypeExpression
&& !(((Tree.QualifiedTypeExpression)invocation.getPrimary()).getPrimary() instanceof Tree.BaseTypeExpression)*/
{
callBuilder.instantiate(new ExpressionAndType(transformedPrimary.expr, null), makeJavaType(invocation.getReturnType(), JT_CLASS_NEW | (transformedPrimary.expr == null ? 0 : JT_NON_QUALIFIED)));
} else {
callBuilder.instantiate(makeJavaType(invocation.getReturnType(), JT_CLASS_NEW));
}
} else {
JCExpression qualifier;
JCExpression qualifierType;
if (declaration.getContainer() instanceof Interface) {
// When doing qualified invocation through an interface we need
// to get the companion.
Interface qualifyingInterface = (Interface) declaration.getContainer();
qualifier = transformedPrimary.expr;
qualifierType = makeJavaType(qualifyingInterface.getType(), JT_COMPANION);
} else {
qualifier = transformedPrimary.expr;
if (declaration.getContainer() instanceof TypeDeclaration) {
qualifierType = makeJavaType(((TypeDeclaration) declaration.getContainer()).getType());
} else {
qualifierType = null;
}
}
Type classType = (Type) qte.getTarget();
JCExpression type;
// special case for package-qualified things that are not really qualified
if (qualifier == null) {
type = makeJavaType(classType, AbstractTransformer.JT_CLASS_NEW);
} else {
// Note: here we're not fully qualifying the class name because the JLS says that if "new" is qualified the class name
// is qualified relative to it
type = makeJavaType(classType, AbstractTransformer.JT_CLASS_NEW | AbstractTransformer.JT_NON_QUALIFIED);
}
callBuilder.instantiate(new ExpressionAndType(qualifier, qualifierType), type);
}
} else {
// instantiator
callBuilder.typeArguments(List.<JCExpression>nil());
java.util.List<Type> typeModels = qte.getTypeArguments().getTypeModels();
if (typeModels != null) {
for (Type tm : typeModels) {
callBuilder.typeArgument(makeJavaType(tm, AbstractTransformer.JT_TYPE_ARGUMENT));
}
}
callBuilder.invoke(naming.makeInstantiatorMethodName(transformedPrimary.expr, Decl.getConstructedClass(declaration)));
}
JCExpression result = callBuilder.build();
if (Strategy.isInstantiatorUntyped(declaration)) {
result = make().TypeCast(makeJavaType(invocation.getReturnType()), result);
}
return result;
}
Aggregations