use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression in project ceylon by eclipse.
the class ExpressionTransformer method transformStringExpression.
public JCExpression transformStringExpression(Tree.StringTemplate expr) {
at(expr);
JCExpression builder;
builder = make().NewClass(null, null, naming.makeFQIdent("java", "lang", "StringBuilder"), List.<JCExpression>nil(), null);
java.util.List<Tree.StringLiteral> literals = expr.getStringLiterals();
java.util.List<Tree.Expression> expressions = expr.getExpressions();
for (int ii = 0; ii < literals.size(); ii += 1) {
Tree.StringLiteral literal = literals.get(ii);
if (!literal.getText().isEmpty()) {
// ignore empty string literals
at(literal);
builder = make().Apply(null, makeSelect(builder, "append"), List.<JCExpression>of(transform(literal)));
}
if (ii == expressions.size()) {
// after that because we've already exhausted all the expressions
break;
}
Tree.Expression expression = expressions.get(ii);
at(expression);
// Here in both cases we don't need a type cast for erasure
if (isCeylonBasicType(expression.getTypeModel()) && expression.getUnboxed()) {
// TODO: Test should be erases to String, long, int, boolean, char, byte, float, double
// If erases to a Java primitive just call append, don't box it just to call format.
String method = isCeylonCharacter(expression.getTypeModel()) ? "appendCodePoint" : "append";
builder = make().Apply(null, makeSelect(builder, method), List.<JCExpression>of(transformExpression(expression, BoxingStrategy.UNBOXED, null)));
} else {
JCMethodInvocation formatted = make().Apply(null, makeSelect(transformExpression(expression), "toString"), List.<JCExpression>nil());
builder = make().Apply(null, makeSelect(builder, "append"), List.<JCExpression>of(formatted));
}
}
return make().Apply(null, makeSelect(builder, "toString"), List.<JCExpression>nil());
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression in project ceylon by eclipse.
the class CeylonDocTool method warningMissingThrows.
protected void warningMissingThrows(Declaration d) {
if (ignoreMissingThrows) {
return;
}
final Scope scope = d.getScope();
final PhasedUnit unit = getUnit(d);
final Node node = getNode(d);
if (scope == null || unit == null || unit.getUnit() == null || node == null || !(d instanceof FunctionOrValue)) {
return;
}
List<Type> documentedExceptions = new ArrayList<Type>();
for (Annotation annotation : d.getAnnotations()) {
if (annotation.getName().equals("throws")) {
String exceptionName = annotation.getPositionalArguments().get(0);
Declaration exceptionDecl = scope.getMemberOrParameter(unit.getUnit(), exceptionName, null, false);
if (exceptionDecl instanceof TypeDeclaration) {
documentedExceptions.add(((TypeDeclaration) exceptionDecl).getType());
}
}
}
final List<Type> thrownExceptions = new ArrayList<Type>();
node.visitChildren(new Visitor() {
@Override
public void visit(Tree.Throw that) {
Expression expression = that.getExpression();
if (expression != null) {
thrownExceptions.add(expression.getTypeModel());
} else {
thrownExceptions.add(unit.getUnit().getExceptionType());
}
}
@Override
public void visit(Tree.Declaration that) {
// the end of searching
}
});
for (Type thrownException : thrownExceptions) {
boolean isDocumented = false;
for (Type documentedException : documentedExceptions) {
if (thrownException.isSubtypeOf(documentedException)) {
isDocumented = true;
break;
}
}
if (!isDocumented) {
richLog.warning(CeylondMessages.msg("warn.missingThrows", thrownException.asString(), getWhere(d), getPosition(getNode(d))));
}
}
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression in project ceylon by eclipse.
the class ConditionGenerator method caseClause.
/**
* Generates code for a case clause, as part of a switch statement. Each case
* is rendered as an if.
*/
private void caseClause(final Tree.CaseClause cc, String expvar, final Tree.Term switchTerm) {
gen.out("if(");
final Tree.CaseItem item = cc.getCaseItem();
Tree.Variable caseVar = null;
Value caseDec = null;
if (item instanceof IsCase) {
IsCase isCaseItem = (IsCase) item;
gen.generateIsOfType(item, expvar, isCaseItem.getType().getTypeModel(), null, false, false);
caseVar = isCaseItem.getVariable();
if (caseVar != null) {
caseDec = caseVar.getDeclarationModel();
directAccess.add(caseDec);
names.forceName(caseDec, expvar);
}
} else if (item instanceof Tree.SatisfiesCase) {
item.addError("case(satisfies) not yet supported", Backend.JavaScript);
gen.out("true");
} else if (item instanceof MatchCase) {
final boolean isNull = switchTerm.getTypeModel().covers(switchTerm.getUnit().getNullType());
boolean first = true;
MatchCase matchCaseItem = (MatchCase) item;
Tree.MatchList matchList = matchCaseItem.getExpressionList();
if (!matchList.getTypes().isEmpty()) {
first = false;
List<Type> union = new ArrayList<Type>();
for (Tree.Type type : matchList.getTypes()) {
ModelUtil.addToUnion(union, type.getTypeModel());
}
gen.generateIsOfType(item, expvar, ModelUtil.union(union, matchList.getUnit()), null, false, false);
}
for (Expression exp : matchList.getExpressions()) {
if (!first)
gen.out(" || ");
final Tree.Term term = exp.getTerm();
if (term instanceof Tree.StringLiteral || term instanceof Tree.NaturalLiteral) {
if (isNull) {
gen.out(gen.getClAlias(), "nn$(", expvar, ")&&");
}
exp.visit(gen);
gen.out(".equals(", expvar, ")");
} else if (ModelUtil.isTypeUnknown(switchTerm.getTypeModel())) {
gen.out(expvar, "===");
if (!gen.isNaturalLiteral(term)) {
exp.visit(gen);
}
} else if (term instanceof Tree.Literal) {
if (switchTerm.getUnit().isOptionalType(switchTerm.getTypeModel())) {
gen.out(expvar, "!==null&&");
}
gen.out(expvar, ".equals(");
exp.visit(gen);
gen.out(")");
} else if (term instanceof Tree.Tuple) {
if (((Tree.Tuple) term).getSequencedArgument() == null) {
gen.out(expvar, "===", gen.getClAlias(), "empty()");
} else {
gen.out(gen.getClAlias(), "is$(", expvar, ",{t:", gen.getClAlias(), "Tuple})&&", expvar, ".equals(");
exp.visit(gen);
gen.out(")");
}
} else {
gen.out(expvar, "===");
exp.visit(gen);
}
first = false;
}
caseVar = matchCaseItem.getVariable();
if (caseVar != null) {
caseDec = caseVar.getDeclarationModel();
directAccess.add(caseDec);
names.forceName(caseDec, expvar);
}
} else {
cc.addUnexpectedError("support for case of type " + cc.getClass().getSimpleName() + " not yet implemented", Backend.JavaScript);
}
gen.out(")");
if (cc.getBlock() == null) {
gen.out("return ");
cc.getExpression().visit(gen);
gen.out(";");
} else {
gen.out(" ");
Set<Value> cap = caseDec != null && caseDec.isJsCaptured() ? Collections.singleton(caseDec) : null;
gen.encloseBlockInFunction(cc.getBlock(), true, cap);
}
if (caseDec != null) {
directAccess.remove(caseDec);
names.forceName(caseDec, null);
}
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression 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);
}
}
}
}
Aggregations