use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class TypeUtils method encodeForRuntime.
public static void encodeForRuntime(final Node that, final Declaration d, final GenerateJsVisitor gen, final RuntimeMetamodelAnnotationGenerator annGen) {
gen.out("function(){return{mod:$CCMM$");
List<TypeParameter> tparms = d instanceof Generic ? d.getTypeParameters() : null;
List<Type> satisfies = null;
List<Type> caseTypes = null;
if (d instanceof Class) {
Class _cd = (Class) d;
if (_cd.getExtendedType() != null) {
gen.out(",'super':");
metamodelTypeNameOrList(false, that, d.getUnit().getPackage(), _cd.getExtendedType(), null, gen);
}
// Parameter types
if (_cd.getParameterList() != null) {
gen.out(",", MetamodelGenerator.KEY_PARAMS, ":");
encodeParameterListForRuntime(false, that, _cd.getParameterList(), gen);
}
satisfies = _cd.getSatisfiedTypes();
caseTypes = _cd.getCaseTypes();
} else if (d instanceof Interface) {
Interface _id = (Interface) d;
satisfies = _id.getSatisfiedTypes();
caseTypes = _id.getCaseTypes();
if (_id.isAlias()) {
ArrayList<Type> s2 = new ArrayList<>(satisfies.size() + 1);
s2.add(_id.getExtendedType());
s2.addAll(satisfies);
satisfies = s2;
}
} else if (d instanceof FunctionOrValue) {
gen.out(",", MetamodelGenerator.KEY_TYPE, ":");
if (d instanceof Function && ((Function) d).getParameterLists().size() > 1) {
Type callableType = ((Function) d).getTypedReference().getFullType();
// This needs a new setting to resolve types but not type parameters
metamodelTypeNameOrList(false, that, d.getUnit().getPackage(), that.getUnit().getCallableReturnType(callableType), null, gen);
} else {
// This needs a new setting to resolve types but not type parameters
metamodelTypeNameOrList(false, that, d.getUnit().getPackage(), ((FunctionOrValue) d).getType(), null, gen);
}
if (d instanceof Function) {
gen.out(",", MetamodelGenerator.KEY_PARAMS, ":");
// Parameter types of the first parameter list
encodeParameterListForRuntime(false, that, ((Function) d).getFirstParameterList(), gen);
tparms = d.getTypeParameters();
}
} else if (d instanceof Constructor) {
gen.out(",", MetamodelGenerator.KEY_PARAMS, ":");
encodeParameterListForRuntime(false, that, ((Constructor) d).getFirstParameterList(), gen);
}
if (!d.isToplevel()) {
// Find the first container that is a Declaration
Declaration _cont = ModelUtil.getContainingDeclaration(d);
// Skip over anonymous types/funs as well as local non-captured fields
while (_cont.isAnonymous() || !(_cont.isToplevel() || _cont.isClassOrInterfaceMember() || _cont instanceof Value == false)) {
// Neither do we skip classes, even if they're anonymous
if ((_cont instanceof Value && (((Value) _cont).isJsCaptured())) || _cont instanceof Class) {
break;
}
Declaration __d = ModelUtil.getContainingDeclaration(_cont);
if (__d == null)
break;
_cont = __d;
}
gen.out(",$cont:");
boolean generateName = true;
if ((_cont.getName() != null && _cont.isAnonymous() && _cont instanceof Function) || (_cont instanceof Value && !((Value) _cont).isTransient())) {
// Anon functions don't have metamodel so go up until we find a non-anon container
Declaration _supercont = ModelUtil.getContainingDeclaration(_cont);
while (_supercont != null && _supercont.getName() != null && _supercont.isAnonymous()) {
_supercont = ModelUtil.getContainingDeclaration(_supercont);
}
if (_supercont == null) {
// If the container is a package, add it because this isn't really toplevel
generateName = false;
gen.out("0");
} else {
_cont = _supercont;
}
}
if (generateName) {
if (_cont instanceof Value) {
if (AttributeGenerator.defineAsProperty(_cont)) {
gen.qualify(that, _cont);
}
gen.out(gen.getNames().getter(_cont, true));
} else if (_cont instanceof Setter) {
gen.out("{setter:");
if (AttributeGenerator.defineAsProperty(_cont)) {
gen.qualify(that, _cont);
gen.out(gen.getNames().getter(((Setter) _cont).getGetter(), true), ".set");
} else {
gen.out(gen.getNames().setter(((Setter) _cont).getGetter()));
}
gen.out("}");
} else {
boolean inProto = gen.opts.isOptimize() && (_cont.getContainer() instanceof TypeDeclaration);
final String path = gen.qualifiedPath(that, _cont, inProto);
if (path != null && !path.isEmpty()) {
gen.out(path, ".");
}
final String contName = gen.getNames().name(_cont);
gen.out(contName);
}
}
}
if (tparms != null && !tparms.isEmpty()) {
gen.out(",", MetamodelGenerator.KEY_TYPE_PARAMS, ":{");
encodeTypeParametersForRuntime(that, d, tparms, true, gen);
gen.out("}");
}
if (satisfies != null && !satisfies.isEmpty()) {
gen.out(",", MetamodelGenerator.KEY_SATISFIES, ":[");
boolean first = true;
for (Type st : satisfies) {
if (!first)
gen.out(",");
first = false;
metamodelTypeNameOrList(false, that, d.getUnit().getPackage(), st, null, gen);
}
gen.out("]");
}
if (caseTypes != null && !caseTypes.isEmpty()) {
gen.out(",of:[");
boolean first = true;
for (Type st : caseTypes) {
// teeheehee
final TypeDeclaration std = st.getDeclaration();
if (!first)
gen.out(",");
first = false;
if (ModelUtil.isConstructor(std)) {
if (std.isAnonymous()) {
// Value constructor
gen.out(gen.getNames().name(d), ".", gen.getNames().valueConstructorName(std));
} else {
gen.out("/*TODO callable constructor*/");
}
} else if (std.isAnonymous()) {
if (std.isStatic()) {
gen.out(gen.getNames().name(ModelUtil.getContainingDeclaration(std)), ".$st$.", gen.getNames().objectName(std));
} else {
gen.out(gen.getNames().getter(std, true));
}
} else {
metamodelTypeNameOrList(false, that, d.getUnit().getPackage(), st, null, gen);
}
}
gen.out("]");
}
if (annGen != null) {
annGen.generateAnnotations();
}
// Path to its model
gen.out(",d:");
outputModelPath(d, gen);
gen.out("};}");
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class TypeGenerator method typeFunctionName.
/**
* Returns the name of the type or its $init$ function if it's local.
*/
static String typeFunctionName(final Tree.StaticType type, final ClassOrInterface coi, final GenerateJsVisitor gen) {
TypeDeclaration d = type.getTypeModel().getDeclaration();
final boolean removeAlias = d == null || !d.isClassOrInterfaceMember() || d instanceof Interface;
if ((removeAlias && d.isAlias()) || d instanceof Constructor) {
Type extendedType = d.getExtendedType();
d = extendedType == null ? null : extendedType.getDeclaration();
}
Declaration cont = ModelUtil.getContainingDeclaration(d);
final boolean inProto = gen.opts.isOptimize() && cont instanceof TypeDeclaration;
final boolean imported = gen.isImported(type.getUnit().getPackage(), d);
String dname = gen.getNames().name(d);
if (d.isAlias()) {
TypeDeclaration d2 = d;
while (d2.isAlias()) {
d2 = d2.getExtendedType().getDeclaration();
}
dname = gen.getNames().name(d2);
}
final String initName = "$init$" + dname + "()";
if (!imported && !d.isClassOrInterfaceMember()) {
return initName;
}
if (inProto && coi.isMember() && !d.isAlias() && (coi.getContainer() == cont || ModelUtil.contains(d, coi))) {
// use its $init$ function
return initName;
}
String tfn;
// #628 If coi is anonymous and inside cont, qualify the path from cont instead
if (coi != null && coi.isAnonymous() && cont instanceof Scope && ModelUtil.contains((Scope) cont, coi)) {
tfn = gen.qualifiedPath(type, cont, inProto);
} else if (inProto && d.isClassOrInterfaceMember()) {
return pathToType(type, d, gen);
} else {
tfn = gen.qualifiedPath(type, d, inProto);
}
tfn = gen.memberAccessBase(type, d, false, tfn);
if (removeAlias && !imported) {
int idx = tfn.lastIndexOf('.');
if (idx > 0) {
tfn = tfn.substring(0, idx + 1) + initName;
} else {
tfn = initName;
}
}
return tfn;
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class Strategy method getEffectiveTypeParameters.
private static List<TypeParameter> getEffectiveTypeParameters(Declaration original, Declaration decl) {
if (Decl.isConstructor(original)) {
original = ModelUtil.getConstructedClass(original);
}
if (Decl.isConstructor(decl)) {
decl = ModelUtil.getConstructedClass(decl);
}
Scope container = decl.getContainer();
if (decl instanceof Value) {
if (decl.isStatic()) {
return getEffectiveTypeParameters(original, (Declaration) container);
} else {
return Collections.emptyList();
}
}
if (decl instanceof Function) {
if (original instanceof ClassAlias || decl.isStatic() && isCeylon(decl)) {
ArrayList<TypeParameter> copyDown = new ArrayList<TypeParameter>(getEffectiveTypeParameters(original, (Declaration) container));
copyDown.addAll(decl.getTypeParameters());
return copyDown;
} else {
return decl.getTypeParameters();
}
} else if (decl instanceof ClassAlias) {
// TODO
/*if (container instanceof Declaration) {
ArrayList<TypeParameter> copyDown = new ArrayList<TypeParameter>(getEffectiveTypeParameters(original, (Declaration)container));
copyDown.addAll(((Class)decl).getTypeParameters());
return copyDown;
} else*/
{
return ((ClassAlias) decl).getTypeParameters();
}
} else if (decl instanceof Class) {
if (((Class) decl).isStatic() && ((Class) decl).isMember() && isCeylon(decl)) {
// TODO and isCeylon
ArrayList<TypeParameter> copyDown = new ArrayList<TypeParameter>(getEffectiveTypeParameters(original, (Declaration) container));
copyDown.addAll(((Class) decl).getTypeParameters());
return copyDown;
} else {
return ((Class) decl).getTypeParameters();
}
} else if (decl instanceof Interface) {
/*if (((Interface) decl).isMember()) {
ArrayList<TypeParameter> copyDown = new ArrayList<TypeParameter>(getEffectiveTypeParameters(original, (Declaration)container));
copyDown.addAll(((Interface)decl).getTypeParameters());
return copyDown;
} else*/
{
return ((Interface) decl).getTypeParameters();
}
} else if (decl instanceof TypeAlias) {
return ((TypeAlias) decl).getTypeParameters();
} else {
throw BugException.unhandledDeclarationCase((Declaration) decl);
}
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class AbstractModelLoader method getRepeatableContainer.
public Interface getRepeatableContainer(Class c) {
if (c instanceof AnnotationProxyClass) {
AnnotationMirror mirror = ((AnnotationProxyClass) c).iface.classMirror.getAnnotation("java.lang.annotation.Repeatable");
if (mirror != null) {
TypeMirror m = (TypeMirror) mirror.getValue();
Module module = findModuleForClassMirror(m.getDeclaredClass());
return (Interface) convertDeclaredTypeToDeclaration(module, m, DeclarationType.TYPE);
}
}
return null;
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class AbstractModelLoader method setExtendedType.
private void setExtendedType(ClassOrInterface klass, ClassMirror classMirror) {
// look at its super type
TypeMirror superClass = classMirror.getSuperclass();
Type extendedType;
if (klass instanceof Interface) {
// interfaces need to have their superclass set to Object
if (superClass == null || superClass.getKind() == TypeKind.NONE)
extendedType = getNonPrimitiveType(getLanguageModule(), CEYLON_OBJECT_TYPE, klass);
else
extendedType = getNonPrimitiveType(ModelUtil.getModule(klass), superClass, klass);
} else if (klass instanceof Class && ((Class) klass).isOverloaded()) {
// if the class is overloaded we already have it stored
extendedType = klass.getExtendedType();
} else {
String className = classMirror.getQualifiedName();
String superClassName = superClass == null ? null : superClass.getQualifiedName();
if (className.equals("ceylon.language.Anything")) {
// ceylon.language.Anything has no super type
extendedType = null;
} else if (className.equals("java.lang.Object")) {
// we pretend its superclass is something else, but note that in theory we shouldn't
// be seeing j.l.Object at all due to unerasure
extendedType = getNonPrimitiveType(getLanguageModule(), CEYLON_BASIC_TYPE, klass);
} else {
// read it from annotation first
String annotationSuperClassName = getAnnotationStringValue(classMirror, CEYLON_CLASS_ANNOTATION, "extendsType");
if (annotationSuperClassName != null && !annotationSuperClassName.isEmpty()) {
extendedType = decodeType(annotationSuperClassName, klass, ModelUtil.getModuleContainer(klass), "extended type");
} else {
// now deal with type erasure, avoid having Object as superclass
if ("java.lang.Object".equals(superClassName)) {
extendedType = getNonPrimitiveType(getLanguageModule(), CEYLON_BASIC_TYPE, klass);
} else if (superClass != null) {
try {
extendedType = getNonPrimitiveType(ModelUtil.getModule(klass), superClass, klass);
} catch (ModelResolutionException x) {
extendedType = logModelResolutionException(x, klass, "Error while resolving extended type of " + klass.getQualifiedNameString());
}
} else {
// FIXME: should this be UnknownType?
extendedType = null;
}
}
}
}
if (extendedType != null)
klass.setExtendedType(extendedType);
}
Aggregations