use of com.redhat.ceylon.model.typechecker.model.TypedDeclaration in project ceylon-compiler by ceylon.
the class StatementTransformer method transformCaseIs.
/**
* Transform a "case(is ...)"
* @param selectorAlias
* @param caseClause
* @param isCase
* @param last
* @return
*/
private JCStatement transformCaseIs(Naming.SyntheticName selectorAlias, Tree.CaseClause caseClause, String tmpVar, Tree.Term outerExpression, Type expectedType, Tree.IsCase isCase, JCStatement last, Type expressionType) {
at(isCase);
// Use the type of the variable, which is more precise than the type we test for.
Type varType = isCase.getVariable().getDeclarationModel().getType();
Type caseType = isCase.getType().getTypeModel();
// note: There's no point using makeOptimizedTypeTest() because cases are disjoint
// anyway and the cheap cases get evaluated first.
JCExpression cond = makeTypeTest(null, selectorAlias, caseType, expressionType);
String name = isCase.getVariable().getIdentifier().getText();
TypedDeclaration varDecl = isCase.getVariable().getDeclarationModel();
Naming.SyntheticName tmpVarName = selectorAlias;
Name substVarName = naming.aliasName(name);
// Want raw type for instanceof since it can't be used with generic types
JCExpression rawToTypeExpr = makeJavaType(varType, JT_NO_PRIMITIVES | JT_RAW);
// Substitute variable with the correct type to use in the rest of the code block
JCExpression tmpVarExpr = at(isCase).TypeCast(rawToTypeExpr, tmpVarName.makeIdent());
JCExpression toTypeExpr;
if (isCeylonBasicType(varType) && varDecl.getUnboxed() == true) {
toTypeExpr = makeJavaType(varType);
tmpVarExpr = unboxType(tmpVarExpr, varType);
} else {
toTypeExpr = makeJavaType(varType, JT_NO_PRIMITIVES);
}
// The variable holding the result for the code inside the code block
JCVariableDecl decl2 = at(isCase).VarDef(make().Modifiers(FINAL), substVarName, toTypeExpr, tmpVarExpr);
// Prepare for variable substitution in the following code block
Substitution prevSubst = naming.addVariableSubst(varDecl, substVarName.toString());
List<JCStatement> stats = List.<JCStatement>of(decl2);
stats = stats.appendList(transformCaseClause(caseClause, tmpVar, outerExpression, expectedType));
JCBlock block = at(isCase).Block(0, stats);
// Deactivate the above variable substitution
prevSubst.close();
last = make().If(cond, block, last);
return last;
}
use of com.redhat.ceylon.model.typechecker.model.TypedDeclaration in project ceylon-compiler by ceylon.
the class NamedArgumentInvocation method makeThis.
private final JCVariableDecl makeThis() {
// first append $this
JCExpression defaultedParameterInstance;
// TODO Fix how we figure out the thisType, because it's doesn't
// handle type parameters correctly
// we used to use thisType = gen.getThisType(getPrimaryDeclaration());
final JCExpression thisType;
Reference target = ((Tree.MemberOrTypeExpression) getPrimary()).getTarget();
if (getPrimary() instanceof Tree.BaseMemberExpression && !gen.expressionGen().isWithinSyntheticClassBody()) {
if (Decl.withinClassOrInterface(getPrimaryDeclaration())) {
// a member method
thisType = gen.makeJavaType(target.getQualifyingType(), JT_NO_PRIMITIVES);
defaultedParameterInstance = gen.naming.makeThis();
} else {
// a local or toplevel function
thisType = gen.naming.makeName((TypedDeclaration) getPrimaryDeclaration(), Naming.NA_WRAPPER);
defaultedParameterInstance = gen.naming.makeName((TypedDeclaration) getPrimaryDeclaration(), Naming.NA_MEMBER);
}
} else if (getPrimary() instanceof Tree.BaseTypeExpression || getPrimary() instanceof Tree.QualifiedTypeExpression) {
TypeDeclaration declaration = (TypeDeclaration) ((Tree.MemberOrTypeExpression) getPrimary()).getDeclaration();
thisType = gen.makeJavaType(declaration.getType(), JT_COMPANION);
defaultedParameterInstance = gen.make().NewClass(null, null, gen.makeJavaType(declaration.getType(), JT_COMPANION), List.<JCExpression>nil(), null);
} else {
if (isOnValueType()) {
thisType = gen.makeJavaType(target.getQualifyingType());
} else {
thisType = gen.makeJavaType(target.getQualifyingType(), JT_NO_PRIMITIVES);
}
defaultedParameterInstance = callVarName.makeIdent();
}
JCVariableDecl thisDecl = gen.makeVar(varBaseName.suffixedBy(Suffix.$argthis$), thisType, defaultedParameterInstance);
return thisDecl;
}
use of com.redhat.ceylon.model.typechecker.model.TypedDeclaration in project ceylon-compiler by ceylon.
the class CallableBuilder method unboundFunctionalMemberReference.
/**
* Used for "static" method or class references. For example:
* <pre>
* value x = Integer.plus;
* value y = Foo.method;
* value z = Outer.Inner;
* </pre>
*/
public static CallableBuilder unboundFunctionalMemberReference(CeylonTransformer gen, Tree.QualifiedMemberOrTypeExpression qmte, Type typeModel, final Functional methodClassOrCtor, Reference producedReference) {
final ParameterList parameterList = methodClassOrCtor.getFirstParameterList();
Type type = typeModel;
JCExpression target;
boolean hasOuter = !(Decl.isConstructor((Declaration) methodClassOrCtor) && gen.getNumParameterLists(typeModel) == 1);
if (!hasOuter) {
type = typeModel;
target = null;
} else {
type = gen.getReturnTypeOfCallable(type);
Type qualifyingType = qmte.getTarget().getQualifyingType();
target = gen.naming.makeUnquotedIdent(Unfix.$instance$);
target = gen.expressionGen().applyErasureAndBoxing(target, producedReference.getQualifyingType(), true, BoxingStrategy.BOXED, qualifyingType);
}
CallableBuilder inner = new CallableBuilder(gen, null, type, parameterList);
//FromParameterModels();
inner.parameterTypes = inner.getParameterTypesFromCallableModel();
if (hasOuter) {
inner.defaultValueCall = inner.new MemberReferenceDefaultValueCall(methodClassOrCtor);
}
CallBuilder callBuilder = CallBuilder.instance(gen);
Type accessType = gen.getParameterTypeOfCallable(typeModel, 0);
if (Decl.isConstructor((Declaration) methodClassOrCtor)) {
Constructor ctor = Decl.getConstructor((Declaration) methodClassOrCtor);
Class cls = Decl.getConstructedClass(ctor);
if (Strategy.generateInstantiator(ctor)) {
callBuilder.invoke(gen.naming.makeInstantiatorMethodName(target, cls));
} else {
callBuilder.instantiate(gen.makeJavaType(gen.getReturnTypeOfCallable(typeModel), JT_CLASS_NEW));
if (!ctor.isShared()) {
accessType = Decl.getPrivateAccessType(qmte);
}
}
} else if (methodClassOrCtor instanceof Function && ((Function) methodClassOrCtor).isParameter()) {
callBuilder.invoke(gen.naming.makeQualifiedName(target, (Function) methodClassOrCtor, Naming.NA_MEMBER));
} else if (methodClassOrCtor instanceof Function) {
callBuilder.invoke(gen.naming.makeQualifiedName(target, (Function) methodClassOrCtor, Naming.NA_MEMBER));
if (!((TypedDeclaration) methodClassOrCtor).isShared()) {
accessType = Decl.getPrivateAccessType(qmte);
}
} else if (methodClassOrCtor instanceof Class) {
Class cls = (Class) methodClassOrCtor;
if (Strategy.generateInstantiator(cls)) {
callBuilder.invoke(gen.naming.makeInstantiatorMethodName(target, cls));
} else {
callBuilder.instantiate(new ExpressionAndType(target, null), gen.makeJavaType(cls.getType(), JT_CLASS_NEW | AbstractTransformer.JT_NON_QUALIFIED));
if (!cls.isShared()) {
accessType = Decl.getPrivateAccessType(qmte);
}
}
} else {
throw BugException.unhandledDeclarationCase((Declaration) methodClassOrCtor, qmte);
}
ListBuffer<ExpressionAndType> reified = ListBuffer.lb();
DirectInvocation.addReifiedArguments(gen, producedReference, reified);
for (ExpressionAndType reifiedArgument : reified) {
callBuilder.argument(reifiedArgument.expression);
}
if (Decl.isConstructor((Declaration) methodClassOrCtor) && !Decl.isDefaultConstructor(Decl.getConstructor((Declaration) methodClassOrCtor))) {
// invoke the param class ctor
Constructor ctor = Decl.getConstructor((Declaration) methodClassOrCtor);
callBuilder.argument(gen.naming.makeNamedConstructorName(ctor, false));
}
for (Parameter parameter : parameterList.getParameters()) {
callBuilder.argument(gen.naming.makeQuotedIdent(Naming.getAliasedParameterName(parameter)));
}
JCExpression innerInvocation = callBuilder.build();
// Need to worry about boxing for Function and FunctionalParameter
if (methodClassOrCtor instanceof TypedDeclaration && !Decl.isConstructor((Declaration) methodClassOrCtor)) {
// use the method return type since the function is actually applied
Type returnType = gen.getReturnTypeOfCallable(type);
innerInvocation = gen.expressionGen().applyErasureAndBoxing(innerInvocation, returnType, // expression is a Callable
CodegenUtil.hasTypeErased((TypedDeclaration) methodClassOrCtor), !CodegenUtil.isUnBoxed((TypedDeclaration) methodClassOrCtor), BoxingStrategy.BOXED, returnType, 0);
} else if (methodClassOrCtor instanceof Class && Strategy.isInstantiatorUntyped((Class) methodClassOrCtor)) {
// $new method declared to return Object, so needs typecast
innerInvocation = gen.make().TypeCast(gen.makeJavaType(((Class) methodClassOrCtor).getType()), innerInvocation);
}
List<JCStatement> innerBody = List.<JCStatement>of(gen.make().Return(innerInvocation));
inner.useDefaultTransformation(innerBody);
if (!hasOuter) {
return inner;
}
ParameterList outerPl = new ParameterList();
Parameter instanceParameter = new Parameter();
instanceParameter.setName(Naming.name(Unfix.$instance$));
Value valueModel = new Value();
instanceParameter.setModel(valueModel);
valueModel.setName(instanceParameter.getName());
valueModel.setInitializerParameter(instanceParameter);
valueModel.setType(accessType);
valueModel.setUnboxed(false);
outerPl.getParameters().add(instanceParameter);
CallableBuilder outer = new CallableBuilder(gen, null, typeModel, outerPl);
outer.parameterTypes = outer.getParameterTypesFromParameterModels();
List<JCStatement> outerBody = List.<JCStatement>of(gen.make().Return(inner.build()));
outer.useDefaultTransformation(outerBody);
outer.companionAccess = Decl.isPrivateAccessRequiringCompanion(qmte);
return outer;
}
use of com.redhat.ceylon.model.typechecker.model.TypedDeclaration in project ceylon-compiler by ceylon.
the class CallableBuilder method javaStaticMethodReference.
public static CallableBuilder javaStaticMethodReference(CeylonTransformer gen, Type typeModel, final Functional methodOrClass, Reference producedReference) {
final ParameterList parameterList = methodOrClass.getFirstParameterList();
CallableBuilder inner = new CallableBuilder(gen, null, typeModel, parameterList);
ArrayList<Type> pt = new ArrayList<>();
for (Parameter p : methodOrClass.getFirstParameterList().getParameters()) {
pt.add(p.getType());
}
inner.parameterTypes = pt;
inner.defaultValueCall = inner.new MemberReferenceDefaultValueCall(methodOrClass);
JCExpression innerInvocation = gen.expressionGen().makeJavaStaticInvocation(gen, methodOrClass, producedReference, parameterList);
// Need to worry about boxing for Function and FunctionalParameter
if (methodOrClass instanceof TypedDeclaration) {
innerInvocation = gen.expressionGen().applyErasureAndBoxing(innerInvocation, methodOrClass.getType(), !CodegenUtil.isUnBoxed((TypedDeclaration) methodOrClass), BoxingStrategy.BOXED, methodOrClass.getType());
} else if (Strategy.isInstantiatorUntyped((Class) methodOrClass)) {
// $new method declared to return Object, so needs typecast
innerInvocation = gen.make().TypeCast(gen.makeJavaType(((Class) methodOrClass).getType()), innerInvocation);
}
List<JCStatement> innerBody = List.<JCStatement>of(gen.make().Return(innerInvocation));
inner.useDefaultTransformation(innerBody);
return inner;
}
use of com.redhat.ceylon.model.typechecker.model.TypedDeclaration in project ceylon-compiler by ceylon.
the class BoxingDeclarationVisitor method visit.
@Override
public void visit(Variable that) {
super.visit(that);
TypedDeclaration declaration = that.getDeclarationModel();
// deal with invalid input
if (declaration == null)
return;
setBoxingState(declaration, declaration, that);
rawTypedDeclaration(declaration);
setErasureState(declaration);
}
Aggregations