use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class JsonPackage method loadMethod.
@SuppressWarnings("unchecked")
Function loadMethod(String name, Map<String, Object> m, Scope parent, final List<TypeParameter> existing) {
Function md = new Function();
md.setName(name);
m.remove(KEY_NAME);
md.setContainer(parent);
md.setScope(parent);
setAnnotations(md, (Integer) m.remove(KEY_PACKED_ANNS), m.remove(KEY_ANNOTATIONS));
md.setUnit(u2);
if (parent == this) {
// Top-level declarations are directly added to the unit
u2.addDeclaration(md);
addMember(null);
}
if (m.containsKey(KEY_FLAGS)) {
int flags = (int) m.remove(KEY_FLAGS);
md.setDeclaredVoid((flags & 1) > 0);
md.setDeferred((flags & 2) > 0);
}
md.setDynamic(m.remove(KEY_DYNAMIC) != null);
final List<TypeParameter> tparms = parseTypeParameters((List<Map<String, Object>>) m.get(KEY_TYPE_PARAMS), md, existing);
final List<TypeParameter> allparms = JsonPackage.merge(tparms, existing);
md.setType(getTypeFromJson((Map<String, Object>) m.remove(KEY_TYPE), parent instanceof Declaration ? (Declaration) parent : null, allparms));
List<List<Map<String, Object>>> paramLists = (List<List<Map<String, Object>>>) m.remove(KEY_PARAMS);
if (paramLists == null) {
md.addParameterList(new ParameterList());
} else {
boolean first = true;
for (List<Map<String, Object>> plist : paramLists) {
ParameterList _params = parseParameters(plist, md, allparms);
_params.setNamedParametersSupported(first);
first = false;
md.addParameterList(_params);
for (Parameter p : _params.getParameters()) {
md.addMember(p.getModel());
}
}
}
return md;
}
use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class JsonPackage method loadClass.
/**
* Loads a class from the specified map. To avoid circularities, when the class is being created it is
* added to the map, and once it's been fully loaded, all other keys are removed.
*/
@SuppressWarnings("unchecked")
org.eclipse.ceylon.model.typechecker.model.Class loadClass(String name, Map<String, Object> m, Scope parent, final List<TypeParameter> existing) {
org.eclipse.ceylon.model.typechecker.model.Class cls;
m.remove(KEY_NAME);
if (m.get(KEY_METATYPE) instanceof org.eclipse.ceylon.model.typechecker.model.Class) {
cls = (org.eclipse.ceylon.model.typechecker.model.Class) m.get(KEY_METATYPE);
if (m.size() <= 3) {
// It's been fully loaded
return cls;
}
} else {
// It's not there, so create it
if (m.containsKey("$alias")) {
cls = new org.eclipse.ceylon.model.typechecker.model.ClassAlias();
} else {
cls = new org.eclipse.ceylon.model.typechecker.model.Class();
}
cls.setAbstract(m.remove("abstract") != null);
cls.setAnonymous(m.remove("$anon") != null);
cls.setDynamic(m.remove(KEY_DYNAMIC) != null);
cls.setContainer(parent);
cls.setScope(parent);
cls.setName(name);
cls.setUnit(u2);
if (parent == this) {
u2.addDeclaration(cls);
}
parent.addMember(cls);
m.put(KEY_METATYPE, cls);
setAnnotations(cls, (Integer) m.remove(KEY_PACKED_ANNS), m.remove(KEY_ANNOTATIONS));
}
// Type parameters are about the first thing we need to load
final List<TypeParameter> tparms = parseTypeParameters((List<Map<String, Object>>) m.remove(KEY_TYPE_PARAMS), cls, existing);
final List<TypeParameter> allparms = JsonPackage.merge(tparms, existing);
if (m.containsKey(KEY_SELF_TYPE)) {
for (TypeParameter t : tparms) {
if (t.getName().equals(m.get(KEY_SELF_TYPE))) {
cls.setSelfType(t.getType());
}
}
}
// This is to avoid circularity
if (!(isLanguagePackage() && ("Nothing".equals(name) || "Anything".equals(name)))) {
if (cls.getExtendedType() == null) {
if (m.containsKey("super")) {
Type father = getTypeFromJson((Map<String, Object>) m.get("super"), parent instanceof Declaration ? (Declaration) parent : null, allparms);
if (father != null) {
m.remove("super");
cls.setExtendedType(father);
}
} else {
cls.setExtendedType(getTypeFromJson(idobj, parent instanceof Declaration ? (Declaration) parent : null, allparms));
}
}
}
if (cls instanceof ClassAlias) {
ClassAlias ca = (ClassAlias) cls;
if (m.containsKey(KEY_CONSTRUCTOR)) {
String constructorName = (String) m.get(KEY_CONSTRUCTOR);
Function ctorFn = (Function) ca.getExtendedType().getDeclaration().getDirectMember(constructorName, null, false);
ca.setConstructor(ctorFn.getType().getDeclaration());
} else {
ca.setConstructor(ca.getExtendedType().getDeclaration());
}
}
if (m.containsKey(KEY_CONSTRUCTORS)) {
final Map<String, Map<String, Object>> constructors = (Map<String, Map<String, Object>>) m.remove(KEY_CONSTRUCTORS);
for (Map.Entry<String, Map<String, Object>> cons : constructors.entrySet()) {
Constructor cnst = new Constructor();
cnst.setName("$def".equals(cons.getKey()) ? null : cons.getKey());
cnst.setContainer(cls);
cnst.setScope(cls);
cnst.setUnit(cls.getUnit());
cnst.setExtendedType(cls.getType());
cnst.setDynamic(cons.getValue().remove(KEY_DYNAMIC) != null);
setAnnotations(cnst, (Integer) cons.getValue().remove(KEY_PACKED_ANNS), cons.getValue().remove(KEY_ANNOTATIONS));
final List<Map<String, Object>> modelPlist = (List<Map<String, Object>>) cons.getValue().remove(KEY_PARAMS);
cls.addMember(cnst);
if (modelPlist == null) {
// It's a value constructor
cls.setEnumerated(true);
Value cv = new Value();
cv.setName(cnst.getName());
cv.setType(cnst.getType());
cv.setContainer(cls);
cv.setScope(cls);
cv.setUnit(cls.getUnit());
cv.setVisibleScope(cls.getVisibleScope());
cv.setShared(cls.isShared());
cv.setDeprecated(cls.isDeprecated());
cls.addMember(cv);
} else {
cls.setConstructors(true);
final ParameterList plist = parseParameters(modelPlist, cnst, allparms);
cnst.addParameterList(plist);
plist.setNamedParametersSupported(true);
Function cf = new Function();
cf.setName(cnst.getName());
final Type ft = cnst.appliedType(cnst.getExtendedType(), Collections.<Type>emptyList());
cf.setType(ft);
cf.addParameterList(plist);
cf.setContainer(cls);
cf.setScope(cls);
cf.setUnit(cls.getUnit());
cf.setVisibleScope(cnst.getVisibleScope());
cf.setShared(cnst.isShared());
cf.setDeprecated(cnst.isDeprecated());
cf.setDynamic(cnst.isDynamic());
cls.addMember(cf);
}
if (cons.getValue().containsKey(KEY_JS_TSENUM)) {
cnst.setTypescriptEnum((String) cons.getValue().get(KEY_JS_TSENUM));
}
}
} else {
ParameterList plist = parseParameters((List<Map<String, Object>>) m.remove(KEY_PARAMS), cls, allparms);
plist.setNamedParametersSupported(true);
cls.setParameterList(plist);
}
if (m.containsKey("of") && cls.getCaseTypes() == null) {
cls.setCaseTypes(parseTypeList((List<Map<String, Object>>) m.get("of"), allparms));
m.remove("of");
}
if (m.containsKey(KEY_SATISFIES)) {
List<Map<String, Object>> stypes = (List<Map<String, Object>>) m.remove(KEY_SATISFIES);
cls.setSatisfiedTypes(parseTypeList(stypes, allparms));
}
if (m.containsKey(KEY_OBJECTS)) {
for (Map.Entry<String, Map<String, Object>> inner : ((Map<String, Map<String, Object>>) m.get(KEY_OBJECTS)).entrySet()) {
loadObject(inner.getKey(), inner.getValue(), cls, allparms);
}
m.remove(KEY_OBJECTS);
}
addAttributesAndMethods(m, cls, allparms);
if (m.containsKey(KEY_INTERFACES)) {
Map<String, Map<String, Object>> cdefs = (Map<String, Map<String, Object>>) m.get(KEY_INTERFACES);
for (Map.Entry<String, Map<String, Object>> cdef : cdefs.entrySet()) {
loadInterface(cdef.getKey(), cdef.getValue(), cls, allparms);
}
m.remove(KEY_INTERFACES);
}
if (m.containsKey(KEY_CLASSES)) {
Map<String, Map<String, Object>> cdefs = (Map<String, Map<String, Object>>) m.get(KEY_CLASSES);
for (Map.Entry<String, Map<String, Object>> cdef : cdefs.entrySet()) {
loadClass(cdef.getKey(), cdef.getValue(), cls, allparms);
}
m.remove(KEY_CLASSES);
}
if (cls.isDynamic() && (getModule().getJsMajor() < 9 || (getModule().getJsMajor() == 9 && getModule().getJsMinor() < 1))) {
// previous versions did not set dynamic flag on members
cls.makeMembersDynamic();
}
return cls;
}
use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class MetamodelGenerator method parameterListMap.
/**
* Create a list of maps for the parameter list. Each map will be a parameter, including
* name, type, default value (if any), and whether it's sequenced.
*/
private List<Map<String, Object>> parameterListMap(ParameterList plist, Declaration from) {
if (plist == null) {
// Possibly an anonymous class for an anonymous object
return null;
}
List<Parameter> parms = plist.getParameters();
if (parms.size() > 0) {
List<Map<String, Object>> p = new ArrayList<>(parms.size());
for (Parameter parm : parms) {
Map<String, Object> pm = new HashMap<>();
pm.put(KEY_NAME, parm.getName());
pm.put(KEY_METATYPE, METATYPE_PARAMETER);
if (parm.isSequenced()) {
pm.put("seq", 1);
}
if (parm.isDefaulted()) {
pm.put(KEY_DEFAULT, 1);
}
if (parm.isAtLeastOne()) {
pm.put("$min1", 1);
}
final FunctionOrValue parmtype = parm.getModel();
if (parmtype != null && parmtype.getDeclarationKind() == DeclarationKind.TYPE_PARAMETER) {
pm.put(KEY_TYPE, parmtype.getName());
} else {
pm.put(KEY_TYPE, typeMap(parm.getType(), from));
}
if (parm.isHidden()) {
pm.put("$hdn", 1);
}
if (parmtype instanceof Function) {
pm.put("$pt", "f");
List<List<Map<String, Object>>> _paramLists = new ArrayList<>(((Function) parmtype).getParameterLists().size());
for (ParameterList subplist : ((Function) parmtype).getParameterLists()) {
List<Map<String, Object>> params = parameterListMap(subplist, from);
if (params == null) {
params = Collections.emptyList();
}
_paramLists.add(params);
}
if (_paramLists.size() > 1 || !_paramLists.get(0).isEmpty()) {
pm.put(KEY_PARAMS, _paramLists);
}
}
// TODO do these guys need anything else?
/*if (parm.getDefaultArgument() != null) {
//This could be compiled to JS...
pm.put(ANN_DEFAULT, parm.getDefaultArgument().getSpecifierExpression().getExpression().getTerm().getText());
}*/
encodeAnnotations(parm.getModel().getAnnotations(), parm.getModel(), pm);
p.add(pm);
}
return p;
}
return null;
}
use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class MetamodelVisitor method visit.
@Override
public void visit(Tree.SpecifierStatement st) {
TypedDeclaration d = ((Tree.SpecifierStatement) st).getDeclaration();
// Just add shared and actual annotations to this declaration
if (!isNativeHeader(d))
return;
if (d != null) {
Annotation ann = new Annotation();
ann.setName("shared");
d.getAnnotations().add(ann);
ann = new Annotation();
ann.setName("actual");
d.getAnnotations().add(ann);
if (d instanceof Function) {
gen.encodeMethod((Function) d);
} else if (d instanceof Value) {
gen.encodeAttributeOrGetter((Value) d);
} else {
throw new RuntimeException("JS compiler doesn't know how to encode " + d.getClass().getName() + " into model");
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class TypeUtils method metamodelTypeNameOrList.
/**
* Prints out an object with a type constructor under the property "t" and its type arguments under
* the property "a", or a union/intersection type with "u" or "i" under property "t" and the list
* of types that compose it in an array under the property "l", or a type parameter as a reference to
* already existing params.
* @param resolveTargsFromScope Indicates whether to resolve a type argument if it's within reach in the
* node's scope. This is useful for parameters of JsCallables but must be disabled for metamodel functions.
* @param node The node to use as starting point for resolution of other references.
* @param pkg The package of the current declaration
* @param pt The produced type for which a name must be output.
* @param gen The generator to use for output.
*/
static void metamodelTypeNameOrList(final boolean resolveTargsFromScope, final Node node, final org.eclipse.ceylon.model.typechecker.model.Package pkg, Type pt, SiteVariance useSiteVariance, GenerateJsVisitor gen) {
if (pt == null) {
// In dynamic blocks we sometimes get a null producedType
gen.out("'$U'");
return;
}
if (!outputMetamodelTypeList(resolveTargsFromScope, node, pkg, pt, gen)) {
TypeDeclaration type = pt.getDeclaration();
if (pt.isTypeParameter()) {
final TypeParameter tparm = (TypeParameter) type;
final Declaration tpowner = tparm.getDeclaration();
final boolean nodeIsDecl = node instanceof Tree.Declaration;
boolean rtafs = tpowner instanceof TypeDeclaration == false && (nodeIsDecl ? ((Tree.Declaration) node).getDeclarationModel() != tpowner : true);
if (rtafs && ModelUtil.contains((Scope) tpowner, node.getScope())) {
// Attempt to resolve this to an argument if the scope allows for it
if (tpowner instanceof TypeDeclaration) {
gen.out(gen.getNames().self((TypeDeclaration) tpowner), ".$$targs$$.", gen.getNames().typeParameterName(tparm));
} else if (tpowner instanceof Function) {
gen.out(gen.getNames().typeArgsParamName((Function) tpowner), ".", gen.getNames().typeParameterName(tparm));
}
} else if (resolveTargsFromScope && tpowner instanceof TypeDeclaration && (nodeIsDecl ? ((Tree.Declaration) node).getDeclarationModel() == tpowner : true) && ModelUtil.contains((Scope) tpowner, node.getScope())) {
typeNameOrList(node, tparm.getType(), gen, false);
} else {
gen.out("'", gen.getNames().typeParameterName(tparm), "'");
}
} else if (pt.isTypeAlias()) {
outputQualifiedTypename(node, gen.isImported(pkg, type), pt, gen, false);
} else {
gen.out("{t:");
// For constructors, output the type of the class
final Type qt = type instanceof Constructor ? pt.getQualifyingType() : pt;
outputQualifiedTypename(node, gen.isImported(pkg, type), qt, gen, false);
// Type Parameters
if (!pt.getTypeArguments().isEmpty()) {
gen.out(",a:{");
boolean first = true;
for (Map.Entry<TypeParameter, Type> e : pt.getTypeArguments().entrySet()) {
if (first)
first = false;
else
gen.out(",");
gen.out(gen.getNames().typeParameterName(e.getKey()), ":");
metamodelTypeNameOrList(resolveTargsFromScope, node, pkg, e.getValue(), pt.getVarianceOverrides().get(e.getKey()), gen);
}
gen.out("}");
}
printSiteVariance(useSiteVariance, gen);
gen.out("}");
}
}
}
Aggregations