/* * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ package org.visage.tools.comp; import com.sun.tools.mjavac.code.Flags; import com.sun.tools.mjavac.code.Scope; import com.sun.tools.mjavac.code.Symbol; import com.sun.tools.mjavac.code.Symbol.ClassSymbol; import com.sun.tools.mjavac.code.Symbol.PackageSymbol; import com.sun.tools.mjavac.code.Symbol.TypeSymbol; import com.sun.tools.mjavac.code.Type.ClassType; import com.sun.tools.mjavac.code.Type.ErrorType; import com.sun.tools.mjavac.comp.AttrContext; import com.sun.tools.mjavac.comp.Enter; import com.sun.tools.mjavac.comp.Env; import com.sun.tools.mjavac.tree.JCTree; import com.sun.tools.mjavac.tree.JCTree.JCClassDecl; import com.sun.tools.mjavac.util.Context; import com.sun.tools.mjavac.util.List; import org.visage.tools.tree.BlockExprJCBlockExpression; import static com.sun.tools.mjavac.code.Flags.*; import static com.sun.tools.mjavac.code.Kinds.*; public class BlockExprEnter extends Enter { public static Enter instance0(Context context) { Enter instance = context.get(enterKey); if (instance == null) instance = new BlockExprEnter(context); return instance; } public static void preRegister(final Context context) { context.put(enterKey, new Context.Factory<Enter>() { public Enter make() { return new BlockExprEnter(context); } }); } protected BlockExprEnter(Context context) { super(context); } /** Visitor method: Scan a single node. */ public void scan(JCTree tree) { if(tree!=null) tree.accept(this); } /** Visitor method: scan a list of nodes. */ public void scan(List<? extends JCTree> trees) { if (trees != null) for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail) scan(l.head); } // Override this method and disable the enforcing of public class being in file with the same name. @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); // Visage change start // if ((tree.mods.flags & PUBLIC) != 0 && !classNameMatchesFileName(c, env)) { // log.error(tree.pos(), // "class.public.should.be.in.file", tree.name); // } // Visage change end } else { if (tree.name.len != 0 && !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.len != 0) 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 = new ErrorType(tree.name, (TypeSymbol)owner); tree.sym = (ClassSymbol)result.tsym; return; } chk.compiled.put(c.flatname, c); 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; boolean wasStatic = (tree.mods.flags & Flags.STATIC) != 0L; c.flags_field = chk.checkFlags(tree.pos(), (tree.mods.flags & ~(Flags.STATIC)), c, tree); if (wasStatic) { c.flags_field |= Flags.STATIC; } c.sourcefile = env.toplevel.sourcefile; c.members_field = new Scope(c); ClassType ct = (ClassType)c.type; 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; while ((owner1.kind & (VAR | MTH)) != 0 && (owner1.flags_field & STATIC) == 0) { owner1 = owner1.owner; } if (owner1.kind == TYP) { ct.setEnclosingType(owner1.type); } } // Enter type parameters. ct.typarams_field = classEnter(tree.typarams, localEnv); // Add non-local class to uncompleted, to make sure it will be // 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; } public void visitBlockExpression(BlockExprJCBlockExpression that) { scan(that.stats); scan(that.value); } }