use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation in project ceylon by eclipse.
the class ClassTransformer method transform.
public void transform(Tree.AttributeDeclaration decl, ClassDefinitionBuilder classBuilder) {
final Value model = decl.getDeclarationModel();
boolean withinInterface = model.isInterfaceMember();
Tree.SpecifierOrInitializerExpression initializer = decl.getSpecifierOrInitializerExpression();
final boolean lazy = initializer instanceof Tree.LazySpecifierExpression;
String attrName = decl.getIdentifier().getText();
boolean memoized = Decl.isMemoized(decl);
boolean isStatic = model.isStatic();
// Only a non-formal or a concrete-non-lazy attribute has a corresponding field
// and if a captured class parameter exists with the same name we skip this part as well
Parameter parameter = CodegenUtil.findParamForDecl(decl);
boolean useField = !lazy && Strategy.useField(model);
boolean createField = !lazy && !model.isFormal() && Strategy.createField(parameter, model) && !model.isJavaNative();
boolean createCompanionField = !lazy && withinInterface && initializer != null;
JCThrow err = null;
JCExpression memoizedInitialValue = null;
if (createCompanionField || createField) {
TypedReference typedRef = getTypedReference(model);
TypedReference nonWideningTypedRef = nonWideningTypeDecl(typedRef);
Type nonWideningType = nonWideningType(typedRef, nonWideningTypedRef);
if (Decl.isIndirect(decl)) {
attrName = Naming.getAttrClassName(model, 0);
nonWideningType = getGetterInterfaceType(model);
}
JCExpression initialValue = null;
BoxingStrategy boxingStrategy = null;
if (initializer != null) {
Tree.Expression expression = initializer.getExpression();
HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(expression.getTerm());
int flags = CodegenUtil.downcastForSmall(expression, model) ? ExpressionTransformer.EXPR_UNSAFE_PRIMITIVE_TYPECAST_OK : 0;
flags |= model.hasUncheckedNullType() ? ExpressionTransformer.EXPR_TARGET_ACCEPTS_NULL : 0;
if (error != null) {
initialValue = null;
err = makeThrowUnresolvedCompilationError(error.getErrorMessage().getMessage());
} else {
boxingStrategy = useJavaBox(model, nonWideningType) && javaBoxExpression(expression.getTypeModel(), nonWideningType) ? BoxingStrategy.JAVA : CodegenUtil.getBoxingStrategy(model);
initialValue = expressionGen().transformExpression(expression, boxingStrategy, isStatic && nonWideningType.isTypeParameter() ? typeFact().getAnythingType() : nonWideningType, flags);
}
}
if (memoized) {
memoizedInitialValue = initialValue;
initialValue = makeDefaultExprForType(nonWideningType);
}
int flags = 0;
if (!CodegenUtil.isUnBoxed(nonWideningTypedRef.getDeclaration())) {
flags |= JT_NO_PRIMITIVES;
}
long modifiers = useField ? modifierTransformation().field(decl) : modifierTransformation().localVar(decl);
// does it in those cases)
if (parameter == null || parameter.isHidden()) {
JCExpression type;
if (isStatic && nonWideningType.isTypeParameter()) {
type = make().Type(syms().objectType);
} else {
type = makeJavaType(nonWideningType, flags);
}
if (createCompanionField) {
classBuilder.getCompanionBuilder((TypeDeclaration) model.getContainer()).field(modifiers, attrName, type, initialValue, !useField);
} else {
List<JCAnnotation> annos = makeAtIgnore().prependList(expressionGen().transformAnnotations(OutputElement.FIELD, decl));
if (classBuilder.hasDelegatingConstructors()) {
annos = annos.prependList(makeAtNoInitCheck());
}
// fields should be ignored, they are accessed by the getters
if (err == null) {
// TODO This should really be using AttributeDefinitionBuilder somehow
if (useField) {
AttributeDefinitionBuilder adb = AttributeDefinitionBuilder.field(this, null, attrName, model, Decl.isIndirect(decl)).fieldAnnotations(annos).fieldNullability(makeNullabilityAnnotations(model)).initialValue(initialValue, boxingStrategy).fieldVisibilityModifiers(modifiers).modifiers(modifiers);
classBuilder.defs(adb.buildFields());
List<JCStatement> buildInit = adb.buildInit(false);
if (!buildInit.isEmpty()) {
if (isStatic) {
classBuilder.defs(make().Block(STATIC, buildInit));
} else {
classBuilder.getInitBuilder().init(buildInit);
}
}
} else if (!memoized) {
classBuilder.field(modifiers, attrName, type, initialValue, !useField, annos);
if (!isEe(model) && model.isLate() && CodegenUtil.needsLateInitField(model, typeFact())) {
classBuilder.field(PRIVATE | Flags.VOLATILE | Flags.TRANSIENT, Naming.getInitializationFieldName(attrName), make().Type(syms().booleanType), make().Literal(false), false, makeAtIgnore());
}
}
}
}
}
// A shared attribute might be initialized in a for statement, so
// we might need a def-assignment subst for it
JCStatement outerSubs = statementGen().openOuterSubstitutionIfNeeded(model, model.getType(), 0);
if (outerSubs != null) {
classBuilder.getInitBuilder().init(outerSubs);
}
}
if (useField || withinInterface || lazy) {
boolean generateInClassOrInterface = !withinInterface || model.isShared() || isStatic;
boolean generateInCompanionClass = withinInterface && lazy && !isStatic;
if (generateInClassOrInterface) {
// Generate getter in main class or interface (when shared)
at(decl.getType());
AttributeDefinitionBuilder getter = makeGetter(decl, false, memoizedInitialValue);
if (err != null) {
getter.getterBlock(make().Block(0, List.<JCStatement>of(err)));
}
classBuilder.attribute(getter);
}
if (generateInCompanionClass) {
Interface container = (Interface) model.getContainer();
// Generate getter in companion class
classBuilder.getCompanionBuilder(container).attribute(makeGetter(decl, true, null));
}
if (Decl.isVariable(model) || model.isLate()) {
if (generateInClassOrInterface) {
// Generate setter in main class or interface (when shared)
classBuilder.attribute(makeSetter(decl, false, memoizedInitialValue));
}
if (generateInCompanionClass) {
Interface container = (Interface) model.getContainer();
// Generate setter in companion class
classBuilder.getCompanionBuilder(container).attribute(makeSetter(decl, true, null));
}
}
}
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation in project ceylon by eclipse.
the class ClassTransformer method addAtContainer.
private void addAtContainer(ClassDefinitionBuilder classBuilder, TypeDeclaration model) {
Scope scope = Decl.getNonSkippedContainer((Scope) model);
Scope declarationScope = Decl.getFirstDeclarationContainer((Scope) model);
boolean inlineObjectInToplevelAttr = Decl.isTopLevelObjectExpressionType(model);
if (scope == null || (scope instanceof Package && !inlineObjectInToplevelAttr) && scope == declarationScope)
return;
if (scope instanceof ClassOrInterface && scope == declarationScope && !inlineObjectInToplevelAttr && // we do not check for types inside initialiser section which are private and not captured because we treat them as members
!(model instanceof Interface && Decl.hasLocalNotInitializerAncestor(model))) {
ClassOrInterface container = (ClassOrInterface) scope;
List<JCAnnotation> atContainer = makeAtContainer(container.getType(), model.isStatic());
classBuilder.annotations(atContainer);
} else {
if (model instanceof Interface)
classBuilder.annotations(makeLocalContainerPath((Interface) model));
Declaration declarationContainer = getDeclarationContainer(model);
classBuilder.annotations(makeAtLocalDeclaration(model.getQualifier(), declarationContainer == null));
}
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation in project ceylon by eclipse.
the class ExpressionTransformer method transformAnonymousAnnotation.
public void transformAnonymousAnnotation(Tree.AnonymousAnnotation annotation, Map<Class, ListBuffer<JCAnnotation>> annos) {
Type docType = ((TypeDeclaration) typeFact().getLanguageModuleDeclaration("DocAnnotation")).getType();
JCAnnotation docAnnotation = at(annotation).Annotation(makeJavaType(docType, JT_ANNOTATION), List.<JCExpression>of(make().Assign(naming.makeUnquotedIdent("description"), transform(annotation.getStringLiteral()))));
putAnnotation(annos, docAnnotation, (Class) docType.getDeclaration());
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation in project ceylon by eclipse.
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 && AnnotationUtil.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());
if (annoCtorDecl != null) {
String aname = annoCtorDecl.getQualifiedNameString();
if ("java.lang::transient".equals(aname) || "java.lang::volatile".equals(aname) || "java.lang::synchronized".equals(aname) || "java.lang::native".equals(aname) || "java.lang::strictfp".equals(aname) || "java.lang::overloaded".equals(aname) || "java.lang::nonbean".equals(aname)) {
continue;
}
}
boolean isNaturalTarget = AnnotationUtil.isNaturalTarget(annoCtorDecl, useSite, target);
EnumSet<OutputElement> possibleTargets = AnnotationUtil.interopAnnotationTargeting(useSite instanceof Declaration ? isEe((Declaration) useSite) : false, outputs, annotation, false, false, useSite instanceof Declaration ? (Declaration) useSite : null);
if ((isNaturalTarget && possibleTargets == null) || (possibleTargets != null && possibleTargets.equals(EnumSet.of(target)))) {
transformAnnotation(annotation, annotationSet);
}
}
}
}
ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>();
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, upcastExprList(annotations.toList()))));
result.append(wrapperAnnotation);
} else if (isRepeatableAnnotation(annotationClass)) {
Interface containerAnnotation = getRepeatableContainer(annotationClass);
JCAnnotation wrapperAnnotation = make().Annotation(makeJavaType(containerAnnotation.appliedType(null, Collections.<Type>emptyList())), List.<JCExpression>of(make().NewArray(null, null, upcastExprList(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 (AnnotationUtil.isNaturalTarget((Function) typeFact().getLanguageModuleDeclaration("deprecated"), useSite, target) && isDeprecatedAnnotation(annotation.getPrimary()) && !(useSite instanceof Function) && !(useSite instanceof Constructor)) {
result.appendList(makeAtDeprecated());
}
}
}
return result.toList();
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation in project ceylon by eclipse.
the class StatementTransformer method transform.
// FIXME There is a similar implementation in ClassGen!
public List<JCStatement> transform(Tree.AttributeDeclaration decl) {
ListBuffer<JCStatement> result = new ListBuffer<JCStatement>();
// If the attribute is really from a parameter then don't generate a local variable
Parameter parameter = CodegenUtil.findParamForDecl(decl);
if (parameter == null) {
final Name attrName = names().fromString(naming.substitute(decl.getDeclarationModel()));
Type t = decl.getDeclarationModel().getType();
JCExpression initialValue = null;
SpecifierOrInitializerExpression initOrSpec = decl.getSpecifierOrInitializerExpression();
if (initOrSpec != null) {
HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(initOrSpec.getExpression().getTerm());
if (error != null) {
return List.<JCStatement>of(this.makeThrowUnresolvedCompilationError(error));
}
int flags = CodegenUtil.downcastForSmall(initOrSpec.getExpression(), decl.getDeclarationModel()) ? ExpressionTransformer.EXPR_UNSAFE_PRIMITIVE_TYPECAST_OK : 0;
flags |= decl.getDeclarationModel().hasUncheckedNullType() ? ExpressionTransformer.EXPR_TARGET_ACCEPTS_NULL : 0;
initialValue = expressionGen().transformExpression(initOrSpec.getExpression(), CodegenUtil.getBoxingStrategy(decl.getDeclarationModel()), decl.getDeclarationModel().getType(), flags);
} else if (decl.getDeclarationModel().isVariable()) {
// Java's definite initialization doesn't always work
// so give variable attribute declarations without
// initializers a default value. See #1153.
initialValue = makeDefaultExprForType(t);
if (CodegenUtil.getBoxingStrategy(decl.getDeclarationModel()) == BoxingStrategy.BOXED && canUnbox(t)) {
initialValue = boxType(initialValue, t);
}
}
List<JCAnnotation> annots = List.<JCAnnotation>nil();
int modifiers = transformLocalFieldDeclFlags(decl);
JCExpression typeExpr = makeJavaType(decl.getDeclarationModel(), t, modifiers);
result.append(at(decl.getIdentifier()).VarDef(at(decl.getIdentifier()).Modifiers(modifiers, annots), attrName, typeExpr, initialValue));
JCStatement outerSubs = openOuterSubstitutionIfNeeded(decl.getDeclarationModel(), t, modifiers);
if (outerSubs != null) {
result.append(outerSubs);
}
}
return result.toList();
}
Aggregations