use of com.sun.tools.javac.util.List in project lombok by rzwitserloot.
the class HandleEqualsAndHashCode method createEquals.
public JCMethodDecl createEquals(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess, boolean needsCanEqual, JCTree source, List<JCAnnotation> onParam) {
JavacTreeMaker maker = typeNode.getTreeMaker();
Name oName = typeNode.toName("o");
Name otherName = typeNode.toName("other");
Name thisName = typeNode.toName("this");
JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(typeNode, "Override"), List.<JCExpression>nil());
JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation));
JCExpression objectType = genJavaLangTypeRef(typeNode, "Object");
JCExpression returnType = maker.TypeIdent(CTC_BOOLEAN);
long finalFlag = JavacHandlerUtil.addFinalIfNeeded(0L, typeNode.getContext());
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
final List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(finalFlag | Flags.PARAMETER, onParam), oName, objectType, null));
/* if (o == this) return true; */
{
statements.append(maker.If(maker.Binary(CTC_EQUAL, maker.Ident(oName), maker.Ident(thisName)), returnBool(maker, true), null));
}
/* if (!(o instanceof Outer.Inner.MyType)) return false; */
{
JCUnary notInstanceOf = maker.Unary(CTC_NOT, maker.Parens(maker.TypeTest(maker.Ident(oName), createTypeReference(typeNode, false))));
statements.append(maker.If(notInstanceOf, returnBool(maker, false), null));
}
/* Outer.Inner.MyType<?> other = (Outer.Inner.MyType<?>) o; */
{
if (!fields.isEmpty() || needsCanEqual) {
final JCExpression selfType1 = createTypeReference(typeNode, true), selfType2 = createTypeReference(typeNode, true);
statements.append(maker.VarDef(maker.Modifiers(finalFlag), otherName, selfType1, maker.TypeCast(selfType2, maker.Ident(oName))));
}
}
/* if (!other.canEqual((java.lang.Object) this)) return false; */
{
if (needsCanEqual) {
List<JCExpression> exprNil = List.nil();
JCExpression thisRef = maker.Ident(thisName);
JCExpression castThisRef = maker.TypeCast(genJavaLangTypeRef(typeNode, "Object"), thisRef);
JCExpression equalityCheck = maker.Apply(exprNil, maker.Select(maker.Ident(otherName), typeNode.toName("canEqual")), List.of(castThisRef));
statements.append(maker.If(maker.Unary(CTC_NOT, equalityCheck), returnBool(maker, false), null));
}
}
/* if (!super.equals(o)) return false; */
if (callSuper) {
JCMethodInvocation callToSuper = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("equals")), List.<JCExpression>of(maker.Ident(oName)));
JCUnary superNotEqual = maker.Unary(CTC_NOT, callToSuper);
statements.append(maker.If(superNotEqual, returnBool(maker, false), null));
}
Name thisDollar = typeNode.toName("this$");
Name otherDollar = typeNode.toName("other$");
for (JavacNode fieldNode : fields) {
JCExpression fType = getFieldType(fieldNode, fieldAccess);
JCExpression thisFieldAccessor = createFieldAccessor(maker, fieldNode, fieldAccess);
JCExpression otherFieldAccessor = createFieldAccessor(maker, fieldNode, fieldAccess, maker.Ident(otherName));
if (fType instanceof JCPrimitiveTypeTree) {
switch(((JCPrimitiveTypeTree) fType).getPrimitiveTypeKind()) {
case FLOAT:
/* if (Float.compare(this.fieldName, other.fieldName) != 0) return false; */
statements.append(generateCompareFloatOrDouble(thisFieldAccessor, otherFieldAccessor, maker, typeNode, false));
break;
case DOUBLE:
/* if (Double.compare(this.fieldName, other.fieldName) != 0) return false; */
statements.append(generateCompareFloatOrDouble(thisFieldAccessor, otherFieldAccessor, maker, typeNode, true));
break;
default:
/* if (this.fieldName != other.fieldName) return false; */
statements.append(maker.If(maker.Binary(CTC_NOT_EQUAL, thisFieldAccessor, otherFieldAccessor), returnBool(maker, false), null));
break;
}
} else if (fType instanceof JCArrayTypeTree) {
/* if (!java.util.Arrays.deepEquals(this.fieldName, other.fieldName)) return false; //use equals for primitive arrays. */
boolean multiDim = ((JCArrayTypeTree) fType).elemtype instanceof JCArrayTypeTree;
boolean primitiveArray = ((JCArrayTypeTree) fType).elemtype instanceof JCPrimitiveTypeTree;
boolean useDeepEquals = multiDim || !primitiveArray;
JCExpression eqMethod = chainDots(typeNode, "java", "util", "Arrays", useDeepEquals ? "deepEquals" : "equals");
List<JCExpression> args = List.of(thisFieldAccessor, otherFieldAccessor);
statements.append(maker.If(maker.Unary(CTC_NOT, maker.Apply(List.<JCExpression>nil(), eqMethod, args)), returnBool(maker, false), null));
} else /* objects */
{
/* final java.lang.Object this$fieldName = this.fieldName; */
/* final java.lang.Object other$fieldName = other.fieldName; */
/* if (this$fieldName == null ? other$fieldName != null : !this$fieldName.equals(other$fieldName)) return false; */
Name fieldName = ((JCVariableDecl) fieldNode.get()).name;
Name thisDollarFieldName = thisDollar.append(fieldName);
Name otherDollarFieldName = otherDollar.append(fieldName);
statements.append(maker.VarDef(maker.Modifiers(finalFlag), thisDollarFieldName, genJavaLangTypeRef(typeNode, "Object"), thisFieldAccessor));
statements.append(maker.VarDef(maker.Modifiers(finalFlag), otherDollarFieldName, genJavaLangTypeRef(typeNode, "Object"), otherFieldAccessor));
JCExpression thisEqualsNull = maker.Binary(CTC_EQUAL, maker.Ident(thisDollarFieldName), maker.Literal(CTC_BOT, null));
JCExpression otherNotEqualsNull = maker.Binary(CTC_NOT_EQUAL, maker.Ident(otherDollarFieldName), maker.Literal(CTC_BOT, null));
JCExpression thisEqualsThat = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(thisDollarFieldName), typeNode.toName("equals")), List.<JCExpression>of(maker.Ident(otherDollarFieldName)));
JCExpression fieldsAreNotEqual = maker.Conditional(thisEqualsNull, otherNotEqualsNull, maker.Unary(CTC_NOT, thisEqualsThat));
statements.append(maker.If(fieldsAreNotEqual, returnBool(maker, false), null));
}
}
/* return true; */
{
statements.append(returnBool(maker, true));
}
JCBlock body = maker.Block(0, statements.toList());
return recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("equals"), returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null), source, typeNode.getContext());
}
use of com.sun.tools.javac.util.List in project ceylon-compiler by ceylon.
the class ClassTransformer method transformClassOrCtorParameters.
private void transformClassOrCtorParameters(Tree.AnyClass def, Class cls, Constructor constructor, Tree.Declaration node, Tree.ParameterList paramList, boolean delegationConstructor, ClassDefinitionBuilder classBuilder, ParameterizedBuilder<?> constructorBuilder, boolean generateInstantiator, ClassDefinitionBuilder instantiatorDeclCb, ClassDefinitionBuilder instantiatorImplCb) {
for (final Tree.Parameter param : paramList.getParameters()) {
// Overloaded instantiators
Parameter paramModel = param.getParameterModel();
Parameter refinedParam = CodegenUtil.findParamForDecl((TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(param.getParameterModel().getModel()));
at(param);
Tree.TypedDeclaration member = def != null ? Decl.getMemberDeclaration(def, param) : null;
// transform the parameter and its annotations
transformParameter(constructorBuilder, param, paramModel, member);
if (Strategy.hasDefaultParameterValueMethod(paramModel) || Strategy.hasDefaultParameterOverload(paramModel) || (generateInstantiator && refinedParam != null && (Strategy.hasDefaultParameterValueMethod(refinedParam) || Strategy.hasDefaultParameterOverload(refinedParam)))) {
ClassDefinitionBuilder cbForDevaultValues;
ClassDefinitionBuilder cbForDevaultValuesDecls = null;
switch(Strategy.defaultParameterMethodOwner(constructor != null ? constructor : cls)) {
case STATIC:
cbForDevaultValues = classBuilder;
break;
case OUTER:
cbForDevaultValues = classBuilder.getContainingClassBuilder();
break;
case OUTER_COMPANION:
cbForDevaultValues = classBuilder.getContainingClassBuilder().getCompanionBuilder(Decl.getClassOrInterfaceContainer(cls, true));
if ((constructor == null || constructor.isShared()) && cls.isShared()) {
cbForDevaultValuesDecls = classBuilder.getContainingClassBuilder();
}
break;
default:
cbForDevaultValues = classBuilder.getCompanionBuilder(cls);
}
if (!delegationConstructor) {
if ((Strategy.hasDefaultParameterValueMethod(paramModel) || (refinedParam != null && Strategy.hasDefaultParameterValueMethod(refinedParam)))) {
if (!generateInstantiator || Decl.equal(refinedParam, paramModel)) {
// transform the default value into a method
cbForDevaultValues.method(makeParamDefaultValueMethod(false, constructor != null ? constructor : cls, paramList, param));
if (cbForDevaultValuesDecls != null) {
cbForDevaultValuesDecls.method(makeParamDefaultValueMethod(true, constructor != null ? constructor : cls, paramList, param));
}
} else if (Strategy.hasDelegatedDpm(cls) && cls.getContainer() instanceof Class) {
// generate a dpm which delegates to the companion
java.util.List<Parameter> parameters = paramList.getModel().getParameters();
MethodDefinitionBuilder mdb = makeDelegateToCompanion((Interface) cls.getRefinedDeclaration().getContainer(), paramModel.getModel().appliedTypedReference(cls.getType(), null), ((TypeDeclaration) cls.getContainer()).getType(), FINAL | (transformClassDeclFlags(cls) & ~ABSTRACT), List.<TypeParameter>nil(), Collections.<java.util.List<Type>>emptyList(), paramModel.getType().getFullType(), Naming.getDefaultedParamMethodName(cls, paramModel), parameters.subList(0, parameters.indexOf(paramModel)), false, Naming.getDefaultedParamMethodName(cls, paramModel), DelegateType.FOR_DEFAULT_VALUE);
cbForDevaultValues.method(mdb);
}
}
}
boolean addOverloadedConstructor = false;
if (generateInstantiator) {
if (Decl.withinInterface(cls)) {
MethodDefinitionBuilder instBuilder = new DefaultedArgumentInstantiator(daoAbstract, cls, constructor, instantiatorDeclCb.isCompanionBuilder()).makeOverload(paramList.getModel(), param.getParameterModel(), cls.getTypeParameters());
instantiatorDeclCb.method(instBuilder);
}
if (!Decl.withinInterface(cls) || !cls.isFormal()) {
MethodDefinitionBuilder instBuilder = new DefaultedArgumentInstantiator(new DaoThis(node, paramList), cls, constructor, instantiatorImplCb.isCompanionBuilder()).makeOverload(paramList.getModel(), param.getParameterModel(), cls.getTypeParameters());
instantiatorImplCb.method(instBuilder);
} else {
addOverloadedConstructor = true;
}
} else {
addOverloadedConstructor = true;
}
if (addOverloadedConstructor) {
// Add overloaded constructors for defaulted parameter
MethodDefinitionBuilder overloadBuilder;
DefaultedArgumentConstructor dac;
if (constructor != null) {
dac = new DefaultedArgumentConstructor(classBuilder.addConstructor(), constructor, node, paramList, delegationConstructor);
} else {
dac = new DefaultedArgumentConstructor(classBuilder.addConstructor(), cls, node, paramList, delegationConstructor);
}
overloadBuilder = dac.makeOverload(paramList.getModel(), param.getParameterModel(), cls.getTypeParameters());
}
}
}
}
use of com.sun.tools.javac.util.List in project ceylon-compiler by ceylon.
the class ClassTransformer method transformRefinementSpecifierStatement.
public List<JCStatement> transformRefinementSpecifierStatement(SpecifierStatement op, ClassDefinitionBuilder classBuilder) {
List<JCStatement> result = List.<JCStatement>nil();
// Check if this is a shortcut form of formal attribute refinement
if (op.getRefinement()) {
Tree.Term baseMemberTerm = op.getBaseMemberExpression();
if (baseMemberTerm instanceof Tree.ParameterizedExpression)
baseMemberTerm = ((Tree.ParameterizedExpression) baseMemberTerm).getPrimary();
Tree.BaseMemberExpression expr = (BaseMemberExpression) baseMemberTerm;
Declaration decl = expr.getDeclaration();
if (Decl.isValue(decl) || Decl.isGetter(decl)) {
// Now build a "fake" declaration for the attribute
Tree.AttributeDeclaration attrDecl = new Tree.AttributeDeclaration(null);
attrDecl.setDeclarationModel((Value) decl);
attrDecl.setIdentifier(expr.getIdentifier());
attrDecl.setScope(op.getScope());
attrDecl.setSpecifierOrInitializerExpression(op.getSpecifierExpression());
attrDecl.setAnnotationList(makeShortcutRefinementAnnotationTrees());
// Make sure the boxing information is set correctly
BoxingDeclarationVisitor v = new CompilerBoxingDeclarationVisitor(this);
v.visit(attrDecl);
// Generate the attribute
transform(attrDecl, classBuilder);
} else if (decl instanceof Function) {
// Now build a "fake" declaration for the method
Tree.MethodDeclaration methDecl = new Tree.MethodDeclaration(null);
Function m = (Function) decl;
methDecl.setDeclarationModel(m);
methDecl.setIdentifier(expr.getIdentifier());
methDecl.setScope(op.getScope());
methDecl.setAnnotationList(makeShortcutRefinementAnnotationTrees());
Tree.SpecifierExpression specifierExpression = op.getSpecifierExpression();
methDecl.setSpecifierExpression(specifierExpression);
if (specifierExpression instanceof Tree.LazySpecifierExpression == false) {
Tree.Expression expression = specifierExpression.getExpression();
Tree.Term expressionTerm = Decl.unwrapExpressionsUntilTerm(expression);
// we can optimise lambdas and static method calls
if (!CodegenUtil.canOptimiseMethodSpecifier(expressionTerm, m)) {
// we need a field to save the callable value
String name = naming.getMethodSpecifierAttributeName(m);
JCExpression specifierType = makeJavaType(expression.getTypeModel());
JCExpression specifier = expressionGen().transformExpression(expression);
classBuilder.field(PRIVATE | FINAL, name, specifierType, specifier, false);
}
}
java.util.List<Tree.ParameterList> parameterListTrees = null;
if (op.getBaseMemberExpression() instanceof Tree.ParameterizedExpression) {
parameterListTrees = new ArrayList<>(m.getParameterLists().size());
parameterListTrees.addAll(((Tree.ParameterizedExpression) op.getBaseMemberExpression()).getParameterLists());
Tree.Term term = specifierExpression.getExpression().getTerm();
// and give it the given block of expr as it's specifier
while (term instanceof Tree.FunctionArgument && m.getParameterLists().size() > 1) {
FunctionArgument functionArgument = (Tree.FunctionArgument) term;
specifierExpression.setExpression(functionArgument.getExpression());
parameterListTrees.addAll(functionArgument.getParameterLists());
term = functionArgument.getExpression().getTerm();
}
}
int plIndex = 0;
// copy from formal declaration
for (ParameterList pl : m.getParameterLists()) {
Tree.ParameterList parameterListTree = null;
if (parameterListTrees != null)
parameterListTree = parameterListTrees.get(plIndex++);
Tree.ParameterList tpl = new Tree.ParameterList(null);
tpl.setModel(pl);
int pIndex = 0;
for (Parameter p : pl.getParameters()) {
Tree.Parameter parameterTree = null;
if (parameterListTree != null)
parameterTree = parameterListTree.getParameters().get(pIndex++);
Tree.Parameter tp = null;
if (p.getModel() instanceof Value) {
Tree.ValueParameterDeclaration tvpd = new Tree.ValueParameterDeclaration(null);
if (parameterTree != null)
tvpd.setTypedDeclaration(((Tree.ParameterDeclaration) parameterTree).getTypedDeclaration());
tvpd.setParameterModel(p);
tp = tvpd;
} else if (p.getModel() instanceof Function) {
Tree.FunctionalParameterDeclaration tfpd = new Tree.FunctionalParameterDeclaration(null);
if (parameterTree != null)
tfpd.setTypedDeclaration(((Tree.ParameterDeclaration) parameterTree).getTypedDeclaration());
tfpd.setParameterModel(p);
tp = tfpd;
} else {
throw BugException.unhandledDeclarationCase(p.getModel());
}
tp.setScope(p.getDeclaration().getContainer());
//tp.setIdentifier(makeIdentifier(p.getName()));
tpl.addParameter(tp);
}
methDecl.addParameterList(tpl);
}
// Make sure the boxing information is set correctly
BoxingDeclarationVisitor v = new CompilerBoxingDeclarationVisitor(this);
v.visit(methDecl);
// Generate the method
classBuilder.method(methDecl, Errors.GENERATE);
}
} else {
// Normal case, just generate the specifier statement
result = result.append(expressionGen().transform(op));
}
Tree.Term term = op.getBaseMemberExpression();
if (term instanceof Tree.BaseMemberExpression) {
Tree.BaseMemberExpression bme = (Tree.BaseMemberExpression) term;
DeferredSpecification ds = statementGen().getDeferredSpecification(bme.getDeclaration());
if (ds != null && needsInnerSubstitution(term.getScope(), bme.getDeclaration())) {
result = result.append(ds.openInnerSubstitution());
}
}
return result;
}
use of com.sun.tools.javac.util.List 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;
}
use of com.sun.tools.javac.util.List in project ceylon-compiler by ceylon.
the class ExpressionTransformer method transform.
public JCTree transform(Tree.MemberLiteral expr) {
at(expr);
Declaration declaration = expr.getDeclaration();
if (declaration == null)
return makeErroneous(expr, "compiler bug: missing declaration");
if (declaration.isToplevel()) {
return makeTopLevelValueOrFunctionLiteral(expr);
} else if (expr.getWantsDeclaration()) {
return makeMemberValueOrFunctionDeclarationLiteral(expr, declaration);
} else {
// get its produced ref
Reference producedReference = expr.getTarget();
// it's a member we get from its container type
Type containerType = producedReference.getQualifyingType();
// if we have no container type it means we have an object member
boolean objectMember = containerType.getDeclaration().isAnonymous();
JCExpression memberCall;
if (objectMember) {
// We don't care about the type args for the cast, nor for the reified container expr, because
// we take the real reified container type from the container instance, and that one has the type
// arguments
containerType = ((Class) declaration.getContainer()).getType();
}
JCExpression typeCall = makeTypeLiteralCall(containerType, false, expr.getTypeModel());
// make sure we cast it to ClassOrInterface
String metatypeName;
if (Decl.isConstructor(declaration)) {
if (Decl.getConstructedClass(declaration).isToplevel()) {
metatypeName = "Class";
} else {
metatypeName = "MemberClass";
}
} else {
metatypeName = "ClassOrInterface";
}
TypeDeclaration classOrInterfaceDeclaration = (TypeDeclaration) typeFact().getLanguageModuleModelDeclaration(metatypeName);
JCExpression classOrInterfaceTypeExpr = makeJavaType(classOrInterfaceDeclaration.appliedReference(null, Arrays.asList(containerType)).getType());
typeCall = make().TypeCast(classOrInterfaceTypeExpr, typeCall);
// we will need a TD for the container
// Note that we don't use Basic for the container for object members, because that's not how we represent
// anonymous types.
JCExpression reifiedContainerExpr = makeReifiedTypeArgument(containerType);
// make a raw call and cast
if (Decl.isConstructor(declaration)) {
Type callableType = producedReference.getFullType();
/*JCExpression reifiedArgumentsExpr;
if (Decl.isEnumeratedConstructor(Decl.getConstructor(declaration))) {
reifiedArgumentsExpr = makeReifiedTypeArgument(typeFact().getCallableTuple(callableType.getQualifyingType()));
} else {
reifiedArgumentsExpr = makeReifiedTypeArgument(typeFact().getCallableTuple(callableType));
}*/
JCExpression reifiedArguments;
if (Decl.isEnumeratedConstructor(Decl.getConstructor(declaration))) {
reifiedArguments = makeReifiedTypeArgument(typeFact().getNothingType());
} else {
reifiedArguments = makeReifiedTypeArgument(typeFact().getCallableTuple(callableType));
}
List<JCExpression> arguments = List.of(reifiedArguments, ceylonLiteral(declaration.getName()));
JCExpression classModel = makeSelect(typeCall, "getDeclaredConstructor");
memberCall = make().Apply(null, classModel, arguments);
} else if (declaration instanceof Function) {
// we need to get types for each type argument
JCExpression closedTypesExpr = null;
if (expr.getTypeArgumentList() != null) {
java.util.List<Type> typeModels = expr.getTypeArgumentList().getTypeModels();
if (typeModels != null) {
closedTypesExpr = getClosedTypesSequential(typeModels);
}
}
// we also need type descriptors for ret and args
Type callableType = producedReference.getFullType();
JCExpression reifiedReturnTypeExpr = makeReifiedTypeArgument(typeFact().getCallableReturnType(callableType));
JCExpression reifiedArgumentsExpr = makeReifiedTypeArgument(typeFact().getCallableTuple(callableType));
List<JCExpression> arguments;
if (closedTypesExpr != null)
arguments = List.of(reifiedContainerExpr, reifiedReturnTypeExpr, reifiedArgumentsExpr, ceylonLiteral(declaration.getName()), closedTypesExpr);
else
arguments = List.of(reifiedContainerExpr, reifiedReturnTypeExpr, reifiedArgumentsExpr, ceylonLiteral(declaration.getName()));
memberCall = make().Apply(null, makeSelect(typeCall, "getMethod"), arguments);
} else if (declaration instanceof Value) {
JCExpression reifiedGetExpr = makeReifiedTypeArgument(producedReference.getType());
String getterName = "getAttribute";
Type ptype;
if (!((Value) declaration).isVariable())
ptype = typeFact().getNothingType();
else
ptype = producedReference.getType();
JCExpression reifiedSetExpr = makeReifiedTypeArgument(ptype);
memberCall = make().Apply(null, makeSelect(typeCall, getterName), List.of(reifiedContainerExpr, reifiedGetExpr, reifiedSetExpr, ceylonLiteral(declaration.getName())));
} else {
return makeErroneous(expr, "Unsupported member type: " + declaration);
}
// if(objectMember){
// // now get the instance and bind it
// // I don't think we need any expected type since objects can't be erased
// JCExpression object = transformExpression(expr.getObjectExpression());
// // reset the location after we transformed the expression
// memberCall = at(expr).Apply(null, makeSelect(memberCall, "bind"), List.of(object));
// }
// cast the member call because we invoke it with no Java generics
memberCall = make().TypeCast(makeJavaType(expr.getTypeModel(), JT_RAW | JT_NO_PRIMITIVES), memberCall);
memberCall = make().TypeCast(makeJavaType(expr.getTypeModel(), JT_NO_PRIMITIVES), memberCall);
return memberCall;
}
}
Aggregations