use of org.eclipse.ceylon.model.typechecker.model.Value in project ceylon by eclipse.
the class AnnotationUtil method isNaturalTarget.
/**
* Whether an annotation (with the given {@code annotationCtorDecl}
* annotation constructor) used on the given declaration ({@code useSite})
* should be added to the Java annotations of the given generated program
* elements ({@code target})
* @param annotationCtorDecl
* @param useSite
* @param target
* @return
*/
public static boolean isNaturalTarget(// use site is either a Declaration, or a Package, or a Module,
Function annotationCtorDecl, // module imports
Object useSite, OutputElement target) {
EnumSet<AnnotationTarget> interopTargets;
if (annotationCtorDecl instanceof AnnotationProxyMethod) {
AnnotationProxyMethod annotationProxyMethod = (AnnotationProxyMethod) annotationCtorDecl;
if (annotationProxyMethod.getAnnotationTarget() == target) {
// Foo__WHATEVER, so honour the WHATEVER
return true;
}
interopTargets = annotationProxyMethod.getAnnotationTargets();
} else {
interopTargets = null;
}
if (useSite instanceof Declaration) {
if (ModelUtil.isConstructor((Declaration) useSite)) {
if (useSite instanceof Functional) {
return target == OutputElement.CONSTRUCTOR;
} else if (useSite instanceof Value) {
// If the constructor has a getter we can't annotate, let's
// put the annotations on the constructor
Class constructedClass = ModelUtil.getConstructedClass((Declaration) useSite);
// See CeylonVisitor.transformSingletonConstructor for those tests
if (constructedClass.isToplevel() || constructedClass.isClassMember())
return target == OutputElement.GETTER;
return target == OutputElement.CONSTRUCTOR;
}
} else if (useSite instanceof Class) {
if (((Class) useSite).getParameterList() != null && interopTargets != null && interopTargets.contains(AnnotationTarget.CONSTRUCTOR) && !interopTargets.contains(AnnotationTarget.TYPE)) {
return target == OutputElement.CONSTRUCTOR;
}
return target == OutputElement.TYPE;
} else if (useSite instanceof Interface) {
return target == OutputElement.TYPE;
} else if (useSite instanceof Value) {
Value value = (Value) useSite;
boolean p = value.isParameter() && target == OutputElement.PARAMETER;
if (annotationCtorDecl instanceof AnnotationProxyMethod) {
if (!value.isTransient() && (interopTargets == null || interopTargets.contains(AnnotationTarget.FIELD))) {
return target == OutputElement.FIELD;
} else {
return target == OutputElement.GETTER;
}
} else {
return p || target == OutputElement.GETTER;
}
} else if (useSite instanceof Setter) {
return target == OutputElement.SETTER;
} else if (useSite instanceof Function) {
return target == OutputElement.METHOD;
} else if (useSite instanceof Constructor) {
return target == OutputElement.CONSTRUCTOR;
} else if (useSite instanceof TypeAlias) {
return target == OutputElement.TYPE;
}
} else if (useSite instanceof Package) {
return (annotationCtorDecl instanceof AnnotationProxyMethod) ? target == OutputElement.PACKAGE : target == OutputElement.TYPE;
} else if (useSite instanceof Module) {
return target == OutputElement.TYPE;
} else if (useSite instanceof Tree.ImportModule) {
return target == OutputElement.FIELD;
}
throw new RuntimeException("" + useSite);
}
use of org.eclipse.ceylon.model.typechecker.model.Value in project ceylon by eclipse.
the class AnnotationUtil method outputs.
public static EnumSet<OutputElement> outputs(Tree.AttributeDeclaration that) {
EnumSet<OutputElement> result = EnumSet.noneOf(OutputElement.class);
Value declarationModel = that.getDeclarationModel();
if (declarationModel != null) {
if (declarationModel.isClassMember()) {
if (declarationModel.isParameter()) {
result.add(PARAMETER);
}
if (ModelUtil.isCaptured(declarationModel)) {
result.add(GETTER);
if (!(that.getSpecifierOrInitializerExpression() instanceof Tree.LazySpecifierExpression)) {
result.add(FIELD);
}
} else if (!declarationModel.isParameter()) {
result.add(LOCAL_VARIABLE);
}
} else if (declarationModel.isInterfaceMember()) {
result.add(GETTER);
} else if (declarationModel.isToplevel()) {
result.add(GETTER);
// only non-lazy get fields
if (!declarationModel.isTransient())
result.add(FIELD);
} else {
if (declarationModel.isParameter()) {
result.add(PARAMETER);
} else {
result.add(LOCAL_VARIABLE);
}
}
}
if (result.contains(GETTER) && // variables with lazy value MUST have a distinct setter
((declarationModel.isVariable() && !declarationModel.isTransient()) || declarationModel.isLate())) {
result.add(SETTER);
}
return result;
}
use of org.eclipse.ceylon.model.typechecker.model.Value in project ceylon by eclipse.
the class ExpressionVisitor method setMetamodelType.
private void setMetamodelType(Tree.MemberLiteral that, Declaration result) {
Type outerType;
if (result.isClassOrInterfaceMember()) {
Tree.StaticType type = that.getType();
outerType = type == null ? that.getScope().getDeclaringType(result) : type.getTypeModel();
} else {
outerType = null;
}
boolean constructor = isConstructor(result);
if (result instanceof Function) {
Function method = (Function) result;
if (method.isAbstraction()) {
that.addError("method is overloaded");
} else {
Tree.TypeArgumentList tal = that.getTypeArgumentList();
if (explicitTypeArguments(method, tal)) {
List<Type> typeArgs = getTypeArguments(tal, outerType, method.getTypeParameters());
if (tal != null) {
tal.setTypeModels(typeArgs);
}
if (acceptsTypeArguments(method, outerType, typeArgs, tal, that) || true) {
TypedReference pr = outerType == null ? method.appliedTypedReference(null, typeArgs) : outerType.getTypedMember(method, typeArgs);
that.setTarget(pr);
Type metatype = constructor ? unit.getConstructorMetatype(pr) : unit.getFunctionMetatype(pr);
that.setTypeModel(metatype);
}
} else {
that.addError("missing type arguments to generic declaration: '" + method.getName(unit) + "'");
}
}
} else if (result instanceof Value) {
Value value = (Value) result;
if (that.getTypeArgumentList() != null) {
that.addError("does not accept type arguments: '" + result.getName(unit) + "' is a value");
} else {
TypedReference reference = value.appliedTypedReference(outerType, NO_TYPE_ARGS);
that.setTarget(reference);
Type metatype = constructor ? unit.getValueConstructorMetatype(reference) : unit.getValueMetatype(reference);
that.setTypeModel(metatype);
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Value in project ceylon by eclipse.
the class ExpressionVisitor method checkReferenceIsNonVariable.
private void checkReferenceIsNonVariable(Tree.BaseMemberExpression ref, boolean isSwitch) {
Declaration d = ref.getDeclaration();
if (d != null) {
int code = isSwitch ? 3101 : 3100;
String help = " (assign to a new local value to narrow type)";
if (!(d instanceof Value)) {
ref.addError("referenced declaration is not a value: '" + d.getName(unit) + "'", code);
} else if (isNonConstant(d)) {
ref.addError("referenced value is non-constant: '" + d.getName(unit) + "'" + help, code);
} else if (d.isDefault() || d.isFormal()) {
ref.addError("referenced value may be refined by a non-constant value: '" + d.getName(unit) + "'" + help, code);
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Value in project ceylon by eclipse.
the class ExpressionVisitor method setEmptyTypeFromSequenceType.
private void setEmptyTypeFromSequenceType(Tree.Variable that, Tree.LocalModifier local, Tree.SpecifierExpression se) {
Type emptyType = unit.getEmptyType();
Value dec = that.getDeclarationModel();
Tree.Expression ex = se.getExpression();
if (ex != null) {
Type expressionType = ex.getTypeModel();
if (!isTypeUnknown(expressionType)) {
Type nullType = unit.getNullType();
emptyType = intersectionType(expressionType, unionType(emptyType, nullType, unit), unit);
}
handleUncheckedNulls(local, ex, dec);
}
local.setTypeModel(emptyType);
dec.setType(emptyType);
}
Aggregations