use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.
the class Attr method visitTypeApply.
/** Visitor method for parameterized types.
* Bound checking is left until later, since types are attributed
* before supertype structure is completely known
*/
public void visitTypeApply(JCTypeApply tree) {
Type owntype = types.createErrorType(tree.type);
// Attribute functor part of application and make sure it's a class.
Type clazztype = chk.checkClassType(tree.clazz.pos(), attribType(tree.clazz, env));
// Attribute type parameters
List<Type> actuals = attribTypes(tree.arguments, env);
if (clazztype.tag == CLASS) {
List<Type> formals = clazztype.tsym.type.getTypeArguments();
if (actuals.length() == formals.length() || actuals.length() == 0) {
List<Type> a = actuals;
List<Type> f = formals;
while (a.nonEmpty()) {
a.head = a.head.withTypeVar(f.head);
a = a.tail;
f = f.tail;
}
// Compute the proper generic outer
Type clazzOuter = clazztype.getEnclosingType();
if (clazzOuter.tag == CLASS) {
Type site;
JCExpression clazz = TreeInfo.typeIn(tree.clazz);
if (clazz.getTag() == JCTree.IDENT) {
site = env.enclClass.sym.type;
} else if (clazz.getTag() == JCTree.SELECT) {
site = ((JCFieldAccess) clazz).selected.type;
} else
throw new AssertionError("" + tree);
if (clazzOuter.tag == CLASS && site != clazzOuter) {
if (site.tag == CLASS)
site = types.asOuterSuper(site, clazzOuter.tsym);
if (site == null)
site = types.erasure(clazzOuter);
clazzOuter = site;
}
}
owntype = new ClassType(clazzOuter, actuals, clazztype.tsym);
} else {
if (formals.length() != 0) {
log.error(tree.pos(), "wrong.number.type.args", Integer.toString(formals.length()));
} else {
log.error(tree.pos(), "type.doesnt.take.params", clazztype.tsym);
}
owntype = types.createErrorType(tree.type);
}
}
result = check(tree, owntype, TYP, pkind, pt);
}
use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.
the class Attr method visitMethodDef.
public void visitMethodDef(JCMethodDecl tree) {
MethodSymbol m = tree.sym;
Lint lint = env.info.lint.augment(m.attributes_field, m.flags());
Lint prevLint = chk.setLint(lint);
MethodSymbol prevMethod = chk.setMethod(m);
try {
deferredLintHandler.flush(tree.pos());
chk.checkDeprecatedAnnotation(tree.pos(), m);
attribBounds(tree.typarams);
// JLS ???
if (m.isStatic()) {
chk.checkHideClashes(tree.pos(), env.enclClass.type, m);
} else {
chk.checkOverrideClashes(tree.pos(), env.enclClass.type, m);
}
chk.checkOverride(tree, m);
// Create a new environment with local scope
// for attributing the method.
Env<AttrContext> localEnv = memberEnter.methodEnv(tree, env);
localEnv.info.lint = lint;
// Enter all type parameters into the local method scope.
for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail) localEnv.info.scope.enterIfAbsent(l.head.type.tsym);
ClassSymbol owner = env.enclClass.sym;
if ((owner.flags() & ANNOTATION) != 0 && tree.params.nonEmpty())
log.error(tree.params.head.pos(), "intf.annotation.members.cant.have.params");
// Attribute all value parameters.
for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
attribStat(l.head, localEnv);
}
chk.checkVarargsMethodDecl(localEnv, tree);
// Check that type parameters are well-formed.
chk.validate(tree.typarams, localEnv);
// Check that result type is well-formed.
chk.validate(tree.restype, localEnv);
// annotation method checks
if ((owner.flags() & ANNOTATION) != 0) {
// annotation method cannot have throws clause
if (tree.thrown.nonEmpty()) {
log.error(tree.thrown.head.pos(), "throws.not.allowed.in.intf.annotation");
}
// annotation method cannot declare type-parameters
if (tree.typarams.nonEmpty()) {
log.error(tree.typarams.head.pos(), "intf.annotation.members.cant.have.type.params");
}
// validate annotation method's return type (could be an annotation type)
chk.validateAnnotationType(tree.restype);
// ensure that annotation method does not clash with members of Object/Annotation
chk.validateAnnotationMethod(tree.pos(), m);
if (tree.defaultValue != null) {
// if default value is an annotation, check it is a well-formed
// annotation value (e.g. no duplicate values, no missing values, etc.)
chk.validateAnnotationTree(tree.defaultValue);
}
}
for (List<JCExpression> l = tree.thrown; l.nonEmpty(); l = l.tail) chk.checkType(l.head.pos(), l.head.type, syms.throwableType);
if (tree.body == null) {
// in a retrofit signature class.
if ((owner.flags() & INTERFACE) == 0 && (tree.mods.flags & (ABSTRACT | NATIVE)) == 0 && !relax)
log.error(tree.pos(), "missing.meth.body.or.decl.abstract");
if (tree.defaultValue != null) {
if ((owner.flags() & ANNOTATION) == 0)
log.error(tree.pos(), "default.allowed.in.intf.annotation.member");
}
} else if ((owner.flags() & INTERFACE) != 0) {
log.error(tree.body.pos(), "intf.meth.cant.have.body");
} else if ((tree.mods.flags & ABSTRACT) != 0) {
log.error(tree.pos(), "abstract.meth.cant.have.body");
} else if ((tree.mods.flags & NATIVE) != 0) {
log.error(tree.pos(), "native.meth.cant.have.body");
} else {
// or we are compiling class java.lang.Object.
if (tree.name == names.init && owner.type != syms.objectType) {
JCBlock body = tree.body;
if (body.stats.isEmpty() || !TreeInfo.isSelfCall(names, body.stats.head)) {
body.stats = body.stats.prepend(memberEnter.SuperCall(make.at(body.pos), List.<Type>nil(), List.<JCVariableDecl>nil(), false));
} else if ((env.enclClass.sym.flags() & ENUM) != 0 && (tree.mods.flags & GENERATEDCONSTR) == 0 && TreeInfo.isSuperCall(names, body.stats.head)) {
// enum constructors are not allowed to call super
// directly, so make sure there aren't any super calls
// in enum constructors, except in the compiler
// generated one.
log.error(tree.body.stats.head.pos(), "call.to.super.not.allowed.in.enum.ctor", env.enclClass.sym);
}
}
// Attribute method body.
attribStat(tree.body, localEnv);
}
localEnv.info.scope.leave();
result = tree.type = m.type;
chk.validateAnnotations(tree.mods.annotations, m);
} finally {
chk.setLint(prevLint);
chk.setMethod(prevMethod);
}
}
use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.
the class CeylonTransformer method makeDefs.
private List<JCTree> makeDefs(CompilationUnit t) {
final ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
t.visit(new SourceDeclarationVisitor() {
@Override
public void loadFromSource(Declaration decl) {
if (!checkNative(decl))
return;
long flags = decl instanceof Tree.AnyInterface ? Flags.INTERFACE : 0;
String name = Naming.toplevelClassName("", decl);
defs.add(makeClassDef(decl, flags, name, WantedDeclaration.Normal));
if (decl instanceof Tree.AnyInterface) {
String implName = Naming.getImplClassName(name);
defs.add(makeClassDef(decl, 0, implName, WantedDeclaration.Normal));
}
// only do it for Bootstrap where we control the annotations, because it's so dodgy ATM
if (options.get(OptionName.BOOTSTRAPCEYLON) != null && decl instanceof Tree.AnyClass && TreeUtil.hasAnnotation(decl.getAnnotationList(), "annotation", decl.getUnit())) {
String annotationName = Naming.suffixName(Suffix.$annotation$, name);
defs.add(makeClassDef(decl, Flags.ANNOTATION, annotationName, WantedDeclaration.Annotation));
for (Tree.StaticType sat : ((Tree.AnyClass) decl).getSatisfiedTypes().getTypes()) {
if (sat instanceof Tree.BaseType && ((Tree.BaseType) sat).getIdentifier().getText().equals("SequencedAnnotation")) {
String annotationsName = Naming.suffixName(Suffix.$annotations$, name);
defs.add(makeClassDef(decl, Flags.ANNOTATION, annotationsName, WantedDeclaration.AnnotationSequence));
}
}
}
}
private JCTree makeClassDef(Declaration decl, long flags, String name, WantedDeclaration wantedDeclaration) {
ListBuffer<JCTree.JCTypeParameter> typarams = new ListBuffer<JCTree.JCTypeParameter>();
if (decl instanceof Tree.ClassOrInterface) {
Tree.ClassOrInterface classDecl = (ClassOrInterface) decl;
if (classDecl.getTypeParameterList() != null) {
for (Tree.TypeParameterDeclaration typeParamDecl : classDecl.getTypeParameterList().getTypeParameterDeclarations()) {
// we don't need a valid name, just a name, and making it BOGUS helps us find it later if it turns out
// we failed to reset everything properly
typarams.add(make().TypeParameter(names().fromString("BOGUS-" + typeParamDecl.getIdentifier().getText()), List.<JCExpression>nil()));
}
}
}
return make().ClassDef(make().Modifiers(flags | Flags.PUBLIC), names().fromString(name), typarams.toList(), null, List.<JCExpression>nil(), makeClassBody(decl, wantedDeclaration));
}
private List<JCTree> makeClassBody(Declaration decl, WantedDeclaration wantedDeclaration) {
// only do it for Bootstrap where we control the annotations, because it's so dodgy ATM
if (wantedDeclaration == WantedDeclaration.Annotation) {
ListBuffer<JCTree> body = new ListBuffer<JCTree>();
for (Tree.Parameter param : ((Tree.ClassDefinition) decl).getParameterList().getParameters()) {
String name;
JCExpression type = make().TypeArray(make().Type(syms().stringType));
if (param instanceof Tree.InitializerParameter)
name = ((Tree.InitializerParameter) param).getIdentifier().getText();
else if (param instanceof Tree.ParameterDeclaration) {
Tree.TypedDeclaration typedDeclaration = ((Tree.ParameterDeclaration) param).getTypedDeclaration();
name = typedDeclaration.getIdentifier().getText();
type = getAnnotationTypeFor(typedDeclaration.getType());
} else
name = "ERROR";
JCMethodDecl method = make().MethodDef(make().Modifiers(Flags.PUBLIC), names().fromString(name), type, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null);
body.append(method);
}
return body.toList();
}
if (wantedDeclaration == WantedDeclaration.AnnotationSequence) {
String name = Naming.toplevelClassName("", decl);
String annotationName = Naming.suffixName(Suffix.$annotation$, name);
JCExpression type = make().TypeArray(make().Ident(names().fromString(annotationName)));
JCMethodDecl method = make().MethodDef(make().Modifiers(Flags.PUBLIC), names().fromString("value"), type, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null);
return List.<JCTree>of(method);
}
return List.<JCTree>nil();
}
private JCExpression getAnnotationTypeFor(Tree.Type type) {
if (type instanceof Tree.BaseType) {
String name = ((Tree.BaseType) type).getIdentifier().getText();
if (name.equals("String") || name.equals("Declaration"))
return make().Type(syms().stringType);
if (name.equals("Boolean"))
return make().Type(syms().booleanType);
if (name.equals("Integer"))
return make().Type(syms().longType);
if (name.equals("Float"))
return make().Type(syms().doubleType);
if (name.equals("Byte"))
return make().Type(syms().byteType);
if (name.equals("Character"))
return make().Type(syms().charType);
if (name.equals("Declaration") || name.equals("ClassDeclaration") || name.equals("InterfaceDeclaration") || name.equals("ClassOrInterfaceDeclaration"))
return make().Type(syms().stringType);
}
if (type instanceof Tree.SequencedType) {
return make().TypeArray(getAnnotationTypeFor(((Tree.SequencedType) type).getType()));
}
if (type instanceof Tree.SequenceType) {
return make().TypeArray(getAnnotationTypeFor(((Tree.SequenceType) type).getElementType()));
}
if (type instanceof Tree.IterableType) {
return make().TypeArray(getAnnotationTypeFor(((Tree.IterableType) type).getElementType()));
}
if (type instanceof Tree.TupleType) {
// can only be one, must be a SequencedType
Tree.Type sequencedType = ((Tree.TupleType) type).getElementTypes().get(0);
return getAnnotationTypeFor(sequencedType);
}
System.err.println("Unknown Annotation type: " + type);
return make().TypeArray(make().Type(syms().stringType));
}
@Override
public void loadFromSource(ModuleDescriptor that) {
// don't think we care about these
}
@Override
public void loadFromSource(PackageDescriptor that) {
// don't think we care about these
}
});
return defs.toList();
}
use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.
the class CeylonTransformer method makeJCCompilationUnitPlaceholder.
/**
* In this pass we only make an empty placeholder which we'll fill in the
* EnterCeylon phase later on
*/
public JCCompilationUnit makeJCCompilationUnitPlaceholder(Tree.CompilationUnit t, JavaFileObject file, String pkgName, PhasedUnit phasedUnit) {
JCExpression pkg = pkgName != null ? getPackage(pkgName) : null;
at(t);
List<JCTree> defs = makeDefs(t);
JCCompilationUnit topLev = new CeylonCompilationUnit(List.<JCTree.JCAnnotation>nil(), pkg, defs, null, null, null, null, t, phasedUnit);
topLev.lineMap = getMap();
topLev.sourcefile = file;
topLev.isCeylonProgram = true;
return topLev;
}
use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.
the class CeylonTransformer method transformAttribute.
public List<JCTree> transformAttribute(TypedDeclaration declarationModel, String attrName, String attrClassName, final Tree.Declaration annotated, final Tree.Block block, final Tree.SpecifierOrInitializerExpression expression, final Tree.TypedDeclaration decl, final Tree.AttributeSetterDefinition setterDecl) {
// For everything else generate a getter/setter method
AttributeDefinitionBuilder builder = AttributeDefinitionBuilder.wrapped(this, attrClassName, null, attrName, declarationModel, declarationModel.isToplevel()).is(Flags.PUBLIC, declarationModel.isShared());
final JCExpression initialValue;
final HasErrorException expressionError;
if (expression != null) {
expressionError = errors().getFirstExpressionErrorAndMarkBrokenness(expression.getExpression());
if (expressionError != null) {
initialValue = make().Erroneous();
} else {
initialValue = transformValueInit(declarationModel, attrName, expression);
}
} else {
expressionError = null;
initialValue = transformValueInit(declarationModel, attrName, expression);
}
// For captured local variable Values, use a VariableBox
if (Decl.isBoxedVariable(declarationModel)) {
if (expressionError != null) {
return List.<JCTree>of(this.makeThrowUnresolvedCompilationError(expressionError));
} else {
return List.<JCTree>of(makeVariableBoxDecl(initialValue, declarationModel));
}
}
// For late-bound getters we only generate a declaration
if (block == null && expression == null && !Decl.isToplevel(declarationModel)) {
JCExpression typeExpr = makeJavaType(getGetterInterfaceType(declarationModel));
JCTree.JCVariableDecl var = makeVar(attrClassName, typeExpr, null);
return List.<JCTree>of(var);
}
// Set the local declarations annotation
if (decl != null) {
List<JCAnnotation> scopeAnnotations;
if (Decl.isToplevel(declarationModel) && setterDecl != null) {
scopeAnnotations = makeAtLocalDeclarations(decl, setterDecl);
} else {
scopeAnnotations = makeAtLocalDeclarations(decl);
}
builder.classAnnotations(scopeAnnotations);
} else if (block != null) {
List<JCAnnotation> scopeAnnotations = makeAtLocalDeclarations(block);
builder.classAnnotations(scopeAnnotations);
}
// Remember the setter class if we generate a getter
if (Decl.isGetter(declarationModel) && declarationModel.isVariable() && Decl.isLocal(declarationModel)) {
// we must have a setter class
Setter setter = ((Value) declarationModel).getSetter();
if (setter != null) {
String setterClassName = Naming.getAttrClassName(setter, 0);
JCExpression setterClassNameExpr = naming.makeUnquotedIdent(setterClassName);
builder.setterClass(makeSelect(setterClassNameExpr, "class"));
}
}
if (declarationModel instanceof Setter || (declarationModel instanceof FunctionOrValue && ((FunctionOrValue) declarationModel).isParameter())) {
// For local setters
JCBlock setterBlock = makeSetterBlock(declarationModel, block, expression);
builder.setterBlock(setterBlock);
builder.skipGetter();
if (Decl.isLocal(decl)) {
// we need to find back the Setter model for local setters, because
// in transformAttribute(Tree.TypedDeclaration decl, Tree.AttributeSetterDefinition setterDecl)
// we turn the declaration model from the Setter to its single parameter
Setter setter = (Setter) declarationModel.getContainer();
String getterClassName = Naming.getAttrClassName(setter.getGetter(), 0);
JCExpression getterClassNameExpr = naming.makeUnquotedIdent(getterClassName);
builder.isSetter(makeSelect(getterClassNameExpr, "class"));
}
} else {
if (Decl.isValue(declarationModel)) {
// For local and toplevel value attributes
if (!declarationModel.isVariable() && !declarationModel.isLate()) {
builder.immutable();
}
} else {
// For local and toplevel getters
boolean prevSyntheticClassBody;
if (Decl.isLocal(declarationModel)) {
prevSyntheticClassBody = expressionGen().withinSyntheticClassBody(true);
} else {
prevSyntheticClassBody = expressionGen().isWithinSyntheticClassBody();
}
JCBlock getterBlock = makeGetterBlock(declarationModel, block, expression);
prevSyntheticClassBody = expressionGen().withinSyntheticClassBody(prevSyntheticClassBody);
builder.getterBlock(getterBlock);
if (Decl.isLocal(declarationModel)) {
// For local getters
builder.immutable();
} else {
// For toplevel getters
if (setterDecl != null) {
JCBlock setterBlock = makeSetterBlock(setterDecl.getDeclarationModel(), setterDecl.getBlock(), setterDecl.getSpecifierExpression());
builder.setterBlock(setterBlock);
//builder.userAnnotationsSetter(expressionGen().transformAnnotations(true, OutputElement.METHOD, setterDecl));
builder.userAnnotationsSetter(expressionGen().transformAnnotations(OutputElement.SETTER, setterDecl));
} else {
builder.immutable();
}
}
}
}
if (annotated != null) {
builder.userAnnotations(expressionGen().transformAnnotations(OutputElement.GETTER, annotated));
}
if (Decl.isLocal(declarationModel)) {
if (expressionError != null) {
return List.<JCTree>of(this.makeThrowUnresolvedCompilationError(expressionError));
}
builder.classAnnotations(makeAtLocalDeclaration(declarationModel.getQualifier(), false));
if (initialValue != null)
builder.valueConstructor();
JCExpression typeExpr;
if (declarationModel instanceof Setter || (declarationModel instanceof FunctionOrValue && ((FunctionOrValue) declarationModel).isParameter())) {
typeExpr = makeQuotedIdent(attrClassName);
} else {
typeExpr = makeJavaType(getGetterInterfaceType(declarationModel));
}
return builder.build().append(makeLocalIdentityInstance(typeExpr, attrClassName, attrClassName, declarationModel.isShared(), initialValue));
} else {
if (expressionError != null) {
builder.initialValueError(expressionError);
} else if (initialValue != null) {
builder.initialValue(initialValue);
}
builder.is(Flags.STATIC, true);
return builder.build();
}
}
Aggregations