Search in sources :

Example 1 with Scope

use of org.eclipse.ceylon.langtools.tools.javac.code.Scope in project ceylon by eclipse.

the class Enter method visitClassDef.

@Override
public void visitClassDef(JCClassDecl tree) {
    Symbol owner = env.info.scope.owner;
    Scope enclScope = enterScope(env);
    ClassSymbol c;
    if (owner.kind == PCK) {
        // We are seeing a toplevel class.
        PackageSymbol packge = (PackageSymbol) owner;
        for (Symbol q = packge; q != null && q.kind == PCK; q = q.owner) q.flags_field |= EXISTS;
        c = reader.enterClass(tree.name, packge);
        packge.members().enterIfAbsent(c);
        if ((tree.mods.flags & PUBLIC) != 0 && !classNameMatchesFileName(c, env) && !sourceLanguage.isCeylon()) {
            log.error(tree.pos(), "class.public.should.be.in.file", tree.name);
        }
    } else {
        if (!tree.name.isEmpty() && !chk.checkUniqueClassName(tree.pos(), tree.name, enclScope)) {
            result = null;
            return;
        }
        if (owner.kind == TYP) {
            // We are seeing a member class.
            c = reader.enterClass(tree.name, (TypeSymbol) owner);
            if ((owner.flags_field & INTERFACE) != 0) {
                tree.mods.flags |= PUBLIC | STATIC;
            }
        } else {
            // We are seeing a local class.
            c = reader.defineClass(tree.name, owner);
            c.flatname = chk.localClassName(c);
            if (!c.name.isEmpty())
                chk.checkTransparentClass(tree.pos(), c, env.info.scope);
        }
    }
    tree.sym = c;
    // Enter class into `compiled' table and enclosing scope.
    if (chk.compiled.get(c.flatname) != null) {
        duplicateClass(tree.pos(), c);
        result = types.createErrorType(tree.name, (TypeSymbol) owner, Type.noType);
        tree.sym = (ClassSymbol) result.tsym;
        return;
    }
    chk.compiled.put(c.flatname, c);
    // CEYLON(stef): don't add anonymous classes to the environment
    if (tree.name.length() != 0)
        enclScope.enter(c);
    // Set up an environment for class block and store in `typeEnvs'
    // table, to be retrieved later in memberEnter and attribution.
    Env<AttrContext> localEnv = classEnv(tree, env);
    typeEnvs.put(c, localEnv);
    // Fill out class fields.
    c.completer = memberEnter;
    c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree);
    c.sourcefile = env.toplevel.sourcefile;
    c.members_field = new Scope(c);
    // determine the enclosing type
    if (sourceLanguage.isCeylon()) {
        // (This would be an illegal access to "this before super").
        if (env.info.isSelfCall && (isNewAnonymousClass(env.tree) || isNewLetClass(env.tree))) {
            c.flags_field |= CEYLON_NOOUTERTHIS;
        }
    }
    ClassType ct = (ClassType) c.type;
    // Ceylon: make sure everything is reset if we Enter twice for bootstrap
    ct.interfaces_field = null;
    ct.allparams_field = null;
    ct.supertype_field = null;
    ct.all_interfaces_field = null;
    // End Ceylon
    if (owner.kind != PCK && (c.flags_field & STATIC) == 0) {
        // We are seeing a local or inner class.
        // Set outer_field of this class to closest enclosing class
        // which contains this class in a non-static context
        // (its "enclosing instance class"), provided such a class exists.
        Symbol owner1 = owner;
        // Ceylon: make sure we skip outer classes if required
        boolean skip = c.skipOuterClass();
        while (skip || ((owner1.kind & (VAR | MTH)) != 0 && (owner1.flags_field & STATIC) == 0)) {
            // Ceylon: we only take new outer class skip orders from types, never from methods/vars
            if (owner1.kind == TYP)
                skip = owner1.skipOuterClass();
            owner1 = owner1.owner;
        }
        if (owner1.kind == TYP) {
            ct.setEnclosingType(owner1.type);
        }
    }
    // Enter type parameters.
    ct.typarams_field = classEnter(tree.typarams, localEnv);
    // completed later.
    if (!c.isLocal() && uncompleted != null)
        uncompleted.append(c);
    // System.err.println("entering " + c.fullname + " in " + c.owner);//DEBUG
    // Recursively enter all member classes.
    classEnter(tree.defs, localEnv);
    result = c.type;
}
Also used : Scope(org.eclipse.ceylon.langtools.tools.javac.code.Scope) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol)

Example 2 with Scope

use of org.eclipse.ceylon.langtools.tools.javac.code.Scope in project ceylon by eclipse.

the class Types method firstUnimplementedAbstractImpl.

// where:
private MethodSymbol firstUnimplementedAbstractImpl(ClassSymbol impl, ClassSymbol c) {
    MethodSymbol undef = null;
    // since they cannot have abstract members.
    if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) {
        Scope s = c.members();
        for (Scope.Entry e = s.elems; undef == null && e != null; e = e.sibling) {
            if (e.sym.kind == MTH && (e.sym.flags() & (ABSTRACT | IPROXY | DEFAULT)) == ABSTRACT) {
                MethodSymbol absmeth = (MethodSymbol) e.sym;
                MethodSymbol implmeth = absmeth.implementation(impl, this, true);
                if (implmeth == null || implmeth == absmeth) {
                    // look for default implementations
                    if (allowDefaultMethods) {
                        MethodSymbol prov = interfaceCandidates(impl.type, absmeth).head;
                        if (prov != null && prov.overrides(absmeth, impl, this, true)) {
                            implmeth = prov;
                        }
                    }
                }
                if (implmeth == null || implmeth == absmeth) {
                    undef = absmeth;
                } else if (sourceLanguage.isCeylon())
                    implmeth.flags_field |= CEYLON_METHOD_OVERRIDE_CHECKED;
            }
        }
        if (undef == null) {
            Type st = supertype(c.type);
            if (st.hasTag(CLASS))
                undef = firstUnimplementedAbstractImpl(impl, (ClassSymbol) st.tsym);
        }
        for (List<Type> l = interfaces(c.type); undef == null && l.nonEmpty(); l = l.tail) {
            undef = firstUnimplementedAbstractImpl(impl, (ClassSymbol) l.head.tsym);
        }
    }
    return undef;
}
Also used : Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) Scope(org.eclipse.ceylon.langtools.tools.javac.code.Scope)

Example 3 with Scope

use of org.eclipse.ceylon.langtools.tools.javac.code.Scope in project ceylon by eclipse.

the class Types method makeFunctionalInterfaceClass.

/**
 * Create a symbol for a class that implements a given functional interface
 * and overrides its functional descriptor. This routine is used for two
 * main purposes: (i) checking well-formedness of a functional interface;
 * (ii) perform functional interface bridge calculation.
 */
public ClassSymbol makeFunctionalInterfaceClass(Env<AttrContext> env, Name name, List<Type> targets, long cflags) {
    if (targets.isEmpty()) {
        return null;
    }
    Symbol descSym = findDescriptorSymbol(targets.head.tsym);
    Type descType = findDescriptorType(targets.head);
    ClassSymbol csym = new ClassSymbol(cflags, name, env.enclClass.sym.outermostClass());
    csym.completer = null;
    csym.members_field = new Scope(csym);
    MethodSymbol instDescSym = new MethodSymbol(descSym.flags(), descSym.name, descType, csym);
    csym.members_field.enter(instDescSym);
    Type.ClassType ctype = new Type.ClassType(Type.noType, List.<Type>nil(), csym);
    ctype.supertype_field = syms.objectType;
    ctype.interfaces_field = targets;
    csym.type = ctype;
    csym.sourcefile = ((ClassSymbol) csym.owner).sourcefile;
    return csym;
}
Also used : Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) Scope(org.eclipse.ceylon.langtools.tools.javac.code.Scope) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol)

Example 4 with Scope

use of org.eclipse.ceylon.langtools.tools.javac.code.Scope in project ceylon by eclipse.

the class Enter method visitTopLevel.

@Override
public void visitTopLevel(JCCompilationUnit tree) {
    JavaFileObject prev = log.useSource(tree.sourcefile);
    boolean addEnv = false;
    boolean isPkgInfo = tree.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE);
    if (tree.pid != null) {
        tree.packge = reader.enterPackage(TreeInfo.fullName(tree.pid));
        if (tree.packageAnnotations.nonEmpty() || pkginfoOpt == PkgInfo.ALWAYS) {
            if (isPkgInfo) {
                addEnv = true;
            } else if (tree.packageAnnotations.nonEmpty()) {
                log.error(tree.packageAnnotations.head.pos(), "pkg.annotations.sb.in.package-info.java");
            }
        }
    } else {
        tree.packge = syms.unnamedPackage;
    }
    // Find all classes in package.
    tree.packge.complete();
    Env<AttrContext> topEnv = topLevelEnv(tree);
    // Save environment of package-info.java file.
    if (isPkgInfo) {
        Env<AttrContext> env0 = typeEnvs.get(tree.packge);
        if (env0 == null) {
            typeEnvs.put(tree.packge, topEnv);
        } else {
            JCCompilationUnit tree0 = env0.toplevel;
            if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) {
                log.warning(tree.pid != null ? tree.pid.pos() : null, "pkg-info.already.seen", tree.packge);
                if (addEnv || (tree0.packageAnnotations.isEmpty())) {
                    typeEnvs.put(tree.packge, topEnv);
                }
            }
        }
        for (Symbol q = tree.packge; q != null && q.kind == PCK; q = q.owner) q.flags_field |= EXISTS;
        Name name = names.package_info;
        ClassSymbol c = reader.enterClass(name, tree.packge);
        c.flatname = names.fromString(tree.packge + "." + name);
        c.sourcefile = tree.sourcefile;
        c.completer = null;
        c.members_field = new Scope(c);
        tree.packge.package_info = c;
    }
    classEnter(tree.defs, topEnv);
    if (addEnv) {
        todo.append(topEnv);
    }
    log.useSource(prev);
    result = null;
}
Also used : JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) Scope(org.eclipse.ceylon.langtools.tools.javac.code.Scope) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol)

Example 5 with Scope

use of org.eclipse.ceylon.langtools.tools.javac.code.Scope in project ceylon by eclipse.

the class Types method makeIntersectionType.

/**
 * Make an intersection type from non-empty list of types.  The list should be ordered according to
 * {@link TypeSymbol#precedes(TypeSymbol, Types)}. This does not cause symbol completion as
 * an extra parameter indicates as to whether all bounds are interfaces - in which case the
 * supertype is implicitly assumed to be 'Object'.
 *
 * @param bounds        the types from which the intersection type is formed
 * @param allInterfaces are all bounds interface types?
 */
public IntersectionClassType makeIntersectionType(List<Type> bounds, boolean allInterfaces) {
    Assert.check(bounds.nonEmpty());
    Type firstExplicitBound = bounds.head;
    if (allInterfaces) {
        bounds = bounds.prepend(syms.objectType);
    }
    ClassSymbol bc = new ClassSymbol(ABSTRACT | PUBLIC | SYNTHETIC | COMPOUND | ACYCLIC, Type.moreInfo ? names.fromString(bounds.toString()) : names.empty, null, syms.noSymbol);
    IntersectionClassType intersectionType = new IntersectionClassType(bounds, bc, allInterfaces);
    bc.type = intersectionType;
    bc.erasure_field = (bounds.head.hasTag(TYPEVAR)) ? // error condition, recover
    syms.objectType : erasure(firstExplicitBound);
    bc.members_field = new Scope(bc);
    return intersectionType;
}
Also used : Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) Scope(org.eclipse.ceylon.langtools.tools.javac.code.Scope)

Aggregations

Scope (org.eclipse.ceylon.langtools.tools.javac.code.Scope)5 Symbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol)3 Type (org.eclipse.ceylon.langtools.tools.javac.code.Type)3 JavaFileObject (org.eclipse.ceylon.javax.tools.JavaFileObject)1