Search in sources :

Example 41 with Class

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;
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) Class(org.eclipse.ceylon.model.typechecker.model.Class)

Example 42 with Class

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;
}
Also used : Scope(org.eclipse.ceylon.model.typechecker.model.Scope) ConditionScope(org.eclipse.ceylon.model.typechecker.model.ConditionScope) LazyClass(org.eclipse.ceylon.model.loader.model.LazyClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) Unit(org.eclipse.ceylon.model.typechecker.model.Unit)

Example 43 with Class

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;
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) ArrayList(java.util.ArrayList) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) Function(org.eclipse.ceylon.model.typechecker.model.Function) Setter(org.eclipse.ceylon.model.typechecker.model.Setter) Class(org.eclipse.ceylon.model.typechecker.model.Class) Package(org.eclipse.ceylon.model.typechecker.model.Package) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Interface(org.eclipse.ceylon.model.typechecker.model.Interface)

Example 44 with Class

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);
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) Class(org.eclipse.ceylon.model.typechecker.model.Class) Package(org.eclipse.ceylon.model.typechecker.model.Package) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 45 with Class

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()) + "'");
            }
        }
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) ModelUtil.getRealScope(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getRealScope) ModelUtil.isConstructor(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isConstructor) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Aggregations

Class (org.eclipse.ceylon.model.typechecker.model.Class)184 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)110 Type (org.eclipse.ceylon.model.typechecker.model.Type)87 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)78 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)72 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)55 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)46 Value (org.eclipse.ceylon.model.typechecker.model.Value)46 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)42 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)39 Function (org.eclipse.ceylon.model.typechecker.model.Function)38 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)36 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)35 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)33 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)33 ArrayList (java.util.ArrayList)32 IntersectionType (org.eclipse.ceylon.model.typechecker.model.IntersectionType)32 JCNewClass (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass)31 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)27 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)23