Source Code Cross Referenced for Declaration.java in  » Scripting » Kawa » gnu » expr » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » Kawa » gnu.expr 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        // Copyright (c) 2003  Per M.A. Bothner.
0002:        // This is free software;  for terms and warranty disclaimer see ./COPYING.
0003:
0004:        package gnu.expr;
0005:
0006:        import gnu.bytecode.*;
0007:        import gnu.mapping.*;
0008:        import gnu.text.SourceLocator;
0009:
0010:        /**
0011:         * The static information associated with a local variable binding.
0012:         * @author	Per Bothner
0013:         *
0014:         * These are the kinds of Declaration we use:
0015:         *
0016:         * A local variable that is not captured by an inner lambda is stored
0017:         * in a Java local variables slot (register).  The predicate isSimple ()
0018:         * is true, and offset is the number of the local variable slot.
0019:         *
0020:         * If a local variable is captured by an inner lambda, the
0021:         * variable is stored in a field of the LambdaExp's heapFrame variable.
0022:         * (The latter declaration has isSimple and isArtificial true.)
0023:         * The Declaration's field specifies the Field used.
0024:         *
0025:         * If a function takes a fixed number of parameters, at most four,
0026:         * then the arguments are passed in Java registers 1..4.
0027:         * If a parameter is not captured by an inner lambda, the parameter
0028:         * has the flags isSimple and isParameter true.
0029:         *
0030:         * If a function takes more than 4 or a variable number of parameters,
0031:         * the arguments are passed in an array (using the applyN virtual method).
0032:         * This array is referenced by the argsArray declaration, which has
0033:         * isSimple(), isParameter(), and isArtificial() true, and its offset is 1.
0034:         * The parameters are copied into the program-named variables by the
0035:         * procedure prologue, so the parameters henceforth act like local variables.
0036:         */
0037:
0038:        public class Declaration implements  SourceLocator {
0039:            static int counter;
0040:            /** Unique id number, to ease print-outs and debugging.
0041:             * If negative, a code to specify a builtin function. */
0042:            protected int id = ++counter;
0043:
0044:            /** The name of the new variable, either an interned String or a Symbol.
0045:             * This is the source-level (non-mangled) name. */
0046:            Object symbol;
0047:
0048:            public void setCode(int code) {
0049:                if (code >= 0)
0050:                    throw new Error("code must be negative");
0051:                this .id = code;
0052:            }
0053:
0054:            public int getCode() {
0055:                return id;
0056:            }
0057:
0058:            public ScopeExp context;
0059:
0060:            protected Type type;
0061:            protected Expression typeExp;
0062:
0063:            public final Expression getTypeExp() {
0064:                return typeExp;
0065:            }
0066:
0067:            public final Type getType() {
0068:                return type;
0069:            }
0070:
0071:            public final void setType(Type type) {
0072:                this .type = type;
0073:                if (var != null)
0074:                    var.setType(type);
0075:                typeExp = QuoteExp.getInstance(type);
0076:            }
0077:
0078:            public final void setTypeExp(Expression typeExp) {
0079:                this .typeExp = typeExp;
0080:                Object typeValue;
0081:                Type t = (typeExp instanceof  QuoteExp
0082:                        && (typeValue = ((QuoteExp) typeExp).getValue()) instanceof  Type ? (Type) typeValue
0083:                        : typeExp instanceof  TypeValue ? ((TypeValue) typeExp)
0084:                                .getImplementationType()
0085:                                : (Type) Type.pointer_type);
0086:                this .type = t;
0087:                if (var != null)
0088:                    var.setType(t);
0089:            }
0090:
0091:            public final String getName() {
0092:                return symbol == null ? null
0093:                        : symbol instanceof  Symbol ? ((Symbol) symbol)
0094:                                .getName() : symbol.toString();
0095:            }
0096:
0097:            public final void setName(Object symbol) {
0098:                this .symbol = symbol;
0099:            }
0100:
0101:            public final Object getSymbol() {
0102:                return symbol;
0103:            }
0104:
0105:            public final void setSymbol(Object symbol) {
0106:                this .symbol = symbol;
0107:            }
0108:
0109:            /* Declarations in a ScopeExp are linked together in a linked list. */
0110:            Declaration next;
0111:
0112:            public final Declaration nextDecl() {
0113:                return next;
0114:            }
0115:
0116:            public final void setNext(Declaration next) {
0117:                this .next = next;
0118:            }
0119:
0120:            /** Index in evalFrame for this scope, if interpreting. */
0121:            int evalIndex;
0122:
0123:            Variable var;
0124:
0125:            public Variable getVariable() {
0126:                return var;
0127:            }
0128:
0129:            public final boolean isSimple() {
0130:                return (flags & IS_SIMPLE) != 0;
0131:            }
0132:
0133:            public final void setSimple(boolean b) {
0134:                setFlag(b, IS_SIMPLE);
0135:                if (var != null && !var.isParameter())
0136:                    var.setSimple(b);
0137:            }
0138:
0139:            public final void setSyntax() {
0140:                setSimple(false);
0141:                setFlag(Declaration.IS_CONSTANT | Declaration.IS_SYNTAX);
0142:            }
0143:
0144:            /** Return the ScopeExp that contains (declares) this Declaration. */
0145:            public final ScopeExp getContext() {
0146:                return context;
0147:            }
0148:
0149:            /** Used to link Declarations in a LambdaExp's capturedVars list. */
0150:            Declaration nextCapturedVar;
0151:
0152:            /** If non-null, field is relative to base.
0153:             * If IS_FLUID, base points to IS_UNKNOWN Symbol. */
0154:            public Declaration base;
0155:
0156:            public Field field;
0157:
0158:            /** If this is a field in some object, load a reference to that object. */
0159:            void loadOwningObject(Declaration owner, Compilation comp) {
0160:                if (owner == null)
0161:                    owner = base;
0162:                if (owner != null)
0163:                    owner.load(null, 0, comp, Target.pushObject);
0164:                else
0165:                    getContext().currentLambda().loadHeapFrame(comp);
0166:            }
0167:
0168:            public void load(AccessExp access, int flags, Compilation comp,
0169:                    Target target) {
0170:                if (target instanceof  IgnoreTarget)
0171:                    return;
0172:                Declaration owner = access == null ? null : access
0173:                        .contextDecl();
0174:                if (isAlias() && value instanceof  ReferenceExp) {
0175:                    ReferenceExp rexp = (ReferenceExp) value;
0176:                    Declaration orig = rexp.binding;
0177:                    if (orig != null
0178:                            && ((flags & ReferenceExp.DONT_DEREFERENCE) == 0 || orig
0179:                                    .isIndirectBinding())
0180:                            && (owner == null || !orig.needsContext())) {
0181:                        orig.load(rexp, flags, comp, target);
0182:                        return;
0183:                    }
0184:                }
0185:                CodeAttr code = comp.getCode();
0186:                Type rtype = getType();
0187:                if ((flags & ReferenceExp.CREATE_FIELD_REFERENCE) != 0) {
0188:                    if (field == null)
0189:                        throw new Error(
0190:                                "internal error: cannot take location of "
0191:                                        + this );
0192:                    Method meth;
0193:                    ClassType ltype;
0194:                    boolean immediate = comp.immediate;
0195:                    if (field.getStaticFlag()) {
0196:                        ltype = ClassType
0197:                                .make("gnu.kawa.reflect.StaticFieldLocation");
0198:                        meth = ltype.getDeclaredMethod("make", immediate ? 1
0199:                                : 2);
0200:                    } else {
0201:                        ltype = ClassType
0202:                                .make("gnu.kawa.reflect.FieldLocation");
0203:                        meth = ltype.getDeclaredMethod("make", immediate ? 2
0204:                                : 3);
0205:
0206:                        loadOwningObject(owner, comp);
0207:                    }
0208:                    if (immediate)
0209:                        comp.compileConstant(this );
0210:                    else {
0211:                        comp.compileConstant(field.getDeclaringClass()
0212:                                .getName());
0213:                        comp.compileConstant(field.getName());
0214:                    }
0215:                    code.emitInvokeStatic(meth);
0216:                    rtype = ltype;
0217:                } else {
0218:                    Object val;
0219:                    if (field != null) {
0220:                        comp.usedClass(field.getDeclaringClass());
0221:                        if (!field.getStaticFlag()) {
0222:                            loadOwningObject(owner, comp);
0223:                            code.emitGetField(field);
0224:                        } else
0225:                            code.emitGetStatic(field);
0226:                    } else if (isIndirectBinding() && comp.immediate
0227:                            && getVariable() == null) {
0228:                        // This is a bit of a kludge.  See comment in ModuleExp.evalModule.
0229:                        Environment env = Environment.getCurrent();
0230:                        Symbol sym = symbol instanceof  Symbol ? (Symbol) symbol
0231:                                : env.getSymbol(symbol.toString());
0232:                        Object property = null;
0233:                        if (isProcedureDecl()
0234:                                && comp.getLanguage()
0235:                                        .hasSeparateFunctionNamespace())
0236:                            property = EnvironmentKey.FUNCTION;
0237:                        gnu.mapping.Location loc = env.getLocation(sym,
0238:                                property);
0239:                        comp.compileConstant(loc, Target
0240:                                .pushValue(Compilation.typeLocation));
0241:                    } else if (comp.immediate
0242:                            && (val = getConstantValue()) != null) {
0243:                        comp.compileConstant(val, target);
0244:                        return;
0245:                    } else {
0246:                        Variable var = getVariable();
0247:                        ClassExp cl;
0248:                        if (context instanceof  ClassExp
0249:                                && var == null
0250:                                && !getFlag(PROCEDURE)
0251:                                && (cl = (ClassExp) context)
0252:                                        .isMakingClassPair()) {
0253:                            String getName = ClassExp.slotToMethodName("get",
0254:                                    getName());
0255:                            Method getter = cl.type.getDeclaredMethod(getName,
0256:                                    0);
0257:                            cl.loadHeapFrame(comp);
0258:                            code.emitInvoke(getter);
0259:                        } else {
0260:                            if (var == null)
0261:                                var = allocateVariable(code);
0262:                            code.emitLoad(var);
0263:                        }
0264:                    }
0265:                    if (isIndirectBinding()
0266:                            && (flags & ReferenceExp.DONT_DEREFERENCE) == 0) {
0267:
0268:                        String filename;
0269:                        int line;
0270:                        if (access != null
0271:                                && (filename = access.getFileName()) != null
0272:                                && (line = access.getLineNumber()) > 0) {
0273:                            // Wrap call to Location.get by a catch handler that
0274:                            // calls setLine on the UnboundLocationException.
0275:                            ClassType typeUnboundLocationException = ClassType
0276:                                    .make("gnu.mapping.UnboundLocationException");
0277:                            // See comment in CheckedTarget.emitCheckedCoerce.
0278:                            boolean isInTry = code.isInTry();
0279:                            int column = access.getColumnNumber();
0280:                            Label startTry = new Label(code);
0281:                            startTry.define(code);
0282:                            code
0283:                                    .emitInvokeVirtual(Compilation.getLocationMethod);
0284:                            Label endTry = new Label(code);
0285:                            endTry.define(code);
0286:                            Label endLabel = new Label(code);
0287:                            if (isInTry)
0288:                                code.emitGoto(endLabel);
0289:                            int fragment_cookie = 0;
0290:                            if (!isInTry)
0291:                                fragment_cookie = code.beginFragment(new Label(
0292:                                        code), endLabel);
0293:                            code.addHandler(startTry, endTry,
0294:                                    typeUnboundLocationException);
0295:
0296:                            code.pushType(typeUnboundLocationException);
0297:                            code.emitDup(typeUnboundLocationException);
0298:                            code.emitPushString(filename);
0299:                            code.emitPushInt(line);
0300:                            code.emitPushInt(column);
0301:                            code.emitInvokeVirtual(typeUnboundLocationException
0302:                                    .getDeclaredMethod("setLine", 3));
0303:                            code.emitThrow();
0304:                            if (isInTry)
0305:                                endLabel.define(code);
0306:                            else
0307:                                code.endFragment(fragment_cookie);
0308:                        } else
0309:                            code
0310:                                    .emitInvokeVirtual(Compilation.getLocationMethod);
0311:
0312:                        rtype = Type.pointer_type;
0313:                    }
0314:                }
0315:                if (target instanceof  SeriesTarget
0316:                        && getFlag(Declaration.IS_SINGLE_VALUE))
0317:                    // A kludge until we get a better type system.
0318:                    ((SeriesTarget) target).compileFromStackSimple(comp, rtype);
0319:                else
0320:                    target.compileFromStack(comp, rtype);
0321:            }
0322:
0323:            /* Compile code to store a value (which must already be on the
0324:               stack) into this variable. */
0325:            public void compileStore(Compilation comp) {
0326:                gnu.bytecode.CodeAttr code = comp.getCode();
0327:                if (isSimple())
0328:                    code.emitStore(getVariable());
0329:                else {
0330:                    if (!field.getStaticFlag()) {
0331:                        loadOwningObject(null, comp);
0332:                        code.emitSwap();
0333:                        code.emitPutField(field);
0334:                    } else
0335:                        code.emitPutStatic(field);
0336:                }
0337:            }
0338:
0339:            /** If non-null, the single expression used to set this variable.
0340:             * If the variable can be set more than once, then value is null. */
0341:            protected Expression value = QuoteExp.undefined_exp;
0342:
0343:            /** The value of this <code>Declaration</code>, if known.
0344:             * Usually the expression used to initialize the <code>Declaration</code>,
0345:             * or null if the <code>Declaration</code> can be assigned a different
0346:             * value after initialization.  Note that this is the semantic value: If the
0347:             * <code>INDIRECT_LOCATION</code> is set, then <code>getValue</code> is the
0348:             * value <em>after</em> de-referencing the resulting <code>Location</code>.
0349:             * An exception is if <code>isAlias()</code>; in that case
0350:             * <code>getValue()</code> is an expression yielding a <code>Location</code>
0351:             * which needs to be de-referenced to get this <code>Declaration</code>'s
0352:             * actual value.
0353:             */
0354:            public final Expression getValue() {
0355:                if (value == QuoteExp.undefined_exp
0356:                        && field != null
0357:                        && ((field.getModifiers() & Access.STATIC
0358:                                + Access.FINAL) == Access.STATIC + Access.FINAL)
0359:                        && !isIndirectBinding()) {
0360:                    try {
0361:                        value = new QuoteExp(field.getReflectField().get(null));
0362:                    } catch (Throwable ex) {
0363:                    }
0364:                }
0365:                return value;
0366:            }
0367:
0368:            /** Set the value assoociated with this Declaration.
0369:             * Most code should use noteValue instead. */
0370:            public final void setValue(Expression value) {
0371:                this .value = value;
0372:            }
0373:
0374:            /** If getValue() is a constant, return the constant value, otherwise null. */
0375:            public final Object getConstantValue() {
0376:                Object v = getValue();
0377:                if (!(v instanceof  QuoteExp) || v == QuoteExp.undefined_exp)
0378:                    return null;
0379:                return ((QuoteExp) v).getValue();
0380:            }
0381:
0382:            /** This prefix is prepended to field names for unknown names. */
0383:            static final String UNKNOWN_PREFIX = "loc$";
0384:
0385:            /** This prefix is used in field names for a declaration that has
0386:             * both EXTERNAL_ACCESS and IS_PRIVATE set. */
0387:            public static final String PRIVATE_PREFIX = "$Prvt$";
0388:
0389:            /** If this flag is set then to get the actual value you have to dereference
0390:             * a <code>gnu.mapping.Location</code>.  I.e. this <code>Declaration</code>'s
0391:             * <code>var</code> or <code>field</code> does not contain the
0392:             * <code>Declaration</code>'s value directly, but rather yields a
0393:             * <code>Location</code> that contains the <code>Declaration</code>'s value.
0394:             * Note that this flag indicates the <em>representation</em>:
0395:             * The result of <code>getValue()</code> is not the location, but the 
0396:             * semantic value. after dereferencing.  Likewise <code>getType</code> is
0397:             * the value after de-referencing, not a <code>Location</code> sub-class. */
0398:            static final int INDIRECT_BINDING = 1;
0399:
0400:            static final int CAN_READ = 2;
0401:            static final int CAN_CALL = 4;
0402:            static final int CAN_WRITE = 8;
0403:            static final int IS_FLUID = 0x10;
0404:            static final int PRIVATE = 0x20;
0405:            static final int IS_SIMPLE = 0x40;
0406:
0407:            /** True if in the function namespace, for languages that distinguishes them.
0408:             * I.e. a function definition or macro definition. */
0409:            static final int PROCEDURE = 0x80;
0410:
0411:            public static final int IS_ALIAS = 0x100;
0412:
0413:            /** Set if this is just a declaration, not a definition. */
0414:            public static final int NOT_DEFINING = 0x200;
0415:
0416:            public static final int EXPORT_SPECIFIED = 0x400;
0417:            public static final int STATIC_SPECIFIED = 0x800;
0418:            public static final int NONSTATIC_SPECIFIED = 0x1000;
0419:            public static final int TYPE_SPECIFIED = 0x2000;
0420:            public static final int IS_CONSTANT = 0x4000;
0421:            public static final int IS_SYNTAX = 0x8000;
0422:            public static final int IS_UNKNOWN = 0x10000;
0423:            public static final int IS_IMPORTED = 0x20000;
0424:
0425:            // This should be a type property, not a variable property, at some point!
0426:            public static final int IS_SINGLE_VALUE = 0x40000;
0427:
0428:            /** This flag bit is set if this can be be acceessed from other modules.
0429:             * Ignored unless PRIVATE.
0430:             * Used when an exported macro references a non-exported name. */
0431:            public static final int EXTERNAL_ACCESS = 0x80000;
0432:
0433:            public final boolean needsExternalAccess() {
0434:                return (flags & EXTERNAL_ACCESS + PRIVATE) == EXTERNAL_ACCESS
0435:                        + PRIVATE
0436:                        // Kludge - needed for macros - see Savannah bug #13601.
0437:                        || (flags & IS_NAMESPACE_PREFIX + PRIVATE) == IS_NAMESPACE_PREFIX
0438:                                + PRIVATE;
0439:            }
0440:
0441:            /** If we need a 'context' supplied from a ReferenceExp or 'this. */
0442:            public final boolean needsContext() {
0443:                return base == null && field != null && !field.getStaticFlag();
0444:            }
0445:
0446:            /** True if this is a field or method in a class definition. */
0447:            public static final int FIELD_OR_METHOD = 0x100000;
0448:
0449:            /** Set if this declares a namespace prefix (as in XML namespaces). */
0450:            public static final int IS_NAMESPACE_PREFIX = 0x200000;
0451:
0452:            public static final int PRIVATE_ACCESS = 0x1000000;
0453:            public static final int PRIVATE_SPECIFIED = PRIVATE_ACCESS; /* deprecated*/
0454:            public static final int PROTECTED_ACCESS = 0x2000000;
0455:            public static final int PUBLIC_ACCESS = 0x4000000;
0456:            public static final int PACKAGE_ACCESS = 0x8000000;
0457:
0458:            public static final int IS_DYNAMIC = 0x10000000;
0459:
0460:            /** Initialize in {@code <init>}/{@code <clinit>}
0461:             * rather than in {@code run}/{@code $run$}>. */
0462:            public static final int EARLY_INIT = 0x20000000;
0463:            /** A reference to a module instance. */
0464:            public static final int MODULE_REFERENCE = 0x40000000;
0465:
0466:            protected int flags = IS_SIMPLE;
0467:
0468:            public final boolean getFlag(int flag) {
0469:                return (flags & flag) != 0;
0470:            }
0471:
0472:            public final void setFlag(boolean setting, int flag) {
0473:                if (setting)
0474:                    flags |= flag;
0475:                else
0476:                    flags &= ~flag;
0477:            }
0478:
0479:            public final void setFlag(int flag) {
0480:                flags |= flag;
0481:            }
0482:
0483:            public final boolean isPublic() {
0484:                return context instanceof  ModuleExp && (flags & PRIVATE) == 0;
0485:            }
0486:
0487:            public final boolean isPrivate() {
0488:                return (flags & PRIVATE) != 0;
0489:            }
0490:
0491:            public final void setPrivate(boolean isPrivate) {
0492:                setFlag(isPrivate, PRIVATE);
0493:            }
0494:
0495:            public short getAccessFlags(short defaultFlags) {
0496:                if (getFlag(Declaration.PRIVATE_ACCESS))
0497:                    return Access.PRIVATE;
0498:                if (getFlag(Declaration.PROTECTED_ACCESS))
0499:                    return Access.PROTECTED;
0500:                if (getFlag(Declaration.PACKAGE_ACCESS))
0501:                    return 0;
0502:                if (getFlag(Declaration.PUBLIC_ACCESS))
0503:                    return Access.PUBLIC;
0504:                return defaultFlags;
0505:            }
0506:
0507:            public final boolean isAlias() {
0508:                return (flags & IS_ALIAS) != 0;
0509:            }
0510:
0511:            public final void setAlias(boolean flag) {
0512:                setFlag(flag, IS_ALIAS);
0513:            }
0514:
0515:            /** True if this is a fluid binding (in a FluidLetExp). */
0516:            public final boolean isFluid() {
0517:                return (flags & IS_FLUID) != 0;
0518:            }
0519:
0520:            public final void setFluid(boolean fluid) {
0521:                setFlag(fluid, IS_FLUID);
0522:            }
0523:
0524:            public final boolean isProcedureDecl() {
0525:                return (flags & PROCEDURE) != 0;
0526:            }
0527:
0528:            public final void setProcedureDecl(boolean val) {
0529:                setFlag(val, PROCEDURE);
0530:            }
0531:
0532:            public final boolean isNamespaceDecl() {
0533:                return (flags & IS_NAMESPACE_PREFIX) != 0;
0534:            }
0535:
0536:            /** True if the value of the variable is the contents of a Location.
0537:             * @see #INDIRECT_BINDING */
0538:            public final boolean isIndirectBinding() {
0539:                return (flags & INDIRECT_BINDING) != 0;
0540:            }
0541:
0542:            /** Note that the value of the variable is the contents of a Location.
0543:             * @see #INDIRECT_BINDING */
0544:            public final void setIndirectBinding(boolean indirectBinding) {
0545:                setFlag(indirectBinding, INDIRECT_BINDING);
0546:            }
0547:
0548:            /* Note:  You probably want to use !ignorable(). */
0549:            public final boolean getCanRead() {
0550:                return (flags & CAN_READ) != 0;
0551:            }
0552:
0553:            public final void setCanRead(boolean read) {
0554:                setFlag(read, CAN_READ);
0555:            }
0556:
0557:            public final void setCanRead() {
0558:                setFlag(true, CAN_READ);
0559:                if (base != null)
0560:                    base.setCanRead();
0561:            }
0562:
0563:            public final boolean getCanCall() {
0564:                return (flags & CAN_CALL) != 0;
0565:            }
0566:
0567:            public final void setCanCall(boolean called) {
0568:                setFlag(called, CAN_CALL);
0569:            }
0570:
0571:            public final void setCanCall() {
0572:                setFlag(true, CAN_CALL);
0573:                if (base != null)
0574:                    base.setCanRead();
0575:            }
0576:
0577:            public final boolean getCanWrite() {
0578:                return (flags & CAN_WRITE) != 0;
0579:            }
0580:
0581:            public final void setCanWrite(boolean written) {
0582:                if (written)
0583:                    flags |= CAN_WRITE;
0584:                else
0585:                    flags &= ~CAN_WRITE;
0586:            }
0587:
0588:            public final void setCanWrite() {
0589:                flags |= CAN_WRITE;
0590:                if (base != null)
0591:                    base.setCanRead();
0592:            }
0593:
0594:            /** Is this an implicit 'this' parameter? */
0595:            public final boolean isThisParameter() {
0596:                return symbol == ThisExp.THIS_NAME;
0597:            }
0598:
0599:            /** True if we never need to access this declaration. */
0600:            // rename to isAccessed?
0601:            public boolean ignorable() {
0602:                if (getCanRead() || isPublic())
0603:                    return false;
0604:                if (getCanWrite() && getFlag(IS_UNKNOWN))
0605:                    return false;
0606:                if (!getCanCall())
0607:                    return true;
0608:                Expression value = getValue();
0609:                if (value == null || !(value instanceof  LambdaExp))
0610:                    return false;
0611:                LambdaExp lexp = (LambdaExp) value;
0612:                return !lexp.isHandlingTailCalls() || lexp.getInlineOnly();
0613:            }
0614:
0615:            /** Does this variable need to be initialized or is default ok
0616:             */
0617:            public boolean needsInit() {
0618:                // This is a kludge.  Ideally, we should do some data-flow analysis.
0619:                // But at least it makes sure require'd variables are not initialized.
0620:                return !ignorable()
0621:                        && !(value == QuoteExp.nullExp && base != null);
0622:            }
0623:
0624:            public boolean isStatic() {
0625:                if (getFlag(STATIC_SPECIFIED))
0626:                    return true;
0627:                if (getFlag(NONSTATIC_SPECIFIED))
0628:                    return false;
0629:                LambdaExp lambda = context.currentLambda();
0630:                return lambda instanceof  ModuleExp
0631:                        && ((ModuleExp) lambda).isStatic();
0632:            }
0633:
0634:            public final boolean isLexical() {
0635:                return (flags & (IS_FLUID | IS_DYNAMIC | IS_UNKNOWN)) == 0;
0636:            }
0637:
0638:            public static final boolean isUnknown(Declaration decl) {
0639:                return decl == null || decl.getFlag(IS_UNKNOWN);
0640:            }
0641:
0642:            /** List of ApplyExp where this declaration is the function called.
0643:             * The applications are chained using their nextCall fields.
0644:             * The chain is not built if STATIC_SPECIFIED. */
0645:            public ApplyExp firstCall;
0646:
0647:            public void noteValue(Expression value) {
0648:                // We allow assigning a real value after undefined ...
0649:                if (this .value == QuoteExp.undefined_exp) {
0650:                    if (value instanceof  LambdaExp)
0651:                        ((LambdaExp) value).nameDecl = this ;
0652:                    this .value = value;
0653:                } else if (this .value != value) {
0654:                    if (this .value instanceof  LambdaExp)
0655:                        ((LambdaExp) this .value).nameDecl = null;
0656:                    this .value = null;
0657:                }
0658:            }
0659:
0660:            protected Declaration() {
0661:            }
0662:
0663:            public Declaration(Variable var) {
0664:                this (var.getName(), var.getType());
0665:                this .var = var;
0666:            }
0667:
0668:            public Declaration(Object name) {
0669:                this (name, Type.pointer_type);
0670:            }
0671:
0672:            public Declaration(Object s, Type type) {
0673:                setName(s);
0674:                setType(type);
0675:            }
0676:
0677:            public Declaration(Object name, Field field) {
0678:                this (name, field.getType());
0679:                this .field = field;
0680:                setSimple(false);
0681:            }
0682:
0683:            Method makeLocationMethod = null;
0684:
0685:            /** Create a Location object, given that isIndirectBinding().
0686:                Assume the initial value is already pushed on the stack;
0687:                leaves initialized Location object on stack.  */
0688:            public void pushIndirectBinding(Compilation comp) {
0689:                CodeAttr code = comp.getCode();
0690:                code.emitPushString(getName());
0691:                if (makeLocationMethod == null) {
0692:                    Type[] args = new Type[2];
0693:                    args[0] = Type.pointer_type;
0694:                    args[1] = Type.string_type;
0695:                    makeLocationMethod = Compilation.typeLocation.addMethod(
0696:                            "make", args, Compilation.typeLocation,
0697:                            Access.PUBLIC | Access.STATIC);
0698:                }
0699:                code.emitInvokeStatic(makeLocationMethod);
0700:            }
0701:
0702:            public final Variable allocateVariable(CodeAttr code) {
0703:                if (!isSimple() || var == null) {
0704:                    String vname = null;
0705:                    if (symbol != null)
0706:                        vname = Compilation.mangleNameIfNeeded(getName());
0707:                    if (isAlias() && getValue() instanceof  ReferenceExp) {
0708:                        Declaration base = followAliases(this );
0709:                        var = base == null ? null : base.var;
0710:                    } else {
0711:                        Type type = isIndirectBinding() ? Compilation.typeLocation
0712:                                : getType().getImplementationType();
0713:                        var = context.getVarScope().addVariable(code, type,
0714:                                vname);
0715:                    }
0716:                }
0717:                return var;
0718:            }
0719:
0720:            String filename;
0721:            int position;
0722:
0723:            public final void setLocation(SourceLocator location) {
0724:                this .filename = location.getFileName();
0725:                setLine(location.getLineNumber(), location.getColumnNumber());
0726:            }
0727:
0728:            public final void setFile(String filename) {
0729:                this .filename = filename;
0730:            }
0731:
0732:            public final void setLine(int lineno, int colno) {
0733:                if (lineno < 0)
0734:                    lineno = 0;
0735:                if (colno < 0)
0736:                    colno = 0;
0737:                position = (lineno << 12) + colno;
0738:            }
0739:
0740:            public final void setLine(int lineno) {
0741:                setLine(lineno, 0);
0742:            }
0743:
0744:            public final String getFileName() {
0745:                return filename;
0746:            }
0747:
0748:            public String getPublicId() {
0749:                return null;
0750:            }
0751:
0752:            public String getSystemId() {
0753:                return filename;
0754:            }
0755:
0756:            /** Get the line number of (the start of) this Expression.
0757:             * The "first" line is line 1; unknown is -1. */
0758:            public final int getLineNumber() {
0759:                int line = position >> 12;
0760:                return line == 0 ? -1 : line;
0761:            }
0762:
0763:            public final int getColumnNumber() {
0764:                int column = position & ((1 << 12) - 1);
0765:                return column == 0 ? -1 : column;
0766:            }
0767:
0768:            public boolean isStableSourceLocation() {
0769:                return true;
0770:            }
0771:
0772:            public void printInfo(OutPort out) {
0773:                StringBuffer sbuf = new StringBuffer();
0774:                printInfo(sbuf);
0775:                out.print(sbuf.toString());
0776:            }
0777:
0778:            public void printInfo(StringBuffer sbuf) {
0779:                sbuf.append(symbol);
0780:                sbuf.append('/');
0781:                sbuf.append(id);
0782:                /*
0783:                int line = getLineNumber();
0784:                if (line != 0)
0785:                  {
0786:                sbuf.append("/line:");
0787:                sbuf.append(line);
0788:                int column = getColumnNumber();
0789:                if (column != 0)
0790:                  {
0791:                    sbuf.append(':');
0792:                    sbuf.append(column);
0793:                  }
0794:                  }
0795:                 */
0796:                sbuf.append("/fl:");
0797:                sbuf.append(Integer.toHexString(flags));
0798:                Expression tx = typeExp;
0799:                Type t = getType();
0800:                if (tx != null && !(tx instanceof  QuoteExp)) {
0801:                    sbuf.append("::");
0802:                    sbuf.append(tx);
0803:                } else if (type != null && t != Type.pointer_type) {
0804:                    sbuf.append("::");
0805:                    sbuf.append(t.getName());
0806:                }
0807:            }
0808:
0809:            public String toString() {
0810:                return "Declaration[" + symbol + '/' + id + ']';
0811:                /*
0812:                StringBuffer sbuf = new StringBuffer();
0813:                sbuf.append("Declaration[");
0814:                printInfo(sbuf);
0815:                sbuf.append(']');
0816:                return sbuf.toString();
0817:                 */
0818:            }
0819:
0820:            public static Declaration followAliases(Declaration decl) {
0821:                while (decl != null && decl.isAlias()) {
0822:                    Expression declValue = decl.getValue();
0823:                    if (!(declValue instanceof  ReferenceExp))
0824:                        break;
0825:                    ReferenceExp rexp = (ReferenceExp) declValue;
0826:                    Declaration orig = rexp.binding;
0827:                    if (orig == null)
0828:                        break;
0829:                    decl = orig;
0830:                }
0831:                return decl;
0832:            }
0833:
0834:            public void makeField(Compilation comp, Expression value) {
0835:                setSimple(false);
0836:                makeField(comp.mainClass, comp, value);
0837:            }
0838:
0839:            public void makeField(ClassType frameType, Compilation comp,
0840:                    Expression value) {
0841:                boolean external_access = needsExternalAccess();
0842:                int fflags = 0;
0843:                boolean isConstant = getFlag(IS_CONSTANT);
0844:                boolean typeSpecified = getFlag(TYPE_SPECIFIED);
0845:                if (isPublic() && !isConstant && !typeSpecified)
0846:                    setIndirectBinding(true);
0847:                if (isPublic() || external_access)
0848:                    fflags |= Access.PUBLIC;
0849:                if (isStatic()
0850:                        || (isConstant && value instanceof  QuoteExp)
0851:                        // "Dynamic" variables use ThreadLocation, based on the current
0852:                        // Environment, so we don't need more than one static field.
0853:                        || (getFlag(Declaration.IS_UNKNOWN
0854:                                | Declaration.IS_DYNAMIC | Declaration.IS_FLUID)
0855:                                && isIndirectBinding() && !isAlias())
0856:                        || (value instanceof  ClassExp && !((LambdaExp) value)
0857:                                .getNeedsClosureEnv()))
0858:                    fflags |= Access.STATIC;
0859:                if ((isIndirectBinding() || isConstant)
0860:                        && (context instanceof  ClassExp || context instanceof  ModuleExp))
0861:                    fflags |= Access.FINAL;
0862:                Type ftype = getType().getImplementationType();
0863:                if (isIndirectBinding()
0864:                        && !ftype.isSubtype(Compilation.typeLocation))
0865:                    if (getFlag(EARLY_INIT) && isAlias())
0866:                        ftype = ClassType
0867:                                .make("gnu.kawa.reflect.FieldLocation");
0868:                    else
0869:                        ftype = Compilation.typeLocation;
0870:                String fname = getName();
0871:                int nlength;
0872:                if (fname == null) {
0873:                    fname = "$unnamed$0";
0874:                    nlength = fname.length() - 2; // Without the "$0".
0875:                } else {
0876:                    fname = Compilation.mangleNameIfNeeded(fname);
0877:                    if (getFlag(IS_UNKNOWN))
0878:                        fname = UNKNOWN_PREFIX + fname;
0879:                    if (external_access
0880:                            && !getFlag(Declaration.MODULE_REFERENCE))
0881:                        fname = PRIVATE_PREFIX + fname;
0882:                    nlength = fname.length();
0883:                }
0884:                int counter = 0;
0885:                while (frameType.getDeclaredField(fname) != null)
0886:                    fname = fname.substring(0, nlength) + '$' + (++counter);
0887:
0888:                field = frameType.addField(fname, ftype, fflags);
0889:                if (value instanceof  QuoteExp) {
0890:                    Object val = ((QuoteExp) value).getValue();
0891:                    if (val.getClass().getName().equals(ftype.getName())) {
0892:                        Literal literal = comp.litTable.findLiteral(val);
0893:                        if (literal.field == null)
0894:                            literal.assign(field, comp.litTable);
0895:                    } else if (ftype instanceof  PrimType
0896:                            || "java.lang.String".equals(ftype.getName())) {
0897:                        if (val instanceof  gnu.text.Char)
0898:                            val = gnu.math.IntNum.make(((gnu.text.Char) val)
0899:                                    .intValue());
0900:                        field.setConstantValue(val, frameType);
0901:                        return;
0902:                    }
0903:                }
0904:                // The EARLY_INIT case is handled in SetExp.compile.
0905:                if (!getFlag(EARLY_INIT)
0906:                        && (isIndirectBinding() || (value != null && !(value instanceof  ClassExp)))) {
0907:                    BindingInitializer.create(this , value, comp);
0908:                }
0909:            }
0910:
0911:            /* Used when evaluating for an indirect binding. */
0912:            gnu.mapping.Location makeIndirectLocationFor() {
0913:                Symbol sym = symbol instanceof  Symbol ? (Symbol) symbol
0914:                        : Namespace.EmptyNamespace.getSymbol(symbol.toString()
0915:                                .intern());
0916:                return gnu.mapping.Location.make(sym);
0917:            }
0918:
0919:            /** Create a declaration corresponding to a static field.
0920:             * @param cname name of class containing field
0921:             * @param fname name of static field
0922:             */
0923:            public static Declaration getDeclarationFromStatic(String cname,
0924:                    String fname) {
0925:                ClassType clas = ClassType.make(cname);
0926:                Field fld = clas.getDeclaredField(fname);
0927:                Declaration decl = new Declaration(fname, fld);
0928:                decl.setFlag(Declaration.IS_CONSTANT
0929:                        | Declaration.STATIC_SPECIFIED);
0930:                return decl;
0931:            }
0932:
0933:            /** Similar to {@code getDeclarationFromStatic},
0934:             * but also do {@code noteValue} with the field's value.
0935:             */
0936:            public static Declaration getDeclarationValueFromStatic(
0937:                    String className, String fieldName, String name) {
0938:                try {
0939:                    Class cls = Class.forName(className);
0940:                    java.lang.reflect.Field fld = cls
0941:                            .getDeclaredField(fieldName);
0942:                    Object value = fld.get(null);
0943:
0944:                    Declaration decl = new Declaration(name, ClassType.make(
0945:                            className).getDeclaredField(fieldName));
0946:                    decl.noteValue(new QuoteExp(value));
0947:                    decl.setFlag(Declaration.IS_CONSTANT
0948:                            | Declaration.STATIC_SPECIFIED);
0949:                    return decl;
0950:                } catch (Exception ex) {
0951:                    throw new WrappedException(ex);
0952:                }
0953:            }
0954:
0955:            public static Declaration getDeclaration(Named proc) {
0956:                return getDeclaration(proc, proc.getName());
0957:            }
0958:
0959:            public static Declaration getDeclaration(Object proc, String name) {
0960:                gnu.bytecode.Field procField = null;
0961:                if (name != null) {
0962:                    /*
0963:                    // This is a way to map from the Procedure's name to a Field,
0964:                    // by assuming the name as the form "classname:fieldname".
0965:                    // It may be better to use names of the form "{classname}fieldname".
0966:                    // For now we don't need this feature.
0967:                    int colon = name.indexOf(':');
0968:                    if (colon > 0)
0969:                      {
0970:                        try
0971:                          {
0972:                            ClassType procType
0973:                              = (ClassType) ClassType.make(name.substring(0, colon));
0974:                            name = name.substring(colon+1);
0975:                            String fname = Compilation.mangleNameIfNeeded(name);
0976:                            procField = procType.getDeclaredField(fname);
0977:                          }
0978:                        catch (Throwable ex)
0979:                          {
0980:                            System.err.println("CAUGHT "+ex+" in getDeclaration for "+proc);
0981:                            return null;
0982:                          }
0983:                      }
0984:                    else
0985:                     */
0986:                    {
0987:                        Class procClass = PrimProcedure.getProcedureClass(proc);
0988:                        if (procClass != null) {
0989:                            ClassType procType = (ClassType) Type
0990:                                    .make(procClass);
0991:                            String fname = Compilation.mangleNameIfNeeded(name);
0992:                            procField = procType.getDeclaredField(fname);
0993:                        }
0994:                    }
0995:                }
0996:                if (procField != null) {
0997:                    int fflags = procField.getModifiers();
0998:                    if ((fflags & Access.STATIC) != 0) {
0999:                        Declaration decl = new Declaration(name, procField);
1000:                        decl.noteValue(new QuoteExp(proc));
1001:                        if ((fflags & Access.FINAL) != 0)
1002:                            decl.setFlag(Declaration.IS_CONSTANT);
1003:                        return decl;
1004:                    }
1005:                }
1006:                return null;
1007:            }
1008:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.