use of org.eclipse.ceylon.model.typechecker.model.ParameterList in project ceylon by eclipse.
the class ClassDeclarationImpl method init.
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
protected void init() {
super.init();
// anonymous classes don't have parameter lists
if (!declaration.isAnonymous()) {
org.eclipse.ceylon.model.typechecker.model.Class classDeclaration = (org.eclipse.ceylon.model.typechecker.model.Class) declaration;
if (classDeclaration.isAbstraction()) {
List<Declaration> overloads = classDeclaration.getOverloads();
if (overloads.size() == 1) {
classDeclaration = (org.eclipse.ceylon.model.typechecker.model.Class) overloads.get(0);
}
// else{
// throw Metamodel.newModelError("Class has more than one overloaded constructor: "+classDeclaration.getNameAsString());
// }
}
ParameterList parameterList = classDeclaration.getParameterList();
if (parameterList != null) {
this.parameters = FunctionalUtil.getParameters(classDeclaration);
} else {
this.parameters = null;
}
} else {
this.parameters = null;
}
if (((Class) declaration).hasConstructors() || ((Class) declaration).hasEnumerated()) {
this.constructors = new LinkedList<ceylon.language.meta.declaration.Declaration>();
for (Declaration d : declaration.getMembers()) {
if (d instanceof Constructor) {
this.constructors.add(Metamodel.<ceylon.language.meta.declaration.Declaration>getOrCreateMetamodel(d));
}
}
} else {
this.constructors = Collections.emptyList();
}
}
use of org.eclipse.ceylon.model.typechecker.model.ParameterList in project ceylon by eclipse.
the class Constructors method generateConstructor.
private static void generateConstructor(final Tree.Constructor that, final Tree.ClassDefinition cdef, final List<Tree.Constructor> constructors, final String fullName, final GenerateJsVisitor gen) {
final Constructor d = TypeUtils.getConstructor(that.getDeclarationModel());
final Class container = cdef.getDeclarationModel();
final Tree.DelegatedConstructor delcons = that.getDelegatedConstructor();
final TypeDeclaration superdec;
final ParameterList superplist;
final boolean callAbstract;
if (delcons == null) {
superdec = null;
superplist = null;
callAbstract = false;
} else {
superdec = delcons.getType().getDeclarationModel();
/**
* Is the delegated constructor is within the same class we call its abstract version
*/
callAbstract = superdec instanceof Class ? superdec == container : ((Constructor) superdec).getContainer() == container;
superplist = superdec instanceof Class ? ((Class) superdec).getParameterList() : ((Constructor) superdec).getFirstParameterList();
}
gen.out("function ", fullName, "$$a");
final boolean withTargs = TypeGenerator.generateParameters(cdef.getTypeParameterList(), that.getParameterList(), container, gen);
final String me = gen.getNames().self(container);
gen.beginBlock();
gen.initParameters(that.getParameterList(), container, null);
if (delcons != null) {
TypeGenerator.callSuperclass(delcons.getType(), delcons.getInvocationExpression(), container, superplist, that, callAbstract, null, gen);
}
// If there's a delegated constructor, run the statements after that one and before this one
gen.generateConstructorStatements(that, classStatementsBetweenConstructors(cdef, delcons, that, gen));
gen.out("return ", me, ";");
gen.endBlockNewLine(true);
gen.out("function ", fullName);
TypeGenerator.generateParameters(cdef.getTypeParameterList(), that.getParameterList(), container, gen);
gen.beginBlock();
if (!d.isAbstract()) {
gen.out("$init$", gen.getNames().name(container), "();");
gen.endLine();
gen.declareSelf(container);
gen.referenceOuter(container);
}
gen.initParameters(that.getParameterList(), container, null);
if (!d.isAbstract()) {
// Call common initializer
gen.out(gen.getNames().name(container), "$$c(");
if (withTargs) {
gen.out("$$targs$$,");
}
gen.out(me, ");");
gen.endLine();
}
gen.out(fullName, "$$a");
TypeGenerator.generateParameters(cdef.getTypeParameterList(), that.getParameterList(), container, gen);
gen.endLine(true);
if (d.isNative()) {
gen.stitchConstructorHelper(cdef, "_cons_before");
}
gen.visitStatements(classStatementsAfterConstructor(cdef, that));
if (d.isNative()) {
gen.stitchConstructorHelper(cdef, "_cons_after");
}
gen.out("return ", me, ";");
gen.endBlockNewLine(true);
}
use of org.eclipse.ceylon.model.typechecker.model.ParameterList in project ceylon by eclipse.
the class AbstractModelLoader method loadFunctionCoercionParameter.
@SuppressWarnings("incomplete-switch")
private Function loadFunctionCoercionParameter(Declaration decl, String paramName, TypeMirror typeMirror, Module moduleScope, Scope scope) {
Function method = new Function();
method.setName(paramName);
method.setUnit(decl.getUnit());
try {
FunctionalInterfaceType functionalInterfaceType = getFunctionalInterfaceType(typeMirror);
MethodMirror functionalMethod = functionalInterfaceType.getMethod();
Type returnType = obtainType(moduleScope, functionalInterfaceType.getReturnType(), scope, TypeLocation.TOPLEVEL);
switch(getUncheckedNullPolicy(false, functionalInterfaceType.getReturnType(), functionalMethod)) {
case Optional:
case UncheckedNull:
returnType = makeOptionalTypePreserveUnderlyingType(returnType, moduleScope);
break;
}
method.setType(returnType);
ParameterList pl = new ParameterList();
// List<VariableMirror> functionalParameters = functionalMethod.getParameters();
List<TypeMirror> parameterTypes = functionalInterfaceType.getParameterTypes();
Map<String, Integer> used = new HashMap<String, Integer>();
for (TypeMirror parameterType : parameterTypes) {
String name;
if (parameterTypes.size() == 1) {
name = "it";
} else {
switch(parameterType.getKind()) {
case ARRAY:
name = "array";
break;
case BOOLEAN:
name = "boolean";
break;
case CHAR:
name = "character";
break;
case BYTE:
name = "byte";
break;
case INT:
case LONG:
case SHORT:
name = "integer";
break;
case FLOAT:
case DOUBLE:
name = "float";
break;
case DECLARED:
String typeName = parameterType.getDeclaredClass().getName();
int first = typeName.codePointAt(0);
name = String.valueOf(Character.toChars(Character.toLowerCase(first))) + typeName.substring(Character.charCount(first));
break;
default:
name = "arg";
}
Integer count = used.get(name);
if (count == null) {
used.put(name, 1);
} else {
int next = count + 1;
used.put(name, next);
name += next;
}
}
Type modelParameterType = obtainType(moduleScope, parameterType, scope, TypeLocation.TOPLEVEL);
Parameter p = new Parameter();
Value v = new Value();
p.setName(name);
v.setName(name);
v.setContainer(method);
v.setScope(method);
p.setModel(v);
v.setInitializerParameter(p);
// Java parameters are all optional unless primitives or annotated as such
switch(getUncheckedNullPolicy(false, parameterType, functionalMethod)) {
case Optional:
modelParameterType = makeOptionalTypePreserveUnderlyingType(modelParameterType, moduleScope);
break;
case UncheckedNull:
v.setUncheckedNullType(true);
break;
}
v.setType(modelParameterType);
pl.getParameters().add(p);
method.addMember(v);
}
method.addParameterList(pl);
} catch (ModelResolutionException x) {
method.setType(logModelResolutionException(x, scope, "Failure to turn functional interface to Callable type"));
}
return method;
}
use of org.eclipse.ceylon.model.typechecker.model.ParameterList in project ceylon by eclipse.
the class AbstractModelLoader method setParameters.
private void setParameters(Functional decl, ClassMirror classMirror, MethodMirror methodMirror, boolean isCeylon, Scope container, boolean isCoercedMethod) {
ParameterList parameters = new ParameterList();
parameters.setNamedParametersSupported(isCeylon);
decl.addParameterList(parameters);
int parameterCount = methodMirror.getParameters().size();
int parameterIndex = 0;
for (VariableMirror paramMirror : methodMirror.getParameters()) {
// ignore some parameters
if (paramMirror.getAnnotation(CEYLON_IGNORE_ANNOTATION) != null)
continue;
boolean isLastParameter = parameterIndex == parameterCount - 1;
boolean isVariadic = isLastParameter && methodMirror.isVariadic();
String paramName = getAnnotationStringValue(paramMirror, CEYLON_NAME_ANNOTATION);
// use whatever param name we find as default
if (paramName == null)
paramName = paramMirror.getName();
Parameter parameter = new Parameter();
parameter.setName(paramName);
TypeMirror typeMirror = paramMirror.getType();
Scope scope = (Scope) decl;
Module module = ModelUtil.getModuleContainer(scope);
Type type;
boolean coercedParameter = false;
if (isVariadic) {
// possibly make it optional
TypeMirror variadicType = typeMirror.getComponentType();
// we pretend it's toplevel because we want to get magic string conversion for variadic methods
if (isCoercedMethod && isCoercedType(variadicType)) {
type = applyTypeCoercion(variadicType, paramMirror, methodMirror, paramName, (Declaration) decl, module, scope);
coercedParameter = true;
} else {
type = obtainType(module, variadicType, scope, TypeLocation.TOPLEVEL);
}
if (!isCeylon) {
// Java parameters are all optional unless primitives or annotated as such
if (getUncheckedNullPolicy(isCeylon, variadicType, paramMirror) != NullStatus.NonOptional) {
type = makeOptionalTypePreserveUnderlyingType(type, module);
}
}
// turn it into a Sequential<T>
type = typeFactory.getSequentialType(type);
} else {
if (isCoercedMethod && isCoercedType(typeMirror)) {
type = applyTypeCoercion(typeMirror, paramMirror, methodMirror, paramName, (Declaration) decl, module, scope);
coercedParameter = true;
} else {
type = obtainType(typeMirror, paramMirror, scope, module, "parameter '" + paramName + "' of method '" + methodMirror.getName() + "'", (Declaration) decl);
}
if (!isCeylon) {
// Java parameters are all optional unless primitives or annotated as such
if (getUncheckedNullPolicy(isCeylon, typeMirror, paramMirror) != NullStatus.NonOptional) {
type = makeOptionalTypePreserveUnderlyingType(type, module);
}
}
}
if (type.isCached()) {
type = type.clone();
}
if (!type.isRaw())
type.setRaw(isRaw(ModelUtil.getModuleContainer(container), typeMirror));
FunctionOrValue value = null;
boolean lookedup = false;
if (isCeylon && decl instanceof Class) {
// For a functional parameter to a class, we can just lookup the member
value = (FunctionOrValue) ((Class) decl).getDirectMember(paramName, null, false);
lookedup = value != null;
}
if (value == null) {
// So either decl is not a Class,
// or the method or value member of decl is not shared
AnnotationMirror functionalParameterAnnotation = paramMirror.getAnnotation(CEYLON_FUNCTIONAL_PARAMETER_ANNOTATION);
if (functionalParameterAnnotation != null) {
// A functional parameter to a method
Function method = loadFunctionalParameter((Declaration) decl, paramName, type, (String) functionalParameterAnnotation.getValue());
value = method;
parameter.setDeclaredAnything(method.isDeclaredVoid());
} else if (coercedParameter && isFunctionCercion(typeMirror)) {
Function method = loadFunctionCoercionParameter((Declaration) decl, paramName, typeMirror, module, scope);
value = method;
parameter.setDeclaredAnything(method.isDeclaredVoid());
} else {
// A value parameter to a method
value = isCeylon ? new Value() : new JavaParameterValue();
value.setType(type);
}
value.setContainer(scope);
value.setScope(scope);
ModelUtil.setVisibleScope(value);
value.setUnit(scope.getUnit());
value.setName(paramName);
} else {
// the method return type, so we try to detect this and fix it
if (value instanceof Function && isCeylon1Dot1(classMirror)) {
Type newType = getSimpleCallableReturnType(value.getType());
if (!newType.isUnknown())
value.setType(newType);
}
}
value.setInitializerParameter(parameter);
value.setCoercionPoint(coercedParameter);
parameter.setModel(value);
if (paramMirror.getAnnotation(CEYLON_SEQUENCED_ANNOTATION) != null || isVariadic)
parameter.setSequenced(true);
if (paramMirror.getAnnotation(CEYLON_DEFAULTED_ANNOTATION) != null)
parameter.setDefaulted(true);
if (parameter.isSequenced() && // FIXME: store info in Sequenced
"ceylon.language.Sequence".equals(paramMirror.getType().getQualifiedName())) {
parameter.setAtLeastOne(true);
}
// unboxed is already set if it's a real method
if (!lookedup) {
// if it's variadic, consider the array element type (T[] == T...) for boxing rules
markUnboxed(value, null, isVariadic ? paramMirror.getType().getComponentType() : paramMirror.getType());
markSmall(value, paramMirror.getType());
}
parameter.setDeclaration((Declaration) decl);
value.setDeprecated(value.isDeprecated() || isDeprecated(paramMirror));
setAnnotations(value, paramMirror, false);
parameters.getParameters().add(parameter);
if (!lookedup) {
parameter.getDeclaration().getMembers().add(parameter.getModel());
}
parameterIndex++;
}
if (decl instanceof Function) {
// Multiple parameter lists
AnnotationMirror functionalParameterAnnotation = methodMirror.getAnnotation(CEYLON_FUNCTIONAL_PARAMETER_ANNOTATION);
if (functionalParameterAnnotation != null) {
parameterNameParser.parseMpl((String) functionalParameterAnnotation.getValue(), ((Function) decl).getType().getFullType(), (Function) decl);
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.ParameterList in project ceylon by eclipse.
the class AbstractModelLoader method complete.
private void complete(AnnotationProxyMethod ctor, AnnotationProxyClass klass, LazyInterface iface) {
ParameterList ctorpl = new ParameterList();
ctorpl.setPositionalParametersSupported(false);
ctor.addParameterList(ctorpl);
List<Parameter> ctorParams = new ArrayList<Parameter>();
for (Declaration member : iface.getMembers()) {
boolean isValue = member.getName().equals("value");
if (member instanceof JavaMethod) {
JavaMethod m = (JavaMethod) member;
Parameter ctorParam = new Parameter();
ctorParams.add(ctorParam);
Value value = new Value();
ctorParam.setModel(value);
value.setInitializerParameter(ctorParam);
ctorParam.setDeclaration(ctor);
value.setContainer(klass);
value.setScope(klass);
ctorParam.setDefaulted(m.isDefaultedAnnotation());
value.setName(member.getName());
ctorParam.setName(member.getName());
value.setType(annotationParameterType(iface.getUnit(), m));
value.setUnboxed(true);
value.setUnit(iface.getUnit());
if (isValue)
ctorpl.getParameters().add(0, ctorParam);
else
ctorpl.getParameters().add(ctorParam);
ctor.addMember(value);
}
}
makeInteropAnnotationConstructorInvocation(ctor, klass, ctorParams);
}
Aggregations