Search in sources :

Example 1 with JavaFileObject

use of org.eclipse.ceylon.javax.tools.JavaFileObject in project ceylon by eclipse.

the class CeylonTransformer method transformPackageInfo.

public List<JCCompilationUnit> transformPackageInfo(CeylonCompilationUnit ccu) {
    final CeylonFileObject fo = (CeylonFileObject) ((CeylonPhasedUnit) ccu.phasedUnit).getFileObject();
    ListBuffer<JCCompilationUnit> packageInfos = new ListBuffer<JCCompilationUnit>();
    for (Tree.PackageDescriptor pack : ccu.ceylonTree.getPackageDescriptors()) {
        List<JCAnnotation> packageAnnotations = expressionGen().transformAnnotations(OutputElement.PACKAGE, pack);
        if (packageAnnotations.isEmpty()) {
            continue;
        }
        JCCompilationUnit packageInfo = make().TopLevel(packageAnnotations, naming.makeQuotedFQIdent(pack.getScope().getQualifiedNameString()), List.<JCTree>nil());
        // Enter.visitTopLevel(JCCompilationUnit) uses the tree.sourceFile
        // to decide whether it's seeing a package-info.java
        // So set up a fake one...
        packageInfo.sourcefile = new JavaFileObject() {

            @Override
            public boolean isNameCompatible(String simpleName, Kind kind) {
                return "package-info".equals(simpleName) && JavaFileObject.Kind.SOURCE == kind;
            }

            @Override
            public URI toUri() {
                return fo.toUri();
            }

            @Override
            public String getName() {
                return fo.getName();
            }

            @Override
            public InputStream openInputStream() throws IOException {
                return fo.openInputStream();
            }

            @Override
            public OutputStream openOutputStream() throws IOException {
                return fo.openOutputStream();
            }

            @Override
            public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
                return fo.openReader(ignoreEncodingErrors);
            }

            @Override
            public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
                return fo.getCharContent(ignoreEncodingErrors);
            }

            @Override
            public Writer openWriter() throws IOException {
                return fo.openWriter();
            }

            @Override
            public long getLastModified() {
                return fo.getLastModified();
            }

            @Override
            public boolean delete() {
                return fo.delete();
            }

            @Override
            public Kind getKind() {
                return fo.getKind();
            }

            @Override
            public NestingKind getNestingKind() {
                return fo.getNestingKind();
            }

            @Override
            public Modifier getAccessLevel() {
                return fo.getAccessLevel();
            }
        };
        packageInfos.add(packageInfo);
    }
    return packageInfos.toList();
}
Also used : JCCompilationUnit(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCCompilationUnit) InputStream(java.io.InputStream) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) OutputStream(java.io.OutputStream) Reader(java.io.Reader) IOException(java.io.IOException) URI(java.net.URI) JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) NestingKind(org.eclipse.ceylon.javax.lang.model.element.NestingKind) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) PackageDescriptor(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PackageDescriptor) Modifier(org.eclipse.ceylon.javax.lang.model.element.Modifier) JCAnnotation(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation) Writer(java.io.Writer) NestingKind(org.eclipse.ceylon.javax.lang.model.element.NestingKind)

Example 2 with JavaFileObject

use of org.eclipse.ceylon.javax.tools.JavaFileObject in project ceylon by eclipse.

the class MemberEnter method importNamedStatic.

/**
 * Import statics types of a given name.  Non-types are handled in Attr.
 *  @param pos           Position to be used for error reporting.
 *  @param tsym          The class from which the name is imported.
 *  @param name          The (simple) name being imported.
 *  @param env           The environment containing the named import
 *                  scope to add to.
 */
private void importNamedStatic(final DiagnosticPosition pos, final TypeSymbol tsym, final Name name, final Env<AttrContext> env) {
    if (tsym.kind != TYP) {
        log.error(DiagnosticFlag.RECOVERABLE, pos, "static.imp.only.classes.and.interfaces");
        return;
    }
    final Scope toScope = env.toplevel.namedImportScope;
    final PackageSymbol packge = env.toplevel.packge;
    final TypeSymbol origin = tsym;
    // enter imported types immediately
    new Object() {

        Set<Symbol> processed = new HashSet<Symbol>();

        void importFrom(TypeSymbol tsym) {
            if (tsym == null || !processed.add(tsym))
                return;
            // also import inherited names
            importFrom(types.supertype(tsym.type).tsym);
            for (Type t : types.interfaces(tsym.type)) importFrom(t.tsym);
            for (Scope.Entry e = tsym.members().lookup(name); e.scope != null; e = e.next()) {
                Symbol sym = e.sym;
                if (sym.isStatic() && sym.kind == TYP && staticImportAccessible(sym, packge) && sym.isMemberOf(origin, types) && chk.checkUniqueStaticImport(pos, sym, toScope))
                    toScope.enter(sym, sym.owner.members(), origin.members(), true);
            }
        }
    }.importFrom(tsym);
    // enter non-types before annotations that might use them
    annotate.earlier(new Annotate.Worker() {

        Set<Symbol> processed = new HashSet<Symbol>();

        boolean found = false;

        public String toString() {
            return "import static " + tsym + "." + name;
        }

        void importFrom(TypeSymbol tsym) {
            if (tsym == null || !processed.add(tsym))
                return;
            // also import inherited names
            importFrom(types.supertype(tsym.type).tsym);
            for (Type t : types.interfaces(tsym.type)) importFrom(t.tsym);
            for (Scope.Entry e = tsym.members().lookup(name); e.scope != null; e = e.next()) {
                Symbol sym = e.sym;
                if (sym.isStatic() && staticImportAccessible(sym, packge) && sym.isMemberOf(origin, types)) {
                    found = true;
                    if (sym.kind != TYP) {
                        toScope.enter(sym, sym.owner.members(), origin.members(), true);
                    }
                }
            }
        }

        public void run() {
            JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
            try {
                importFrom(tsym);
                if (!found) {
                    log.error(pos, "cant.resolve.location", KindName.STATIC, name, List.<Type>nil(), List.<Type>nil(), Kinds.typeKindName(tsym.type), tsym.type);
                }
            } finally {
                log.useSource(prev);
            }
        }
    });
}
Also used : Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol) JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) HashSet(java.util.HashSet)

Example 3 with JavaFileObject

use of org.eclipse.ceylon.javax.tools.JavaFileObject in project ceylon by eclipse.

the class MemberEnter method complete.

/* ********************************************************************
 * Source completer
 *********************************************************************/
/**
 * Complete entering a class.
 *  @param sym         The symbol of the class to be completed.
 */
public void complete(Symbol sym) throws CompletionFailure {
    // Suppress some (recursive) MemberEnter invocations
    if (!completionEnabled) {
        // Re-install same completer for next time around and return.
        Assert.check((sym.flags() & Flags.COMPOUND) == 0);
        sym.completer = this;
        return;
    }
    ClassSymbol c = (ClassSymbol) sym;
    ClassType ct = (ClassType) c.type;
    Env<AttrContext> env = typeEnvs.get(c);
    JCClassDecl tree = (JCClassDecl) env.tree;
    boolean wasFirst = isFirst;
    isFirst = false;
    try {
        annotate.enterStart();
        JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
        DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
        try {
            // Save class environment for later member enter (2) processing.
            halfcompleted.append(env);
            // Mark class as not yet attributed.
            c.flags_field |= UNATTRIBUTED;
            // clauses have been seen.
            if (c.owner.kind == PCK) {
                memberEnter(env.toplevel, env.enclosing(TOPLEVEL));
                todo.append(env);
            }
            if (c.owner.kind == TYP)
                c.owner.complete();
            // create an environment for evaluating the base clauses
            Env<AttrContext> baseEnv = baseEnv(tree, env);
            if (tree.extending != null)
                typeAnnotate(tree.extending, baseEnv, sym, tree.pos());
            for (JCExpression impl : tree.implementing) typeAnnotate(impl, baseEnv, sym, tree.pos());
            annotate.flush();
            // Determine supertype.
            Type supertype = (tree.extending != null) ? attr.attribBase(tree.extending, baseEnv, true, false, true) : ((tree.mods.flags & Flags.ENUM) != 0) ? attr.attribBase(enumBase(tree.pos, c), baseEnv, true, false, false) : (c.fullname == names.java_lang_Object) ? Type.noType : syms.objectType;
            ct.supertype_field = modelMissingTypes(supertype, tree.extending, false);
            // Determine interfaces.
            ListBuffer<Type> interfaces = new ListBuffer<Type>();
            // lazy init
            ListBuffer<Type> all_interfaces = null;
            Set<Type> interfaceSet = new HashSet<Type>();
            List<JCExpression> interfaceTrees = tree.implementing;
            for (JCExpression iface : interfaceTrees) {
                Type i = attr.attribBase(iface, baseEnv, false, true, true);
                if (i.hasTag(CLASS)) {
                    interfaces.append(i);
                    if (all_interfaces != null)
                        all_interfaces.append(i);
                    chk.checkNotRepeated(iface.pos(), types.erasure(i), interfaceSet);
                } else {
                    if (all_interfaces == null)
                        all_interfaces = new ListBuffer<Type>().appendList(interfaces);
                    all_interfaces.append(modelMissingTypes(i, iface, true));
                }
            }
            if ((c.flags_field & Flags.ANNOTATION) != 0) {
                ct.interfaces_field = List.of(syms.annotationType);
                ct.all_interfaces_field = ct.interfaces_field;
            } else {
                ct.interfaces_field = interfaces.toList();
                ct.all_interfaces_field = (all_interfaces == null) ? ct.interfaces_field : all_interfaces.toList();
            }
            if (c.fullname == names.java_lang_Object) {
                if (tree.extending != null) {
                    chk.checkNonCyclic(tree.extending.pos(), supertype);
                    ct.supertype_field = Type.noType;
                } else if (tree.implementing.nonEmpty()) {
                    chk.checkNonCyclic(tree.implementing.head.pos(), ct.interfaces_field.head);
                    ct.interfaces_field = List.nil();
                }
            }
            // Annotations.
            // In general, we cannot fully process annotations yet,  but we
            // can attribute the annotation types and then check to see if the
            // @Deprecated annotation is present.
            attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
            if (hasDeprecatedAnnotation(tree.mods.annotations))
                c.flags_field |= DEPRECATED;
            annotateLater(tree.mods.annotations, baseEnv, c, tree.pos());
            // class type parameters use baseEnv but everything uses env
            chk.checkNonCyclicDecl(tree);
            attr.attribTypeVariables(tree.typarams, baseEnv);
            // Do this here, where we have the symbol.
            for (JCTypeParameter tp : tree.typarams) typeAnnotate(tp, baseEnv, sym, tree.pos());
            // Add default constructor if needed.
            if ((c.flags() & INTERFACE) == 0 && !TreeInfo.hasConstructors(tree.defs)) {
                List<Type> argtypes = List.nil();
                List<Type> typarams = List.nil();
                List<Type> thrown = List.nil();
                long ctorFlags = 0;
                boolean based = false;
                boolean addConstructor = true;
                JCNewClass nc = null;
                if (c.name.isEmpty()) {
                    nc = (JCNewClass) env.next.tree;
                    if (nc.constructor != null) {
                        addConstructor = nc.constructor.kind != ERR;
                        Type superConstrType = types.memberType(c.type, nc.constructor);
                        argtypes = superConstrType.getParameterTypes();
                        typarams = superConstrType.getTypeArguments();
                        ctorFlags = nc.constructor.flags() & VARARGS;
                        if (nc.encl != null) {
                            argtypes = argtypes.prepend(nc.encl.type);
                            based = true;
                        }
                        thrown = superConstrType.getThrownTypes();
                    }
                }
                if (addConstructor) {
                    MethodSymbol basedConstructor = nc != null ? (MethodSymbol) nc.constructor : null;
                    JCTree constrDef = DefaultConstructor(make.at(tree.pos), c, basedConstructor, typarams, argtypes, thrown, ctorFlags, based);
                    tree.defs = tree.defs.prepend(constrDef);
                }
            }
            // enter symbols for 'this' into current scope.
            VarSymbol thisSym = new VarSymbol(FINAL | HASINIT, names._this, c.type, c);
            thisSym.pos = Position.FIRSTPOS;
            env.info.scope.enter(thisSym);
            // if this is a class, enter symbol for 'super' into current scope.
            if ((c.flags_field & INTERFACE) == 0 && ct.supertype_field.hasTag(CLASS)) {
                VarSymbol superSym = new VarSymbol(FINAL | HASINIT, names._super, ct.supertype_field, c);
                superSym.pos = Position.FIRSTPOS;
                env.info.scope.enter(superSym);
            }
            // name as a top-level package.
            if (checkClash && c.owner.kind == PCK && c.owner != syms.unnamedPackage && reader.packageExists(c.fullname)) {
                log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), c);
            }
            if (c.owner.kind == PCK && (c.flags_field & PUBLIC) == 0 && !env.toplevel.sourcefile.isNameCompatible(c.name.toString(), JavaFileObject.Kind.SOURCE)) {
                c.flags_field |= AUXILIARY;
            }
        } catch (CompletionFailure ex) {
            chk.completionError(tree.pos(), ex);
        } finally {
            deferredLintHandler.setPos(prevLintPos);
            log.useSource(prev);
        }
        // classes in a second phase.
        if (wasFirst) {
            try {
                while (halfcompleted.nonEmpty()) {
                    Env<AttrContext> toFinish = halfcompleted.next();
                    finish(toFinish);
                    if (allowTypeAnnos) {
                        typeAnnotations.organizeTypeAnnotationsSignatures(toFinish, (JCClassDecl) toFinish.tree);
                        typeAnnotations.validateTypeAnnotationsSignatures(toFinish, (JCClassDecl) toFinish.tree);
                    }
                }
            } finally {
                isFirst = true;
            }
        }
    } finally {
        annotate.enterDone();
    }
}
Also used : JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) DiagnosticPosition(org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticPosition) HashSet(java.util.HashSet)

Example 4 with JavaFileObject

use of org.eclipse.ceylon.javax.tools.JavaFileObject in project ceylon by eclipse.

the class MemberEnter method importStaticAll.

/**
 * Import all static members of a class or package on demand.
 *  @param pos           Position to be used for error reporting.
 *  @param tsym          The class or package the members of which are imported.
 *  @param env           The env in which the imported classes will be entered.
 */
private void importStaticAll(int pos, final TypeSymbol tsym, Env<AttrContext> env) {
    final JavaFileObject sourcefile = env.toplevel.sourcefile;
    final Scope toScope = env.toplevel.starImportScope;
    final PackageSymbol packge = env.toplevel.packge;
    final TypeSymbol origin = tsym;
    // enter imported types immediately
    new Object() {

        Set<Symbol> processed = new HashSet<Symbol>();

        void importFrom(TypeSymbol tsym) {
            if (tsym == null || !processed.add(tsym))
                return;
            // also import inherited names
            importFrom(types.supertype(tsym.type).tsym);
            for (Type t : types.interfaces(tsym.type)) importFrom(t.tsym);
            final Scope fromScope = tsym.members();
            for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
                Symbol sym = e.sym;
                if (sym.kind == TYP && (sym.flags() & STATIC) != 0 && staticImportAccessible(sym, packge) && sym.isMemberOf(origin, types) && !toScope.includes(sym))
                    toScope.enter(sym, fromScope, origin.members(), true);
            }
        }
    }.importFrom(tsym);
    // enter non-types before annotations that might use them
    annotate.earlier(new Annotate.Worker() {

        Set<Symbol> processed = new HashSet<Symbol>();

        public String toString() {
            return "import static " + tsym + ".*" + " in " + sourcefile;
        }

        void importFrom(TypeSymbol tsym) {
            if (tsym == null || !processed.add(tsym))
                return;
            // also import inherited names
            importFrom(types.supertype(tsym.type).tsym);
            for (Type t : types.interfaces(tsym.type)) importFrom(t.tsym);
            final Scope fromScope = tsym.members();
            for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
                Symbol sym = e.sym;
                if (sym.isStatic() && sym.kind != TYP && staticImportAccessible(sym, packge) && !toScope.includes(sym) && sym.isMemberOf(origin, types)) {
                    toScope.enter(sym, fromScope, origin.members(), true);
                }
            }
        }

        public void run() {
            importFrom(tsym);
        }
    });
}
Also used : Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol) JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) HashSet(java.util.HashSet)

Example 5 with JavaFileObject

use of org.eclipse.ceylon.javax.tools.JavaFileObject in project ceylon by eclipse.

the class Todo method addByFile.

private void addByFile(Env<AttrContext> env) {
    JavaFileObject file = env.toplevel.sourcefile;
    if (fileMap == null)
        fileMap = new HashMap<JavaFileObject, FileQueue>();
    FileQueue fq = fileMap.get(file);
    if (fq == null) {
        fq = new FileQueue();
        fileMap.put(file, fq);
        contentsByFile.add(fq);
    }
    fq.fileContents.add(env);
}
Also used : JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) HashMap(java.util.HashMap)

Aggregations

JavaFileObject (org.eclipse.ceylon.javax.tools.JavaFileObject)53 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)9 File (java.io.File)8 IOException (java.io.IOException)8 HashSet (java.util.HashSet)8 CeylonFileObject (org.eclipse.ceylon.compiler.java.codegen.CeylonFileObject)5 TaskEvent (org.eclipse.ceylon.langtools.source.util.TaskEvent)5 Symbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol)5 Type (org.eclipse.ceylon.langtools.tools.javac.code.Type)5 InputStream (java.io.InputStream)4 ListBuffer (org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer)4 LinkedHashSet (java.util.LinkedHashSet)3 VirtualFile (org.eclipse.ceylon.compiler.typechecker.io.VirtualFile)3 JavacFileManager (org.eclipse.ceylon.langtools.tools.javac.file.JavacFileManager)3 JCCompilationUnit (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCCompilationUnit)3 FileInputStream (java.io.FileInputStream)2 OutputStream (java.io.OutputStream)2 PrintWriter (java.io.PrintWriter)2 ByteBuffer (java.nio.ByteBuffer)2 CharBuffer (java.nio.CharBuffer)2