Skip to content

Commit

Permalink
Work on #196 for Callables
Browse files Browse the repository at this point in the history
  • Loading branch information
chochos committed May 2, 2013
1 parent c0b5481 commit 302e2fb
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 5 deletions.
Expand Up @@ -122,6 +122,10 @@ public void visit(QualifiedMemberOrTypeExpression qe) {
private boolean needIndent = true;
private int indentLevel = 0;

Package getCurrentPackage() {
return root.getUnit().getPackage();
}

private static void setCLAlias(String alias) {
clAlias = alias + ".";
}
Expand Down Expand Up @@ -1120,6 +1124,9 @@ private void methodDeclaration(TypeDeclaration outer, MethodDeclaration that) {
singleExprFunction(that.getParameterLists(),
that.getSpecifierExpression().getExpression(), that.getScope());
endLine(true);
out(names.name(m), "$$metamodel$$=");
TypeUtils.encodeForRuntime(m, this);
endLine(true);
share(m);
}
else if (outer == null) { // don't do the following in a prototype definition
Expand Down Expand Up @@ -1155,7 +1162,23 @@ public void visit(MethodDefinition that) {
//Add reference to metamodel
out(names.name(d), ".$$metamodel$$=");
TypeUtils.encodeForRuntime(d, this);
out(";");
out(";//", names.name(d), ".$$targs$$=");
Map<TypeParameter, ProducedType> _parms = new HashMap<>();
for (TypeParameter ctp : types.callable.getTypeParameters()) {
if ("Return".equals(ctp.getName())) {
_parms.put(ctp, d.getType());
} else if ("Arguments".equals(ctp.getName())) {
try {
com.redhat.ceylon.compiler.typechecker.model.ParameterList plist = d.getParameterLists().get(0);
_parms.put(ctp, types.tupleFromParameters(plist.getParameters()));
} catch (Exception ex) {
System.err.println("WTF????? This should never happen! JS compiler is seriously broken...");
ex.printStackTrace();
}
}
}
TypeUtils.printTypeArguments(that, _parms, this);
endLine(true);
}
}

Expand Down Expand Up @@ -1472,6 +1495,14 @@ private void generateAttributeGetter(MethodOrValue decl,
if (boxType == 4) {
//Pass Callable argument types
out(",");
if (decl instanceof Method) {
//Add parameters
TypeUtils.encodeParameterListForRuntime(((Method)decl).getParameterLists().get(0),
GenerateJsVisitor.this);
out(",");
} else {
out("[],");
}
TypeUtils.printTypeArguments(expr, expr.getExpression().getTypeModel().getTypeArguments(), this);
}
boxUnboxEnd(boxType);
Expand Down Expand Up @@ -2369,6 +2400,15 @@ else if (bmeDecl instanceof MethodOrValue) {
}
if (boxType == 4) {
out(",");
if (moval instanceof Method) {
//Add parameters
TypeUtils.encodeParameterListForRuntime(((Method)moval).getParameterLists().get(0),
GenerateJsVisitor.this);
out(",");
} else {
//TODO extract parameters from Value
out("[],");
}
TypeUtils.printTypeArguments(specStmt.getSpecifierExpression().getExpression(),
specStmt.getSpecifierExpression().getExpression().getTypeModel().getTypeArguments(),
GenerateJsVisitor.this);
Expand Down Expand Up @@ -3802,6 +3842,7 @@ private void generateParameterLists(List<ParameterList> plist, Scope scope,
if (count==0) {
out(function);
} else {
//TODO add metamodel
out("return function");
}
paramList.visit(this);
Expand Down
Expand Up @@ -8,6 +8,7 @@

import com.redhat.ceylon.compiler.typechecker.model.Declaration;
import com.redhat.ceylon.compiler.typechecker.model.Functional;
import com.redhat.ceylon.compiler.typechecker.model.Method;
import com.redhat.ceylon.compiler.typechecker.model.ProducedType;
import com.redhat.ceylon.compiler.typechecker.model.TypeParameter;
import com.redhat.ceylon.compiler.typechecker.model.UnionType;
Expand Down Expand Up @@ -250,6 +251,14 @@ List<String> generatePositionalArguments(Tree.ArgumentList that, List<Tree.Posit
}
if (boxType == 4) {
gen.out(",");
//Add parameters
Method _m = extractMethod(expr.getTerm());
if (_m == null) {
gen.out("[],");
} else {
TypeUtils.encodeParameterListForRuntime(_m.getParameterLists().get(0), gen);
gen.out(",");
}
TypeUtils.printTypeArguments(arg, arg.getTypeModel().getTypeArguments(), gen);
}
gen.boxUnboxEnd(boxType);
Expand All @@ -270,6 +279,13 @@ List<String> generatePositionalArguments(Tree.ArgumentList that, List<Tree.Posit
arg.visit(gen);
if (boxType == 4) {
gen.out(",");
Method _m = extractMethod(expr.getTerm());
if (_m == null) {
gen.out("[],");
} else {
TypeUtils.encodeParameterListForRuntime(_m.getParameterLists().get(0), gen);
gen.out(",");
}
TypeUtils.printTypeArguments(arg, arg.getTypeModel().getTypeArguments(), gen);
}
gen.boxUnboxEnd(boxType);
Expand Down Expand Up @@ -343,4 +359,19 @@ void nativeObject(Tree.NamedArgumentList argList) {
}
}

Method extractMethod(Tree.Term term) {
if (term instanceof Tree.FunctionArgument) {
return (((Tree.FunctionArgument)term).getDeclarationModel());
} else if (term instanceof Tree.MemberOrTypeExpression) {
if (((Tree.MemberOrTypeExpression)term).getDeclaration() instanceof Method) {
return (Method)((Tree.MemberOrTypeExpression)term).getDeclaration();
}
} else if (term instanceof Tree.InvocationExpression) {
gen.out("/*Callable from Invocation ", term.toString(), "*/");
} else {
gen.out("/*Callable EXPR of type ", term.getClass().getName(), "*/");
}
return null;
}

}
42 changes: 38 additions & 4 deletions src/main/java/com/redhat/ceylon/compiler/js/TypeUtils.java
Expand Up @@ -312,6 +312,26 @@ static void generateDynamicCheck(Tree.Term term, final ProducedType t, final Gen
gen.out(")?", tmp, ":", GenerateJsVisitor.getClAlias(), "throwexc('dynamic objects cannot be used here'))");
}

static void encodeParameterListForRuntime(ParameterList plist, GenerateJsVisitor gen) {
boolean first = true;
gen.out("[");
for (Parameter p : plist.getParameters()) {
if (first) first=false; else gen.out(",");
gen.out("{", MetamodelGenerator.KEY_NAME, ":'", p.getNameAsString(), "',");
gen.out(MetamodelGenerator.KEY_METATYPE, ":'", MetamodelGenerator.METATYPE_PARAMETER, "',");
if (p.isSequenced()) {
gen.out("seq:1,");
}
if (p.isDefaulted()) {
gen.out(MetamodelGenerator.KEY_DEFAULT, ":1,");
}
gen.out(MetamodelGenerator.KEY_TYPE, ":");
metamodelTypeNameOrList(gen.getCurrentPackage(), p.getType(), gen);
gen.out("}");
}
gen.out("]");
}

/** Output a metamodel map for runtime use. */
static void encodeForRuntime(Declaration d, GenerateJsVisitor gen) {
gen.out("{", MetamodelGenerator.KEY_NAME, ":'", d.getNameAsString(),
Expand Down Expand Up @@ -339,9 +359,9 @@ static void encodeForRuntime(Declaration d, GenerateJsVisitor gen) {
gen.out(MetamodelGenerator.METATYPE_METHOD, "',", MetamodelGenerator.KEY_TYPE, ":");
//This needs a new setting to resolve types but not type parameters
metamodelTypeNameOrList(d.getUnit().getPackage(), ((Method)d).getType(), gen);
gen.out(",", MetamodelGenerator.KEY_PARAMS, ":[");
//TODO: parameter lists, parameters
gen.out("]");
gen.out(",", MetamodelGenerator.KEY_PARAMS, ":");
//Parameter types of the first parameter list
encodeParameterListForRuntime(((Method)d).getParameterLists().get(0), gen);
tparms = ((Method) d).getTypeParameters();

} else if (d instanceof com.redhat.ceylon.compiler.typechecker.model.Value) {
Expand Down Expand Up @@ -410,6 +430,10 @@ static void encodeForRuntime(Declaration d, GenerateJsVisitor gen) {
* already existing params. */
static void metamodelTypeNameOrList(final com.redhat.ceylon.compiler.typechecker.model.Package pkg,
ProducedType pt, GenerateJsVisitor gen) {
if (pt == null) {
//In dynamic blocks we sometimes get a null producedType
pt = ((TypeDeclaration)pkg.getModule().getLanguageModule().getDirectPackage("ceylon.language").getDirectMember("Anything", null, false)).getType();
}
TypeDeclaration type = pt.getDeclaration();
if (type.isAlias()) {
type = type.getExtendedTypeDeclaration();
Expand All @@ -423,7 +447,17 @@ static void metamodelTypeNameOrList(final com.redhat.ceylon.compiler.typechecker
} else {
gen.out("{t:");
outputQualifiedTypename(gen.isImported(pkg, type), pt, gen);
//TODO type parameters
//Type Parameters
if (!pt.getTypeArgumentList().isEmpty()) {
gen.out(",a:{");
boolean first = true;
for (Map.Entry<TypeParameter, ProducedType> e : pt.getTypeArguments().entrySet()) {
if (first) first=false; else gen.out(",");
gen.out(e.getKey().getNameAsString(), ":");
metamodelTypeNameOrList(pkg, e.getValue(), gen);
}
gen.out("}");
}
gen.out("}");
}
}
Expand Down

0 comments on commit 302e2fb

Please sign in to comment.