use of org.eclipse.ceylon.model.typechecker.model.FunctionOrValue in project ceylon by eclipse.
the class JsonPackage method parseParameters.
/**
* Creates a parameter list from a list of maps where each map represents a parameter.
* @param params The list of maps to create the parameters.
* @param owner The declaration to assign to each parameter.
* @param typeParameters The type parameters which can be referenced from the parameters.
*/
private ParameterList parseParameters(List<Map<String, Object>> params, Declaration owner, List<TypeParameter> typeParameters) {
ParameterList plist = new ParameterList();
if (params != null) {
for (Map<String, Object> p : params) {
Parameter param = new Parameter();
final String paramtype = (String) p.get("$pt");
param.setHidden(p.containsKey("$hdn"));
param.setName((String) p.get(KEY_NAME));
param.setDeclaration(owner);
param.setDefaulted(p.containsKey(KEY_DEFAULT));
param.setSequenced(p.containsKey("seq"));
param.setAtLeastOne(p.containsKey("$min1"));
if (paramtype == null || "v".equals(paramtype)) {
Value _v = new Value();
param.setModel(_v);
} else if ("f".equals(paramtype)) {
@SuppressWarnings("unchecked") List<List<Map<String, Object>>> paramLists = (List<List<Map<String, Object>>>) p.get(KEY_PARAMS);
Function _m = new Function();
param.setModel(_m);
if (paramLists == null) {
_m.addParameterList(new ParameterList());
} else {
boolean first = true;
for (List<Map<String, Object>> subplist : paramLists) {
ParameterList _params = parseParameters(subplist, _m, typeParameters);
if (first) {
first = false;
} else {
_params.setNamedParametersSupported(false);
}
_m.addParameterList(_params);
}
}
} else {
throw new IllegalArgumentException("Unknown parameter type " + paramtype);
}
FunctionOrValue paramModel = param.getModel();
if (paramModel != null) {
paramModel.setInitializerParameter(param);
paramModel.setName(param.getName());
paramModel.setUnit(u2);
if (owner instanceof Scope) {
Scope scope = (Scope) owner;
paramModel.setContainer(scope);
paramModel.setScope(scope);
}
if (p.get(KEY_TYPE) instanceof Map) {
@SuppressWarnings("unchecked") final Map<String, Object> ktype = (Map<String, Object>) p.get(KEY_TYPE);
paramModel.setType(getTypeFromJson(ktype, owner, typeParameters));
} else {
// parameter type
for (TypeParameter tp : typeParameters) {
if (tp.getName().equals(p.get(KEY_TYPE))) {
paramModel.setType(tp.getType());
}
}
}
setAnnotations(paramModel, (Integer) p.remove(KEY_PACKED_ANNS), p.remove(KEY_ANNOTATIONS));
}
// owner.getMembers().add(param);
plist.getParameters().add(param);
}
}
return plist;
}
use of org.eclipse.ceylon.model.typechecker.model.FunctionOrValue in project ceylon by eclipse.
the class JsonPackage method getTypeFromJson.
/**
* Looks up a type from model data, creating it if necessary. The returned type will have its
* type parameters substituted if needed.
*/
private Type getTypeFromJson(Map<String, Object> m, Declaration container, List<TypeParameter> typeParams) {
TypeDeclaration td = null;
if (m.get(KEY_METATYPE) instanceof TypeDeclaration) {
td = (TypeDeclaration) m.get(KEY_METATYPE);
if (td instanceof ClassOrInterface && td.getUnit().getPackage() instanceof JsonPackage) {
((JsonPackage) td.getUnit().getPackage()).load(td.getName(), typeParams);
}
}
final String tname = (String) m.get(KEY_NAME);
if ("$U".equals(tname)) {
m.put(KEY_METATYPE, unknown);
return unknown.getType();
}
if (td == null && m.containsKey("comp")) {
@SuppressWarnings("unchecked") final List<Map<String, Object>> tmaps = (List<Map<String, Object>>) m.get(KEY_TYPES);
final ArrayList<Type> types = new ArrayList<>(tmaps.size());
if ("u".equals(m.get("comp"))) {
UnionType ut = new UnionType(u2);
for (Map<String, Object> tmap : tmaps) {
types.add(getTypeFromJson(tmap, container, typeParams));
}
ut.setCaseTypes(types);
td = ut;
} else if ("i".equals(m.get("comp"))) {
IntersectionType it = new IntersectionType(u2);
for (Map<String, Object> tmap : tmaps) {
types.add(getTypeFromJson(tmap, container, typeParams));
}
it.setSatisfiedTypes(types);
td = it;
} else {
throw new IllegalArgumentException("Invalid composite type '" + m.get("comp") + "'");
}
} else if (td == null) {
final String pname = (String) m.get(KEY_PACKAGE);
if (pname == null) {
// It's a ref to a type parameter
final List<TypeParameter> containerTypeParameters;
if (container instanceof Constructor) {
containerTypeParameters = ((Generic) container.getContainer()).getTypeParameters();
} else if (container instanceof Generic) {
containerTypeParameters = container.getTypeParameters();
} else {
containerTypeParameters = null;
}
if (containerTypeParameters != null) {
for (TypeParameter typeParam : containerTypeParameters) {
if (typeParam.getName().equals(tname)) {
td = typeParam;
}
}
}
if (td == null && typeParams != null) {
for (TypeParameter typeParam : typeParams) {
if (typeParam.getName().equals(tname)) {
td = typeParam;
}
}
}
} else {
String mname = (String) m.get(KEY_MODULE);
if ("$".equals(mname)) {
mname = LANGUAGE_MODULE_NAME;
}
org.eclipse.ceylon.model.typechecker.model.Package rp;
if ("$".equals(pname) || LANGUAGE_MODULE_NAME.equals(pname)) {
// Language module package
rp = isLanguagePackage() ? this : getModule().getLanguageModule().getDirectPackage(LANGUAGE_MODULE_NAME);
} else if (mname == null) {
// local type
if (".".equals(pname)) {
rp = this;
if (container instanceof TypeDeclaration && tname.equals(container.getName())) {
td = (TypeDeclaration) container;
}
} else {
rp = getModule().getDirectPackage(pname);
}
} else {
rp = getModule().getPackage(pname);
}
if (rp == null) {
throw new CompilerErrorException("Package not found: " + pname);
}
if (rp != this && rp instanceof JsonPackage && !((JsonPackage) rp).loaded) {
((JsonPackage) rp).loadIfNecessary();
}
final boolean nested = tname.indexOf('.') > 0;
final String level1 = nested ? tname.substring(0, tname.indexOf('.')) : tname;
if (rp != null && !nested) {
Declaration d = rp.getDirectMember(tname, null, false);
if (d instanceof TypeDeclaration) {
td = (TypeDeclaration) d;
if (td.isTuple()) {
if (m.containsKey(KEY_TYPES)) {
@SuppressWarnings("unchecked") List<Map<String, Object>> elemaps = (List<Map<String, Object>>) m.get(KEY_TYPES);
ArrayList<Type> elems = new ArrayList<>(elemaps.size());
for (Map<String, Object> elem : elemaps) {
elems.add(getTypeFromJson(elem, container, typeParams));
}
Type tail = elems.get(elems.size() - 1);
if ((tail.isSequence() || tail.isSequential()) && !tail.isTuple() && !tail.isEmpty()) {
elems.remove(elems.size() - 1);
} else {
tail = null;
}
return u2.getTupleType(elems, tail, -1);
} else if (m.containsKey("count")) {
@SuppressWarnings("unchecked") Map<String, Object> elem = (Map<String, Object>) m.get(KEY_TYPE);
Type[] elems = new Type[(int) m.remove("count")];
Arrays.fill(elems, getTypeFromJson(elem, container, typeParams));
return u2.getTupleType(Arrays.asList(elems), null, -1);
}
}
} else if (d instanceof FunctionOrValue) {
td = ((FunctionOrValue) d).getTypeDeclaration();
}
}
if (td == null && rp instanceof JsonPackage) {
if (nested) {
td = ((JsonPackage) rp).loadNestedType(tname, typeParams);
} else {
td = (TypeDeclaration) ((JsonPackage) rp).load(tname, typeParams);
}
}
// Then look in the top-level declarations
if (nested && td == null) {
for (Declaration d : rp.getMembers()) {
if (d instanceof TypeDeclaration && level1.equals(d.getName())) {
td = (TypeDeclaration) d;
}
}
final String[] path = tname.split("\\.");
for (int i = 1; i < path.length; i++) {
td = (TypeDeclaration) td.getDirectMember(path[i], null, false);
}
}
}
}
// From 1.2.3 we stored type arguments in maps
final Type newType = loadTypeArguments(m, td, container, typeParams);
if (newType != null) {
return newType;
}
// This is the old pre 1.2.3 stuff
@SuppressWarnings("unchecked") final List<Map<String, Object>> modelParms = (List<Map<String, Object>>) m.get(KEY_TYPE_PARAMS);
if (td != null && modelParms != null) {
// Substitute type parameters
final HashMap<TypeParameter, Type> concretes = new HashMap<>();
HashMap<TypeParameter, SiteVariance> variances = null;
if (td.getTypeParameters().size() < modelParms.size()) {
if (td.getUnit().getPackage() == this) {
parseTypeParameters(modelParms, td, null);
}
}
final Iterator<TypeParameter> viter = td.getTypeParameters().iterator();
for (Map<String, Object> ptparm : modelParms) {
TypeParameter _cparm = viter.next();
if (ptparm.containsKey(KEY_PACKAGE) || ptparm.containsKey(KEY_TYPES)) {
// Substitute for proper type
final Type _pt = getTypeFromJson(ptparm, container, typeParams);
concretes.put(_cparm, _pt);
} else if (ptparm.containsKey(KEY_NAME) && typeParams != null) {
// Look for type parameter with same name
for (TypeParameter typeParam : typeParams) {
if (typeParam.getName().equals(ptparm.get(KEY_NAME))) {
concretes.put(_cparm, typeParam.getType());
}
}
}
Integer usv = (Integer) ptparm.get(KEY_US_VARIANCE);
if (usv != null) {
if (variances == null) {
variances = new HashMap<>();
}
variances.put(_cparm, SiteVariance.values()[usv]);
}
}
if (!concretes.isEmpty()) {
return td.getType().substitute(concretes, variances);
}
}
if (td == null) {
try {
throw new IllegalArgumentException(String.format("Couldn't find type %s::%s for %s in %s<%s> (FROM pkg %s)", m.get(KEY_PACKAGE), m.get(KEY_NAME), m.get(KEY_MODULE), m, typeParams, getNameAsString()));
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
}
}
return td.getType();
}
use of org.eclipse.ceylon.model.typechecker.model.FunctionOrValue in project ceylon by eclipse.
the class TestModuleManager method compareMembers.
private void compareMembers(Declaration m1, Declaration m2) {
if (m1 instanceof FunctionOrValue) {
return;
} else if (m1.getMembers() == null) {
Assert.assertNull(m2.getMembers());
return;
}
if (m1.getMembers().size() != m2.getMembers().size()) {
System.out.println(m1 + " (src) tiene " + m1.getMembers());
System.out.println(m2 + " (js) tiene " + m2.getMembers());
}
Assert.assertEquals(m1 + " member count", m1.getMembers().size(), m2.getMembers().size());
for (Declaration d0 : m1.getMembers()) {
String n = d0.getQualifiedNameString();
if (n.indexOf('.') < 0) {
n += "(" + d0.getContainer().getQualifiedNameString() + ")";
}
Declaration d1 = findMatchingDeclaration(d0, m2.getMembers());
Assert.assertNotNull(n + " not found in " + m2, d1);
Assert.assertEquals(n + " declaration kinds differ", d0.getDeclarationKind(), d1.getDeclarationKind());
if (d0.getContainer() == null) {
Assert.assertNull(d1.getContainer());
} else {
Assert.assertEquals(d0.getContainer().getQualifiedNameString(), d1.getContainer().getQualifiedNameString());
}
if (d0 instanceof TypeDeclaration) {
Assert.assertEquals(d0.getClass(), d1.getClass());
compareTypeDeclarations((TypeDeclaration) d0, (TypeDeclaration) d1);
}
compareMembers(d0, d1);
}
}
use of org.eclipse.ceylon.model.typechecker.model.FunctionOrValue in project ceylon by eclipse.
the class MethodOrValueReferenceVisitor method visitConstructorPlan.
/**
* Marks declarations as captured if they are used in more than one generated constructor, according
* to the given plan and knowledge on how we split up constructor delegates.
*/
private void visitConstructorPlan(ConstructorPlan constructorPlan) {
// if there is no delegation all statements are put in the same method so we can't capture
if (constructorPlan.delegate == null && !constructorPlan.isDelegate)
return;
boolean cs = enterCapturingScope();
int useCount = usedIn(constructorPlan, false);
FunctionOrValue fov = ((FunctionOrValue) declaration);
fov.setCaptured(useCount > 1);
if (fov instanceof Value) {
Value val = (Value) fov;
if (val.getSetter() != null)
val.getSetter().setCaptured(useCount > 1);
}
exitCapturingScope(cs);
}
use of org.eclipse.ceylon.model.typechecker.model.FunctionOrValue in project ceylon by eclipse.
the class MethodOrValueReferenceVisitor method usedIn.
/**
* Returns 1 if the declaration is captured in the given statements, 0 otherwise.
*/
private int usedIn(List<Statement> stmts) {
for (Tree.Statement stmt : stmts) {
// count declarations as usage
if (stmt instanceof Tree.TypedDeclaration) {
Tree.TypedDeclaration td = (Tree.TypedDeclaration) stmt;
if (td.getDeclarationModel() == declaration)
return 1;
}
stmt.visit(this);
if (declaration.isCaptured())
break;
}
boolean used = declaration.isCaptured();
FunctionOrValue fov = (FunctionOrValue) declaration;
fov.setCaptured(false);
if (fov instanceof Value) {
Value val = (Value) fov;
if (val.getSetter() != null)
val.getSetter().setCaptured(false);
}
return used ? 1 : 0;
}
Aggregations