use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class AnnotationModelVisitor method visit.
@Override
public void visit(Tree.BaseMemberExpression bme) {
if (annotationConstructor != null) {
Declaration declaration = bme.getDeclaration();
if (checkingInvocationPrimary && isAnnotationConstructor(bme.getDeclaration())) {
Function ctor = (Function) bme.getDeclaration();
instantiation.setPrimary(ctor);
if (ctor.getAnnotationConstructor() != null && ctor.getAnnotationConstructor() != instantiation) {
for (AnnotationConstructorParameter p : ((AnnotationInvocation) ctor.getAnnotationConstructor()).getConstructorParameters()) {
instantiation.addConstructorParameter(p);
}
}
} else if (checkingArguments || checkingDefaults) {
if (declaration instanceof Value && ((Value) declaration).isParameter()) {
Value constructorParameter = (Value) declaration;
ParameterAnnotationTerm a = new ParameterAnnotationTerm();
a.setSpread(spread);
// XXX Is this right?
a.setSourceParameter(constructorParameter.getInitializerParameter());
this.term = a;
} else if (isBooleanTrue(declaration)) {
LiteralAnnotationTerm argument = new BooleanLiteralAnnotationTerm(true);
appendLiteralArgument(bme, argument);
} else if (isBooleanFalse(declaration)) {
LiteralAnnotationTerm argument = new BooleanLiteralAnnotationTerm(false);
appendLiteralArgument(bme, argument);
} else if (bme.getUnit().isEmptyType(bme.getTypeModel()) && bme.getUnit().isIterableType(bme.getTypeModel()) && elements == null) {
// If we're dealing with an iterable, empty means empty collection, not object
endCollection(startCollection(bme), bme);
} else if (Decl.isAnonCaseOfEnumeratedType(bme)) {
LiteralAnnotationTerm argument = new ObjectLiteralAnnotationTerm(bme.getTypeModel());
appendLiteralArgument(bme, argument);
} else {
bme.addError("compiler bug: unsupported base member expression in annotation constructor", Backend.Java);
}
} else {
bme.addError("compiler bug: unsupported base member expression in annotation constructor", Backend.Java);
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Function 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.Function 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.Function in project ceylon by eclipse.
the class ExpressionVisitor method substitutions.
private static Map<TypeParameter, Type> substitutions(FunctionOrValue refined, FunctionOrValue member) {
if (refined instanceof Function) {
Function refinedMethod = (Function) refined;
Function method = (Function) member;
List<TypeParameter> refinedParams = refinedMethod.getTypeParameters();
List<TypeParameter> params = method.getTypeParameters();
Map<TypeParameter, Type> result = new HashMap<TypeParameter, Type>(params.size());
for (int i = 0; i < refinedParams.size() && i < params.size(); i++) {
result.put(refinedParams.get(i), params.get(i).getType());
}
return result;
} else {
return NO_SUBSTITUTIONS;
}
}
use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class ExpressionVisitor method refineMethod.
private void refineMethod(Tree.SpecifierStatement that) {
Function refinedMethod = (Function) that.getRefined();
Function method = (Function) that.getDeclaration();
ClassOrInterface ci = (ClassOrInterface) method.getContainer();
Declaration root = method.getRefinedDeclaration();
TypeDeclaration td = (TypeDeclaration) root.getContainer();
List<Declaration> interveningRefinements = getInterveningRefinements(method, root, ci, td);
if (interveningRefinements.isEmpty()) {
that.getBaseMemberExpression().addError("shortcut refinement does not exactly refine any overloaded inherited member");
} else {
Reference refinedProducedReference = accountForIntermediateRefinements(that, refinedMethod, method, ci, interveningRefinements);
List<Tree.ParameterList> parameterLists;
Tree.Term me = that.getBaseMemberExpression();
if (me instanceof Tree.ParameterizedExpression) {
Tree.ParameterizedExpression pe = (Tree.ParameterizedExpression) me;
parameterLists = pe.getParameterLists();
} else {
parameterLists = emptyList();
}
List<ParameterList> refinedParamLists = refinedMethod.getParameterLists();
List<ParameterList> methodParamLists = method.getParameterLists();
Map<TypeParameter, Type> subs = substitutions(refinedMethod, method);
for (int i = 0; i < refinedParamLists.size() && i < methodParamLists.size(); i++) {
ParameterList refinedParameters = refinedParamLists.get(i);
ParameterList parameters = methodParamLists.get(i);
Tree.ParameterList parameterList = parameterLists.size() <= i ? null : parameterLists.get(i);
List<Parameter> rps = refinedParameters.getParameters();
for (int j = 0; j < rps.size(); j++) {
Parameter refinedParameter = rps.get(j);
Type refinedParameterType = refinedProducedReference.getTypedParameter(refinedParameter).getFullType().substitute(subs, null);
Parameter parameter;
if (parameterList == null || parameterList.getParameters().size() <= j) {
parameter = parameters.getParameters().get(j);
parameter.getModel().setType(refinedParameterType);
parameter.setSequenced(refinedParameter.isSequenced());
} else {
Tree.Parameter param = parameterList.getParameters().get(j);
parameter = param.getParameterModel();
Type parameterType = parameter.getModel().getTypedReference().getFullType();
Node typeNode = param;
if (param instanceof Tree.ParameterDeclaration) {
Tree.ParameterDeclaration pd = (Tree.ParameterDeclaration) param;
Tree.Type type = pd.getTypedDeclaration().getType();
if (type != null) {
typeNode = type;
}
}
checkIsExactlyIgnoringNull(refinedParameters.isNamedParametersSupported(), parameterType, refinedParameterType, typeNode, "type of parameter '" + parameter.getName() + "' of '" + method.getName() + "' declared by '" + ci.getName() + "' is different to type of corresponding parameter " + message(refinedMethod, refinedParameter), 9200);
if (refinedParameter.isSequenced() && !parameter.isSequenced()) {
param.addError("parameter must be variadic: parameter " + message(refinedMethod, refinedParameter) + " is variadic");
}
if (!refinedParameter.isSequenced() && parameter.isSequenced()) {
param.addError("parameter may not be variadic: parameter " + message(refinedMethod, refinedParameter) + " is not variadic");
}
}
}
}
}
}
Aggregations