use of org.eclipse.ceylon.model.typechecker.model.Functional in project ceylon by eclipse.
the class AnnotationInvocationVisitor method transformConstructorArgument.
public static JCExpression transformConstructorArgument(ExpressionTransformer exprGen, Tree.InvocationExpression invocation, Parameter classParameter, AnnotationArgument argument, org.eclipse.ceylon.langtools.tools.javac.util.List<AnnotationFieldName> fieldPath) {
AnnotationInvocation anno = annoCtorModel(invocation);
AnnotationInvocationVisitor visitor = new AnnotationInvocationVisitor(exprGen, invocation, anno);
visitor.parameter = classParameter;
AnnotationTerm term = argument.getTerm();
if (term instanceof ParameterAnnotationTerm) {
ParameterAnnotationTerm parameterArgument = (ParameterAnnotationTerm) term;
Parameter sp = parameterArgument.getSourceParameter();
int argumentIndex = ((Functional) sp.getDeclaration()).getFirstParameterList().getParameters().indexOf(sp);
if (invocation.getPositionalArgumentList() != null) {
java.util.List<Tree.PositionalArgument> positionalArguments = invocation.getPositionalArgumentList().getPositionalArguments();
if (parameterArgument.isSpread()) {
visitor.transformSpreadArgument(positionalArguments.subList(argumentIndex, positionalArguments.size()), classParameter);
} else {
if (0 <= argumentIndex && argumentIndex < positionalArguments.size()) {
Tree.PositionalArgument pargument = positionalArguments.get(argumentIndex);
if (pargument.getParameter().isSequenced()) {
visitor.transformVarargs(argumentIndex, positionalArguments);
} else {
visitor.transformArgument(pargument);
}
} else if (sp.isDefaulted()) {
visitor.makeDefaultExpr(invocation, parameterArgument, sp);
} else if (sp.isSequenced()) {
visitor.appendBuiltArray(visitor.startArray());
}
}
} else if (invocation.getNamedArgumentList() != null) {
boolean found = false;
for (Tree.NamedArgument na : invocation.getNamedArgumentList().getNamedArguments()) {
Parameter parameter = na.getParameter();
int parameterIndex = anno.indexOfConstructorParameter(parameter);
if (parameterIndex == argumentIndex) {
visitor.transformArgument(na);
found = true;
break;
}
}
Tree.SequencedArgument sa = invocation.getNamedArgumentList().getSequencedArgument();
if (sa != null) {
Parameter parameter = sa.getParameter();
int parameterIndex = anno.indexOfConstructorParameter(parameter);
if (parameterIndex == argumentIndex) {
ListBuffer<JCExpression> prevArray = visitor.startArray();
for (Tree.PositionalArgument pa : sa.getPositionalArguments()) {
if (pa instanceof Tree.ListedArgument) {
visitor.transformArgument(pa);
} else if (pa instanceof Tree.SpreadArgument) {
ListBuffer<JCExpression> listed = visitor.arrayExprs;
visitor.arrayExprs = null;
((Tree.SpreadArgument) pa).getExpression().visit(visitor);
listed.addAll(((JCNewArray) visitor.argumentExpr).elems);
visitor.argumentExpr = null;
visitor.arrayExprs = listed;
}
}
visitor.appendBuiltArray(prevArray);
found = true;
}
}
if (!found) {
if (sp.isDefaulted()) {
visitor.makeDefaultExpr(invocation, parameterArgument, sp);
} else if (sp.isSequenced()) {
visitor.appendBuiltArray(visitor.startArray());
} else {
visitor.append(exprGen.makeErroneous(invocation, "Unable to find argument"));
}
}
}
} else if (term instanceof LiteralAnnotationTerm) {
visitor.append(term.makeAnnotationArgumentValue(visitor.exprGen, visitor.anno, fieldPath.append(argument)));
} else if (term instanceof InvocationAnnotationTerm) {
AnnotationInvocation instantiation = ((InvocationAnnotationTerm) term).getInstantiation();
visitor.append(transformConstructor(visitor.exprGen, invocation, instantiation, fieldPath.append(argument)));
} else {
visitor.append(visitor.exprGen.makeErroneous(invocation, "Unable to find argument"));
}
return visitor.getExpression();
}
use of org.eclipse.ceylon.model.typechecker.model.Functional in project ceylon by eclipse.
the class AttributeGenerator method addGetterAndSetterToPrototype.
static void addGetterAndSetterToPrototype(final TypeDeclaration outer, final Tree.AttributeDeclaration that, final GenerateJsVisitor gen, final boolean verboseStitcher) {
final Value d = that.getDeclarationModel();
if (!gen.opts.isOptimize() || d.isToplevel())
return;
gen.comment(that);
final String atname = gen.getNames().valueName(d);
final String outerName = d.isStatic() ? gen.getNames().name(outer) + ".$st$" : gen.getNames().self(outer);
if (d.isFormal()) {
generateAttributeMetamodel(that, false, false, gen);
} else if (that.getSpecifierOrInitializerExpression() == null) {
gen.defineAttribute(outerName, gen.getNames().name(d));
gen.out("{");
if (TypeUtils.isNativeExternal(d)) {
// this is for native member attribute declaration with no value
gen.stitchNative(d, that);
} else {
if (d.isStatic()) {
if (d.isLate()) {
gen.generateUnitializedAttributeReadCheck(outerName + "." + atname, gen.getNames().name(d), that.getSpecifierOrInitializerExpression());
gen.out("return ", outerName, ".", atname, ";");
} else {
gen.out("return ");
that.getSpecifierOrInitializerExpression().visit(gen);
gen.out(";");
}
} else {
if (d.isLate()) {
// Just return the private value #451
gen.generateUnitializedAttributeReadCheck("this." + atname, gen.getNames().name(d), that.getSpecifierOrInitializerExpression());
}
gen.out("return this.", atname, ";");
}
}
gen.out("},");
Tree.AttributeSetterDefinition setterDef = null;
boolean setterDefined = false;
if (d.isVariable() || d.isLate()) {
setterDef = gen.associatedSetterDefinition(d);
if (setterDef == null) {
setterDefined = true;
final String par = gen.getNames().createTempVariable();
gen.out("function(", par, "){");
gen.generateImmutableAttributeReassignmentCheck(d, "this." + atname, gen.getNames().name(d));
gen.out("return this.", atname, "=", par, ";}");
} else if (!gen.stitchNative(setterDef.getDeclarationModel(), that)) {
gen.out("function(", gen.getNames().name(setterDef.getDeclarationModel().getParameter()), ")");
setter(setterDef, gen);
setterDefined = true;
}
}
if (!setterDefined) {
gen.out("undefined");
}
gen.out(",");
TypeUtils.encodeForRuntime(that, that.getDeclarationModel(), that.getAnnotationList(), gen);
if (setterDef != null) {
gen.out(",");
TypeUtils.encodeForRuntime(setterDef, setterDef.getDeclarationModel(), that.getAnnotationList(), gen);
}
gen.out(")");
gen.endLine(true);
} else {
org.eclipse.ceylon.model.typechecker.model.Parameter param = null;
if (d.isParameter()) {
param = ((Functional) d.getContainer()).getParameter(d.getName());
}
if ((that.getSpecifierOrInitializerExpression() != null) || d.isVariable() || param != null || d.isLate() || TypeUtils.isNativeExternal(d)) {
if (that.getSpecifierOrInitializerExpression() instanceof LazySpecifierExpression) {
// attribute is defined by a lazy expression ("=>" syntax)
gen.defineAttribute(outerName, gen.getNames().name(d));
gen.beginBlock();
gen.initSelf(that);
boolean stitch = TypeUtils.isNativeExternal(d);
if (stitch) {
stitch = gen.stitchNative(d, that);
if (stitch && verboseStitcher) {
gen.spitOut("Stitching in native getter " + d.getQualifiedNameString() + ", ignoring Ceylon declaration");
}
}
if (!stitch) {
final Expression expr = that.getSpecifierOrInitializerExpression().getExpression();
gen.out("return ");
if (!gen.isNaturalLiteral(expr.getTerm())) {
gen.visitSingleExpression(expr);
}
}
gen.endBlock();
Tree.AttributeSetterDefinition setterDef = null;
if (d.isVariable()) {
setterDef = gen.associatedSetterDefinition(d);
if (setterDef != null) {
gen.out(",function(", gen.getNames().name(setterDef.getDeclarationModel().getParameter()), ")");
setter(setterDef, gen);
}
}
if (setterDef == null) {
gen.out(",undefined");
}
gen.out(",");
TypeUtils.encodeForRuntime(that, that.getDeclarationModel(), that.getAnnotationList(), gen);
if (setterDef != null) {
gen.out(",");
TypeUtils.encodeForRuntime(setterDef, setterDef.getDeclarationModel(), that.getAnnotationList(), gen);
}
gen.out(")");
gen.endLine(true);
} else {
final String privname = param == null ? gen.getNames().privateName(d) : gen.getNames().name(param) + "_";
gen.defineAttribute(outerName, gen.getNames().name(d));
gen.out("{");
if (d.isLate()) {
gen.generateUnitializedAttributeReadCheck("this." + privname, gen.getNames().name(d), that.getSpecifierOrInitializerExpression());
}
if (TypeUtils.isNativeExternal(d)) {
if (gen.stitchNative(d, that)) {
if (verboseStitcher) {
gen.spitOut("Stitching in native getter " + d.getQualifiedNameString() + ", ignoring Ceylon declaration");
}
} else {
gen.out("return ");
gen.visitSingleExpression(that.getSpecifierOrInitializerExpression().getExpression());
}
gen.out("}");
} else {
if (d.isStatic()) {
gen.out("return ");
gen.visitSingleExpression(that.getSpecifierOrInitializerExpression().getExpression());
gen.out("}");
} else {
gen.out("return this.", privname, ";}");
}
}
if (d.isVariable() || d.isLate()) {
final String pname = gen.getNames().createTempVariable();
gen.out(",function(", pname, "){");
gen.generateImmutableAttributeReassignmentCheck(d, "this." + privname, gen.getNames().name(d));
gen.out("return this.", privname, "=", pname, ";}");
} else {
gen.out(",undefined");
}
gen.out(",");
TypeUtils.encodeForRuntime(that, that.getDeclarationModel(), that.getAnnotationList(), gen);
gen.out(")");
gen.endLine(true);
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Functional in project ceylon by eclipse.
the class BmeGenerator method generateBme.
static void generateBme(final Tree.BaseMemberExpression bme, final GenerateJsVisitor gen, boolean nonNull) {
final boolean forInvoke = bme.getDirectlyInvoked();
Declaration decl = bme.getDeclaration();
if (decl != null) {
String name = decl.getName();
Package pkg = decl.getUnit().getPackage();
// map Ceylon true/false/null directly to JS true/false/null
if (pkg.isLanguagePackage()) {
if ("true".equals(name) || "false".equals(name) || "null".equals(name)) {
gen.out(name);
return;
}
}
if (ModelUtil.isConstructor(decl)) {
Constructor cd = TypeUtils.getConstructor(decl);
Declaration cdc = (Declaration) cd.getContainer();
if (!gen.qualify(bme, cd)) {
gen.out(gen.getNames().name(cdc), gen.getNames().constructorSeparator(decl));
}
if (decl instanceof Value) {
gen.out(gen.getNames().name(decl));
} else {
gen.out(gen.getNames().name(cd));
}
if (!forInvoke && decl instanceof Value) {
gen.out("()");
}
return;
}
}
String exp = gen.memberAccess(bme, null);
if (decl == null && gen.isInDynamicBlock()) {
if ("undefined".equals(exp)) {
gen.out(exp);
} else if (nonNull) {
gen.out("(typeof ", exp, "==='undefined'||", exp, "===null?");
gen.generateThrow(null, "Undefined or null reference: " + exp, bme);
gen.out(":", exp, ")");
} else {
gen.out(exp);
}
} else {
final boolean isCallable = !forInvoke && (decl instanceof Functional || bme.getUnit().getCallableDeclaration().equals(bme.getTypeModel().getDeclaration()));
final boolean hasTparms = hasTypeParameters(bme);
if (isCallable && (decl.isParameter() || (decl.isToplevel() && !hasTparms))) {
// Callables passed as arguments are already wrapped in JsCallable
gen.out(exp);
return;
}
String who = isCallable && decl.isMember() ? gen.getMember(bme, null) : null;
if (who == null || who.isEmpty()) {
// We may not need to wrap this in certain cases
ClassOrInterface cont = ModelUtil.getContainingClassOrInterface(bme.getScope());
who = cont == null ? "0" : gen.getNames().self(cont);
}
if (isCallable && (who != null || hasTparms)) {
if (hasTparms) {
// Function refs with type arguments must be passed as a special function
printGenericMethodReference(gen, bme, who, exp);
} else {
// Member methods must be passed as JsCallables
gen.out(gen.getClAlias(), "jsc$3(", who, ",", exp, ")");
}
} else {
gen.out(exp);
}
}
}
Aggregations