/*
* Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package org.visage.tools.tree;
import org.visage.api.VisageBindStatus;
import org.visage.api.tree.TimeLiteralTree.Duration;
import org.visage.api.tree.TypeTree.Cardinality;
import org.visage.api.tree.Tree.VisageKind;
import com.sun.tools.mjavac.code.*;
import com.sun.tools.mjavac.code.Symbol.TypeSymbol;
import com.sun.tools.mjavac.code.Symbol.ClassSymbol;
import com.sun.tools.mjavac.code.Type.ClassType;
import com.sun.tools.mjavac.util.*;
import com.sun.tools.mjavac.util.JCDiagnostic.DiagnosticPosition;
import org.visage.tools.code.VisageClassSymbol;
import org.visage.tools.code.VisageFlags;
import org.visage.tools.code.VisageSymtab;
import org.visage.tools.code.VisageTypes;
import org.visage.tools.code.VisageVarSymbol;
import org.visage.tools.comp.VisageDefs;
import static com.sun.tools.mjavac.code.Flags.*;
import static com.sun.tools.mjavac.code.Kinds.*;
import static com.sun.tools.mjavac.code.TypeTags.*;
import visage.lang.AngleUnit;
import visage.lang.LengthUnit;
/* Visage version of tree maker
*/
public class VisageTreeMaker implements VisageTreeFactory {
/** The context key for the tree factory. */
protected static final Context.Key<VisageTreeMaker> visageTreeMakerKey =
new Context.Key<VisageTreeMaker>();
/** Get the VisageTreeMaker instance. */
public static VisageTreeMaker instance(Context context) {
VisageTreeMaker instance = context.get(visageTreeMakerKey);
if (instance == null)
instance = new VisageTreeMaker(context);
return instance;
}
/** The position at which subsequent trees will be created.
*/
public int pos = Position.NOPOS;
/** The toplevel tree to which created trees belong.
*/
public VisageScript toplevel;
/** The current name table. */
protected Name.Table names;
/** The current type table. */
protected VisageTypes types;
/** The current symbol table. */
protected VisageSymtab syms;
/** The current defs table. */
protected VisageDefs defs;
/** Create a tree maker with null toplevel and NOPOS as initial position.
*/
protected VisageTreeMaker(Context context) {
context.put(visageTreeMakerKey, this);
this.pos = Position.NOPOS;
this.toplevel = null;
this.names = Name.Table.instance(context);
this.syms = (VisageSymtab)VisageSymtab.instance(context);
this.types = VisageTypes.instance(context);
this.defs = VisageDefs.instance(context);
}
/** Create a tree maker with a given toplevel and FIRSTPOS as initial position.
*/
protected VisageTreeMaker(VisageScript toplevel, Name.Table names, VisageTypes types, VisageSymtab syms) {
this.pos = Position.FIRSTPOS;
this.toplevel = toplevel;
this.names = names;
this.types = types;
this.syms = syms;
}
/** Create a new tree maker for a given toplevel.
*/
public VisageTreeMaker forToplevel(VisageScript toplevel) {
return new VisageTreeMaker(toplevel, names, types, syms);
}
/** Reassign current position.
*/
public VisageTreeMaker at(int pos) {
this.pos = pos;
return this;
}
/** Reassign current position.
*/
public VisageTreeMaker at(DiagnosticPosition pos) {
this.pos = (pos == null ? Position.NOPOS : pos.getStartPosition());
return this;
}
public VisageImport Import(VisageExpression qualid) {
VisageImport tree = new VisageImport(qualid);
tree.pos = pos;
return tree;
}
public VisageSkip Skip() {
VisageSkip tree = new VisageSkip();
tree.pos = pos;
return tree;
}
public VisageWhileLoop WhileLoop(VisageExpression cond, VisageExpression body) {
VisageWhileLoop tree = new VisageWhileLoop(cond, body);
tree.pos = pos;
return tree;
}
public VisageTry Try(VisageBlock body, List<VisageCatch> catchers, VisageBlock finalizer) {
VisageTry tree = new VisageTry(body, catchers, finalizer);
tree.pos = pos;
return tree;
}
public VisageCatch ErroneousCatch(List<? extends VisageTree> errs) {
VisageCatch tree = new VisageErroneousCatch(errs);
tree.pos = pos;
return tree;
}
public VisageCatch Catch(VisageVar param, VisageBlock body) {
VisageCatch tree = new VisageCatch(param, body);
tree.pos = pos;
return tree;
}
public VisageIfExpression Conditional(VisageExpression cond,
VisageExpression thenpart,
VisageExpression elsepart)
{
VisageIfExpression tree = new VisageIfExpression(cond, thenpart, elsepart);
tree.pos = pos;
return tree;
}
public VisageBreak Break(Name label) {
VisageBreak tree = new VisageBreak(label, null);
tree.pos = pos;
return tree;
}
public VisageContinue Continue(Name label) {
VisageContinue tree = new VisageContinue(label, null);
tree.pos = pos;
return tree;
}
public VisageReturn Return(VisageExpression expr) {
VisageReturn tree = new VisageReturn(expr);
tree.pos = pos;
return tree;
}
public VisageThrow Throw(VisageExpression expr) {
VisageThrow tree = new VisageThrow(expr);
tree.pos = pos;
return tree;
}
public VisageThrow ErroneousThrow() {
VisageThrow tree = new VisageErroneousThrow();
tree.pos = pos;
return tree;
}
public VisageFunctionInvocation Apply(List<VisageExpression> typeargs,
VisageExpression fn,
List<VisageExpression> args)
{
VisageFunctionInvocation tree = new VisageFunctionInvocation(
typeargs != null? typeargs : List.<VisageExpression>nil(),
fn,
args != null? args : List.<VisageExpression>nil());
tree.pos = pos;
return tree;
}
public VisageParens Parens(VisageExpression expr) {
VisageParens tree = new VisageParens(expr);
tree.pos = pos;
return tree;
}
public VisageAssign Assign(VisageExpression lhs, VisageExpression rhs) {
VisageAssign tree = new VisageAssign(lhs, rhs);
tree.pos = pos;
return tree;
}
public VisageAssignOp Assignop(VisageTag opcode, VisageExpression lhs, VisageExpression rhs) {
VisageAssignOp tree = new VisageAssignOp(opcode, lhs, rhs, null);
tree.pos = pos;
return tree;
}
public VisageBinary Binary(VisageTag opcode, VisageExpression lhs, VisageExpression rhs) {
VisageBinary tree = new VisageBinary(opcode, lhs, rhs, null);
tree.pos = pos;
return tree;
}
public VisageTypeCast TypeCast(VisageTree clazz, VisageExpression expr) {
VisageTypeCast tree = new VisageTypeCast(clazz, expr);
tree.pos = pos;
return tree;
}
public VisageInstanceOf TypeTest(VisageExpression expr, VisageTree clazz) {
VisageInstanceOf tree = new VisageInstanceOf(expr, clazz);
tree.pos = pos;
return tree;
}
public VisageSelect Select(VisageExpression selected, Name selector, boolean nullCheck) {
VisageSelect tree = new VisageSelect(selected, selector, null, nullCheck);
tree.pos = pos;
return tree;
}
public VisageIdentSequenceProxy IdentSequenceProxy(Name name, Symbol sym, VisageVarSymbol boundSizeSym) {
VisageIdentSequenceProxy tree = new VisageIdentSequenceProxy(name, sym, boundSizeSym);
tree.pos = pos;
return tree;
}
public VisageIdent Ident(Name name) {
VisageIdent tree = new VisageIdent(name, null);
tree.pos = pos;
return tree;
}
public VisageErroneousIdent ErroneousIdent() {
VisageErroneousIdent tree = new VisageErroneousIdent(List.<VisageTree>nil());
tree.pos = pos;
return tree;
}
public VisageLiteral Literal(int tag, Object value) {
VisageLiteral tree = new VisageLiteral(tag, value);
tree.pos = pos;
return tree;
}
public VisageModifiers Modifiers(long flags) {
VisageModifiers tree = new VisageModifiers(flags);
boolean noFlags = (flags & Flags.StandardFlags) == 0;
tree.pos = (noFlags) ? Position.NOPOS : pos;
return tree;
}
public VisageErroneous Erroneous() {
return Erroneous(List.<VisageTree>nil());
}
public VisageErroneous Erroneous(List<? extends VisageTree> errs) {
VisageErroneous tree = new VisageErroneous(errs);
tree.pos = pos;
return tree;
}
/* ***************************************************************************
* Derived building blocks.
****************************************************************************/
/** Create an identifier from a symbol.
*/
public VisageIdent Ident(Symbol sym) {
VisageIdent id = new VisageIdent(
(sym.name != names.empty)
? sym.name
: sym.flatName(), sym);
id.setPos(pos);
id.setType(sym.type);
id.sym = sym;
return id;
}
/** Create a selection node from a qualifier tree and a symbol.
* @param base The qualifier tree.
*/
public VisageExpression Select(VisageExpression base, Symbol sym, boolean nullCheck) {
return new VisageSelect(base, sym.name, sym, nullCheck).setPos(pos).setType(sym.type);
}
/** Create an identifier that refers to the variable declared in given variable
* declaration.
*/
public VisageIdent Ident(VisageVar param) {
return Ident(param.sym);
}
/** Create a list of identifiers referring to the variables declared
* in given list of variable declarations.
*/
public List<VisageExpression> Idents(List<VisageVar> params) {
ListBuffer<VisageExpression> ids = new ListBuffer<VisageExpression>();
for (List<VisageVar> l = params; l.nonEmpty(); l = l.tail)
ids.append(Ident(l.head));
return ids.toList();
}
/** Create a tree representing the script class of a given enclosing class.
*/
public VisageClassSymbol ScriptSymbol(Symbol sym) {
VisageClassSymbol owner = (VisageClassSymbol)sym;
if (owner.scriptSymbol == null) {
Name scriptName = owner.name.append(defs.scriptClassSuffixName);
owner.scriptSymbol = new VisageClassSymbol(Flags.STATIC | Flags.PUBLIC, scriptName, owner);
owner.scriptSymbol.type = new ClassType(Type.noType, List.<Type>nil(), owner.scriptSymbol);
}
return owner.scriptSymbol;
}
public VisageIdent Script(Symbol sym) {
return Ident(ScriptSymbol(sym));
}
/** Create a tree representing `this', given its type.
*/
public VisageVarSymbol ThisSymbol(Type t) {
VisageClassSymbol owner = (VisageClassSymbol)t.tsym;
if (owner.thisSymbol == null) {
long flags = FINAL | HASINIT | VisageFlags.VARUSE_SPECIAL;
owner.thisSymbol = new VisageVarSymbol(types, names, flags, names._this, t, owner);
}
return owner.thisSymbol;
}
public VisageIdent This(Type t) {
return Ident(ThisSymbol(t));
}
/** Create a tree representing `super', given its type and owner.
*/
public VisageVarSymbol SuperSymbol(Type t, TypeSymbol sym) {
VisageClassSymbol owner = (VisageClassSymbol)sym;
if (owner.superSymbol == null) {
long flags = FINAL | HASINIT | VisageFlags.VARUSE_SPECIAL;
owner.superSymbol = new VisageVarSymbol(types, names, flags, names._super, t, owner);
}
return owner.superSymbol;
}
public VisageIdent Super(Type t, TypeSymbol owner) {
return Ident(SuperSymbol(t, owner));
}
/** Create a tree representing the script instance of the enclosing class.
*/
public VisageVarSymbol ScriptAccessSymbol(Symbol sym) {
VisageClassSymbol owner = (VisageClassSymbol)sym;
if (owner.scriptAccessSymbol == null) {
Name scriptLevelAccessName = defs.scriptLevelAccessField(names, sym);
VisageClassSymbol script = ScriptSymbol(sym);
long flags = FINAL | STATIC | PUBLIC | HASINIT | VisageFlags.VARUSE_SPECIAL;
owner.scriptAccessSymbol = new VisageVarSymbol(types, names, flags, scriptLevelAccessName, script.type, owner);
}
return owner.scriptAccessSymbol;
}
public VisageIdent ScriptAccess(Symbol sym) {
return Ident(ScriptAccessSymbol(sym));
}
/**
* Create a method invocation from a method tree and a list of
* argument trees.
*/
public VisageFunctionInvocation App(VisageExpression meth, List<VisageExpression> args) {
return Apply(null, meth, args).setType(meth.type.getReturnType());
}
/**
* Create a no-arg method invocation from a method tree
*/
public VisageFunctionInvocation App(VisageExpression meth) {
return Apply(null, meth, List.<VisageExpression>nil()).setType(meth.type.getReturnType());
}
/** Create a tree representing given type.
*/
public VisageExpression Type(Type t) {
if (t == null) {
return null;
}
VisageExpression tp;
switch (t.tag) {
case FLOAT:
tp = Ident(syms.floatTypeName);
break;
case DOUBLE:
tp = Ident(syms.doubleTypeName);
break;
case CHAR:
tp = Ident(syms.charTypeName);
break;
case BYTE:
tp = Ident(syms.byteTypeName);
break;
case SHORT:
tp = Ident(syms.shortTypeName);
break;
case INT:
tp = Ident(syms.integerTypeName);
break;
case LONG:
tp = Ident(syms.longTypeName);
break;
case BOOLEAN:
tp = Ident(syms.booleanTypeName);
break;
case VOID:
tp = Ident(syms.voidTypeName);
break;
case ARRAY:
VisageExpression elem = Type(types.elemtype(t));
elem = elem instanceof VisageType ? elem : TypeClass(elem, Cardinality.SINGLETON);
tp = TypeArray((VisageType)elem);
break;
case CLASS:
Type outer = t.getEnclosingType();
tp = outer.tag == CLASS && t.tsym.owner.kind == TYP
? Select(Type(outer), t.tsym, false)
: QualIdent(t.tsym);
break;
default:
throw new AssertionError("unexpected type: " + t);
}
return tp.setType(t);
}
/** Create a list of trees representing given list of types.
*/
public List<VisageExpression> Types(List<Type> ts) {
ListBuffer<VisageExpression> typeList = new ListBuffer<VisageExpression>();
for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
typeList.append(Type(l.head));
return typeList.toList();
}
public VisageLiteral LiteralInteger(String text, int radix) {
long longVal = Convert.string2long(text, radix);
// For decimal, allow Integer negative numbers
if ((radix==10)? (longVal <= Integer.MAX_VALUE && longVal >= Integer.MIN_VALUE) : ((longVal & ~0xFFFFFFFFL) == 0L))
return Literal(TypeTags.INT, Integer.valueOf((int) longVal));
else
return Literal(TypeTags.LONG, Long.valueOf(longVal));
}
public VisageLiteral Literal(Object value) {
VisageLiteral result = null;
if (value instanceof String) {
result = Literal(CLASS, value).
setType(syms.stringType.constType(value));
} else if (value instanceof Integer) {
result = Literal(INT, value).
setType(syms.intType.constType(value));
} else if (value instanceof Long) {
result = Literal(LONG, value).
setType(syms.longType.constType(value));
} else if (value instanceof Byte) {
result = Literal(BYTE, value).
setType(syms.byteType.constType(value));
} else if (value instanceof Character) {
result = Literal(CHAR, value).
setType(syms.charType.constType(value));
} else if (value instanceof Double) {
result = Literal(DOUBLE, value).
setType(syms.doubleType.constType(value));
} else if (value instanceof Float) {
result = Literal(FLOAT, value).
setType(syms.floatType.constType(value));
} else if (value instanceof Short) {
result = Literal(SHORT, value).
setType(syms.shortType.constType(value));
} else if (value instanceof Boolean) {
result = Literal(BOOLEAN, ((Boolean) value).booleanValue() ? 1 : 0).
setType(syms.booleanType.constType(value));
} else {
throw new AssertionError(value);
}
return result;
}
/** Make an attributed type cast expression.
*/
public VisageTypeCast TypeCast(Type type, VisageExpression expr) {
return (VisageTypeCast)TypeCast(Type(type), expr).setType(type);
}
/* ***************************************************************************
* Helper methods.
****************************************************************************/
/** Can given symbol be referred to in unqualified form?
*/
boolean isUnqualifiable(Symbol sym) {
if (sym.name == names.empty ||
sym.owner == null ||
sym.owner.kind == MTH || sym.owner.kind == VAR) {
return true;
} else if (sym.kind == TYP && toplevel != null) {
Scope.Entry e;
e = toplevel.namedImportScope.lookup(sym.name);
if (e.scope != null) {
return
e.sym == sym &&
e.next().scope == null;
}
e = toplevel.packge.members().lookup(sym.name);
if (e.scope != null) {
return
e.sym == sym &&
e.next().scope == null;
}
e = toplevel.starImportScope.lookup(sym.name);
if (e.scope != null) {
return
e.sym == sym &&
e.next().scope == null;
}
}
return false;
}
/** The name of synthetic parameter number `i'.
*/
public Name paramName(int i) { return names.fromString("x" + i); }
public VisageClassDeclaration ClassDeclaration(VisageModifiers mods,
Name name,
List<VisageExpression> supertypes,
List<VisageTree> declarations) {
VisageClassDeclaration tree = new VisageClassDeclaration(mods,
name,
supertypes,
declarations,
null);
tree.pos = pos;
return tree;
}
public VisageBlock Block(long flags, List<VisageExpression> stats, VisageExpression value) {
VisageBlock tree = new VisageBlock(flags, stats, value);
tree.pos = pos;
return tree;
}
public VisageBlock ErroneousBlock() {
VisageErroneousBlock tree = new VisageErroneousBlock(List.<VisageTree>nil());
tree.pos = pos;
return tree;
}
public VisageBlock ErroneousBlock(List<? extends VisageTree> errs) {
VisageErroneousBlock tree = new VisageErroneousBlock(errs);
tree.pos = pos;
return tree;
}
public VisageFunctionDefinition FunctionDefinition(
VisageModifiers modifiers,
Name name,
VisageType restype,
List<VisageVar> params,
VisageBlock bodyExpression) {
VisageFunctionDefinition tree = new VisageFunctionDefinition(
modifiers,
name,
restype,
params,
bodyExpression);
tree.operation.definition = tree;
tree.pos = pos;
return tree;
}
public VisageFunctionValue FunctionValue(
VisageType restype,
List<VisageVar> params,
VisageBlock bodyExpression) {
VisageFunctionValue tree = new VisageFunctionValue(
restype,
params,
bodyExpression);
tree.pos = pos;
return tree;
}
public VisageInitDefinition InitDefinition(
VisageBlock body) {
VisageInitDefinition tree = new VisageInitDefinition(
body);
tree.pos = pos;
return tree;
}
public VisagePostInitDefinition PostInitDefinition(VisageBlock body) {
VisagePostInitDefinition tree = new VisagePostInitDefinition(body);
tree.pos = pos;
return tree;
}
public VisageSequenceEmpty EmptySequence() {
VisageSequenceEmpty tree = new VisageSequenceEmpty();
tree.pos = pos;
return tree;
}
public VisageSequenceRange RangeSequence(VisageExpression lower, VisageExpression upper, VisageExpression stepOrNull, boolean exclusive) {
VisageSequenceRange tree = new VisageSequenceRange(lower, upper, stepOrNull, exclusive);
tree.pos = pos;
return tree;
}
public VisageSequenceExplicit ExplicitSequence(List<VisageExpression> items) {
VisageSequenceExplicit tree = new VisageSequenceExplicit(items);
tree.pos = pos;
return tree;
}
public VisageSequenceIndexed SequenceIndexed(VisageExpression sequence, VisageExpression index) {
VisageSequenceIndexed tree = new VisageSequenceIndexed(sequence, index);
tree.pos = pos;
return tree;
}
public VisageSequenceSlice SequenceSlice(VisageExpression sequence, VisageExpression firstIndex, VisageExpression lastIndex, int endKind) {
VisageSequenceSlice tree = new VisageSequenceSlice(sequence, firstIndex,
lastIndex, endKind);
tree.pos = pos;
return tree;
}
public VisageSequenceInsert SequenceInsert(VisageExpression sequence, VisageExpression element, VisageExpression position, boolean after) {
VisageSequenceInsert tree = new VisageSequenceInsert(sequence, element, position, after);
tree.pos = pos;
return tree;
}
public VisageSequenceDelete SequenceDelete(VisageExpression sequence) {
VisageSequenceDelete tree = new VisageSequenceDelete(sequence, null);
tree.pos = pos;
return tree;
}
public VisageSequenceDelete SequenceDelete(VisageExpression sequence, VisageExpression element) {
VisageSequenceDelete tree = new VisageSequenceDelete(sequence, element);
tree.pos = pos;
return tree;
}
public VisageStringExpression StringExpression(List<VisageExpression> parts,
String translationKey) {
VisageStringExpression tree = new VisageStringExpression(parts, translationKey);
tree.pos = pos;
return tree;
}
public VisageInstanciate Instanciate(VisageKind kind, VisageExpression clazz, VisageClassDeclaration def, List<VisageExpression> args, List<VisageObjectLiteralPart> parts, List<VisageVar> localVars) {
VisageInstanciate tree = new VisageInstanciate(kind, clazz, def, args, parts, localVars, null);
tree.pos = pos;
return tree;
}
public VisageInstanciate ObjectLiteral(VisageExpression ident,
List<VisageTree> defs) {
return Instanciate(VisageKind.INSTANTIATE_OBJECT_LITERAL,
ident,
List.<VisageExpression>nil(),
defs);
}
public VisageInstanciate InstanciateNew(VisageExpression ident,
List<VisageExpression> args) {
return Instanciate(VisageKind.INSTANTIATE_NEW,
ident,
args != null? args : List.<VisageExpression>nil(),
List.<VisageTree>nil());
}
public VisageInstanciate Instanciate(VisageKind kind, VisageExpression ident,
List<VisageExpression> args,
List<VisageTree> defs) {
// Don't try and process object literals that have erroneous elements
//
if (ident instanceof VisageErroneous) return null;
ListBuffer<VisageObjectLiteralPart> partsBuffer = ListBuffer.lb();
ListBuffer<VisageTree> defsBuffer = ListBuffer.lb();
ListBuffer<VisageExpression> varsBuffer = ListBuffer.lb();
boolean boundParts = false;
if (defs != null) {
for (VisageTree def : defs) {
if (def instanceof VisageObjectLiteralPart) {
VisageObjectLiteralPart olp = (VisageObjectLiteralPart) def;
partsBuffer.append(olp);
boundParts |= olp.isExplicitlyBound();
} else if (def instanceof VisageVar /* && ((VisageVar)def).isLocal()*/) {
// for now, at least, assume any var declaration inside an object literal is local
varsBuffer.append((VisageVar) def);
} else {
defsBuffer.append(def);
}
}
}
VisageClassDeclaration klass = null;
if (defsBuffer.size() > 0 || boundParts) {
VisageExpression id = ident;
while (id instanceof VisageSelect) id = ((VisageSelect)id).getExpression();
Name cname = objectLiteralClassName(((VisageIdent)id).getName());
long innerClassFlags = Flags.SYNTHETIC | Flags.FINAL; // to enable, change to Flags.FINAL
klass = this.ClassDeclaration(this.Modifiers(innerClassFlags), cname, List.<VisageExpression>of(ident), defsBuffer.toList());
}
VisageInstanciate tree = new VisageInstanciate(kind, ident,
klass,
args==null? List.<VisageExpression>nil() : args,
partsBuffer.toList(),
List.convert(VisageVar.class, varsBuffer.toList()),
null);
tree.pos = pos;
return tree;
}
public VisageObjectLiteralPart ObjectLiteralPart(
Name attrName,
VisageExpression expr,
VisageBindStatus bindStatus) {
VisageObjectLiteralPart tree =
new VisageObjectLiteralPart(attrName, expr, bindStatus, null);
tree.pos = pos;
return tree;
}
public VisageType TypeAny(Cardinality cardinality) {
VisageType tree = new VisageTypeAny(cardinality);
tree.pos = pos;
return tree;
}
public VisageType ErroneousType() {
VisageType tree = new VisageErroneousType(List.<VisageTree>nil());
tree.pos = pos;
return tree;
}
public VisageType ErroneousType(List<? extends VisageTree> errs) {
VisageType tree = new VisageErroneousType(errs);
tree.pos = pos;
return tree;
}
public VisageType TypeUnknown() {
VisageType tree = new VisageTypeUnknown();
tree.pos = pos;
return tree;
}
public VisageType TypeClass(VisageExpression className,Cardinality cardinality) {
return TypeClass(className, cardinality, null);
}
public VisageType TypeClass(VisageExpression className,Cardinality cardinality, ClassSymbol sym) {
VisageType tree = new VisageTypeClass(className, cardinality, sym);
tree.pos = pos;
return tree;
}
public VisageType TypeFunctional(List<VisageType> params,
VisageType restype,
Cardinality cardinality) {
VisageType tree = new VisageTypeFunctional(params,
restype,
cardinality);
tree.pos = pos;
return tree;
}
public VisageType TypeArray(VisageType elementType) {
VisageType tree = new VisageTypeArray(elementType);
tree.pos = pos;
return tree;
}
public VisageOverrideClassVar TriggerWrapper(VisageIdent expr, VisageOnReplace onReplace, VisageOnReplace onInvalidate) {
VisageOverrideClassVar tree = new VisageOverrideClassVar(null, null, null, expr, null, null, onReplace, onInvalidate, null);
tree.pos = pos;
return tree;
}
public VisageOnReplace ErroneousOnReplace(List<? extends VisageTree> errs) {
VisageOnReplace tree = new VisageErroneousOnReplace(errs, VisageOnReplace.Kind.ONREPLACE);
tree.pos = pos;
return tree;
}
public VisageOnReplace ErroneousOnInvalidate(List<? extends VisageTree> errs) {
VisageOnReplace tree = new VisageErroneousOnReplace(errs, VisageOnReplace.Kind.ONINVALIDATE);
tree.pos = pos;
return tree;
}
public VisageOnReplace OnReplace(VisageVar oldValue, VisageBlock body) {
VisageOnReplace tree = new VisageOnReplace(oldValue, body, VisageOnReplace.Kind.ONREPLACE);
tree.pos = pos;
return tree;
}
public VisageOnReplace OnReplace(VisageVar oldValue, VisageVar firstIndex,
VisageVar lastIndex, VisageVar newElements, VisageBlock body) {
return OnReplace(oldValue, firstIndex, lastIndex,
VisageSequenceSlice.END_INCLUSIVE, newElements, body);
}
public VisageOnReplace OnReplace(VisageVar oldValue, VisageVar firstIndex,
VisageVar lastIndex, int endKind, VisageVar newElements, VisageBlock body) {
VisageOnReplace tree = OnReplace(oldValue, firstIndex, lastIndex,
endKind, newElements, null, body);
tree.pos = pos;
return tree;
}
public VisageOnReplace OnReplace(VisageVar oldValue, VisageVar firstIndex,
VisageVar lastIndex, int endKind, VisageVar newElements, VisageVar saveVar, VisageBlock body) {
VisageOnReplace tree = new VisageOnReplace(oldValue, firstIndex, lastIndex,
endKind, newElements, saveVar, body, VisageOnReplace.Kind.ONREPLACE);
tree.pos = pos;
return tree;
}
public VisageOnReplace OnInvalidate(VisageBlock body) {
VisageOnReplace tree = new VisageOnReplace(null, body, VisageOnReplace.Kind.ONINVALIDATE);
tree.pos = pos;
return tree;
}
public VisageVarInit VarInit(VisageVar var) {
VisageVarInit tree = new VisageVarInit(var);
tree.pos = (var==null) ? Position.NOPOS : var.pos;
return tree;
}
public VisageVarRef VarRef(VisageExpression expr, VisageVarRef.RefKind kind) {
VisageVarRef tree = new VisageVarRef(expr, kind);
tree.pos = pos;
return tree;
}
public VisageVar Var(Name name,
VisageType type,
VisageModifiers mods,
VisageExpression initializer,
VisageBindStatus bindStatus,
VisageOnReplace onReplace,
VisageOnReplace onInvalidate) {
VisageVar tree = new VisageVar(name, type,
mods, initializer, bindStatus, onReplace, onInvalidate, null);
tree.pos = pos;
return tree;
}
public VisageOverrideClassVar OverrideClassVar(Name name, VisageType type, VisageModifiers mods, VisageIdent expr,
VisageExpression initializer,
VisageBindStatus bindStatus,
VisageOnReplace onReplace,
VisageOnReplace onInvalidate) {
VisageOverrideClassVar tree = new VisageOverrideClassVar(name, type, mods, expr, initializer,
bindStatus, onReplace, onInvalidate, null);
tree.pos = pos;
return tree;
}
public VisageVar Param(Name name,
VisageType type) {
VisageVar tree = new VisageVar(name, type,
Modifiers(Flags.PARAMETER), null, VisageBindStatus.UNBOUND, null, null, null);
tree.pos = pos;
return tree;
}
public VisageForExpression ForExpression(
List<VisageForExpressionInClause> inClauses,
VisageExpression bodyExpr) {
VisageForExpression tree = new VisageForExpression(VisageKind.FOR_EXPRESSION_FOR, inClauses, bodyExpr);
tree.pos = pos;
return tree;
}
public VisageForExpression Predicate(
List<VisageForExpressionInClause> inClauses,
VisageExpression bodyExpr) {
VisageForExpression tree = new VisageForExpression(VisageKind.FOR_EXPRESSION_PREDICATE, inClauses, bodyExpr);
tree.pos = pos;
return tree;
}
public VisageForExpressionInClause InClause(
VisageVar var,
VisageExpression seqExpr,
VisageExpression whereExpr) {
VisageForExpressionInClause tree = new VisageForExpressionInClause(var, seqExpr, whereExpr);
tree.pos = pos;
return tree;
}
public VisageErroneousForExpressionInClause ErroneousInClause(List<? extends VisageTree> errs) {
VisageErroneousForExpressionInClause tree = new VisageErroneousForExpressionInClause(errs);
tree.pos = pos;
return tree;
}
public VisageExpression Identifier(Name name) {
String str = name.toString();
if (str.indexOf('.') < 0 && str.indexOf('<') < 0) {
return Ident(name);
}
return Identifier(str);
}
public VisageExpression Identifier(String str) {
assert str.indexOf('<') < 0 : "attempt to parse a type with 'Identifier'. Use TypeTree";
VisageExpression tree = null;
int inx;
int lastInx = 0;
do {
inx = str.indexOf('.', lastInx);
int endInx;
if (inx < 0) {
endInx = str.length();
} else {
endInx = inx;
}
String part = str.substring(lastInx, endInx);
Name partName = names.fromString(part);
tree = tree == null?
Ident(partName) :
Select(tree, partName, false);
lastInx = endInx + 1;
} while (inx >= 0);
return tree;
}
public VisageInterpolateValue InterpolateValue(VisageExpression attr, VisageExpression v, VisageExpression interp) {
VisageInterpolateValue tree = new VisageInterpolateValue(attr, v, interp);
tree.pos = pos;
return tree;
}
public VisageInvalidate Invalidate(VisageExpression var) {
VisageInvalidate tree = new VisageInvalidate(var);
tree.pos = pos;
return tree;
}
public VisageIndexof Indexof (VisageIdent name) {
VisageIndexof tree = new VisageIndexof(name);
tree.pos = pos;
return tree;
}
public VisageTimeLiteral TimeLiteral(String str) {
int i = 0;
char[] buf = str.toCharArray();
// Locate the duration specifier.
//
while (i < buf.length && (Character.isDigit(buf[i]) || buf[i] == '.' || buf[i] == 'e' || buf[i] == 'E'))
i++;
assert i > 0; // lexer should only pass valid time strings
assert buf.length - i > 0; // lexer should only pass valid time strings
String dur = str.substring(i);
Duration duration =
dur.equals("ms") ? Duration.MILLIS :
dur.equals("s") ? Duration.SECONDS :
dur.equals("m") ? Duration.MINUTES :
dur.equals("h") ? Duration.HOURS : null;
assert duration != null;
Object timeVal;
Double value;
try {
// Extract the literal value up to but excluding the duration
// specifier.
//
String s = str.substring(0, i);
// Even though the number of hours/mounts/etc may be specified
// as an integer, we still need to use a double value always because
// durations such as 999999m will overflow an integer.
//
value = Double.valueOf(s) * duration.getMultiplier();
// Now use an integer if we will not overflow the maximum vlaue
// for an integer and the value is an integer number.
//
if (value <= Integer.MAX_VALUE && value >= Integer.MIN_VALUE && value == value.intValue()) {
timeVal = new Integer(value.intValue());
}
else
{
// Has to stay as a double or it would overflow, or it was
// not an integer vlaue, such as 5.5m
//
timeVal = value;
}
}
catch (NumberFormatException ex) {
// error already reported in scanner
timeVal = Double.NaN;
}
VisageLiteral literal = Literal(timeVal);
VisageTimeLiteral tree = new VisageTimeLiteral(literal, duration);
tree.pos = pos;
return tree;
}
public VisageTimeLiteral TimeLiteral(VisageLiteral literal, Duration duration) {
VisageTimeLiteral tree = new VisageTimeLiteral(literal, duration);
tree.pos = pos;
return tree;
}
public VisageErroneousTimeLiteral ErroneousTimeLiteral() {
VisageErroneousTimeLiteral tree = new VisageErroneousTimeLiteral(List.<VisageTree>nil());
tree.pos = pos;
return tree;
}
public VisageLengthLiteral LengthLiteral(String str) {
int i = 0;
char[] buf = str.toCharArray();
// Locate the length specifier. (also swallows the 'e' in "em")
//
while (i < buf.length && (Character.isDigit(buf[i]) || buf[i] == '.' || buf[i] == 'e' || buf[i] == 'E'))
i++;
if (str.substring(i).equals("m")) {
// ate the 'e' in "em", backup one.
i--;
}
assert i > 0; // lexer should only pass valid length strings
assert buf.length - i > 0; // lexer should only pass valid length strings
String u = str.substring(i);
LengthUnit units =
u.equals("in") ? LengthUnit.INCH :
u.equals("cm") ? LengthUnit.CENTIMETER :
u.equals("mm") ? LengthUnit.MILLIMETER :
u.equals("pt") ? LengthUnit.POINT :
u.equals("pc") ? LengthUnit.PICA :
u.equals("em") ? LengthUnit.EM :
u.equals("px") ? LengthUnit.PIXEL :
u.equals("dp") ? LengthUnit.DENSITY_INDEPENDENT_PIXEL :
u.equals("sp") ? LengthUnit.SCALE_INDEPENDENT_PIXEL :
u.equals("%") ? LengthUnit.PERCENTAGE : null;
assert units != null : "unknown unit: '" + u + "'";
Object lengthVal;
Double value;
try {
// Extract the literal value up to but excluding the length
// specifier.
//
String s = str.substring(0, i);
value = Double.valueOf(s);
// Now use an integer if we will not overflow the maximum vlaue
// for an integer and the value is an integer number.
//
if (value <= Integer.MAX_VALUE && value >= Integer.MIN_VALUE && value == value.intValue()) {
lengthVal = new Integer(value.intValue());
}
else
{
// Has to stay as a double or it would overflow, or it was
// not an integer vlaue, such as 5.5mm
//
lengthVal = value;
}
}
catch (NumberFormatException ex) {
// error already reported in scanner
lengthVal = Double.NaN;
}
VisageLiteral literal = Literal(lengthVal);
VisageLengthLiteral tree = new VisageLengthLiteral(literal, units);
tree.pos = pos;
return tree;
}
public VisageLengthLiteral LengthLiteral(VisageLiteral literal, LengthUnit units) {
VisageLengthLiteral tree = new VisageLengthLiteral(literal, units);
tree.pos = pos;
return tree;
}
public VisageErroneousLengthLiteral ErroneousLengthLiteral() {
VisageErroneousLengthLiteral tree = new VisageErroneousLengthLiteral(List.<VisageTree>nil());
tree.pos = pos;
return tree;
}
public VisageAngleLiteral AngleLiteral(String str) {
int i = 0;
char[] buf = str.toCharArray();
// Locate the angle specifier.
//
while (i < buf.length && (Character.isDigit(buf[i]) || buf[i] == '.' || buf[i] == 'e' || buf[i] == 'E'))
i++;
assert i > 0; // lexer should only pass valid angle strings
assert buf.length - i > 0; // lexer should only pass valid angle strings
String u = str.substring(i);
AngleUnit units =
u.equals("deg") ? AngleUnit.DEGREE :
u.equals("rad") ? AngleUnit.RADIAN :
u.equals("turn") ? AngleUnit.TURN : null;
assert units != null;
Object angleVal;
Double value;
try {
// Extract the literal value up to but excluding the angle
// specifier.
//
String s = str.substring(0, i);
value = Double.valueOf(s);
// Now use an integer if we will not overflow the maximum vlaue
// for an integer and the value is an integer number.
//
if (value <= Integer.MAX_VALUE && value >= Integer.MIN_VALUE && value == value.intValue()) {
angleVal = new Integer(value.intValue());
}
else
{
// Has to stay as a double or it would overflow, or it was
// not an integer vlaue, such as 5.5mm
//
angleVal = value;
}
}
catch (NumberFormatException ex) {
// error already reported in scanner
angleVal = Double.NaN;
}
VisageLiteral literal = Literal(angleVal);
VisageAngleLiteral tree = new VisageAngleLiteral(literal, units);
tree.pos = pos;
return tree;
}
public VisageAngleLiteral AngleLiteral(VisageLiteral literal, AngleUnit units) {
VisageAngleLiteral tree = new VisageAngleLiteral(literal, units);
tree.pos = pos;
return tree;
}
public VisageErroneousAngleLiteral ErroneousAngleLiteral() {
VisageErroneousAngleLiteral tree = new VisageErroneousAngleLiteral(List.<VisageTree>nil());
tree.pos = pos;
return tree;
}
public VisageColorLiteral ColorLiteral(String str) {
// valid strings: #rgb, #rrggbb, #rgb|a, or #rrggbb|aa
String color;
String alpha = null;
switch (str.length()) {
case 4:
color = str.substring(1);
break;
case 7:
color = str.substring(1);
break;
case 6:
color = str.substring(1, 4);
alpha = str.substring(5);
break;
case 10:
color = str.substring(1, 7);
alpha = str.substring(8);
break;
default:
throw new IllegalStateException("malformed color literal string: " + str);
}
int colorVal = Integer.parseInt(color, 16);
int alphaVal = alpha == null ? 0xFF : Integer.parseInt(alpha, 16);
switch (str.length()) {
case 6:
alphaVal |= alphaVal << 4;
case 4:
int r = (colorVal >> 8) & 0xF; r |= r << 4;
int g = (colorVal >> 4) & 0xF; g |= g << 4;
int b = colorVal & 0xF; b |= b << 4;
colorVal = r << 16 | g << 8 | b;
}
VisageLiteral literal = Literal(colorVal | alphaVal << 24);
VisageColorLiteral tree = new VisageColorLiteral(literal);
tree.pos = pos;
return tree;
}
public VisageColorLiteral ColorLiteral(VisageLiteral literal) {
VisageColorLiteral tree = new VisageColorLiteral(literal);
tree.pos = pos;
return tree;
}
public VisageErroneousColorLiteral ErroneousColorLiteral() {
VisageErroneousColorLiteral tree = new VisageErroneousColorLiteral(List.<VisageTree>nil());
tree.pos = pos;
return tree;
}
public VisageKeyFrameLiteral KeyFrameLiteral(VisageExpression start, List<VisageExpression> values, VisageExpression trigger) {
VisageKeyFrameLiteral tree = new VisageKeyFrameLiteral(start, values, trigger);
tree.pos = pos;
return tree;
}
public VisageUnary Unary(VisageTag opcode, VisageExpression arg) {
VisageUnary tree = new VisageUnary(opcode, arg);
tree.pos = pos;
return tree;
}
private int syntheticClassNumber = 0;
Name syntheticClassName(Name superclass, String infix) {
return names.fromString(superclass.toString() + infix + ++syntheticClassNumber);
}
Name objectLiteralClassName(Name superclass) {
return syntheticClassName(superclass, VisageDefs.objectLiteralClassInfix);
}
/**
* Clone of javac's VisageTreeMaker.Script, minus the assertion check of defs types.
*/
public VisageScript Script(VisageExpression pid,
List<VisageTree> defs) {
VisageScript tree = new VisageScript(pid, defs,
null, null, null, null);
tree.pos = pos;
return tree;
}
public VisageExpression QualIdent(Symbol sym) {
if (sym.kind ==Kinds.PCK && sym.owner == syms.rootPackage)
return Ident(sym);
return isUnqualifiable(sym)
? Ident(sym)
: Select(QualIdent(sym.owner), sym, false);
}
}