1 4 package gnu.expr; 5 import gnu.bytecode.*; 6 import gnu.mapping.*; 7 import gnu.text.SourceLocator; 8 9 36 37 public class Declaration 38 implements SourceLocator 39 { 40 static int counter; 41 43 protected int id = ++counter; 44 45 47 Object symbol; 48 49 public void setCode (int code) 50 { 51 if (code >= 0) throw new Error ("code must be negative"); 52 this.id = code; 53 } 54 55 public int getCode () { return id; } 56 57 public ScopeExp context; 58 59 protected Type type; 60 protected Expression typeExp; 61 public final Expression getTypeExp() { return typeExp; } 62 public final Type getType() { return type; } 63 public final void setType(Type type) 64 { 65 this.type = type; 66 if (var != null) var.setType(type); 67 typeExp = QuoteExp.getInstance(type); 68 } 69 70 public final void setTypeExp (Expression typeExp) 71 { 72 this.typeExp = typeExp; 73 Object typeValue; 74 Type t = (typeExp instanceof QuoteExp 75 && (typeValue = ((QuoteExp) typeExp).getValue()) instanceof Type 76 ? (Type) typeValue 77 : typeExp instanceof TypeValue 78 ? ((TypeValue) typeExp).getImplementationType() 79 : (Type) Type.pointer_type); 80 this.type = t; 81 if (var != null) var.setType(t); 82 } 83 84 public final String getName() 85 { 86 return symbol == null ? null : symbol instanceof Symbol ? ((Symbol) symbol).getName() 87 : symbol.toString(); 88 } 89 public final void setName(Object symbol) 90 { 91 this.symbol = symbol; 92 } 93 94 public final Object getSymbol() { return symbol; } 95 public final void setSymbol(Object symbol) { this.symbol = symbol; } 96 97 98 Declaration next; 99 100 public final Declaration nextDecl() { return next; } 101 public final void setNext(Declaration next) { this.next = next; } 102 103 104 int evalIndex; 105 106 Variable var; 107 public Variable getVariable() { return var; } 108 109 public final boolean isSimple() 110 { return (flags & IS_SIMPLE) != 0; } 111 112 public final void setSimple(boolean b) 113 { 114 setFlag(b, IS_SIMPLE); 115 if (var != null && ! var.isParameter()) var.setSimple(b); 116 } 117 118 public final void setSyntax () 119 { 120 setSimple(false); 121 setFlag(Declaration.IS_CONSTANT | Declaration.IS_SYNTAX); 122 } 123 124 125 public final ScopeExp getContext() { return context; } 126 127 128 Declaration nextCapturedVar; 129 130 132 public Declaration base; 133 134 public Field field; 135 136 137 void loadOwningObject (Declaration owner, Compilation comp) 138 { 139 if (owner == null) 140 owner = base; 141 if (owner != null) 142 owner.load(null, 0, comp, Target.pushObject); 143 else 144 getContext().currentLambda().loadHeapFrame(comp); 145 } 146 147 public void load (AccessExp access, int flags, 148 Compilation comp, Target target) 149 { 150 if (target instanceof IgnoreTarget) 151 return; 152 Declaration owner = access == null ? null : access.contextDecl(); 153 if (isAlias() && value instanceof ReferenceExp) 154 { 155 ReferenceExp rexp = (ReferenceExp) value; 156 Declaration orig = rexp.binding; 157 if (orig != null 158 && ((flags & ReferenceExp.DONT_DEREFERENCE) == 0 159 || orig.isIndirectBinding()) 160 && (owner == null || ! orig.needsContext())) 161 { 162 orig.load(rexp, flags, comp, target); 163 return; 164 } 165 } 166 CodeAttr code = comp.getCode(); 167 Type rtype = getType(); 168 if ((flags & ReferenceExp.CREATE_FIELD_REFERENCE) != 0) 169 { 170 if (field == null) 171 throw new Error ("internal error: cannot take location of "+this); 172 Method meth; 173 ClassType ltype; 174 boolean immediate = comp.immediate; 175 if (field.getStaticFlag()) 176 { 177 ltype = ClassType.make("gnu.kawa.reflect.StaticFieldLocation"); 178 meth = ltype.getDeclaredMethod("make", immediate ? 1 : 2); 179 } 180 else 181 { 182 ltype = ClassType.make("gnu.kawa.reflect.FieldLocation"); 183 meth = ltype.getDeclaredMethod("make", immediate ? 2 : 3); 184 185 loadOwningObject(owner, comp); 186 } 187 if (immediate) 188 comp.compileConstant(this); 189 else 190 { 191 comp.compileConstant(field.getDeclaringClass().getName()); 192 comp.compileConstant(field.getName()); 193 } 194 code.emitInvokeStatic(meth); 195 rtype = ltype; 196 } 197 else 198 { 199 Object val; 200 if (field != null) 201 { 202 comp.usedClass(field.getDeclaringClass()); 203 if (! field.getStaticFlag()) 204 { 205 loadOwningObject(owner, comp); 206 code.emitGetField(field); 207 } 208 else 209 code.emitGetStatic(field); 210 } 211 else if (isIndirectBinding() && comp.immediate && getVariable() == null) 212 { 213 Environment env = Environment.getCurrent(); 215 Symbol sym = symbol instanceof Symbol ? (Symbol) symbol 216 : env.getSymbol(symbol.toString()); 217 Object property = null; 218 if (isProcedureDecl() 219 && comp.getLanguage().hasSeparateFunctionNamespace()) 220 property = EnvironmentKey.FUNCTION; 221 gnu.mapping.Location loc = env.getLocation(sym, property); 222 comp.compileConstant(loc, Target.pushValue(Compilation.typeLocation)); 223 } 224 else if (comp.immediate && (val = getConstantValue()) != null) 225 { 226 comp.compileConstant(val, target); 227 return; 228 } 229 else 230 { 231 Variable var = getVariable(); 232 ClassExp cl; 233 if (context instanceof ClassExp && var == null 234 && ! getFlag(PROCEDURE) 235 && (cl = (ClassExp) context).isMakingClassPair()) 236 { 237 String getName = ClassExp.slotToMethodName("get", getName()); 238 Method getter = cl.type.getDeclaredMethod(getName, 0); 239 cl.loadHeapFrame(comp); 240 code.emitInvoke(getter); 241 } 242 else 243 { 244 if (var == null) 245 var = allocateVariable(code); 246 code.emitLoad(var); 247 } 248 } 249 if (isIndirectBinding() 250 && (flags & ReferenceExp.DONT_DEREFERENCE) == 0) 251 { 252 253 String filename; 254 int line; 255 if (access != null 256 && (filename = access.getFileName()) != null 257 && (line = access.getLineNumber()) > 0) 258 { 259 ClassType typeUnboundLocationException 262 = ClassType.make("gnu.mapping.UnboundLocationException"); 263 boolean isInTry = code.isInTry(); 265 int column = access.getColumnNumber(); 266 Label startTry = new Label(code); 267 startTry.define(code); 268 code.emitInvokeVirtual(Compilation.getLocationMethod); 269 Label endTry = new Label(code); 270 endTry.define(code); 271 Label endLabel = new Label(code); 272 if (isInTry) 273 code.emitGoto(endLabel); 274 int fragment_cookie = 0; 275 if (! isInTry) 276 fragment_cookie 277 = code.beginFragment(new Label(code), endLabel); 278 code.addHandler(startTry, endTry, typeUnboundLocationException); 279 280 code.pushType(typeUnboundLocationException); 281 code.emitDup(typeUnboundLocationException); 282 code.emitPushString(filename); 283 code.emitPushInt(line); 284 code.emitPushInt(column); 285 code.emitInvokeVirtual(typeUnboundLocationException 286 .getDeclaredMethod("setLine", 3)); 287 code.emitThrow(); 288 if (isInTry) 289 endLabel.define(code); 290 else 291 code.endFragment(fragment_cookie); 292 } 293 else 294 code.emitInvokeVirtual(Compilation.getLocationMethod); 295 296 rtype = Type.pointer_type; 297 } 298 } 299 if (target instanceof SeriesTarget 300 && getFlag(Declaration.IS_SINGLE_VALUE)) 301 ((SeriesTarget) target).compileFromStackSimple(comp, rtype); 303 else 304 target.compileFromStack(comp, rtype); 305 } 306 307 309 public void compileStore (Compilation comp) 310 { 311 gnu.bytecode.CodeAttr code = comp.getCode(); 312 if (isSimple ()) 313 code.emitStore(getVariable()); 314 else 315 { 316 if (! field.getStaticFlag()) 317 { 318 loadOwningObject(null, comp); 319 code.emitSwap(); 320 code.emitPutField(field); 321 } 322 else 323 code.emitPutStatic(field); 324 } 325 } 326 327 329 protected Expression value = QuoteExp.undefined_exp; 330 331 342 public final Expression getValue() 343 { 344 if (value == QuoteExp.undefined_exp 345 && field != null 346 && ((field.getModifiers() & Access.STATIC+Access.FINAL) 347 == Access.STATIC+Access.FINAL) 348 && ! isIndirectBinding()) 349 { 350 try 351 { 352 value = new QuoteExp(field.getReflectField().get(null)); 353 } 354 catch (Throwable ex) 355 { 356 } 357 } 358 return value; 359 } 360 361 363 public final void setValue(Expression value) { this.value = value; } 364 365 366 public final Object getConstantValue() 367 { 368 Object v = getValue(); 369 if (! (v instanceof QuoteExp) || v == QuoteExp.undefined_exp) 370 return null; 371 return ((QuoteExp) v).getValue(); 372 } 373 374 375 static final String UNKNOWN_PREFIX = "loc$"; 376 377 379 public static final String PRIVATE_PREFIX = "$Prvt$"; 380 381 390 static final int INDIRECT_BINDING = 1; 391 392 static final int CAN_READ = 2; 393 static final int CAN_CALL = 4; 394 static final int CAN_WRITE = 8; 395 static final int IS_FLUID = 0x10; 396 static final int PRIVATE = 0x20; 397 static final int IS_SIMPLE = 0x40; 398 399 401 static final int PROCEDURE = 0x80; 402 403 public static final int IS_ALIAS = 0x100; 404 405 406 public static final int NOT_DEFINING = 0x200; 407 408 public static final int EXPORT_SPECIFIED = 0x400; 409 public static final int STATIC_SPECIFIED = 0x800; 410 public static final int NONSTATIC_SPECIFIED = 0x1000; 411 public static final int TYPE_SPECIFIED = 0x2000; 412 public static final int IS_CONSTANT = 0x4000; 413 public static final int IS_SYNTAX = 0x8000; 414 public static final int IS_UNKNOWN = 0x10000; 415 public static final int IS_IMPORTED = 0x20000; 416 417 public static final int IS_SINGLE_VALUE = 0x40000; 419 420 423 public static final int EXTERNAL_ACCESS = 0x80000; 424 425 public final boolean needsExternalAccess () 426 { 427 return (flags & EXTERNAL_ACCESS+PRIVATE) == EXTERNAL_ACCESS+PRIVATE 428 || (flags & IS_NAMESPACE_PREFIX+PRIVATE) == IS_NAMESPACE_PREFIX+PRIVATE; 430 } 431 432 433 public final boolean needsContext () 434 { 435 return base == null && field != null && ! field.getStaticFlag(); 436 } 437 438 439 public static final int FIELD_OR_METHOD = 0x100000; 440 441 442 public static final int IS_NAMESPACE_PREFIX = 0x200000; 443 444 public static final int PRIVATE_ACCESS = 0x1000000; 445 public static final int PRIVATE_SPECIFIED = PRIVATE_ACCESS; 446 public static final int PROTECTED_ACCESS = 0x2000000; 447 public static final int PUBLIC_ACCESS = 0x4000000; 448 public static final int PACKAGE_ACCESS = 0x8000000; 449 450 public static final int IS_DYNAMIC = 0x10000000; 451 452 454 public static final int EARLY_INIT = 0x20000000; 455 456 public static final int MODULE_REFERENCE = 0x40000000; 457 458 protected int flags = IS_SIMPLE; 459 460 public final boolean getFlag (int flag) 461 { 462 return (flags & flag) != 0; 463 } 464 465 public final void setFlag (boolean setting, int flag) 466 { 467 if (setting) flags |= flag; 468 else flags &= ~flag; 469 } 470 471 public final void setFlag (int flag) 472 { 473 flags |= flag; 474 } 475 476 public final boolean isPublic() 477 { return context instanceof ModuleExp && (flags & PRIVATE) == 0; } 478 479 public final boolean isPrivate() { return (flags & PRIVATE) != 0; } 480 481 public final void setPrivate(boolean isPrivate) 482 { 483 setFlag(isPrivate, PRIVATE); 484 } 485 486 public short getAccessFlags (short defaultFlags) 487 { 488 if (getFlag(Declaration.PRIVATE_ACCESS)) 489 return Access.PRIVATE; 490 if (getFlag(Declaration.PROTECTED_ACCESS)) 491 return Access.PROTECTED; 492 if (getFlag(Declaration.PACKAGE_ACCESS)) 493 return 0; 494 if (getFlag(Declaration.PUBLIC_ACCESS)) 495 return Access.PUBLIC; 496 return defaultFlags; 497 } 498 499 public final boolean isAlias() { return (flags & IS_ALIAS) != 0; } 500 public final void setAlias(boolean flag) { setFlag(flag, IS_ALIAS); } 501 502 503 public final boolean isFluid () { return (flags & IS_FLUID) != 0; } 504 505 public final void setFluid (boolean fluid) { setFlag(fluid, IS_FLUID); } 506 507 public final boolean isProcedureDecl () { return (flags & PROCEDURE) != 0; } 508 509 public final void setProcedureDecl (boolean val) { setFlag(val, PROCEDURE); } 510 511 public final boolean isNamespaceDecl () 512 { 513 return (flags & IS_NAMESPACE_PREFIX) != 0; 514 } 515 516 518 public final boolean isIndirectBinding() 519 { return (flags & INDIRECT_BINDING) != 0; } 520 521 523 public final void setIndirectBinding(boolean indirectBinding) 524 { 525 setFlag(indirectBinding, INDIRECT_BINDING); 526 } 527 528 529 public final boolean getCanRead() { return (flags & CAN_READ) != 0; } 530 public final void setCanRead(boolean read) 531 { 532 setFlag(read, CAN_READ); 533 } 534 public final void setCanRead() 535 { 536 setFlag(true, CAN_READ); 537 if (base != null) 538 base.setCanRead(); 539 } 540 541 public final boolean getCanCall() { return (flags & CAN_CALL) != 0; } 542 public final void setCanCall(boolean called) { setFlag(called, CAN_CALL); } 543 public final void setCanCall() 544 { 545 setFlag(true, CAN_CALL); 546 if (base != null) 547 base.setCanRead(); 548 } 549 550 public final boolean getCanWrite() 551 { return (flags & CAN_WRITE) != 0; } 552 553 public final void setCanWrite(boolean written) 554 { 555 if (written) flags |= CAN_WRITE; 556 else flags &= ~CAN_WRITE; 557 } 558 559 public final void setCanWrite() 560 { 561 flags |= CAN_WRITE; 562 if (base != null) 563 base.setCanRead(); 564 } 565 566 567 public final boolean isThisParameter () 568 { 569 return symbol == ThisExp.THIS_NAME; 570 } 571 572 573 public boolean ignorable() 575 { 576 if (getCanRead() || isPublic()) 577 return false; 578 if (getCanWrite() && getFlag(IS_UNKNOWN)) 579 return false; 580 if (! getCanCall()) 581 return true; 582 Expression value = getValue(); 583 if (value == null || ! (value instanceof LambdaExp)) 584 return false; 585 LambdaExp lexp = (LambdaExp) value; 586 return ! lexp.isHandlingTailCalls() || lexp.getInlineOnly(); 587 } 588 589 591 public boolean needsInit() 592 { 593 return ! ignorable() 596 && ! (value == QuoteExp.nullExp && base != null); 597 } 598 599 public boolean isStatic() 600 { 601 if (getFlag(STATIC_SPECIFIED)) 602 return true; 603 if (getFlag(NONSTATIC_SPECIFIED)) 604 return false; 605 LambdaExp lambda = context.currentLambda(); 606 return lambda instanceof ModuleExp 607 && ((ModuleExp) lambda).isStatic(); 608 } 609 610 public final boolean isLexical() 611 { 612 return (flags & (IS_FLUID|IS_DYNAMIC|IS_UNKNOWN)) == 0; 613 } 614 615 public static final boolean isUnknown (Declaration decl) 616 { 617 return decl == null || decl.getFlag(IS_UNKNOWN); 618 } 619 620 623 public ApplyExp firstCall; 624 625 public void noteValue (Expression value) 626 { 627 if (this.value == QuoteExp.undefined_exp) 629 { 630 if (value instanceof LambdaExp) 631 ((LambdaExp) value).nameDecl = this; 632 this.value = value; 633 } 634 else if (this.value != value) 635 { 636 if (this.value instanceof LambdaExp) 637 ((LambdaExp) this.value).nameDecl = null; 638 this.value = null; 639 } 640 } 641 642 protected Declaration() 643 { 644 } 645 646 public Declaration (Variable var) 647 { 648 this(var.getName(), var.getType()); 649 this.var = var; 650 } 651 652 public Declaration (Object name) 653 { 654 this(name, Type.pointer_type); 655 } 656 657 public Declaration (Object s, Type type) 658 { 659 setName(s); 660 setType(type); 661 } 662 663 public Declaration (Object name, Field field) 664 { 665 this(name, field.getType()); 666 this.field = field; 667 setSimple(false); 668 } 669 670 Method makeLocationMethod = null; 671 672 675 public void pushIndirectBinding (Compilation comp) 676 { 677 CodeAttr code = comp.getCode(); 678 code.emitPushString(getName()); 679 if (makeLocationMethod == null) 680 { 681 Type[] args = new Type[2]; 682 args[0] = Type.pointer_type; 683 args[1] = Type.string_type; 684 makeLocationMethod 685 = Compilation.typeLocation.addMethod("make", args, 686 Compilation.typeLocation, 687 Access.PUBLIC|Access.STATIC); 688 } 689 code.emitInvokeStatic(makeLocationMethod); 690 } 691 692 public final Variable allocateVariable(CodeAttr code) 693 { 694 if (! isSimple() || var == null) 695 { 696 String vname = null; 697 if (symbol != null) 698 vname = Compilation.mangleNameIfNeeded(getName()); 699 if (isAlias() && getValue() instanceof ReferenceExp) 700 { 701 Declaration base = followAliases(this); 702 var = base == null ? null : base.var; 703 } 704 else 705 { 706 Type type = isIndirectBinding() ? Compilation.typeLocation 707 : getType().getImplementationType(); 708 var = context.getVarScope().addVariable(code, type, vname); 709 } 710 } 711 return var; 712 } 713 714 String filename; 715 int position; 716 717 public final void setLocation (SourceLocator location) 718 { 719 this.filename = location.getFileName(); 720 setLine(location.getLineNumber(), location.getColumnNumber()); 721 } 722 723 public final void setFile (String filename) 724 { 725 this.filename = filename; 726 } 727 728 public final void setLine (int lineno, int colno) 729 { 730 if (lineno < 0) 731 lineno = 0; 732 if (colno < 0) 733 colno = 0; 734 position = (lineno << 12) + colno; 735 } 736 737 public final void setLine (int lineno) 738 { 739 setLine (lineno, 0); 740 } 741 742 public final String getFileName () 743 { 744 return filename; 745 } 746 747 public String getPublicId () 748 { 749 return null; 750 } 751 752 public String getSystemId () 753 { 754 return filename; 755 } 756 757 759 public final int getLineNumber() 760 { 761 int line = position >> 12; 762 return line == 0 ? -1 : line; 763 } 764 765 public final int getColumnNumber() 766 { 767 int column = position & ((1 << 12) - 1); 768 return column == 0 ? -1 : column; 769 } 770 771 public boolean isStableSourceLocation() { return true; } 772 773 public void printInfo(OutPort out) 774 { 775 StringBuffer sbuf = new StringBuffer (); 776 printInfo(sbuf); 777 out.print(sbuf.toString()); 778 } 779 780 public void printInfo(StringBuffer sbuf) 781 { 782 sbuf.append(symbol); 783 sbuf.append('/'); 784 sbuf.append(id); 785 799 sbuf.append("/fl:"); 800 sbuf.append(Integer.toHexString(flags)); 801 Expression tx = typeExp; 802 Type t = getType(); 803 if (tx != null && ! (tx instanceof QuoteExp)) 804 { 805 sbuf.append("::"); 806 sbuf.append(tx); 807 } 808 else if (type != null && t != Type.pointer_type) 809 { 810 sbuf.append("::"); 811 sbuf.append(t.getName()); 812 } 813 } 814 815 816 public String toString() 817 { 818 return "Declaration["+symbol+'/'+id+']'; 819 826 } 827 828 public static Declaration followAliases (Declaration decl) 829 { 830 while (decl != null && decl.isAlias()) 831 { 832 Expression declValue = decl.getValue(); 833 if (! (declValue instanceof ReferenceExp)) 834 break; 835 ReferenceExp rexp = (ReferenceExp) declValue; 836 Declaration orig = rexp.binding; 837 if (orig == null) 838 break; 839 decl = orig; 840 } 841 return decl; 842 } 843 844 public void makeField(Compilation comp, Expression value) 845 { 846 setSimple(false); 847 makeField(comp.mainClass, comp, value); 848 } 849 850 public void makeField(ClassType frameType, Compilation comp, Expression value) 851 { 852 boolean external_access = needsExternalAccess(); 853 int fflags = 0; 854 boolean isConstant = getFlag(IS_CONSTANT); 855 boolean typeSpecified = getFlag(TYPE_SPECIFIED); 856 if (isPublic() && ! isConstant && ! typeSpecified) 857 setIndirectBinding(true); 858 if (isPublic() || external_access) 859 fflags |= Access.PUBLIC; 860 if (isStatic() 861 || (isConstant && value instanceof QuoteExp) 862 || (getFlag(Declaration.IS_UNKNOWN 865 |Declaration.IS_DYNAMIC|Declaration.IS_FLUID) 866 && isIndirectBinding() && ! isAlias()) 867 || (value instanceof ClassExp 868 && ! ((LambdaExp) value).getNeedsClosureEnv())) 869 fflags |= Access.STATIC; 870 if ((isIndirectBinding() || isConstant) 871 && (context instanceof ClassExp || context instanceof ModuleExp)) 872 fflags |= Access.FINAL; 873 Type ftype = getType().getImplementationType(); 874 if (isIndirectBinding() && ! ftype.isSubtype(Compilation.typeLocation)) 875 if (getFlag(EARLY_INIT) && isAlias()) 876 ftype = ClassType.make("gnu.kawa.reflect.FieldLocation"); 877 else 878 ftype = Compilation.typeLocation; 879 String fname = getName(); 880 int nlength; 881 if (fname==null) 882 { 883 fname = "$unnamed$0"; 884 nlength = fname.length() - 2; } 886 else 887 { 888 fname = Compilation.mangleNameIfNeeded(fname); 889 if (getFlag(IS_UNKNOWN)) 890 fname = UNKNOWN_PREFIX + fname; 891 if (external_access && ! getFlag(Declaration.MODULE_REFERENCE)) 892 fname = PRIVATE_PREFIX + fname; 893 nlength = fname.length(); 894 } 895 int counter = 0; 896 while (frameType.getDeclaredField(fname) != null) 897 fname = fname.substring(0, nlength) + '$' + (++ counter); 898 899 field = frameType.addField (fname, ftype, fflags); 900 if (value instanceof QuoteExp) 901 { 902 Object val = ((QuoteExp) value).getValue(); 903 if (val.getClass().getName().equals(ftype.getName())) 904 { 905 Literal literal = comp.litTable.findLiteral(val); 906 if (literal.field == null) 907 literal.assign(field, comp.litTable); 908 } 909 else if (ftype instanceof PrimType 910 || "java.lang.String".equals(ftype.getName())) 911 { 912 if (val instanceof gnu.text.Char) 913 val = gnu.math.IntNum.make(((gnu.text.Char) val).intValue()); 914 field.setConstantValue(val, frameType); 915 return; 916 } 917 } 918 if (! getFlag(EARLY_INIT) 920 && (isIndirectBinding() 921 || (value != null && ! (value instanceof ClassExp)))) 922 { 923 BindingInitializer.create(this, value, comp); 924 } 925 } 926 927 928 gnu.mapping.Location makeIndirectLocationFor () 929 { 930 Symbol sym = symbol instanceof Symbol ? (Symbol) symbol 931 : Namespace.EmptyNamespace.getSymbol(symbol.toString().intern()); 932 return gnu.mapping.Location.make(sym); 933 } 934 935 939 public static Declaration 940 getDeclarationFromStatic (String cname, String fname) 941 { 942 ClassType clas = ClassType.make(cname); 943 Field fld = clas.getDeclaredField(fname); 944 Declaration decl = new Declaration(fname, fld); 945 decl.setFlag(Declaration.IS_CONSTANT|Declaration.STATIC_SPECIFIED); 946 return decl; 947 } 948 949 952 public static Declaration 953 getDeclarationValueFromStatic (String className, 954 String fieldName, String name) 955 { 956 try 957 { 958 Class cls = Class.forName(className); 959 java.lang.reflect.Field fld = cls.getDeclaredField(fieldName); 960 Object value = fld.get(null); 961 962 Declaration decl 963 = new Declaration(name, 964 ClassType.make(className) 965 .getDeclaredField(fieldName)); 966 decl.noteValue(new QuoteExp(value)); 967 decl.setFlag(Declaration.IS_CONSTANT|Declaration.STATIC_SPECIFIED); 968 return decl; 969 } 970 catch (Exception ex) 971 { 972 throw new WrappedException(ex); 973 } 974 } 975 976 public static Declaration getDeclaration(Named proc) 977 { 978 return getDeclaration(proc, proc.getName()); 979 } 980 981 public static Declaration getDeclaration(Object proc, String name) 982 { 983 gnu.bytecode.Field procField = null; 984 if (name != null) 985 { 986 1010 { 1011 Class procClass = PrimProcedure.getProcedureClass(proc); 1012 if (procClass != null) 1013 { 1014 ClassType procType = (ClassType) Type.make(procClass); 1015 String fname = Compilation.mangleNameIfNeeded(name); 1016 procField = procType.getDeclaredField(fname); 1017 } 1018 } 1019 } 1020 if (procField != null) 1021 { 1022 int fflags = procField.getModifiers(); 1023 if ((fflags & Access.STATIC) != 0) 1024 { 1025 Declaration decl = new Declaration(name, procField); 1026 decl.noteValue(new QuoteExp(proc)); 1027 if ((fflags & Access.FINAL) != 0) 1028 decl.setFlag(Declaration.IS_CONSTANT); 1029 return decl; 1030 } 1031 } 1032 return null; 1033 } 1034} 1035 | Popular Tags |