use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.
the class BoxingDeclarationVisitor method visit.
@Override
public void visit(Tree.Parameter that) {
super.visit(that);
TypedDeclaration declaration = that.getParameterModel().getModel();
visitAttributeOrParameter(declaration, that);
}
use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.
the class BoxingVisitor method visit.
@Override
public void visit(BaseMemberExpression that) {
super.visit(that);
// handle errors gracefully
if (that.getDeclaration() == null)
return;
TypedDeclaration decl = (TypedDeclaration) that.getDeclaration();
if (CodegenUtil.isUnBoxed(decl) || // special cases for true/false
isBooleanTrue(decl) || isBooleanFalse(decl))
CodegenUtil.markUnBoxed(that);
if (CodegenUtil.isRaw(decl))
CodegenUtil.markRaw(that);
if (CodegenUtil.hasTypeErased(decl))
CodegenUtil.markTypeErased(that);
if (CodegenUtil.hasUntrustedType(decl))
CodegenUtil.markUntrustedType(that);
}
use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.
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 JCExpression unboundFunctionalMemberReference(CeylonTransformer gen, Tree.QualifiedMemberOrTypeExpression qmte, Type typeModel, final Functional methodClassOrCtor, Reference producedReference, Type expectedType) {
final ParameterList parameterList = methodClassOrCtor.getFirstParameterList();
Type type = typeModel;
JCExpression target;
boolean memberClassCtorRef = ModelUtil.getConstructor((Declaration) methodClassOrCtor) != null && !ModelUtil.getConstructedClass((Declaration) methodClassOrCtor).isToplevel() && qmte.getPrimary() instanceof Tree.QualifiedTypeExpression;
boolean hasOuter = !(Decl.isConstructor((Declaration) methodClassOrCtor) && gen.getNumParameterLists(typeModel) == 1);
if (!hasOuter) {
type = typeModel;
if (memberClassCtorRef) {
target = gen.naming.makeUnquotedIdent(Unfix.$instance$);
} else {
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, qmte, 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);
boolean needsCast = false;
if (Decl.isConstructor((Declaration) methodClassOrCtor)) {
Constructor ctor = ModelUtil.getConstructor((Declaration) methodClassOrCtor);
Class cls = ModelUtil.getConstructedClass(ctor);
if (Strategy.generateInstantiator(ctor)) {
needsCast = Strategy.isInstantiatorUntyped(ctor);
callBuilder.invoke(gen.naming.makeInstantiatorMethodName(target, cls));
} else if (Decl.isJavaArrayWith(ctor)) {
callBuilder.arrayWith(gen.getReturnTypeOfCallable(typeModel).getQualifyingType(), gen.makeJavaType(gen.getReturnTypeOfCallable(typeModel), JT_CLASS_NEW));
} 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 = new ListBuffer<ExpressionAndType>();
DirectInvocation.addReifiedArguments(gen, producedReference, reified);
for (ExpressionAndType reifiedArgument : reified) {
callBuilder.argument(reifiedArgument.expression);
}
if (Decl.isConstructor((Declaration) methodClassOrCtor) && !Decl.isDefaultConstructor(ModelUtil.getConstructor((Declaration) methodClassOrCtor)) && !Decl.isJavaArrayWith((Constructor) methodClassOrCtor)) {
// invoke the param class ctor
Constructor ctor = ModelUtil.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();
if (needsCast) {
innerInvocation = gen.make().TypeCast(gen.makeJavaType(gen.getReturnTypeOfCallable(type)), innerInvocation);
}
// 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);
JCExpression callable = inner.build();
if (!hasOuter) {
if (memberClassCtorRef) {
;
JCVariableDecl def = gen.makeVar(Unfix.$instance$.toString(), gen.makeJavaType(((QualifiedMemberOrTypeExpression) qmte.getPrimary()).getPrimary().getTypeModel()), gen.expressionGen().transformQualifiedMemberPrimary(qmte));
return gen.make().LetExpr(def, callable);
}
return callable;
}
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, qmte, typeModel, outerPl);
outer.parameterTypes = outer.getParameterTypesFromParameterModels();
List<JCStatement> outerBody = List.<JCStatement>of(gen.make().Return(callable));
outer.useDefaultTransformation(outerBody);
outer.companionAccess = Decl.isPrivateAccessRequiringCompanion(qmte);
if (expectedType != null)
outer.checkForFunctionalInterface(expectedType);
return outer.build();
}
use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.
the class CeylonTransformer method transformAttribute.
public List<JCTree> transformAttribute(Tree.TypedDeclaration decl, Tree.AttributeSetterDefinition setterDecl) {
at(decl);
TypedDeclaration declarationModel = decl.getDeclarationModel();
final String attrName = declarationModel.getName();
final String attrClassName = Naming.getAttrClassName(declarationModel, 0);
final Tree.SpecifierOrInitializerExpression expression;
final Tree.Block block;
if (decl instanceof Tree.AttributeDeclaration) {
Tree.AttributeDeclaration adecl = (Tree.AttributeDeclaration) decl;
expression = adecl.getSpecifierOrInitializerExpression();
block = null;
} else if (decl instanceof Tree.AttributeGetterDefinition) {
expression = null;
Tree.AttributeGetterDefinition gdef = (Tree.AttributeGetterDefinition) decl;
block = gdef.getBlock();
} else if (decl instanceof Tree.AttributeSetterDefinition) {
Tree.AttributeSetterDefinition sdef = (Tree.AttributeSetterDefinition) decl;
block = sdef.getBlock();
expression = sdef.getSpecifierExpression();
if (Decl.isLocal(decl.getDeclarationModel())) {
declarationModel = ((Tree.AttributeSetterDefinition) decl).getDeclarationModel().getParameter().getModel();
}
} else {
throw new RuntimeException();
}
return transformAttribute(declarationModel, attrName, attrClassName, decl, block, expression, decl, setterDecl);
}
use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.
the class CeylonTransformer method makeDefs.
private List<JCTree> makeDefs(CompilationUnit t) {
final ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
t.visit(new SourceDeclarationVisitor() {
@Override
public void loadFromSource(Declaration decl) {
if (!checkNative(decl))
return;
Stack<Tree.Declaration> ancestors = new Stack<>();
long flags = decl instanceof Tree.AnyInterface ? Flags.INTERFACE : 0;
String name = Naming.toplevelClassName("", decl);
defs.add(makeClassDef(decl, flags, name, WantedDeclaration.Normal, defs, ancestors));
if (decl instanceof Tree.AnyInterface) {
String implName = Naming.getImplClassName(name);
defs.add(makeClassDef(decl, 0, implName, WantedDeclaration.InterfaceImpl, defs, ancestors));
}
if (Decl.isAnnotationClassNoModel(decl)) {
String annotationName = Naming.suffixName(Suffix.$annotation$, name);
defs.add(makeClassDef(decl, Flags.ANNOTATION | Flags.INTERFACE, annotationName, WantedDeclaration.Annotation, defs, ancestors));
if (Decl.isSequencedAnnotationClassNoModel((Tree.AnyClass) decl)) {
String annotationsName = Naming.suffixName(Suffix.$annotations$, name);
defs.add(makeClassDef(decl, Flags.ANNOTATION | Flags.INTERFACE, annotationsName, WantedDeclaration.AnnotationSequence, defs, ancestors));
}
}
}
private JCTree makeClassDef(Tree.Declaration decl, long flags, String name, WantedDeclaration wantedDeclaration, ListBuffer<JCTree> toplevelDeclarations, Stack<Tree.Declaration> ancestors) {
if (decl instanceof Tree.AnyInterface == false && TreeUtil.hasAnnotation(decl.getAnnotationList(), "static", null)) {
flags |= Flags.STATIC;
}
ListBuffer<JCTree.JCTypeParameter> typarams = new ListBuffer<JCTree.JCTypeParameter>();
if (decl instanceof Tree.ClassOrInterface) {
Tree.ClassOrInterface classDecl = (ClassOrInterface) decl;
if (decl instanceof Tree.AnyInterface) {
// interfaces are pulled up and catch container type params
for (Tree.Declaration ancestor : ancestors) {
if (ancestor instanceof Tree.ClassOrInterface) {
addTypeParameters(typarams, (Tree.ClassOrInterface) ancestor);
}
}
}
addTypeParameters(typarams, classDecl);
}
ancestors.push(decl);
JCTree ret = make().ClassDef(make().Modifiers(flags | Flags.PUBLIC), names().fromString(name), typarams.toList(), null, List.<JCExpression>nil(), makeClassBody(decl, wantedDeclaration, toplevelDeclarations, ancestors));
ancestors.pop();
return ret;
}
private void addTypeParameters(ListBuffer<JCTypeParameter> typarams, Tree.ClassOrInterface classDecl) {
if (classDecl.getTypeParameterList() != null) {
for (Tree.TypeParameterDeclaration typeParamDecl : classDecl.getTypeParameterList().getTypeParameterDeclarations()) {
// we don't need a valid name, just a name, and making it BOGUS helps us find it later if it turns out
// we failed to reset everything properly
typarams.add(make().TypeParameter(names().fromString("BOGUS-" + typeParamDecl.getIdentifier().getText()), List.<JCExpression>nil()));
}
}
}
private List<JCTree> makeClassBody(Declaration decl, WantedDeclaration wantedDeclaration, ListBuffer<JCTree> toplevelDeclarations, Stack<Tree.Declaration> ancestors) {
// only do it for Bootstrap where we control the annotations, because it's so dodgy ATM
if (wantedDeclaration == WantedDeclaration.Annotation) {
ListBuffer<JCTree> body = new ListBuffer<JCTree>();
for (Tree.Parameter param : ((Tree.ClassDefinition) decl).getParameterList().getParameters()) {
String name;
JCExpression type = make().TypeArray(make().Type(syms().stringType));
if (param instanceof Tree.InitializerParameter)
name = ((Tree.InitializerParameter) param).getIdentifier().getText();
else if (param instanceof Tree.ParameterDeclaration) {
Tree.TypedDeclaration typedDeclaration = ((Tree.ParameterDeclaration) param).getTypedDeclaration();
name = typedDeclaration.getIdentifier().getText();
type = getAnnotationTypeFor(typedDeclaration.getType());
} else
name = "ERROR";
JCMethodDecl method = make().MethodDef(make().Modifiers(Flags.PUBLIC), names().fromString(name), type, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null);
body.append(method);
}
return body.toList();
}
if (wantedDeclaration == WantedDeclaration.AnnotationSequence) {
String name = Naming.toplevelClassName("", decl);
String annotationName = Naming.suffixName(Suffix.$annotation$, name);
JCExpression type = make().TypeArray(make().Ident(names().fromString(annotationName)));
JCMethodDecl method = make().MethodDef(make().Modifiers(Flags.PUBLIC), names().fromString("value"), type, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null);
return List.<JCTree>of(method);
}
ListBuffer<JCTree> defs = new ListBuffer<>();
java.util.List<Statement> statements = null;
if (decl instanceof Tree.ClassDefinition)
statements = ((Tree.ClassDefinition) decl).getClassBody().getStatements();
else if (decl instanceof Tree.InterfaceDefinition) {
// only walk interface members if we're generating the impl class
if (wantedDeclaration == WantedDeclaration.InterfaceImpl)
statements = ((Tree.InterfaceDefinition) decl).getInterfaceBody().getStatements();
}
if (statements != null) {
for (Tree.Statement member : statements) {
if (member instanceof Tree.ClassOrInterface && checkNative((Tree.Declaration) member)) {
long flags = member instanceof Tree.AnyInterface ? Flags.INTERFACE : 0;
String initialName = Naming.toplevelClassName("", (Tree.Declaration) member);
String name;
if (member instanceof Tree.AnyInterface) {
// interfaces are pulled to the toplevel
StringBuffer strbuf = new StringBuffer();
for (Tree.Declaration part : ancestors) strbuf.append(part.getIdentifier().getText()).append("$");
name = strbuf.append(initialName).toString();
} else {
name = initialName;
}
JCTree def = makeClassDef((Tree.Declaration) member, flags, name, WantedDeclaration.Normal, toplevelDeclarations, ancestors);
if (member instanceof Tree.AnyInterface) {
toplevelDeclarations.add(def);
String implName = Naming.getImplClassName(initialName);
defs.add(makeClassDef((Tree.Declaration) member, 0, implName, WantedDeclaration.InterfaceImpl, defs, ancestors));
} else
defs.add(def);
// FIXME: interfaces impl?
}
}
}
return defs.toList();
}
private JCExpression getAnnotationTypeFor(Tree.Type type) {
if (type instanceof Tree.BaseType) {
String name = ((Tree.BaseType) type).getIdentifier().getText();
if (name.equals("String") || name.equals("Declaration"))
return make().Type(syms().stringType);
if (name.equals("Boolean"))
return make().Type(syms().booleanType);
if (name.equals("Integer"))
return make().Type(syms().longType);
if (name.equals("Float"))
return make().Type(syms().doubleType);
if (name.equals("Byte"))
return make().Type(syms().byteType);
if (name.equals("Character"))
return make().Type(syms().charType);
if (name.equals("Declaration") || name.equals("ClassDeclaration") || name.equals("InterfaceDeclaration") || name.equals("ClassOrInterfaceDeclaration"))
return make().Type(syms().stringType);
// probably an enum value then
return make().TypeArray(make().Type(syms().stringType));
}
if (type instanceof Tree.SequencedType) {
return make().TypeArray(getAnnotationTypeFor(((Tree.SequencedType) type).getType()));
}
if (type instanceof Tree.SequenceType) {
return make().TypeArray(getAnnotationTypeFor(((Tree.SequenceType) type).getElementType()));
}
if (type instanceof Tree.IterableType) {
return make().TypeArray(getAnnotationTypeFor(((Tree.IterableType) type).getElementType()));
}
if (type instanceof Tree.TupleType) {
// can only be one, must be a SequencedType
Tree.Type sequencedType = ((Tree.TupleType) type).getElementTypes().get(0);
return getAnnotationTypeFor(sequencedType);
}
System.err.println("Unknown Annotation type: " + type);
return make().TypeArray(make().Type(syms().stringType));
}
@Override
public void loadFromSource(ModuleDescriptor that) {
// don't think we care about these
}
@Override
public void loadFromSource(PackageDescriptor that) {
// don't think we care about these
}
});
return defs.toList();
}
Aggregations