use of org.eclipse.ceylon.model.typechecker.model.Class in project ceylon by eclipse.
the class NamedArgumentInvocation method appendVarsForDefaulted.
private boolean appendVarsForDefaulted(java.util.List<Parameter> declaredParams) {
boolean hasDefaulted = false;
if (!Decl.isOverloaded(getPrimaryDeclaration())) {
// append any arguments for defaulted parameters
for (Parameter param : declaredParams) {
if (bound.contains(param)) {
continue;
}
final JCExpression argExpr;
if (Strategy.hasDefaultParameterValueMethod(param)) {
// special handling for "element" optional param of java array constructors
if (getPrimaryDeclaration() instanceof Class && gen.isJavaArray(((Class) getPrimaryDeclaration()).getType())) {
// default values are hard-coded to Java default values, and are actually ignored
continue;
} else if (gen.typeFact().getExceptionDeclaration().equals(getPrimaryDeclaration())) {
// erasure means there's no default value method, but we know it's null
argExpr = gen.makeNull();
} else if (getQmePrimary() != null && gen.isJavaArray(getQmePrimary().getTypeModel())) {
// we support array methods with optional parameters
if (getPrimaryDeclaration() instanceof Function && getPrimaryDeclaration().getName().equals("copyTo")) {
if (param.getName().equals("sourcePosition") || param.getName().equals("destinationPosition")) {
argExpr = gen.makeInteger(0);
hasDefaulted |= true;
} else if (param.getName().equals("length")) {
argExpr = gen.makeSelect(varBaseName.suffixedBy(Suffix.$argthis$).makeIdent(), "length");
hasDefaulted |= true;
} else {
argExpr = gen.makeErroneous(this.getNode(), "compiler bug: argument to copyTo method of java array type not supported: " + param.getName());
}
} else {
argExpr = gen.makeErroneous(this.getNode(), "compiler bug: virtual method of java array type not supported: " + getPrimaryDeclaration());
}
} else {
argExpr = makeDefaultedArgumentMethodCall(param);
hasDefaulted |= true;
}
} else if (Strategy.hasEmptyDefaultArgument(param)) {
argExpr = gen.makeEmptyAsSequential(true);
} else if (gen.typeFact().isIterableType(param.getType())) {
// must be an iterable we need to fill with empty
// FIXME: deal with this erasure bug later
argExpr = gen.make().TypeCast(gen.makeJavaType(gen.typeFact().getIterableDeclaration().getType(), AbstractTransformer.JT_RAW), gen.makeEmpty());
} else {
// more expensive but worth a try
Type appliedType = gen.getTypeForParameter(param, producedReference, AbstractTransformer.TP_TO_BOUND);
if (gen.typeFact().isIterableType(appliedType)) {
argExpr = gen.make().TypeCast(gen.makeJavaType(gen.typeFact().getIterableDeclaration().getType(), AbstractTransformer.JT_RAW), gen.makeEmpty());
} else {
argExpr = gen.makeErroneous(this.getNode(), "compiler bug: missing argument, and parameter is not defaulted");
}
}
appendDefaulted(param, argExpr);
}
}
return hasDefaulted;
}
use of org.eclipse.ceylon.model.typechecker.model.Class in project ceylon by eclipse.
the class Decl method isJavaObjectArrayWith.
public static boolean isJavaObjectArrayWith(Constructor ctor) {
if (ctor.isClassMember() && "with".equals(ctor.getName())) {
Unit unit = ctor.getUnit();
Scope cls = ctor.getContainer();
if (cls instanceof Class) {
return cls.equals(unit.getJavaObjectArrayDeclaration());
}
}
return false;
}
use of org.eclipse.ceylon.model.typechecker.model.Class in project ceylon by eclipse.
the class TypeUtils method generateModelPath.
/**
* Returns the list of keys to get from the package to the declaration, in the model.
*/
public static List<String> generateModelPath(final Declaration d) {
final ArrayList<String> sb = new ArrayList<>();
final Package pkg = d.getUnit().getPackage();
sb.add(pkg.isLanguagePackage() ? "$" : pkg.getNameAsString());
if (d.isToplevel()) {
sb.add(d.getName());
if (d instanceof Setter) {
sb.add("$set");
}
} else {
Declaration p = d;
final int i = sb.size();
while (p instanceof Declaration) {
if (p instanceof Setter) {
sb.add(i, "$set");
}
final String mname = TypeUtils.modelName(p);
if (!(mname.startsWith("anon$") || mname.startsWith("anonymous#"))) {
sb.add(i, mname);
// Build the path in reverse
if (!p.isToplevel()) {
if (p instanceof Class) {
sb.add(i, p.isAnonymous() ? MetamodelGenerator.KEY_OBJECTS : MetamodelGenerator.KEY_CLASSES);
} else if (p instanceof org.eclipse.ceylon.model.typechecker.model.Interface) {
sb.add(i, MetamodelGenerator.KEY_INTERFACES);
} else if (p instanceof Function) {
if (!p.isAnonymous()) {
sb.add(i, MetamodelGenerator.KEY_METHODS);
}
} else if (p instanceof TypeAlias || p instanceof Setter) {
sb.add(i, MetamodelGenerator.KEY_ATTRIBUTES);
} else if (p instanceof Constructor || ModelUtil.isConstructor(p)) {
sb.add(i, MetamodelGenerator.KEY_CONSTRUCTORS);
} else {
// It's a value
TypeDeclaration td = ((TypedDeclaration) p).getTypeDeclaration();
sb.add(i, (td != null && td.isAnonymous()) ? MetamodelGenerator.KEY_OBJECTS : MetamodelGenerator.KEY_ATTRIBUTES);
}
}
}
p = ModelUtil.getContainingDeclaration(p);
while (p != null && p instanceof ClassOrInterface == false && !(p.isToplevel() || p.isAnonymous() || p.isClassOrInterfaceMember() || p.isJsCaptured())) {
p = ModelUtil.getContainingDeclaration(p);
}
}
}
return sb;
}
use of org.eclipse.ceylon.model.typechecker.model.Class in project ceylon by eclipse.
the class JsIdentifierNames method getName.
private String getName(Declaration decl, boolean forGetterSetter, boolean priv) {
if (decl == null) {
return null;
}
String name = decl.getName();
if (name == null && ModelUtil.isConstructor(decl)) {
return "$c$";
}
if (name.startsWith("anonymous#")) {
name = "anon$" + name.substring(10);
}
if (decl.isDynamic()) {
return JsUtils.escapeStringLiteral(decl.getName());
}
boolean nonLocal = !priv;
if (nonLocal) {
// check if it's a shared member or a toplevel function
nonLocal = decl.isMember() ? decl.isShared() || decl instanceof TypeDeclaration : decl.isToplevel() && (forGetterSetter || decl instanceof Function || decl instanceof ClassOrInterface || decl instanceof TypeAlias);
}
if (nonLocal && decl instanceof Class && ((Class) decl).isAnonymous() && !forGetterSetter) {
// A lower-case class name belongs to an object and is not public.
nonLocal = false;
}
if (nonLocal) {
// The identifier might be accessed from other .js files, so it must
// be reliably reproducible. In most cases simply using the original
// name is ok because otherwise it would result in a name collision in
// Ceylon too. We just have to take care of a few exceptions:
String suffix = nestingSuffix(decl, false);
if (suffix.length() > 0) {
// nested type
name += suffix;
} else if ((!forGetterSetter && !ModelUtil.isConstructor(decl) && reservedWords.contains(name)) || isJsGlobal(decl)) {
// JavaScript keyword or global declaration
name = "$_" + name;
}
} else {
// The identifier will not be used outside the generated .js file,
// so we can simply disambiguate it with a numeric ID.
name = uniquePrivateName(decl, priv);
}
// Fix #204 - same top-level declarations in different packages
final Package declPkg = decl.getUnit().getPackage();
if (decl.isToplevel() && !declPkg.equals(declPkg.getModule().getRootPackage())) {
final Package raiz = declPkg.getModule().getRootPackage();
// rootPackage can be null when compiling from IDE
String rootName = raiz == null ? (declPkg.getModule().isDefaultModule() ? "" : declPkg.getModule().getNameAsString()) : raiz.getNameAsString();
String pkgName = declPkg.getNameAsString();
rootName = pkgName.substring(rootName.length()).replaceAll("\\.", "\\$");
if (rootName.length() > 0 && rootName.charAt(0) != '$') {
rootName = '$' + rootName;
}
name += rootName;
}
if (decl instanceof TypeAlias) {
name += "()";
}
return JsUtils.escapeStringLiteral(name);
}
use of org.eclipse.ceylon.model.typechecker.model.Class in project ceylon by eclipse.
the class RefinementVisitor method checkNonMember.
private void checkNonMember(Tree.Declaration that, Declaration dec) {
boolean mayBeShared = !(dec instanceof TypeParameter);
boolean nonTypeMember = !dec.isClassOrInterfaceMember();
String name = dec.getName();
if (dec.isStatic()) {
if (nonTypeMember) {
that.addError("static declaration is not a member of a class or interface: '" + name + "' is not defined directly in the body of a class or interface");
} else {
ClassOrInterface type = (ClassOrInterface) dec.getContainer();
if (!type.isToplevel()) {
that.addError("static declaration belongs to a nested a class or interface: '" + name + "' is a member of nested type '" + type.getName() + "'");
}
}
}
if (nonTypeMember && mayBeShared) {
if (dec.isActual()) {
that.addError("actual declaration is not a member of a class or interface: '" + name + "'", 1301);
}
if (dec.isFormal()) {
that.addError("formal declaration is not a member of a class or interface: '" + name + "'", 1302);
}
if (dec.isDefault()) {
that.addError("default declaration is not a member of a class or interface: '" + name + "'", 1303);
}
} else if (!dec.isShared() && mayBeShared) {
if (dec.isActual()) {
that.addError("actual declaration must be shared: '" + name + "'", 701);
}
if (dec.isFormal()) {
that.addError("formal declaration must be shared: '" + name + "'", 702);
}
if (dec.isDefault()) {
that.addError("default declaration must be shared: '" + name + "'", 703);
}
} else {
if (dec.isActual()) {
that.addError("declaration may not be actual: '" + name + "'", 1301);
}
if (dec.isFormal()) {
that.addError("declaration may not be formal: '" + name + "'", 1302);
}
if (dec.isDefault()) {
that.addError("declaration may not be default: '" + name + "'", 1303);
}
}
if (isOverloadedVersion(dec)) {
if (isConstructor(dec)) {
checkOverloadedAnnotation(that, dec);
checkOverloadedParameters(that, dec);
} else {
that.addError("duplicate declaration: the name '" + name + "' is not unique in this scope");
}
} else if (isAbstraction(dec)) {
// that is considered overloaded in the model
if (that instanceof Tree.ClassDefinition && !that.hasErrors()) {
Tree.ClassDefinition def = (Tree.ClassDefinition) that;
// this is an abstraction
Class abs = (Class) dec;
// correctly located)
for (Tree.Statement st : def.getClassBody().getStatements()) {
if (st instanceof Tree.Constructor) {
Tree.Constructor node = (Tree.Constructor) st;
if (node.getIdentifier() == null) {
Constructor con = node.getConstructor();
// get the corresponding overloaded version
Class cla = classOverloadForConstructor(abs, con);
checkOverloadedAnnotation(node, con);
checkOverloadedParameters(node, cla);
}
}
}
}
}
if (isConstructor(dec) && dec.isShared()) {
Scope container = dec.getContainer();
if (container instanceof Class) {
Class clazz = (Class) container;
Declaration member = intersectionOfSupertypes(clazz).getDeclaration().getMember(name, null, false);
if (member != null && member.isShared() && !isConstructor(member)) {
Declaration supertype = (Declaration) member.getContainer();
that.addError("constructor has same name as an inherited member '" + clazz.getName() + "' inherits '" + member.getName() + "' from '" + supertype.getName(that.getUnit()) + "'");
}
}
}
}
Aggregations