Source Code Cross Referenced for SlotGet.java in  » Scripting » Kawa » gnu » kawa » reflect » 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.kawa.reflect 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package gnu.kawa.reflect;
002:
003:        import gnu.mapping.*;
004:        import gnu.expr.*;
005:        import gnu.bytecode.*;
006:        import gnu.lists.FString;
007:        import gnu.kawa.lispexpr.LangPrimType;
008:
009:        public class SlotGet extends Procedure2 implements  HasSetter,
010:                CanInline, Inlineable {
011:            static Class[] noClasses = {};
012:
013:            /** True if this is a "static-field" operation. */
014:            boolean isStatic;
015:
016:            Procedure setter;
017:            public static final SlotGet field = new SlotGet("field", false,
018:                    SlotSet.set$Mnfield$Ex);
019:            public static final SlotGet slotRef = new SlotGet("slot-ref",
020:                    false, SlotSet.set$Mnfield$Ex);
021:            public static final SlotGet staticField = new SlotGet(
022:                    "static-field", true, SlotSet.set$Mnstatic$Mnfield$Ex);
023:
024:            public SlotGet(String name, boolean isStatic) {
025:                super (name);
026:                this .isStatic = isStatic;
027:            }
028:
029:            public SlotGet(String name, boolean isStatic, Procedure setter) {
030:                super (name);
031:                this .isStatic = isStatic;
032:                this .setter = setter;
033:            }
034:
035:            public static Object field(Object obj, String fname) {
036:                return field.apply2(obj, fname);
037:            }
038:
039:            public static Object staticField(Object obj, String fname) {
040:                return staticField.apply2(obj, fname);
041:            }
042:
043:            public Object apply2(Object arg1, Object arg2) {
044:                String name, fname;
045:                String getName = null, isName = null;
046:                if (arg2 instanceof  gnu.bytecode.Field) {
047:                    fname = ((gnu.bytecode.Field) arg2).getName();
048:                    name = Compilation.demangleName(fname, true);
049:                } else if (arg2 instanceof  gnu.bytecode.Method) {
050:                    String mname = ((gnu.bytecode.Method) arg2).getName();
051:                    name = Compilation.demangleName(mname, false);
052:                    if (mname.startsWith("get"))
053:                        getName = mname;
054:                    else if (mname.startsWith("is"))
055:                        isName = mname;
056:                    fname = null;
057:                } else if (!(arg2 instanceof  String)
058:                        && !(arg2 instanceof  FString))
059:                    throw new WrongType(this , 2, arg2, "string");
060:                else {
061:                    name = arg2.toString();
062:                    fname = gnu.expr.Compilation.mangleNameIfNeeded(name);
063:                }
064:                // "intern" fname if it is "class" or "length":
065:                if ("class".equals(fname))
066:                    fname = "class";
067:                else if ("length".equals(fname))
068:                    fname = "length";
069:                return getSlotValue(isStatic, arg1, name, fname, getName,
070:                        isName, Language.getDefaultLanguage());
071:            }
072:
073:            /** The actual gets of finding the field value.
074:             * The compiler emits calls to this method if the field name is literals
075:             * but the actual field is not known at compile time.
076:             * This speeds lookup a bit.
077:             */
078:            public static Object getSlotValue(boolean isStatic, Object obj,
079:                    String name, String fname, String getName, String isName,
080:                    Language language) {
081:                Class clas = isStatic ? coerceToClass(obj) : obj.getClass();
082:                if (fname == "length" && clas.isArray()) {
083:                    int length = java.lang.reflect.Array.getLength(obj);
084:                    return language.coerceToObject(length);
085:                }
086:                if (fname == "class")
087:                    return clas;
088:                boolean illegalAccess = false;
089:                if (fname != null) {
090:                    java.lang.reflect.Field field;
091:                    try {
092:                        field = clas.getField(fname);
093:                    } catch (Exception ex) {
094:                        field = null;
095:                    }
096:                    if (field != null) {
097:                        if (isStatic
098:                                && (field.getModifiers() & java.lang.reflect.Modifier.STATIC) == 0)
099:                            throw new RuntimeException(
100:                                    "cannot access non-static field '" + fname
101:                                            + '\'');
102:                        try {
103:                            return language.coerceToObject(field.getType(),
104:                                    field.get(obj));
105:                        } catch (IllegalAccessException ex) {
106:                            illegalAccess = true;
107:                        } catch (Exception ex) {
108:                            ex.printStackTrace(); // FIXME?
109:                        }
110:                    }
111:                }
112:
113:                // Try looking for a method "getFname" or "isFname" instead:
114:                try {
115:                    String mname = null;
116:                    java.lang.reflect.Method getmethod = null;
117:
118:                    try {
119:                        mname = getName != null ? getName : ClassExp
120:                                .slotToMethodName("get", name);
121:                        getmethod = clas.getMethod(mname, noClasses);
122:                    } catch (Exception getEx) {
123:                        mname = isName != null ? isName : ClassExp
124:                                .slotToMethodName("is", name);
125:                        getmethod = clas.getMethod(mname, noClasses);
126:                    }
127:
128:                    if (isStatic
129:                            && (getmethod.getModifiers() & java.lang.reflect.Modifier.STATIC) == 0)
130:                        throw new RuntimeException(
131:                                "cannot call non-static getter method '"
132:                                        + mname + '\'');
133:                    Object result = getmethod.invoke(obj, Values.noArgs);
134:                    result = language.coerceToObject(getmethod.getReturnType(),
135:                            result);
136:                    return result;
137:                } catch (java.lang.reflect.InvocationTargetException ex) {
138:                    throw WrappedException
139:                            .wrapIfNeeded(ex.getTargetException());
140:                } catch (IllegalAccessException ex) {
141:                    illegalAccess = true;
142:                } catch (java.lang.NoSuchMethodException ex) {
143:                }
144:                if (illegalAccess)
145:                    throw new RuntimeException("illegal access for field "
146:                            + fname);
147:                else
148:                    throw new RuntimeException("no such field " + fname
149:                            + " in " + clas.getName());
150:            }
151:
152:            static Class coerceToClass(Object obj) {
153:                if (obj instanceof  Class)
154:                    return (Class) obj;
155:                if (obj instanceof  gnu.bytecode.Type)
156:                    return ((gnu.bytecode.Type) obj).getReflectClass();
157:                throw new RuntimeException("argument is neither Class nor Type");
158:            }
159:
160:            public void setN(Object[] args) {
161:                int nargs = args.length;
162:                if (nargs != 3)
163:                    throw new WrongArguments(getSetter(), nargs);
164:                set2(args[0], args[1], args[2]);
165:            }
166:
167:            public void set2(Object obj, Object name, Object value) {
168:                SlotSet.apply(isStatic, obj, (String) name, value);
169:            }
170:
171:            /** Get a named property - field or 'get' accessor method.
172:             * @param clas the class type declaring the property.
173:             * @param name the source (unmangled) name of the property.
174:             */
175:            public static Member lookupMember(ClassType clas, String name,
176:                    ClassType caller) {
177:                gnu.bytecode.Field field = clas.getField(Compilation
178:                        .mangleNameIfNeeded(name), -1);
179:                if (field != null) {
180:                    if (caller == null)
181:                        caller = Type.pointer_type;
182:                    if (caller.isAccessible(field.getDeclaringClass(), field
183:                            .getModifiers()))
184:                        return field;
185:                }
186:
187:                // Try looking for a method "getFname" instead:
188:                String getname = ClassExp.slotToMethodName("get", name);
189:                gnu.bytecode.Method method = clas.getMethod(getname,
190:                        Type.typeArray0);
191:                if (method == null)
192:                    return field;
193:                else
194:                    return method;
195:            }
196:
197:            public Expression inline(ApplyExp exp, ExpWalker walker) {
198:                Compilation comp = walker.getCompilation();
199:                Language language = comp.getLanguage();
200:                Type type;
201:                Expression[] args = exp.getArgs();
202:                Expression arg0 = args[0];
203:                Expression arg1 = args[1];
204:                String name = null;
205:                if (arg1 instanceof  QuoteExp) {
206:                    Object val1 = ((QuoteExp) arg1).getValue();
207:                    if (val1 instanceof  String || val1 instanceof  FString
208:                            || val1 instanceof  Symbol)
209:                        name = val1.toString();
210:                }
211:                if (isStatic) {
212:                    type = language.getTypeFor(arg0);
213:                    int known = Invoke.checkKnownClass(type, comp);
214:                    if (known < 0)
215:                        return exp;
216:                    if ("class".equals(name)) {
217:                        if (known > 0)
218:                            return QuoteExp.getInstance(type.getReflectClass());
219:                        Method method = Compilation.typeType.getDeclaredMethod(
220:                                "getReflectClass", 0);
221:                        return new ApplyExp(method, new Expression[] { arg0 });
222:                    }
223:                    if (type != null) {
224:                        Expression[] nargs = new Expression[] {
225:                                new QuoteExp(type), arg1 };
226:                        ApplyExp nexp = new ApplyExp(exp.getFunction(), nargs);
227:                        nexp.setLine(exp);
228:                        exp = nexp;
229:                    }
230:                } else
231:                    type = arg0.getType();
232:                if (type instanceof  ClassType && name != null) {
233:                    ClassType ctype = (ClassType) type;
234:                    ClassType caller = comp.curClass != null ? comp.curClass
235:                            : comp.mainClass;
236:                    Member part = lookupMember(ctype, name, caller);
237:                    if (part instanceof  gnu.bytecode.Field) {
238:                        gnu.bytecode.Field field = (gnu.bytecode.Field) part;
239:                        ctype = field.getDeclaringClass();
240:                        int modifiers = field.getModifiers();
241:                        boolean isStaticField = (modifiers & Access.STATIC) != 0;
242:                        if (isStatic && !isStaticField)
243:                            return new ErrorExp(
244:                                    "cannot access non-static field `" + name
245:                                            + "' using `" + getName() + '\'',
246:                                    comp);
247:                        if (caller != null
248:                                && !caller.isAccessible(ctype, modifiers))
249:                            return new ErrorExp("field " + ctype.getName()
250:                                    + '.' + name + " is not accessible here",
251:                                    comp);
252:                    }
253:
254:                    else if (part instanceof  gnu.bytecode.Method) {
255:                        gnu.bytecode.Method method = (gnu.bytecode.Method) part;
256:                        ctype = method.getDeclaringClass();
257:                        int modifiers = method.getModifiers();
258:                        boolean isStaticMethod = method.getStaticFlag();
259:                        if (isStatic && !isStaticMethod)
260:                            return new ErrorExp(
261:                                    "cannot call non-static getter method `"
262:                                            + name + "' using `" + getName()
263:                                            + '\'', comp);
264:                        if (caller != null
265:                                && !caller.isAccessible(ctype, modifiers))
266:                            return new ErrorExp("method " + method
267:                                    + " is not accessible here", comp);
268:                    }
269:                    if (part != null) {
270:                        Expression[] nargs = new Expression[] { arg0,
271:                                new QuoteExp(part) };
272:                        ApplyExp nexp = new ApplyExp(exp.getFunction(), nargs);
273:                        nexp.setLine(exp);
274:                        return nexp;
275:                    }
276:                    if (type != Type.pointer_type)
277:                        comp.error('e', "no slot `" + name + "' in "
278:                                + ctype.getName());
279:                }
280:                if (name != null && !(type instanceof  ArrayType)) {
281:                    String fname = gnu.expr.Compilation
282:                            .mangleNameIfNeeded(name);
283:                    // So we can quickly check for "class" or "length".
284:                    // The name gets interned anyway when compiled.
285:                    fname = fname.intern();
286:                    String getName = ClassExp.slotToMethodName("get", name);
287:                    String isName = ClassExp.slotToMethodName("is", name);
288:                    ApplyExp nexp = new ApplyExp(
289:                            Invoke.invokeStatic,
290:                            new Expression[] {
291:                                    QuoteExp
292:                                            .getInstance("gnu.kawa.reflect.SlotGet"),
293:                                    QuoteExp.getInstance("getSlotValue"),
294:                                    isStatic ? QuoteExp.trueExp
295:                                            : QuoteExp.falseExp, args[0],
296:                                    QuoteExp.getInstance(name),
297:                                    QuoteExp.getInstance(fname),
298:                                    QuoteExp.getInstance(getName),
299:                                    QuoteExp.getInstance(isName),
300:                                    QuoteExp.getInstance(language) });
301:                    nexp.setLine(exp);
302:                    return ((InlineCalls) walker).walkApplyOnly(nexp);
303:                }
304:                return exp;
305:            }
306:
307:            public void compile(ApplyExp exp, Compilation comp, Target target) {
308:                Expression[] args = exp.getArgs();
309:                Expression arg0 = args[0];
310:                Expression arg1 = args[1];
311:                Language language = comp.getLanguage();
312:                Type type = isStatic ? language.getTypeFor(arg0) : arg0
313:                        .getType();
314:                CodeAttr code = comp.getCode();
315:                if (type instanceof  ClassType && arg1 instanceof  QuoteExp) {
316:                    ClassType ctype = (ClassType) type;
317:                    Object part = ((QuoteExp) arg1).getValue();
318:                    if (part instanceof  gnu.bytecode.Field) {
319:                        gnu.bytecode.Field field = (gnu.bytecode.Field) part;
320:                        int modifiers = field.getModifiers();
321:                        boolean isStaticField = (modifiers & Access.STATIC) != 0;
322:                        args[0].compile(comp, isStaticField ? Target.Ignore
323:                                : Target.pushValue(ctype));
324:                        if (isStaticField) {
325:                            boolean inlined = false;
326:                            /*
327:                            FIXME This isn't quite safe.  We should only "inline"
328:                            the value if the field whose initializer is a constant
329:                            expression (JLS 2nd ed 15.28).  We cannot determine this
330:                            using reflection instead we have to parse the .class file.
331:
332:                            Type ftype = field.getType();
333:                            if ((modifiers & Access.FINAL) != 0
334:                                && ftype instanceof PrimType)
335:                              {
336:                                // We inline int final fields.
337:                                // Other kinds of final fields are less obviously a win.
338:                                char sig = ftype.getSignature().charAt(0);
339:                                if (sig != 'F' && sig != 'D' && sig != 'J')
340:                                  {
341:                                    try
342:                                      {
343:                                        java.lang.reflect.Field rfield
344:                                          = field.getReflectField();
345:                                        int val = rfield.getInt(null);
346:                                        code.emitPushInt(val);
347:                                        inlined = true;
348:                                      }
349:                                    catch (Exception ex)
350:                                      {
351:                                      }
352:                                  }
353:                              }
354:                             */
355:                            if (!inlined)
356:                                code.emitGetStatic(field);
357:                        } else
358:                            code.emitGetField(field);
359:                        Type ftype = field.getType();
360:                        Class fclass = ftype.getReflectClass();
361:                        if (fclass != null)
362:                            ftype = language.getTypeFor(fclass);
363:                        target.compileFromStack(comp, ftype);
364:                        return;
365:                    }
366:                    if (part instanceof  Method) {
367:                        gnu.bytecode.Method method = (gnu.bytecode.Method) part;
368:                        int modifiers = method.getModifiers();
369:                        boolean isStaticMethod = method.getStaticFlag();
370:                        args[0].compile(comp, isStaticMethod ? Target.Ignore
371:                                : Target.pushValue(ctype));
372:                        if (isStaticMethod)
373:                            code.emitInvokeStatic(method);
374:                        else if (ctype.isInterface())
375:                            code.emitInvokeInterface(method);
376:                        else
377:                            code.emitInvokeVirtual(method);
378:                        target.compileFromStack(comp, method.getReturnType());
379:                        return;
380:                    }
381:                }
382:                String name = ClassMethods.checkName(arg1);
383:                if (type instanceof  ArrayType && "length".equals(name)
384:                        && !isStatic) {
385:                    args[0].compile(comp, Target.pushValue(type));
386:                    code.emitArrayLength();
387:                    target.compileFromStack(comp, LangPrimType.intType); // FIXME
388:                    return;
389:                }
390:                ApplyExp.compile(exp, comp, target);
391:            }
392:
393:            public Type getReturnType(Expression[] args) {
394:                int nargs = args.length;
395:                if (nargs == 2) {
396:                    Expression arg0 = args[0];
397:                    Expression arg1 = args[1];
398:                    if (arg1 instanceof  QuoteExp) {
399:                        Object part = ((QuoteExp) arg1).getValue();
400:                        if (part instanceof  gnu.bytecode.Field)
401:                            return ((gnu.bytecode.Field) part).getType();
402:                        if (part instanceof  gnu.bytecode.Method)
403:                            return ((gnu.bytecode.Method) part).getReturnType();
404:                        if (!isStatic
405:                                && arg0.getType() instanceof  ArrayType
406:                                && "length".equals(ClassMethods.checkName(arg1,
407:                                        true)))
408:                            return gnu.kawa.lispexpr.LangPrimType.intType; // FIXME
409:                    }
410:                }
411:                return Type.pointer_type;
412:            }
413:
414:            public Procedure getSetter() {
415:                return setter == null ? super .getSetter() : setter;
416:            }
417:
418:            /**
419:             * Convenience method to make an Expression that gets the value of a field.
420:             * @param value evaluates to object that has the named field
421:             * @param fieldName name of field in value
422:             * @return expression that get the name field from value
423:             */
424:            public static ApplyExp makeGetField(Expression value,
425:                    String fieldName) {
426:                Expression[] args = new Expression[2];
427:                args[0] = value;
428:                args[1] = new QuoteExp(fieldName);
429:                return new ApplyExp(gnu.kawa.reflect.SlotGet.field, args);
430:            }
431:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.