Compare commits
18 Commits
tags/head
...
feature_te
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4deff0f5b3 | ||
|
|
d216922288 | ||
|
|
08f680433c | ||
|
|
89e1e0b369 | ||
|
|
55343a8357 | ||
|
|
7162f44fb0 | ||
|
|
4315b3c594 | ||
|
|
e9a3c94008 | ||
|
|
3f59f5fe78 | ||
|
|
912df7ffb0 | ||
|
|
cebaa144a3 | ||
|
|
4624a1fac1 | ||
|
|
a2f1aa1853 | ||
|
|
58f4e45171 | ||
|
|
6173778ce9 | ||
|
|
745205236a | ||
|
|
5d57d0f9ce | ||
|
|
0ef232e897 |
@@ -1,851 +0,0 @@
|
||||
The majority of Rhino is MPL 1.1 / GPL 2.0 dual licensed:
|
||||
|
||||
The Mozilla Public License (http://www.mozilla.org/MPL/MPL-1.1.txt):
|
||||
============================================================================
|
||||
MOZILLA PUBLIC LICENSE
|
||||
Version 1.1
|
||||
|
||||
---------------
|
||||
|
||||
1. Definitions.
|
||||
|
||||
1.0.1. "Commercial Use" means distribution or otherwise making the
|
||||
Covered Code available to a third party.
|
||||
|
||||
1.1. "Contributor" means each entity that creates or contributes to
|
||||
the creation of Modifications.
|
||||
|
||||
1.2. "Contributor Version" means the combination of the Original
|
||||
Code, prior Modifications used by a Contributor, and the Modifications
|
||||
made by that particular Contributor.
|
||||
|
||||
1.3. "Covered Code" means the Original Code or Modifications or the
|
||||
combination of the Original Code and Modifications, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.4. "Electronic Distribution Mechanism" means a mechanism generally
|
||||
accepted in the software development community for the electronic
|
||||
transfer of data.
|
||||
|
||||
1.5. "Executable" means Covered Code in any form other than Source
|
||||
Code.
|
||||
|
||||
1.6. "Initial Developer" means the individual or entity identified
|
||||
as the Initial Developer in the Source Code notice required by Exhibit
|
||||
A.
|
||||
|
||||
1.7. "Larger Work" means a work which combines Covered Code or
|
||||
portions thereof with code not governed by the terms of this License.
|
||||
|
||||
1.8. "License" means this document.
|
||||
|
||||
1.8.1. "Licensable" means having the right to grant, to the maximum
|
||||
extent possible, whether at the time of the initial grant or
|
||||
subsequently acquired, any and all of the rights conveyed herein.
|
||||
|
||||
1.9. "Modifications" means any addition to or deletion from the
|
||||
substance or structure of either the Original Code or any previous
|
||||
Modifications. When Covered Code is released as a series of files, a
|
||||
Modification is:
|
||||
A. Any addition to or deletion from the contents of a file
|
||||
containing Original Code or previous Modifications.
|
||||
|
||||
B. Any new file that contains any part of the Original Code or
|
||||
previous Modifications.
|
||||
|
||||
1.10. "Original Code" means Source Code of computer software code
|
||||
which is described in the Source Code notice required by Exhibit A as
|
||||
Original Code, and which, at the time of its release under this
|
||||
License is not already Covered Code governed by this License.
|
||||
|
||||
1.10.1. "Patent Claims" means any patent claim(s), now owned or
|
||||
hereafter acquired, including without limitation, method, process,
|
||||
and apparatus claims, in any patent Licensable by grantor.
|
||||
|
||||
1.11. "Source Code" means the preferred form of the Covered Code for
|
||||
making modifications to it, including all modules it contains, plus
|
||||
any associated interface definition files, scripts used to control
|
||||
compilation and installation of an Executable, or source code
|
||||
differential comparisons against either the Original Code or another
|
||||
well known, available Covered Code of the Contributor's choice. The
|
||||
Source Code can be in a compressed or archival form, provided the
|
||||
appropriate decompression or de-archiving software is widely available
|
||||
for no charge.
|
||||
|
||||
1.12. "You" (or "Your") means an individual or a legal entity
|
||||
exercising rights under, and complying with all of the terms of, this
|
||||
License or a future version of this License issued under Section 6.1.
|
||||
For legal entities, "You" includes any entity which controls, is
|
||||
controlled by, or is under common control with You. For purposes of
|
||||
this definition, "control" means (a) the power, direct or indirect,
|
||||
to cause the direction or management of such entity, whether by
|
||||
contract or otherwise, or (b) ownership of more than fifty percent
|
||||
(50%) of the outstanding shares or beneficial ownership of such
|
||||
entity.
|
||||
|
||||
2. Source Code License.
|
||||
|
||||
2.1. The Initial Developer Grant.
|
||||
The Initial Developer hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license, subject to third party intellectual property
|
||||
claims:
|
||||
(a) under intellectual property rights (other than patent or
|
||||
trademark) Licensable by Initial Developer to use, reproduce,
|
||||
modify, display, perform, sublicense and distribute the Original
|
||||
Code (or portions thereof) with or without Modifications, and/or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patents Claims infringed by the making, using or
|
||||
selling of Original Code, to make, have made, use, practice,
|
||||
sell, and offer for sale, and/or otherwise dispose of the
|
||||
Original Code (or portions thereof).
|
||||
|
||||
(c) the licenses granted in this Section 2.1(a) and (b) are
|
||||
effective on the date Initial Developer first distributes
|
||||
Original Code under the terms of this License.
|
||||
|
||||
(d) Notwithstanding Section 2.1(b) above, no patent license is
|
||||
granted: 1) for code that You delete from the Original Code; 2)
|
||||
separate from the Original Code; or 3) for infringements caused
|
||||
by: i) the modification of the Original Code or ii) the
|
||||
combination of the Original Code with other software or devices.
|
||||
|
||||
2.2. Contributor Grant.
|
||||
Subject to third party intellectual property claims, each Contributor
|
||||
hereby grants You a world-wide, royalty-free, non-exclusive license
|
||||
|
||||
(a) under intellectual property rights (other than patent or
|
||||
trademark) Licensable by Contributor, to use, reproduce, modify,
|
||||
display, perform, sublicense and distribute the Modifications
|
||||
created by such Contributor (or portions thereof) either on an
|
||||
unmodified basis, with other Modifications, as Covered Code
|
||||
and/or as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims infringed by the making, using, or
|
||||
selling of Modifications made by that Contributor either alone
|
||||
and/or in combination with its Contributor Version (or portions
|
||||
of such combination), to make, use, sell, offer for sale, have
|
||||
made, and/or otherwise dispose of: 1) Modifications made by that
|
||||
Contributor (or portions thereof); and 2) the combination of
|
||||
Modifications made by that Contributor with its Contributor
|
||||
Version (or portions of such combination).
|
||||
|
||||
(c) the licenses granted in Sections 2.2(a) and 2.2(b) are
|
||||
effective on the date Contributor first makes Commercial Use of
|
||||
the Covered Code.
|
||||
|
||||
(d) Notwithstanding Section 2.2(b) above, no patent license is
|
||||
granted: 1) for any code that Contributor has deleted from the
|
||||
Contributor Version; 2) separate from the Contributor Version;
|
||||
3) for infringements caused by: i) third party modifications of
|
||||
Contributor Version or ii) the combination of Modifications made
|
||||
by that Contributor with other software (except as part of the
|
||||
Contributor Version) or other devices; or 4) under Patent Claims
|
||||
infringed by Covered Code in the absence of Modifications made by
|
||||
that Contributor.
|
||||
|
||||
3. Distribution Obligations.
|
||||
|
||||
3.1. Application of License.
|
||||
The Modifications which You create or to which You contribute are
|
||||
governed by the terms of this License, including without limitation
|
||||
Section 2.2. The Source Code version of Covered Code may be
|
||||
distributed only under the terms of this License or a future version
|
||||
of this License released under Section 6.1, and You must include a
|
||||
copy of this License with every copy of the Source Code You
|
||||
distribute. You may not offer or impose any terms on any Source Code
|
||||
version that alters or restricts the applicable version of this
|
||||
License or the recipients' rights hereunder. However, You may include
|
||||
an additional document offering the additional rights described in
|
||||
Section 3.5.
|
||||
|
||||
3.2. Availability of Source Code.
|
||||
Any Modification which You create or to which You contribute must be
|
||||
made available in Source Code form under the terms of this License
|
||||
either on the same media as an Executable version or via an accepted
|
||||
Electronic Distribution Mechanism to anyone to whom you made an
|
||||
Executable version available; and if made available via Electronic
|
||||
Distribution Mechanism, must remain available for at least twelve (12)
|
||||
months after the date it initially became available, or at least six
|
||||
(6) months after a subsequent version of that particular Modification
|
||||
has been made available to such recipients. You are responsible for
|
||||
ensuring that the Source Code version remains available even if the
|
||||
Electronic Distribution Mechanism is maintained by a third party.
|
||||
|
||||
3.3. Description of Modifications.
|
||||
You must cause all Covered Code to which You contribute to contain a
|
||||
file documenting the changes You made to create that Covered Code and
|
||||
the date of any change. You must include a prominent statement that
|
||||
the Modification is derived, directly or indirectly, from Original
|
||||
Code provided by the Initial Developer and including the name of the
|
||||
Initial Developer in (a) the Source Code, and (b) in any notice in an
|
||||
Executable version or related documentation in which You describe the
|
||||
origin or ownership of the Covered Code.
|
||||
|
||||
3.4. Intellectual Property Matters
|
||||
(a) Third Party Claims.
|
||||
If Contributor has knowledge that a license under a third party's
|
||||
intellectual property rights is required to exercise the rights
|
||||
granted by such Contributor under Sections 2.1 or 2.2,
|
||||
Contributor must include a text file with the Source Code
|
||||
distribution titled "LEGAL" which describes the claim and the
|
||||
party making the claim in sufficient detail that a recipient will
|
||||
know whom to contact. If Contributor obtains such knowledge after
|
||||
the Modification is made available as described in Section 3.2,
|
||||
Contributor shall promptly modify the LEGAL file in all copies
|
||||
Contributor makes available thereafter and shall take other steps
|
||||
(such as notifying appropriate mailing lists or newsgroups)
|
||||
reasonably calculated to inform those who received the Covered
|
||||
Code that new knowledge has been obtained.
|
||||
|
||||
(b) Contributor APIs.
|
||||
If Contributor's Modifications include an application programming
|
||||
interface and Contributor has knowledge of patent licenses which
|
||||
are reasonably necessary to implement that API, Contributor must
|
||||
also include this information in the LEGAL file.
|
||||
|
||||
(c) Representations.
|
||||
Contributor represents that, except as disclosed pursuant to
|
||||
Section 3.4(a) above, Contributor believes that Contributor's
|
||||
Modifications are Contributor's original creation(s) and/or
|
||||
Contributor has sufficient rights to grant the rights conveyed by
|
||||
this License.
|
||||
|
||||
3.5. Required Notices.
|
||||
You must duplicate the notice in Exhibit A in each file of the Source
|
||||
Code. If it is not possible to put such notice in a particular Source
|
||||
Code file due to its structure, then You must include such notice in a
|
||||
location (such as a relevant directory) where a user would be likely
|
||||
to look for such a notice. If You created one or more Modification(s)
|
||||
You may add your name as a Contributor to the notice described in
|
||||
Exhibit A. You must also duplicate this License in any documentation
|
||||
for the Source Code where You describe recipients' rights or ownership
|
||||
rights relating to Covered Code. You may choose to offer, and to
|
||||
charge a fee for, warranty, support, indemnity or liability
|
||||
obligations to one or more recipients of Covered Code. However, You
|
||||
may do so only on Your own behalf, and not on behalf of the Initial
|
||||
Developer or any Contributor. You must make it absolutely clear than
|
||||
any such warranty, support, indemnity or liability obligation is
|
||||
offered by You alone, and You hereby agree to indemnify the Initial
|
||||
Developer and every Contributor for any liability incurred by the
|
||||
Initial Developer or such Contributor as a result of warranty,
|
||||
support, indemnity or liability terms You offer.
|
||||
|
||||
3.6. Distribution of Executable Versions.
|
||||
You may distribute Covered Code in Executable form only if the
|
||||
requirements of Section 3.1-3.5 have been met for that Covered Code,
|
||||
and if You include a notice stating that the Source Code version of
|
||||
the Covered Code is available under the terms of this License,
|
||||
including a description of how and where You have fulfilled the
|
||||
obligations of Section 3.2. The notice must be conspicuously included
|
||||
in any notice in an Executable version, related documentation or
|
||||
collateral in which You describe recipients' rights relating to the
|
||||
Covered Code. You may distribute the Executable version of Covered
|
||||
Code or ownership rights under a license of Your choice, which may
|
||||
contain terms different from this License, provided that You are in
|
||||
compliance with the terms of this License and that the license for the
|
||||
Executable version does not attempt to limit or alter the recipient's
|
||||
rights in the Source Code version from the rights set forth in this
|
||||
License. If You distribute the Executable version under a different
|
||||
license You must make it absolutely clear that any terms which differ
|
||||
from this License are offered by You alone, not by the Initial
|
||||
Developer or any Contributor. You hereby agree to indemnify the
|
||||
Initial Developer and every Contributor for any liability incurred by
|
||||
the Initial Developer or such Contributor as a result of any such
|
||||
terms You offer.
|
||||
|
||||
3.7. Larger Works.
|
||||
You may create a Larger Work by combining Covered Code with other code
|
||||
not governed by the terms of this License and distribute the Larger
|
||||
Work as a single product. In such a case, You must make sure the
|
||||
requirements of this License are fulfilled for the Covered Code.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation.
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Code due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description
|
||||
must be included in the LEGAL file described in Section 3.4 and must
|
||||
be included with all distributions of the Source Code. Except to the
|
||||
extent prohibited by statute or regulation, such description must be
|
||||
sufficiently detailed for a recipient of ordinary skill to be able to
|
||||
understand it.
|
||||
|
||||
5. Application of this License.
|
||||
|
||||
This License applies to code to which the Initial Developer has
|
||||
attached the notice in Exhibit A and to related Covered Code.
|
||||
|
||||
6. Versions of the License.
|
||||
|
||||
6.1. New Versions.
|
||||
Netscape Communications Corporation ("Netscape") may publish revised
|
||||
and/or new versions of the License from time to time. Each version
|
||||
will be given a distinguishing version number.
|
||||
|
||||
6.2. Effect of New Versions.
|
||||
Once Covered Code has been published under a particular version of the
|
||||
License, You may always continue to use it under the terms of that
|
||||
version. You may also choose to use such Covered Code under the terms
|
||||
of any subsequent version of the License published by Netscape. No one
|
||||
other than Netscape has the right to modify the terms applicable to
|
||||
Covered Code created under this License.
|
||||
|
||||
6.3. Derivative Works.
|
||||
If You create or use a modified version of this License (which you may
|
||||
only do in order to apply it to code which is not already Covered Code
|
||||
governed by this License), You must (a) rename Your license so that
|
||||
the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
|
||||
"MPL", "NPL" or any confusingly similar phrase do not appear in your
|
||||
license (except to note that your license differs from this License)
|
||||
and (b) otherwise make it clear that Your version of the license
|
||||
contains terms which differ from the Mozilla Public License and
|
||||
Netscape Public License. (Filling in the name of the Initial
|
||||
Developer, Original Code or Contributor in the notice described in
|
||||
Exhibit A shall not of themselves be deemed to be modifications of
|
||||
this License.)
|
||||
|
||||
7. DISCLAIMER OF WARRANTY.
|
||||
|
||||
COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
|
||||
WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
|
||||
DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
|
||||
THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
|
||||
IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
|
||||
YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
|
||||
COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
|
||||
OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
|
||||
ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
|
||||
|
||||
8. TERMINATION.
|
||||
|
||||
8.1. This License and the rights granted hereunder will terminate
|
||||
automatically if You fail to comply with terms herein and fail to cure
|
||||
such breach within 30 days of becoming aware of the breach. All
|
||||
sublicenses to the Covered Code which are properly granted shall
|
||||
survive any termination of this License. Provisions which, by their
|
||||
nature, must remain in effect beyond the termination of this License
|
||||
shall survive.
|
||||
|
||||
8.2. If You initiate litigation by asserting a patent infringement
|
||||
claim (excluding declatory judgment actions) against Initial Developer
|
||||
or a Contributor (the Initial Developer or Contributor against whom
|
||||
You file such action is referred to as "Participant") alleging that:
|
||||
|
||||
(a) such Participant's Contributor Version directly or indirectly
|
||||
infringes any patent, then any and all rights granted by such
|
||||
Participant to You under Sections 2.1 and/or 2.2 of this License
|
||||
shall, upon 60 days notice from Participant terminate prospectively,
|
||||
unless if within 60 days after receipt of notice You either: (i)
|
||||
agree in writing to pay Participant a mutually agreeable reasonable
|
||||
royalty for Your past and future use of Modifications made by such
|
||||
Participant, or (ii) withdraw Your litigation claim with respect to
|
||||
the Contributor Version against such Participant. If within 60 days
|
||||
of notice, a reasonable royalty and payment arrangement are not
|
||||
mutually agreed upon in writing by the parties or the litigation claim
|
||||
is not withdrawn, the rights granted by Participant to You under
|
||||
Sections 2.1 and/or 2.2 automatically terminate at the expiration of
|
||||
the 60 day notice period specified above.
|
||||
|
||||
(b) any software, hardware, or device, other than such Participant's
|
||||
Contributor Version, directly or indirectly infringes any patent, then
|
||||
any rights granted to You by such Participant under Sections 2.1(b)
|
||||
and 2.2(b) are revoked effective as of the date You first made, used,
|
||||
sold, distributed, or had made, Modifications made by that
|
||||
Participant.
|
||||
|
||||
8.3. If You assert a patent infringement claim against Participant
|
||||
alleging that such Participant's Contributor Version directly or
|
||||
indirectly infringes any patent where such claim is resolved (such as
|
||||
by license or settlement) prior to the initiation of patent
|
||||
infringement litigation, then the reasonable value of the licenses
|
||||
granted by such Participant under Sections 2.1 or 2.2 shall be taken
|
||||
into account in determining the amount or value of any payment or
|
||||
license.
|
||||
|
||||
8.4. In the event of termination under Sections 8.1 or 8.2 above,
|
||||
all end user license agreements (excluding distributors and resellers)
|
||||
which have been validly granted by You or any distributor hereunder
|
||||
prior to termination shall survive termination.
|
||||
|
||||
9. LIMITATION OF LIABILITY.
|
||||
|
||||
UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
|
||||
(INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
|
||||
DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
|
||||
OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
|
||||
ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
|
||||
CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
|
||||
WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
|
||||
COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
|
||||
INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
|
||||
LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
|
||||
RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
|
||||
PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
|
||||
EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
|
||||
THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
|
||||
|
||||
10. U.S. GOVERNMENT END USERS.
|
||||
|
||||
The Covered Code is a "commercial item," as that term is defined in
|
||||
48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
|
||||
software" and "commercial computer software documentation," as such
|
||||
terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
|
||||
C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
|
||||
all U.S. Government End Users acquire Covered Code with only those
|
||||
rights set forth herein.
|
||||
|
||||
11. MISCELLANEOUS.
|
||||
|
||||
This License represents the complete agreement concerning subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. This License shall be governed by
|
||||
California law provisions (except to the extent applicable law, if
|
||||
any, provides otherwise), excluding its conflict-of-law provisions.
|
||||
With respect to disputes in which at least one party is a citizen of,
|
||||
or an entity chartered or registered to do business in the United
|
||||
States of America, any litigation relating to this License shall be
|
||||
subject to the jurisdiction of the Federal Courts of the Northern
|
||||
District of California, with venue lying in Santa Clara County,
|
||||
California, with the losing party responsible for costs, including
|
||||
without limitation, court costs and reasonable attorneys' fees and
|
||||
expenses. The application of the United Nations Convention on
|
||||
Contracts for the International Sale of Goods is expressly excluded.
|
||||
Any law or regulation which provides that the language of a contract
|
||||
shall be construed against the drafter shall not apply to this
|
||||
License.
|
||||
|
||||
12. RESPONSIBILITY FOR CLAIMS.
|
||||
|
||||
As between Initial Developer and the Contributors, each party is
|
||||
responsible for claims and damages arising, directly or indirectly,
|
||||
out of its utilization of rights under this License and You agree to
|
||||
work with Initial Developer and Contributors to distribute such
|
||||
responsibility on an equitable basis. Nothing herein is intended or
|
||||
shall be deemed to constitute any admission of liability.
|
||||
|
||||
13. MULTIPLE-LICENSED CODE.
|
||||
|
||||
Initial Developer may designate portions of the Covered Code as
|
||||
"Multiple-Licensed". "Multiple-Licensed" means that the Initial
|
||||
Developer permits you to utilize portions of the Covered Code under
|
||||
Your choice of the NPL or the alternative licenses, if any, specified
|
||||
by the Initial Developer in the file described in Exhibit A.
|
||||
|
||||
EXHIBIT A -Mozilla Public License.
|
||||
|
||||
``The contents of this file are subject to the Mozilla Public License
|
||||
Version 1.1 (the "License"); you may not use this file except in
|
||||
compliance with the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS"
|
||||
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing rights and limitations
|
||||
under the License.
|
||||
|
||||
The Original Code is ______________________________________.
|
||||
|
||||
The Initial Developer of the Original Code is ________________________.
|
||||
Portions created by ______________________ are Copyright (C) ______
|
||||
_______________________. All Rights Reserved.
|
||||
|
||||
Contributor(s): ______________________________________.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms
|
||||
of the _____ license (the "[___] License"), in which case the
|
||||
provisions of [______] License are applicable instead of those
|
||||
above. If you wish to allow use of your version of this file only
|
||||
under the terms of the [____] License and not to allow others to use
|
||||
your version of this file under the MPL, indicate your decision by
|
||||
deleting the provisions above and replace them with the notice and
|
||||
other provisions required by the [___] License. If you do not delete
|
||||
the provisions above, a recipient may use your version of this file
|
||||
under either the MPL or the [___] License."
|
||||
|
||||
[NOTE: The text of this Exhibit A may differ slightly from the text of
|
||||
the notices in the Source Code files of the Original Code. You should
|
||||
use the text of this Exhibit A rather than the text found in the
|
||||
Original Code Source Code for Your Modifications.]
|
||||
============================================================================
|
||||
|
||||
============================================================================
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
============================================================================
|
||||
|
||||
Additionally, some files (currently the contents of
|
||||
toolsrc/org/mozilla/javascript/tools/debugger/treetable/) are available
|
||||
only under the following license:
|
||||
|
||||
============================================================================
|
||||
* Copyright 1997, 1998 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Sun Microsystems nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
============================================================================
|
||||
@@ -1,48 +0,0 @@
|
||||
<html>
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License Version
|
||||
- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
- the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is Rhino code, released
|
||||
- May 6, 1999.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Netscape Communications Corporation.
|
||||
- Portions created by the Initial Developer are Copyright (C) 1998-1999
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Norris Boyd
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
- case the provisions of the GPL are applicable instead of those above. If
|
||||
- you wish to allow use of your version of this file only under the terms of
|
||||
- the GPL and not to allow others to use your version of this file under the
|
||||
- MPL, indicate your decision by deleting the provisions above and replacing
|
||||
- them with the notice and other provisions required by the GPL. If you do
|
||||
- not delete the provisions above, a recipient may use your version of this
|
||||
- file under either the MPL or the GPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
<body>
|
||||
<h1>
|
||||
<span CLASS=LXRSHORTDESC>
|
||||
Rhino: JavaScript in Java<p>
|
||||
</span>
|
||||
</h1>
|
||||
<span CLASS=LXRLONGDESC>
|
||||
Rhino is an implementation of JavaScript in Java. Documentation can be found
|
||||
<a href="http://www.mozilla.org/rhino/index.html">here</a>.
|
||||
</span>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,66 +0,0 @@
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Rhino code, released May 6, 1999.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
# case the provisions of the GPL are applicable instead of those above. If
|
||||
# you wish to allow use of your version of this file only under the terms of
|
||||
# the GPL and not to allow others to use your version of this file under the
|
||||
# MPL, indicate your decision by deleting the provisions above and replacing
|
||||
# them with the notice and other provisions required by the GPL. If you do
|
||||
# not delete the provisions above, a recipient may use your version of this
|
||||
# file under either the MPL or the GPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
apiClasses=\
|
||||
src/org/mozilla/javascript/Callable.java,\
|
||||
src/org/mozilla/javascript/ClassCache.java,\
|
||||
src/org/mozilla/javascript/ClassShutter.java,\
|
||||
src/org/mozilla/javascript/CompilerEnvirons.java,\
|
||||
src/org/mozilla/javascript/ContinuationPending.java,\
|
||||
src/org/mozilla/javascript/Context.java,\
|
||||
src/org/mozilla/javascript/ContextAction.java,\
|
||||
src/org/mozilla/javascript/ContextFactory.java,\
|
||||
src/org/mozilla/javascript/GeneratedClassLoader.java,\
|
||||
src/org/mozilla/javascript/EcmaError.java,\
|
||||
src/org/mozilla/javascript/ErrorReporter.java,\
|
||||
src/org/mozilla/javascript/EvaluatorException.java,\
|
||||
src/org/mozilla/javascript/Function.java,\
|
||||
src/org/mozilla/javascript/FunctionObject.java,\
|
||||
src/org/mozilla/javascript/GeneratedClassLoader.java,\
|
||||
src/org/mozilla/javascript/ImporterTopLevel.java,\
|
||||
src/org/mozilla/javascript/JavaScriptException.java,\
|
||||
src/org/mozilla/javascript/RefCallable.java,\
|
||||
src/org/mozilla/javascript/RhinoException.java,\
|
||||
src/org/mozilla/javascript/Script.java,\
|
||||
src/org/mozilla/javascript/Scriptable.java,\
|
||||
src/org/mozilla/javascript/ScriptableObject.java,\
|
||||
src/org/mozilla/javascript/SecurityController.java,\
|
||||
src/org/mozilla/javascript/WrapFactory.java,\
|
||||
src/org/mozilla/javascript/WrappedException.java,\
|
||||
src/org/mozilla/javascript/Wrapper.java,\
|
||||
src/org/mozilla/javascript/Synchronizer.java,\
|
||||
src/org/mozilla/javascript/optimizer/ClassCompiler.java,\
|
||||
src/org/mozilla/javascript/debug/DebuggableScript.java,\
|
||||
src/org/mozilla/javascript/serialize/ScriptableInputStream.java,\
|
||||
src/org/mozilla/javascript/serialize/ScriptableOutputStream.java
|
||||
@@ -1 +0,0 @@
|
||||
This version was built on @datestamp@.
|
||||
@@ -1,65 +0,0 @@
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Rhino code, released
|
||||
# May 6, 1999.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Igor Bukanov
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
# case the provisions of the GPL are applicable instead of those above. If
|
||||
# you wish to allow use of your version of this file only under the terms of
|
||||
# the GPL and not to allow others to use your version of this file under the
|
||||
# MPL, indicate your decision by deleting the provisions above and replacing
|
||||
# them with the notice and other provisions required by the GPL. If you do
|
||||
# not delete the provisions above, a recipient may use your version of this
|
||||
# file under either the MPL or the GPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
name: rhino
|
||||
Name: Rhino
|
||||
version: 1_7R3pre
|
||||
# See Context#getImplementationVersion() for format of this!
|
||||
implementation.version: Rhino 1.7 release 3 PRERELEASE ${implementation.date}
|
||||
|
||||
build.dir: build
|
||||
rhino.jar: js.jar
|
||||
small-rhino.jar: smalljs.jar
|
||||
rhino-14.jar: js-14.jar
|
||||
small-rhino-14.jar: smalljs-14.jar
|
||||
dist.name: rhino${version}
|
||||
dist.dir: ${build.dir}/${dist.name}
|
||||
|
||||
# compilation destionation
|
||||
classes: ${build.dir}/classes
|
||||
|
||||
# compilation settings
|
||||
debug: on
|
||||
target-jvm: 1.5
|
||||
source-level: 1.5
|
||||
|
||||
# jar generation settings
|
||||
jar-compression: true
|
||||
|
||||
# optional external packages
|
||||
xmlbeans: .
|
||||
xbean.jar: ${xmlbeans}/lib/xbean.jar
|
||||
jsr173.jar: ${xmlbeans}/lib/jsr173_1.0_api.jar
|
||||
@@ -1,343 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License Version
|
||||
- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
- the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is Rhino code, released May 6, 1999.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Netscape Communications Corporation.
|
||||
- Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
- case the provisions of the GPL are applicable instead of those above. If
|
||||
- you wish to allow use of your version of this file only under the terms of
|
||||
- the GPL and not to allow others to use your version of this file under the
|
||||
- MPL, indicate your decision by deleting the provisions above and replacing
|
||||
- them with the notice and other provisions required by the GPL. If you do
|
||||
- not delete the provisions above, a recipient may use your version of this
|
||||
- file under either the MPL or the GPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
|
||||
|
||||
<!--
|
||||
Build file for Rhino using Ant (see http://jakarta.apache.org/ant/index.html)
|
||||
Requires Ant version 1.2 or later
|
||||
|
||||
Compilation currently requires JDK 1.5 or later. Can cross-compile to
|
||||
support JDK 1.4.
|
||||
-->
|
||||
|
||||
<project name="Rhino" default="help" basedir=".">
|
||||
|
||||
<target name="properties">
|
||||
<!-- Allow user to override default settings from build.properties -->
|
||||
<property file="build.local.properties" />
|
||||
<tstamp>
|
||||
<!-- Specify date part of Context#getImplementationVersion() -->
|
||||
<format property="implementation.date" pattern="yyyy MM dd"/>
|
||||
</tstamp>
|
||||
<property file="build.properties"/>
|
||||
|
||||
<property name="dist.file" value="rhino${version}.zip"/>
|
||||
<property name="dist.source-only-zip" value="rhino${version}-sources.zip"/>
|
||||
|
||||
<property file="apiClasses.properties"/>
|
||||
<property name="xmlimplsrc-build-file"
|
||||
location="xmlimplsrc/build.xml"/>
|
||||
|
||||
<available property="xmlimplsrc-present?"
|
||||
file="${xmlimplsrc-build-file}" />
|
||||
|
||||
</target>
|
||||
|
||||
<target name="init" depends="properties">
|
||||
<mkdir dir="${build.dir}"/>
|
||||
<mkdir dir="${classes}"/>
|
||||
<mkdir dir="${dist.dir}"/>
|
||||
</target>
|
||||
|
||||
<target name="compile" depends="init">
|
||||
<ant antfile="src/build.xml" target="compile"/>
|
||||
<ant antfile="toolsrc/build.xml" target="compile"/>
|
||||
<antcall target="xmlimplsrc-compile" />
|
||||
</target>
|
||||
|
||||
<target name="compile-all" depends="compile">
|
||||
<ant antfile="deprecatedsrc/build.xml" target="compile"/>
|
||||
</target>
|
||||
|
||||
<target name="graph" depends="init">
|
||||
<ant antfile="src/build.xml" target="graph"/>
|
||||
</target>
|
||||
|
||||
<target name="shell" depends="compile">
|
||||
<ant antfile="src/build.xml" target="shell"/>
|
||||
</target>
|
||||
|
||||
<target name="copy-source" depends="init">
|
||||
<ant antfile="src/build.xml" target="copy-source"/>
|
||||
<ant antfile="toolsrc/build.xml" target="copy-source"/>
|
||||
<ant antfile="testsrc/build.xml" target="copy-source"/>
|
||||
<antcall target="xmlimplsrc-copy-source" />
|
||||
<ant antfile="deprecatedsrc/build.xml" target="copy-source"/>
|
||||
<copy todir="${dist.dir}" file="build.xml"/>
|
||||
<copy todir="${dist.dir}" file="build.properties"/>
|
||||
<copy todir="${dist.dir}" file="apiClasses.properties"/>
|
||||
<copy todir="${dist.dir}" file="LICENSE.txt"/>
|
||||
</target>
|
||||
|
||||
<target name="xmlimplsrc-compile" if="xmlimplsrc-present?">
|
||||
<echo>Calling ${xmlimplsrc-build-file}</echo>
|
||||
<!-- Ignore compilation errors under JDK less then 1.4 -->
|
||||
<property name="xmlimpl.compile.failonerror" value="no"/>
|
||||
<ant antfile="${xmlimplsrc-build-file}" target="compile"/>
|
||||
</target>
|
||||
|
||||
<target name="xmlimplsrc-copy-source" if="xmlimplsrc-present?">
|
||||
<echo>Calling ${xmlimplsrc-build-file}</echo>
|
||||
<ant antfile="${xmlimplsrc-build-file}" target="copy-source"/>
|
||||
</target>
|
||||
|
||||
<target name="jar" depends="compile-all">
|
||||
<property name="jarfile" location="${dist.dir}/${rhino.jar}"/>
|
||||
<jar jarfile="${jarfile}"
|
||||
basedir="${classes}"
|
||||
manifest="src/manifest"
|
||||
compress="${jar-compression}"
|
||||
/>
|
||||
</target>
|
||||
|
||||
<target name="console" depends="jar">
|
||||
<property name="jarfile" location="${dist.dir}/${rhino.jar}"/>
|
||||
<java jar="${jarfile}"
|
||||
fork="true">
|
||||
<arg line="-version 170"/>
|
||||
</java>
|
||||
</target>
|
||||
|
||||
<target name="retrotranslator" depends="retrotranslator-check,retrotranslator-download">
|
||||
<taskdef name="retrotranslator" classpath="build/download/Retrotranslator-1.2.3-bin/retrotranslator-transformer-1.2.3.jar"
|
||||
classname="net.sf.retrotranslator.transformer.RetrotranslatorTask"/>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="retrotranslator-check">
|
||||
<condition property="retrotranslator.available">
|
||||
<and>
|
||||
<available file="build/download/Retrotranslator-1.2.3-bin/retrotranslator-transformer-1.2.3.jar"/>
|
||||
<available file="build/download/Retrotranslator-1.2.3-bin/retrotranslator-runtime-1.2.3.jar"/>
|
||||
<available file="build/download/Retrotranslator-1.2.3-bin/backport-util-concurrent-3.1.jar"/>
|
||||
</and>
|
||||
</condition>
|
||||
</target>
|
||||
|
||||
<target name="retrotranslator-download" unless="retrotranslator.available">
|
||||
<mkdir dir="build/download"/>
|
||||
<get src="http://downloads.sourceforge.net/retrotranslator/Retrotranslator-1.2.3-bin.zip" dest="build/download/Retrotranslator-1.2.3-bin.zip" usetimestamp="true"/>
|
||||
<unzip src="build/download/Retrotranslator-1.2.3-bin.zip" dest="build/download"/>
|
||||
</target>
|
||||
|
||||
<target name="retrojar" depends="jar,retrotranslator">
|
||||
<retrotranslator
|
||||
srcjar="${jarfile}"
|
||||
destjar="${dist.dir}/${rhino-14.jar}"
|
||||
embed="org.mozilla.javascript"
|
||||
/>
|
||||
</target>
|
||||
|
||||
<target name="smalljar" depends="compile">
|
||||
<property name="smalljarfile" location="${dist.dir}/${small-rhino.jar}"/>
|
||||
<jar basedir="${classes}" destfile="${smalljarfile}"
|
||||
compress="${jar-compression}">
|
||||
<include name="org/mozilla/javascript/*.class"/>
|
||||
|
||||
<include name="org/mozilla/javascript/debug/*.class"/>
|
||||
<include name="org/mozilla/javascript/resources/*.properties"/>
|
||||
<include name="org/mozilla/javascript/xml/*.class"/>
|
||||
<include name="org/mozilla/javascript/continuations/*.class"/>
|
||||
<include name="org/mozilla/javascript/jdk13/*.class"/>
|
||||
|
||||
<!-- exclude classes that defines only int constants -->
|
||||
<exclude name="org/mozilla/javascript/Token.class"/>
|
||||
|
||||
<!-- exclude classes that uses class generation library -->
|
||||
<exclude name="org/mozilla/javascript/JavaAdapter*.class"/>
|
||||
|
||||
<include name="org/mozilla/javascript/regexp/*.class"
|
||||
unless="no-regexp"/>
|
||||
</jar>
|
||||
|
||||
</target>
|
||||
|
||||
<target name="retrosmalljar" depends="smalljar,retrotranslator">
|
||||
<retrotranslator
|
||||
srcjar="${smalljarfile}"
|
||||
destjar="${dist.dir}/${small-rhino-14.jar}"
|
||||
embed="org.mozilla.javascript"
|
||||
/>
|
||||
</target>
|
||||
|
||||
<target name="copy-examples" depends="init">
|
||||
<mkdir dir="${dist.dir}/examples"/>
|
||||
<copy todir="${dist.dir}/examples">
|
||||
<fileset dir="examples" includes="**/*.java,**/*.js,**/*.html" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="copy-misc" depends="init">
|
||||
<filter token="datestamp" value="${TODAY}"/>
|
||||
<copy todir="${dist.dir}" filtering="yes">
|
||||
<fileset dir=".">
|
||||
<patternset>
|
||||
<include name="build-date"/>
|
||||
</patternset>
|
||||
</fileset>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="copy-all" depends="copy-source,copy-examples,copy-misc">
|
||||
</target>
|
||||
|
||||
<target name="javadoc" depends="init">
|
||||
<mkdir dir="${dist.dir}/javadoc"/>
|
||||
<javadoc sourcefiles="${apiClasses}"
|
||||
sourcepath="src"
|
||||
destdir="${dist.dir}/javadoc"
|
||||
version="true"
|
||||
author="true"
|
||||
windowtitle="${Name}" />
|
||||
</target>
|
||||
|
||||
<target name="dev-javadoc" depends="init">
|
||||
<mkdir dir="${dist.dir}/javadoc"/>
|
||||
<javadoc sourcepath="src"
|
||||
destdir="${dist.dir}/javadoc"
|
||||
version="true"
|
||||
package="true"
|
||||
author="true"
|
||||
windowtitle="${Name}">
|
||||
<fileset
|
||||
dir="."
|
||||
includes="**/*.java"
|
||||
excludes="**/deprecatedsrc/**/*.java"
|
||||
/>
|
||||
</javadoc>
|
||||
</target>
|
||||
|
||||
<target name="dist" depends="deepclean,jar,retrojar,copy-all,javadoc">
|
||||
<delete file="${dist.file}" />
|
||||
<zip destfile="${dist.file}">
|
||||
<fileset dir="${build.dir}" includes="${dist.name}/**"/>
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
<target name="source-zip" depends="copy-source,copy-examples,javadoc">
|
||||
<delete file="${dist.source-only-zip}" />
|
||||
<zip destfile="${dist.source-only-zip}">
|
||||
<zipfileset prefix="${dist.name}" dir="${dist.dir}">
|
||||
<include name="*src/**"/>
|
||||
<include name="build.xml"/>
|
||||
<include name="*.properties"/>
|
||||
<include name="examples/**"/>
|
||||
</zipfileset>
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
<target name="compile-debugger">
|
||||
<ant antfile="toolsrc/build.xml" target="compile-debugger"/>
|
||||
</target>
|
||||
|
||||
<target name="clean" depends="properties">
|
||||
<delete quiet="true" file="${dist.dir}/${rhino.jar}"/>
|
||||
<delete quiet="true" file="${dist.dir}/${small-rhino.jar}"/>
|
||||
<delete quiet="true" dir="${build.dir}"/>
|
||||
</target>
|
||||
|
||||
<target name="deepclean" depends="properties">
|
||||
<delete quiet="true" dir="${build.dir}"/>
|
||||
<delete quiet="true" file="${dist.file}"/>
|
||||
<delete quiet="true" file="${dist.source-only-zip}"/>
|
||||
</target>
|
||||
|
||||
<!--
|
||||
The next two targets run the JavaScript Test Library tests. Note that these tests are quite extensive and take a long time
|
||||
to run. They are not documented in the 'help' target for now.
|
||||
-->
|
||||
|
||||
<!--
|
||||
Run the tests using JUnit. Beware that if you are using Ant from the command-line, there are some difficulties you may
|
||||
encounter setting this up correctly; see http://ant.apache.org/faq.html#delegating-classloader
|
||||
|
||||
IDEs that use Ant as the build system probably handle this fine.
|
||||
-->
|
||||
<target name="junit-all" depends="compile">
|
||||
<ant antfile="testsrc/build.xml" target="junit-coveragereport"/>
|
||||
</target>
|
||||
|
||||
<!--
|
||||
Run the tests using the Java port of jsdriver.pl. Note that running this port
|
||||
from the command-line may be more useful running this Ant target, as running
|
||||
from the command line allows configuration options, such as running with a
|
||||
non-default optimization level, or running only a subset of the tests.
|
||||
-->
|
||||
<target name="jsdriver-run" depends="compile">
|
||||
<ant antfile="testsrc/build.xml" target="jsdriver" />
|
||||
</target>
|
||||
|
||||
<!--
|
||||
Compile the JsDriver test driver.
|
||||
-->
|
||||
<target name="jsdriver" depends="compile">
|
||||
<ant antfile="testsrc/build.xml" target="clean" />
|
||||
<ant antfile="testsrc/build.xml" target="compile" />
|
||||
</target>
|
||||
|
||||
<target name="help" depends="properties">
|
||||
<echo>The following targets are available with this build file:
|
||||
|
||||
clean remove all compiled classes and copied property files
|
||||
|
||||
compile compile classes and copy all property files
|
||||
into ${classes} directory
|
||||
excluding deprecated code
|
||||
|
||||
compile-all compile all classes and copy all property files
|
||||
into ${classes} directory
|
||||
including deprecated code
|
||||
|
||||
deepclean remove all generated files and directories
|
||||
|
||||
dist create ${dist.file} with full Rhino distribution
|
||||
|
||||
help print this help
|
||||
|
||||
jar create ${rhino.jar} in ${dist.dir}
|
||||
|
||||
smalljar create ${small-rhino.jar} in ${dist.dir} with
|
||||
minimalist set of Rhino classes. See footprint.html
|
||||
from the doc directory for details.
|
||||
|
||||
javadoc generate Rhino API documentation
|
||||
in ${dist.dir}/javadoc
|
||||
|
||||
source-zip create ${dist.source-only-zip} with all Rhino
|
||||
source files necessary to recreate ${dist.file}
|
||||
</echo>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
@@ -1,61 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License Version
|
||||
- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
- the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is Rhino code, released May 6, 1999.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Netscape Communications Corporation.
|
||||
- Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
- case the provisions of the GPL are applicable instead of those above. If
|
||||
- you wish to allow use of your version of this file only under the terms of
|
||||
- the GPL and not to allow others to use your version of this file under the
|
||||
- MPL, indicate your decision by deleting the provisions above and replacing
|
||||
- them with the notice and other provisions required by the GPL. If you do
|
||||
- not delete the provisions above, a recipient may use your version of this
|
||||
- file under either the MPL or the GPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
|
||||
|
||||
<project name="src" default="compile" basedir="..">
|
||||
|
||||
<property file="build.properties"/>
|
||||
|
||||
<target name="compile">
|
||||
<javac srcdir="deprecatedsrc"
|
||||
destdir="${classes}"
|
||||
includes="org/mozilla/javascript/*.java"
|
||||
deprecation="on"
|
||||
debug="${debug}"
|
||||
target="${target-jvm}"
|
||||
source="${source-level}"
|
||||
>
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<target name="copy-source">
|
||||
<mkdir dir="${dist.dir}/deprecatedsrc"/>
|
||||
<copy todir="${dist.dir}/deprecatedsrc">
|
||||
<fileset dir="deprecatedsrc"
|
||||
includes="**/*.java,**/*.properties,**/*.xml,manifest"/>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
@@ -1,53 +0,0 @@
|
||||
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
// API class
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* @deprecated The exception is no longer thrown by Rhino runtime as
|
||||
* {@link EvaluatorException} is used instead.
|
||||
*/
|
||||
public class ClassDefinitionException extends RuntimeException
|
||||
{
|
||||
static final long serialVersionUID = -5637830967241712746L;
|
||||
|
||||
public ClassDefinitionException(String detail) {
|
||||
super(detail);
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
// API class
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* @deprecated The exception is no longer thrown by Rhino runtime as
|
||||
* {@link EvaluatorException} is used instead.
|
||||
*/
|
||||
public class NotAFunctionException extends RuntimeException
|
||||
{
|
||||
static final long serialVersionUID = 6461524852170711724L;
|
||||
|
||||
public NotAFunctionException() { }
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// API class
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* @deprecated This exception is no longer thrown by Rhino runtime.
|
||||
*/
|
||||
public class PropertyException extends RuntimeException
|
||||
{
|
||||
static final long serialVersionUID = -8221564865490676219L;
|
||||
|
||||
public PropertyException(String detail) {
|
||||
super(detail);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,367 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ethan Hugg
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript.xml.impl.xmlbeans;
|
||||
|
||||
import org.apache.xmlbeans.XmlCursor;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class LogicalEquality
|
||||
{
|
||||
public static boolean nodesEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if (xmlOne.isStartdoc())
|
||||
{
|
||||
xmlOne.toFirstContentToken();
|
||||
}
|
||||
|
||||
if (xmlTwo.isStartdoc())
|
||||
{
|
||||
xmlTwo.toFirstContentToken();
|
||||
}
|
||||
|
||||
if (xmlOne.currentTokenType() == xmlTwo.currentTokenType())
|
||||
{
|
||||
if (xmlOne.isEnddoc())
|
||||
{
|
||||
// Both empty
|
||||
result = true;
|
||||
}
|
||||
else if (xmlOne.isAttr())
|
||||
{
|
||||
result = attributesEqual(xmlOne, xmlTwo);
|
||||
}
|
||||
else if (xmlOne.isText())
|
||||
{
|
||||
result = textNodesEqual(xmlOne, xmlTwo);
|
||||
}
|
||||
else if (xmlOne.isComment())
|
||||
{
|
||||
result = commentsEqual(xmlOne, xmlTwo);
|
||||
}
|
||||
else if (xmlOne.isProcinst())
|
||||
{
|
||||
result = processingInstructionsEqual(xmlOne, xmlTwo);
|
||||
}
|
||||
else if (xmlOne.isStart())
|
||||
{
|
||||
// Compare root elements
|
||||
result = elementsEqual(xmlOne, xmlTwo);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean elementsEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
|
||||
{
|
||||
boolean result = true;
|
||||
|
||||
if (!qnamesEqual(xmlOne.getName(), xmlTwo.getName()))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// These filter out empty text nodes.
|
||||
nextToken(xmlOne);
|
||||
nextToken(xmlTwo);
|
||||
|
||||
do
|
||||
{
|
||||
if (xmlOne.currentTokenType() != xmlTwo.currentTokenType())
|
||||
{
|
||||
// Not same token
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
else if (xmlOne.isEnd())
|
||||
{
|
||||
// Done with this element, step over end
|
||||
break;
|
||||
}
|
||||
else if (xmlOne.isEnddoc())
|
||||
{
|
||||
// Shouldn't get here
|
||||
break;
|
||||
}
|
||||
else if (xmlOne.isAttr())
|
||||
{
|
||||
// This one will move us to the first non-attr token.
|
||||
result = attributeListsEqual(xmlOne, xmlTwo);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xmlOne.isText())
|
||||
{
|
||||
result = textNodesEqual(xmlOne, xmlTwo);
|
||||
}
|
||||
else if (xmlOne.isComment())
|
||||
{
|
||||
result = commentsEqual(xmlOne, xmlTwo);
|
||||
}
|
||||
else if (xmlOne.isProcinst())
|
||||
{
|
||||
result = processingInstructionsEqual(xmlOne, xmlTwo);
|
||||
}
|
||||
else if (xmlOne.isStart())
|
||||
{
|
||||
result = elementsEqual(xmlOne, xmlTwo);
|
||||
}
|
||||
else
|
||||
{
|
||||
//XML.log("Unknown token type" + xmlOne.currentTokenType());
|
||||
}
|
||||
|
||||
// These filter out empty text nodes.
|
||||
nextToken(xmlOne);
|
||||
nextToken(xmlTwo);
|
||||
}
|
||||
}
|
||||
while(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param xmlOne
|
||||
* @param xmlTwo
|
||||
* @return
|
||||
*/
|
||||
private static boolean attributeListsEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
|
||||
{
|
||||
boolean result = true;
|
||||
TreeMap mapOne = loadAttributeMap(xmlOne);
|
||||
TreeMap mapTwo = loadAttributeMap(xmlTwo);
|
||||
|
||||
if (mapOne.size() != mapTwo.size())
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Set keysOne = mapOne.keySet();
|
||||
Set keysTwo = mapTwo.keySet();
|
||||
Iterator itOne = keysOne.iterator();
|
||||
Iterator itTwo = keysTwo.iterator();
|
||||
|
||||
while (result && itOne.hasNext())
|
||||
{
|
||||
String valueOne = (String) itOne.next();
|
||||
String valueTwo = (String) itTwo.next();
|
||||
|
||||
if (!valueOne.equals(valueTwo))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
javax.xml.namespace.QName qnameOne = (javax.xml.namespace.QName) mapOne.get(valueOne);
|
||||
javax.xml.namespace.QName qnameTwo = (javax.xml.namespace.QName) mapTwo.get(valueTwo);
|
||||
|
||||
if (!qnamesEqual(qnameOne, qnameTwo))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param xml
|
||||
* @return
|
||||
*/
|
||||
private static TreeMap loadAttributeMap(XmlCursor xml)
|
||||
{
|
||||
TreeMap result = new TreeMap();
|
||||
|
||||
while (xml.isAttr())
|
||||
{
|
||||
result.put(xml.getTextValue(), xml.getName());
|
||||
nextToken(xml);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param xmlOne
|
||||
* @param xmlTwo
|
||||
* @return
|
||||
*/
|
||||
private static boolean attributesEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if (xmlOne.isAttr() && xmlTwo.isAttr())
|
||||
{
|
||||
if (qnamesEqual(xmlOne.getName(), xmlTwo.getName()))
|
||||
{
|
||||
if (xmlOne.getTextValue().equals(xmlTwo.getTextValue()))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param xmlOne
|
||||
* @param xmlTwo
|
||||
* @return
|
||||
*/
|
||||
private static boolean textNodesEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if (xmlOne.isText() && xmlTwo.isText())
|
||||
{
|
||||
if (xmlOne.getChars().equals(xmlTwo.getChars()))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param xmlOne
|
||||
* @param xmlTwo
|
||||
* @return
|
||||
*/
|
||||
private static boolean commentsEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if (xmlOne.isComment() && xmlTwo.isComment())
|
||||
{
|
||||
if (xmlOne.getTextValue().equals(xmlTwo.getTextValue()))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param xmlOne
|
||||
* @param xmlTwo
|
||||
* @return
|
||||
*/
|
||||
private static boolean processingInstructionsEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if (xmlOne.isProcinst() && xmlTwo.isProcinst())
|
||||
{
|
||||
if (qnamesEqual(xmlOne.getName(), xmlTwo.getName()))
|
||||
{
|
||||
if (xmlOne.getTextValue().equals(xmlTwo.getTextValue()))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param qnameOne
|
||||
* @param qnameTwo
|
||||
* @return
|
||||
*/
|
||||
private static boolean qnamesEqual(javax.xml.namespace.QName qnameOne, javax.xml.namespace.QName qnameTwo)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if (qnameOne.getNamespaceURI().equals(qnameTwo.getNamespaceURI()))
|
||||
{
|
||||
if (qnameOne.getLocalPart().equals(qnameTwo.getLocalPart()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* filter out empty textNodes here
|
||||
*
|
||||
* @param xml
|
||||
*/
|
||||
private static void nextToken(XmlCursor xml)
|
||||
{
|
||||
do
|
||||
{
|
||||
xml.toNextToken();
|
||||
|
||||
if (!xml.isText())
|
||||
{
|
||||
// Not a text node
|
||||
break;
|
||||
}
|
||||
else if (xml.getChars().trim().length() > 0)
|
||||
{
|
||||
// Text node is not empty
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (true);
|
||||
}
|
||||
}
|
||||
@@ -1,335 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ethan Hugg
|
||||
* Terry Lucas
|
||||
* Milen Nankov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript.xml.impl.xmlbeans;
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
|
||||
/**
|
||||
* Class Namespace
|
||||
*
|
||||
*/
|
||||
class Namespace extends IdScriptableObject
|
||||
{
|
||||
static final long serialVersionUID = -5765755238131301744L;
|
||||
|
||||
private static final Object NAMESPACE_TAG = "Namespace";
|
||||
|
||||
private XMLLibImpl lib;
|
||||
private String prefix;
|
||||
private String uri;
|
||||
|
||||
public Namespace(XMLLibImpl lib, String uri)
|
||||
{
|
||||
super(lib.globalScope(), lib.namespacePrototype);
|
||||
|
||||
if (uri == null)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.lib = lib;
|
||||
this.prefix = (uri.length() == 0) ? "" : null;
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
|
||||
public Namespace(XMLLibImpl lib, String prefix, String uri)
|
||||
{
|
||||
super(lib.globalScope(), lib.namespacePrototype);
|
||||
|
||||
if (uri == null)
|
||||
throw new IllegalArgumentException();
|
||||
if (uri.length() == 0) {
|
||||
// prefix should be "" for empty uri
|
||||
if (prefix == null)
|
||||
throw new IllegalArgumentException();
|
||||
if (prefix.length() != 0)
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
this.lib = lib;
|
||||
this.prefix = prefix;
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public void exportAsJSClass(boolean sealed)
|
||||
{
|
||||
exportAsJSClass(MAX_PROTOTYPE_ID, lib.globalScope(), sealed);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String uri()
|
||||
{
|
||||
return uri;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String prefix()
|
||||
{
|
||||
return prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
return uri();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String toLocaleString ()
|
||||
{
|
||||
return toString();
|
||||
}
|
||||
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (!(obj instanceof Namespace)) return false;
|
||||
return equals((Namespace)obj);
|
||||
}
|
||||
|
||||
protected Object equivalentValues(Object value)
|
||||
{
|
||||
if (!(value instanceof Namespace)) return Scriptable.NOT_FOUND;
|
||||
boolean result = equals((Namespace)value);
|
||||
return result ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
|
||||
private boolean equals(Namespace n)
|
||||
{
|
||||
return uri().equals(n.uri());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getClassName ()
|
||||
{
|
||||
return "Namespace";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param hint
|
||||
* @return
|
||||
*/
|
||||
public Object getDefaultValue (Class hint)
|
||||
{
|
||||
return uri();
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
private static final int
|
||||
Id_prefix = 1,
|
||||
Id_uri = 2,
|
||||
MAX_INSTANCE_ID = 2;
|
||||
|
||||
protected int getMaxInstanceId()
|
||||
{
|
||||
return super.getMaxInstanceId() + MAX_INSTANCE_ID;
|
||||
}
|
||||
|
||||
protected int findInstanceIdInfo(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2004-07-20 19:50:50 CEST
|
||||
L0: { id = 0; String X = null;
|
||||
int s_length = s.length();
|
||||
if (s_length==3) { X="uri";id=Id_uri; }
|
||||
else if (s_length==6) { X="prefix";id=Id_prefix; }
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
}
|
||||
// #/generated#
|
||||
|
||||
if (id == 0) return super.findInstanceIdInfo(s);
|
||||
|
||||
int attr;
|
||||
switch (id) {
|
||||
case Id_prefix:
|
||||
case Id_uri:
|
||||
attr = PERMANENT | READONLY;
|
||||
break;
|
||||
default: throw new IllegalStateException();
|
||||
}
|
||||
return instanceIdInfo(attr, super.getMaxInstanceId() + id);
|
||||
}
|
||||
// #/string_id_map#
|
||||
|
||||
protected String getInstanceIdName(int id)
|
||||
{
|
||||
switch (id - super.getMaxInstanceId()) {
|
||||
case Id_prefix: return "prefix";
|
||||
case Id_uri: return "uri";
|
||||
}
|
||||
return super.getInstanceIdName(id);
|
||||
}
|
||||
|
||||
protected Object getInstanceIdValue(int id)
|
||||
{
|
||||
switch (id - super.getMaxInstanceId()) {
|
||||
case Id_prefix:
|
||||
if (prefix == null) return Undefined.instance;
|
||||
return prefix;
|
||||
case Id_uri:
|
||||
return uri;
|
||||
}
|
||||
return super.getInstanceIdValue(id);
|
||||
}
|
||||
|
||||
|
||||
// #string_id_map#
|
||||
private static final int
|
||||
Id_constructor = 1,
|
||||
Id_toString = 2,
|
||||
Id_toSource = 3,
|
||||
MAX_PROTOTYPE_ID = 3;
|
||||
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2004-08-21 12:07:01 CEST
|
||||
L0: { id = 0; String X = null; int c;
|
||||
int s_length = s.length();
|
||||
if (s_length==8) {
|
||||
c=s.charAt(3);
|
||||
if (c=='o') { X="toSource";id=Id_toSource; }
|
||||
else if (c=='t') { X="toString";id=Id_toString; }
|
||||
}
|
||||
else if (s_length==11) { X="constructor";id=Id_constructor; }
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
}
|
||||
// #/generated#
|
||||
return id;
|
||||
}
|
||||
// #/string_id_map#
|
||||
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_constructor: arity=2; s="constructor"; break;
|
||||
case Id_toString: arity=0; s="toString"; break;
|
||||
case Id_toSource: arity=0; s="toSource"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(NAMESPACE_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
public Object execIdCall(IdFunctionObject f,
|
||||
Context cx,
|
||||
Scriptable scope,
|
||||
Scriptable thisObj,
|
||||
Object[] args)
|
||||
{
|
||||
if (!f.hasTag(NAMESPACE_TAG)) {
|
||||
return super.execIdCall(f, cx, scope, thisObj, args);
|
||||
}
|
||||
int id = f.methodId();
|
||||
switch (id) {
|
||||
case Id_constructor:
|
||||
return jsConstructor(cx, (thisObj == null), args);
|
||||
case Id_toString:
|
||||
return realThis(thisObj, f).toString();
|
||||
case Id_toSource:
|
||||
return realThis(thisObj, f).js_toSource();
|
||||
}
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
private Namespace realThis(Scriptable thisObj, IdFunctionObject f)
|
||||
{
|
||||
if(!(thisObj instanceof Namespace))
|
||||
throw incompatibleCallError(f);
|
||||
return (Namespace)thisObj;
|
||||
}
|
||||
|
||||
private Object jsConstructor(Context cx, boolean inNewExpr, Object[] args)
|
||||
{
|
||||
if (!inNewExpr && args.length == 1) {
|
||||
return lib.castToNamespace(cx, args[0]);
|
||||
}
|
||||
|
||||
if (args.length == 0) {
|
||||
return lib.constructNamespace(cx);
|
||||
} else if (args.length == 1) {
|
||||
return lib.constructNamespace(cx, args[0]);
|
||||
} else {
|
||||
return lib.constructNamespace(cx, args[0], args[1]);
|
||||
}
|
||||
}
|
||||
|
||||
private String js_toSource()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append('(');
|
||||
toSourceImpl(prefix, uri, sb);
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
static void toSourceImpl(String prefix, String uri, StringBuffer sb)
|
||||
{
|
||||
sb.append("new Namespace(");
|
||||
if (uri.length() == 0) {
|
||||
if (!"".equals(prefix)) throw new IllegalArgumentException(prefix);
|
||||
} else {
|
||||
sb.append('\'');
|
||||
if (prefix != null) {
|
||||
sb.append(ScriptRuntime.escapeString(prefix, '\''));
|
||||
sb.append("', '");
|
||||
}
|
||||
sb.append(ScriptRuntime.escapeString(uri, '\''));
|
||||
sb.append('\'');
|
||||
}
|
||||
sb.append(')');
|
||||
}
|
||||
}
|
||||
@@ -1,350 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Milen Nankov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript.xml.impl.xmlbeans;
|
||||
|
||||
import java.util.*;
|
||||
import org.apache.xmlbeans.XmlCursor;
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
|
||||
class NamespaceHelper
|
||||
{
|
||||
private XMLLibImpl lib;
|
||||
private final Map prefixToURI = new HashMap();
|
||||
private final Map uriToPrefix = new HashMap();
|
||||
// A set of URIs that are used without explicit namespace declaration in scope.
|
||||
private final Set undeclared = new HashSet();
|
||||
|
||||
private NamespaceHelper(XMLLibImpl lib)
|
||||
{
|
||||
this.lib = lib;
|
||||
// Insert the default namespace
|
||||
prefixToURI.put("", "");
|
||||
Set prefixes = new HashSet();
|
||||
prefixes.add("");
|
||||
uriToPrefix.put("", prefixes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Declared a new namespace
|
||||
*
|
||||
* @param prefix
|
||||
* @param uri
|
||||
* @param declarations
|
||||
*/
|
||||
private void declareNamespace(String prefix, String uri, ObjArray declarations)
|
||||
{
|
||||
Set prefixes = (Set)uriToPrefix.get(uri);
|
||||
if(prefixes == null)
|
||||
{
|
||||
prefixes = new HashSet();
|
||||
uriToPrefix.put(uri, prefixes);
|
||||
}
|
||||
|
||||
if(!prefixes.contains(prefix))
|
||||
{
|
||||
String oldURI = (String)prefixToURI.get(prefix);
|
||||
|
||||
// Add the new mapping
|
||||
prefixes.add(prefix);
|
||||
prefixToURI.put(prefix, uri);
|
||||
if(declarations != null)
|
||||
declarations.add(new Namespace(lib, prefix, uri));
|
||||
|
||||
if(oldURI != null)
|
||||
{
|
||||
// Update the existing mapping
|
||||
prefixes = (Set)uriToPrefix.get(oldURI);
|
||||
prefixes.remove(prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the internal state of this NamespaceHelper to reflect the
|
||||
* existance of the XML token pointed to by the cursor.
|
||||
*/
|
||||
private void processName(XmlCursor cursor, ObjArray declarations)
|
||||
{
|
||||
javax.xml.namespace.QName qname = cursor.getName();
|
||||
String uri = qname.getNamespaceURI();
|
||||
Set prefixes = (Set)uriToPrefix.get(uri);
|
||||
if(prefixes == null || prefixes.size() == 0)
|
||||
{
|
||||
undeclared.add(uri);
|
||||
if(declarations != null)
|
||||
declarations.add(new Namespace(lib, uri));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the internal state of this NamespaceHelper with the
|
||||
* namespace information of the element pointed to by the cursor.
|
||||
*/
|
||||
private void update(XmlCursor cursor, ObjArray declarations)
|
||||
{
|
||||
// Process the Namespace declarations
|
||||
cursor.push();
|
||||
while(cursor.toNextToken().isAnyAttr())
|
||||
{
|
||||
if(cursor.isNamespace())
|
||||
{
|
||||
javax.xml.namespace.QName name = cursor.getName();
|
||||
String prefix = name.getLocalPart();
|
||||
String uri = name.getNamespaceURI();
|
||||
|
||||
declareNamespace(prefix, uri, declarations);
|
||||
}
|
||||
}
|
||||
cursor.pop();
|
||||
|
||||
// Process the element
|
||||
processName(cursor, declarations);
|
||||
|
||||
// Process the attributes
|
||||
cursor.push();
|
||||
boolean hasNext = cursor.toFirstAttribute();
|
||||
while(hasNext)
|
||||
{
|
||||
processName(cursor, declarations);
|
||||
hasNext = cursor.toNextAttribute();
|
||||
}
|
||||
cursor.pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Object[] array of Namespace objects in scope at the cursor.
|
||||
*/
|
||||
public static Object[] inScopeNamespaces(XMLLibImpl lib, XmlCursor cursor)
|
||||
{
|
||||
ObjArray namespaces = new ObjArray();
|
||||
NamespaceHelper helper = new NamespaceHelper(lib);
|
||||
|
||||
cursor.push();
|
||||
|
||||
int depth = 0;
|
||||
while(cursor.hasPrevToken())
|
||||
{
|
||||
if(cursor.isContainer())
|
||||
{
|
||||
cursor.push();
|
||||
depth++;
|
||||
}
|
||||
|
||||
cursor.toParent();
|
||||
}
|
||||
|
||||
for(int i = 0; i < depth; i++)
|
||||
{
|
||||
cursor.pop();
|
||||
helper.update(cursor, null);
|
||||
}
|
||||
|
||||
Iterator i = helper.prefixToURI.entrySet().iterator();
|
||||
while(i.hasNext())
|
||||
{
|
||||
Map.Entry entry = (Map.Entry)i.next();
|
||||
Namespace ns = new Namespace(lib, (String)entry.getKey(),
|
||||
(String)entry.getValue());
|
||||
namespaces.add(ns);
|
||||
}
|
||||
|
||||
i = helper.undeclared.iterator();
|
||||
while(i.hasNext())
|
||||
{
|
||||
Namespace ns = new Namespace(lib, (String)i.next());
|
||||
namespaces.add(ns);
|
||||
}
|
||||
|
||||
cursor.pop();
|
||||
|
||||
return namespaces.toArray();
|
||||
}
|
||||
|
||||
static Namespace getNamespace(XMLLibImpl lib, XmlCursor cursor,
|
||||
Object[] inScopeNamespaces)
|
||||
{
|
||||
String uri;
|
||||
String prefix;
|
||||
|
||||
if (cursor.isProcinst()) {
|
||||
uri = "";
|
||||
prefix = "";
|
||||
} else {
|
||||
javax.xml.namespace.QName qname = cursor.getName();
|
||||
uri = qname.getNamespaceURI();
|
||||
prefix = qname.getPrefix();
|
||||
}
|
||||
|
||||
if (inScopeNamespaces == null)
|
||||
return new Namespace(lib, prefix, uri);
|
||||
|
||||
Namespace result = null;
|
||||
for (int i = 0; i != inScopeNamespaces.length; ++i) {
|
||||
Namespace ns = (Namespace)inScopeNamespaces[i];
|
||||
if(ns == null) continue;
|
||||
|
||||
String nsURI = ns.uri();
|
||||
if(nsURI.equals(uri))
|
||||
{
|
||||
if(prefix.equals(ns.prefix()))
|
||||
{
|
||||
result = ns;
|
||||
break;
|
||||
}
|
||||
|
||||
if(result == null ||
|
||||
(result.prefix() == null &&
|
||||
ns.prefix() != null))
|
||||
result = ns;
|
||||
}
|
||||
}
|
||||
|
||||
if(result == null)
|
||||
result = new Namespace(lib, prefix, uri);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return List of Namespace objects that are declared in the container pointed to by the cursor.
|
||||
*/
|
||||
public static Object[] namespaceDeclarations(XMLLibImpl lib, XmlCursor cursor)
|
||||
{
|
||||
ObjArray declarations = new ObjArray();
|
||||
NamespaceHelper helper = new NamespaceHelper(lib);
|
||||
|
||||
cursor.push();
|
||||
|
||||
int depth = 0;
|
||||
while(cursor.hasPrevToken())
|
||||
{
|
||||
if(cursor.isContainer())
|
||||
{
|
||||
cursor.push();
|
||||
depth++;
|
||||
}
|
||||
|
||||
cursor.toParent();
|
||||
}
|
||||
|
||||
for(int i = 0; i < depth - 1; i++)
|
||||
{
|
||||
cursor.pop();
|
||||
helper.update(cursor, null);
|
||||
}
|
||||
|
||||
if(depth > 0)
|
||||
{
|
||||
cursor.pop();
|
||||
helper.update(cursor, declarations);
|
||||
}
|
||||
|
||||
cursor.pop();
|
||||
|
||||
return declarations.toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Prefix to URI map of all namespaces in scope at the cursor.
|
||||
*/
|
||||
public static Map getAllNamespaces(XMLLibImpl lib, XmlCursor cursor)
|
||||
{
|
||||
NamespaceHelper helper = new NamespaceHelper(lib);
|
||||
|
||||
cursor.push();
|
||||
|
||||
int depth = 0;
|
||||
while(cursor.hasPrevToken())
|
||||
{
|
||||
if(cursor.isContainer())
|
||||
{
|
||||
cursor.push();
|
||||
depth++;
|
||||
}
|
||||
|
||||
cursor.toParent();
|
||||
}
|
||||
|
||||
for(int i = 0; i < depth; i++)
|
||||
{
|
||||
cursor.pop();
|
||||
helper.update(cursor, null);
|
||||
}
|
||||
|
||||
cursor.pop();
|
||||
|
||||
return helper.prefixToURI;
|
||||
}
|
||||
|
||||
public static void getNamespaces(XmlCursor cursor, Map prefixToURI)
|
||||
{
|
||||
cursor.push();
|
||||
while(cursor.toNextToken().isAnyAttr())
|
||||
{
|
||||
if(cursor.isNamespace())
|
||||
{
|
||||
javax.xml.namespace.QName name = cursor.getName();
|
||||
String prefix = name.getLocalPart();
|
||||
String uri = name.getNamespaceURI();
|
||||
|
||||
prefixToURI.put(prefix, uri);
|
||||
}
|
||||
}
|
||||
cursor.pop();
|
||||
}
|
||||
|
||||
public static void removeNamespace(XmlCursor cursor, String prefix)
|
||||
{
|
||||
cursor.push();
|
||||
while(cursor.toNextToken().isAnyAttr())
|
||||
{
|
||||
if(cursor.isNamespace())
|
||||
{
|
||||
javax.xml.namespace.QName name = cursor.getName();
|
||||
if(name.getLocalPart().equals(prefix))
|
||||
{
|
||||
cursor.removeXml();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
cursor.pop();
|
||||
}
|
||||
}
|
||||
@@ -1,321 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ethan Hugg
|
||||
* Terry Lucas
|
||||
* Milen Nankov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript.xml.impl.xmlbeans;
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
|
||||
/**
|
||||
* Class QName
|
||||
*
|
||||
*/
|
||||
final class QName extends IdScriptableObject
|
||||
{
|
||||
static final long serialVersionUID = 416745167693026750L;
|
||||
|
||||
private static final Object QNAME_TAG = "QName";
|
||||
|
||||
XMLLibImpl lib;
|
||||
private String prefix;
|
||||
private String localName;
|
||||
private String uri;
|
||||
|
||||
QName(XMLLibImpl lib, String uri, String localName, String prefix)
|
||||
{
|
||||
super(lib.globalScope(), lib.qnamePrototype);
|
||||
if (localName == null) throw new IllegalArgumentException();
|
||||
this.lib = lib;
|
||||
this.uri = uri;
|
||||
this.prefix = prefix;
|
||||
this.localName = localName;
|
||||
}
|
||||
|
||||
void exportAsJSClass(boolean sealed)
|
||||
{
|
||||
exportAsJSClass(MAX_PROTOTYPE_ID, lib.globalScope(), sealed);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
String result;
|
||||
|
||||
if (uri == null)
|
||||
{
|
||||
result = "*::".concat(localName);
|
||||
}
|
||||
else if(uri.length() == 0)
|
||||
{
|
||||
result = localName;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = uri + "::" + localName;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public String localName()
|
||||
{
|
||||
return localName;
|
||||
}
|
||||
|
||||
String prefix()
|
||||
{
|
||||
return (prefix == null) ? prefix : "";
|
||||
}
|
||||
|
||||
String uri()
|
||||
{
|
||||
return uri;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if(!(obj instanceof QName)) return false;
|
||||
return equals((QName)obj);
|
||||
}
|
||||
|
||||
protected Object equivalentValues(Object value)
|
||||
{
|
||||
if(!(value instanceof QName)) return Scriptable.NOT_FOUND;
|
||||
boolean result = equals((QName)value);
|
||||
return result ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
|
||||
private boolean equals(QName q)
|
||||
{
|
||||
boolean result;
|
||||
|
||||
if (uri == null) {
|
||||
result = q.uri == null && localName.equals(q.localName);
|
||||
} else {
|
||||
result = uri.equals(q.uri) && localName.equals(q.localName);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getClassName ()
|
||||
{
|
||||
return "QName";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param hint
|
||||
* @return
|
||||
*/
|
||||
public Object getDefaultValue (Class hint)
|
||||
{
|
||||
return toString();
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
private static final int
|
||||
Id_localName = 1,
|
||||
Id_uri = 2,
|
||||
MAX_INSTANCE_ID = 2;
|
||||
|
||||
protected int getMaxInstanceId()
|
||||
{
|
||||
return super.getMaxInstanceId() + MAX_INSTANCE_ID;
|
||||
}
|
||||
|
||||
protected int findInstanceIdInfo(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2004-07-18 12:32:51 CEST
|
||||
L0: { id = 0; String X = null;
|
||||
int s_length = s.length();
|
||||
if (s_length==3) { X="uri";id=Id_uri; }
|
||||
else if (s_length==9) { X="localName";id=Id_localName; }
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
}
|
||||
// #/generated#
|
||||
|
||||
if (id == 0) return super.findInstanceIdInfo(s);
|
||||
|
||||
int attr;
|
||||
switch (id) {
|
||||
case Id_localName:
|
||||
case Id_uri:
|
||||
attr = PERMANENT | READONLY;
|
||||
break;
|
||||
default: throw new IllegalStateException();
|
||||
}
|
||||
return instanceIdInfo(attr, super.getMaxInstanceId() + id);
|
||||
}
|
||||
// #/string_id_map#
|
||||
|
||||
protected String getInstanceIdName(int id)
|
||||
{
|
||||
switch (id - super.getMaxInstanceId()) {
|
||||
case Id_localName: return "localName";
|
||||
case Id_uri: return "uri";
|
||||
}
|
||||
return super.getInstanceIdName(id);
|
||||
}
|
||||
|
||||
protected Object getInstanceIdValue(int id)
|
||||
{
|
||||
switch (id - super.getMaxInstanceId()) {
|
||||
case Id_localName: return localName;
|
||||
case Id_uri: return uri;
|
||||
}
|
||||
return super.getInstanceIdValue(id);
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
private static final int
|
||||
Id_constructor = 1,
|
||||
Id_toString = 2,
|
||||
Id_toSource = 3,
|
||||
MAX_PROTOTYPE_ID = 3;
|
||||
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2004-08-21 12:45:13 CEST
|
||||
L0: { id = 0; String X = null; int c;
|
||||
int s_length = s.length();
|
||||
if (s_length==8) {
|
||||
c=s.charAt(3);
|
||||
if (c=='o') { X="toSource";id=Id_toSource; }
|
||||
else if (c=='t') { X="toString";id=Id_toString; }
|
||||
}
|
||||
else if (s_length==11) { X="constructor";id=Id_constructor; }
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
}
|
||||
// #/generated#
|
||||
return id;
|
||||
}
|
||||
// #/string_id_map#
|
||||
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_constructor: arity=2; s="constructor"; break;
|
||||
case Id_toString: arity=0; s="toString"; break;
|
||||
case Id_toSource: arity=0; s="toSource"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(QNAME_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
public Object execIdCall(IdFunctionObject f,
|
||||
Context cx,
|
||||
Scriptable scope,
|
||||
Scriptable thisObj,
|
||||
Object[] args)
|
||||
{
|
||||
if (!f.hasTag(QNAME_TAG)) {
|
||||
return super.execIdCall(f, cx, scope, thisObj, args);
|
||||
}
|
||||
int id = f.methodId();
|
||||
switch (id) {
|
||||
case Id_constructor:
|
||||
return jsConstructor(cx, (thisObj == null), args);
|
||||
case Id_toString:
|
||||
return realThis(thisObj, f).toString();
|
||||
case Id_toSource:
|
||||
return realThis(thisObj, f).js_toSource();
|
||||
}
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
private QName realThis(Scriptable thisObj, IdFunctionObject f)
|
||||
{
|
||||
if(!(thisObj instanceof QName))
|
||||
throw incompatibleCallError(f);
|
||||
return (QName)thisObj;
|
||||
}
|
||||
|
||||
private Object jsConstructor(Context cx, boolean inNewExpr, Object[] args)
|
||||
{
|
||||
if (!inNewExpr && args.length == 1) {
|
||||
return lib.castToQName(cx, args[0]);
|
||||
}
|
||||
if (args.length == 0) {
|
||||
return lib.constructQName(cx, Undefined.instance);
|
||||
} else if (args.length == 1) {
|
||||
return lib.constructQName(cx, args[0]);
|
||||
} else {
|
||||
return lib.constructQName(cx, args[0], args[1]);
|
||||
}
|
||||
}
|
||||
|
||||
private String js_toSource()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append('(');
|
||||
toSourceImpl(uri, localName, prefix, sb);
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static void toSourceImpl(String uri, String localName,
|
||||
String prefix, StringBuffer sb)
|
||||
{
|
||||
sb.append("new QName(");
|
||||
if (uri == null && prefix == null) {
|
||||
if (!"*".equals(localName)) {
|
||||
sb.append("null, ");
|
||||
}
|
||||
} else {
|
||||
Namespace.toSourceImpl(prefix, uri, sb);
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append('\'');
|
||||
sb.append(ScriptRuntime.escapeString(localName, '\''));
|
||||
sb.append("')");
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,269 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript.xml.impl.xmlbeans;
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
|
||||
class XMLCtor extends IdFunctionObject
|
||||
{
|
||||
static final long serialVersionUID = -8708195078359817341L;
|
||||
|
||||
private static final Object XMLCTOR_TAG = "XMLCtor";
|
||||
|
||||
private XMLLibImpl lib;
|
||||
|
||||
XMLCtor(XML xml, Object tag, int id, int arity)
|
||||
{
|
||||
super(xml, tag, id, arity);
|
||||
this.lib = xml.lib;
|
||||
activatePrototypeMap(MAX_FUNCTION_ID);
|
||||
}
|
||||
|
||||
private void writeSetting(Scriptable target)
|
||||
{
|
||||
for (int i = 1; i <= MAX_INSTANCE_ID; ++i) {
|
||||
int id = super.getMaxInstanceId() + i;
|
||||
String name = getInstanceIdName(id);
|
||||
Object value = getInstanceIdValue(id);
|
||||
ScriptableObject.putProperty(target, name, value);
|
||||
}
|
||||
}
|
||||
|
||||
private void readSettings(Scriptable source)
|
||||
{
|
||||
for (int i = 1; i <= MAX_INSTANCE_ID; ++i) {
|
||||
int id = super.getMaxInstanceId() + i;
|
||||
String name = getInstanceIdName(id);
|
||||
Object value = ScriptableObject.getProperty(source, name);
|
||||
if (value == Scriptable.NOT_FOUND) {
|
||||
continue;
|
||||
}
|
||||
switch (i) {
|
||||
case Id_ignoreComments:
|
||||
case Id_ignoreProcessingInstructions:
|
||||
case Id_ignoreWhitespace:
|
||||
case Id_prettyPrinting:
|
||||
if (!(value instanceof Boolean)) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case Id_prettyIndent:
|
||||
if (!(value instanceof Number)) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
setInstanceIdValue(id, value);
|
||||
}
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
private static final int
|
||||
Id_ignoreComments = 1,
|
||||
Id_ignoreProcessingInstructions = 2,
|
||||
Id_ignoreWhitespace = 3,
|
||||
Id_prettyIndent = 4,
|
||||
Id_prettyPrinting = 5,
|
||||
|
||||
MAX_INSTANCE_ID = 5;
|
||||
|
||||
protected int getMaxInstanceId()
|
||||
{
|
||||
return super.getMaxInstanceId() + MAX_INSTANCE_ID;
|
||||
}
|
||||
|
||||
protected int findInstanceIdInfo(String s) {
|
||||
int id;
|
||||
// #generated# Last update: 2004-07-19 13:03:52 CEST
|
||||
L0: { id = 0; String X = null; int c;
|
||||
L: switch (s.length()) {
|
||||
case 12: X="prettyIndent";id=Id_prettyIndent; break L;
|
||||
case 14: c=s.charAt(0);
|
||||
if (c=='i') { X="ignoreComments";id=Id_ignoreComments; }
|
||||
else if (c=='p') { X="prettyPrinting";id=Id_prettyPrinting; }
|
||||
break L;
|
||||
case 16: X="ignoreWhitespace";id=Id_ignoreWhitespace; break L;
|
||||
case 28: X="ignoreProcessingInstructions";id=Id_ignoreProcessingInstructions; break L;
|
||||
}
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
}
|
||||
// #/generated#
|
||||
|
||||
if (id == 0) return super.findInstanceIdInfo(s);
|
||||
|
||||
int attr;
|
||||
switch (id) {
|
||||
case Id_ignoreComments:
|
||||
case Id_ignoreProcessingInstructions:
|
||||
case Id_ignoreWhitespace:
|
||||
case Id_prettyIndent:
|
||||
case Id_prettyPrinting:
|
||||
attr = PERMANENT | DONTENUM;
|
||||
break;
|
||||
default: throw new IllegalStateException();
|
||||
}
|
||||
return instanceIdInfo(attr, super.getMaxInstanceId() + id);
|
||||
}
|
||||
|
||||
// #/string_id_map#
|
||||
|
||||
protected String getInstanceIdName(int id)
|
||||
{
|
||||
switch (id - super.getMaxInstanceId()) {
|
||||
case Id_ignoreComments: return "ignoreComments";
|
||||
case Id_ignoreProcessingInstructions: return "ignoreProcessingInstructions";
|
||||
case Id_ignoreWhitespace: return "ignoreWhitespace";
|
||||
case Id_prettyIndent: return "prettyIndent";
|
||||
case Id_prettyPrinting: return "prettyPrinting";
|
||||
}
|
||||
return super.getInstanceIdName(id);
|
||||
}
|
||||
|
||||
protected Object getInstanceIdValue(int id)
|
||||
{
|
||||
switch (id - super.getMaxInstanceId()) {
|
||||
case Id_ignoreComments:
|
||||
return ScriptRuntime.wrapBoolean(lib.ignoreComments);
|
||||
case Id_ignoreProcessingInstructions:
|
||||
return ScriptRuntime.wrapBoolean(lib.ignoreProcessingInstructions);
|
||||
case Id_ignoreWhitespace:
|
||||
return ScriptRuntime.wrapBoolean(lib.ignoreWhitespace);
|
||||
case Id_prettyIndent:
|
||||
return ScriptRuntime.wrapInt(lib.prettyIndent);
|
||||
case Id_prettyPrinting:
|
||||
return ScriptRuntime.wrapBoolean(lib.prettyPrinting);
|
||||
}
|
||||
return super.getInstanceIdValue(id);
|
||||
}
|
||||
|
||||
protected void setInstanceIdValue(int id, Object value)
|
||||
{
|
||||
switch (id - super.getMaxInstanceId()) {
|
||||
case Id_ignoreComments:
|
||||
lib.ignoreComments = ScriptRuntime.toBoolean(value);
|
||||
return;
|
||||
case Id_ignoreProcessingInstructions:
|
||||
lib.ignoreProcessingInstructions = ScriptRuntime.toBoolean(value);
|
||||
return;
|
||||
case Id_ignoreWhitespace:
|
||||
lib.ignoreWhitespace = ScriptRuntime.toBoolean(value);
|
||||
return;
|
||||
case Id_prettyIndent:
|
||||
lib.prettyIndent = ScriptRuntime.toInt32(value);
|
||||
return;
|
||||
case Id_prettyPrinting:
|
||||
lib.prettyPrinting = ScriptRuntime.toBoolean(value);
|
||||
return;
|
||||
}
|
||||
super.setInstanceIdValue(id, value);
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
private static final int
|
||||
Id_defaultSettings = 1,
|
||||
Id_settings = 2,
|
||||
Id_setSettings = 3,
|
||||
MAX_FUNCTION_ID = 3;
|
||||
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2004-07-19 13:03:52 CEST
|
||||
L0: { id = 0; String X = null;
|
||||
int s_length = s.length();
|
||||
if (s_length==8) { X="settings";id=Id_settings; }
|
||||
else if (s_length==11) { X="setSettings";id=Id_setSettings; }
|
||||
else if (s_length==15) { X="defaultSettings";id=Id_defaultSettings; }
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
}
|
||||
// #/generated#
|
||||
return id;
|
||||
}
|
||||
// #/string_id_map#
|
||||
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_defaultSettings: arity=0; s="defaultSettings"; break;
|
||||
case Id_settings: arity=0; s="settings"; break;
|
||||
case Id_setSettings: arity=1; s="setSettings"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(XMLCTOR_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (!f.hasTag(XMLCTOR_TAG)) {
|
||||
return super.execIdCall(f, cx, scope, thisObj, args);
|
||||
}
|
||||
int id = f.methodId();
|
||||
switch (id) {
|
||||
case Id_defaultSettings: {
|
||||
lib.defaultSettings();
|
||||
Scriptable obj = cx.newObject(scope);
|
||||
writeSetting(obj);
|
||||
return obj;
|
||||
}
|
||||
case Id_settings: {
|
||||
Scriptable obj = cx.newObject(scope);
|
||||
writeSetting(obj);
|
||||
return obj;
|
||||
}
|
||||
case Id_setSettings: {
|
||||
if (args.length == 0
|
||||
|| args[0] == null
|
||||
|| args[0] == Undefined.instance)
|
||||
{
|
||||
lib.defaultSettings();
|
||||
} else if (args[0] instanceof Scriptable) {
|
||||
readSettings((Scriptable)args[0]);
|
||||
}
|
||||
return Undefined.instance;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
}
|
||||
@@ -1,754 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript.xml.impl.xmlbeans;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
import org.mozilla.javascript.xml.*;
|
||||
|
||||
import org.apache.xmlbeans.XmlCursor;
|
||||
import org.apache.xmlbeans.XmlObject;
|
||||
|
||||
public final class XMLLibImpl extends XMLLib implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Scriptable globalScope;
|
||||
|
||||
XML xmlPrototype;
|
||||
XMLList xmlListPrototype;
|
||||
Namespace namespacePrototype;
|
||||
QName qnamePrototype;
|
||||
|
||||
|
||||
// Environment settings...
|
||||
boolean ignoreComments;
|
||||
boolean ignoreProcessingInstructions;
|
||||
boolean ignoreWhitespace;
|
||||
boolean prettyPrinting;
|
||||
int prettyIndent;
|
||||
|
||||
Scriptable globalScope()
|
||||
{
|
||||
return globalScope;
|
||||
}
|
||||
|
||||
private XMLLibImpl(Scriptable globalScope)
|
||||
{
|
||||
this.globalScope = globalScope;
|
||||
defaultSettings();
|
||||
}
|
||||
|
||||
public static void init(Context cx, Scriptable scope, boolean sealed)
|
||||
{
|
||||
// To force LinkageError if XmlObject is not available
|
||||
XmlObject.class.getName();
|
||||
|
||||
XMLLibImpl lib = new XMLLibImpl(scope);
|
||||
XMLLib bound = lib.bindToScope(scope);
|
||||
if (bound == lib) {
|
||||
lib.exportToScope(sealed);
|
||||
}
|
||||
}
|
||||
|
||||
private void exportToScope(boolean sealed)
|
||||
{
|
||||
xmlPrototype = XML.createEmptyXML(this);
|
||||
xmlListPrototype = new XMLList(this);
|
||||
namespacePrototype = new Namespace(this, "", "");
|
||||
qnamePrototype = new QName(this, "", "", "");
|
||||
|
||||
xmlPrototype.exportAsJSClass(sealed);
|
||||
xmlListPrototype.exportAsJSClass(sealed);
|
||||
namespacePrototype.exportAsJSClass(sealed);
|
||||
qnamePrototype.exportAsJSClass(sealed);
|
||||
}
|
||||
|
||||
void defaultSettings()
|
||||
{
|
||||
ignoreComments = true;
|
||||
ignoreProcessingInstructions = true;
|
||||
ignoreWhitespace = true;
|
||||
prettyPrinting = true;
|
||||
prettyIndent = 2;
|
||||
}
|
||||
|
||||
XMLName toAttributeName(Context cx, Object nameValue)
|
||||
{
|
||||
String uri;
|
||||
String localName;
|
||||
|
||||
if (nameValue instanceof String) {
|
||||
uri = "";
|
||||
localName = (String)nameValue;
|
||||
} else if (nameValue instanceof XMLName) {
|
||||
XMLName xmlName = (XMLName)nameValue;
|
||||
if (!xmlName.isAttributeName()) {
|
||||
xmlName.setAttributeName();
|
||||
}
|
||||
return xmlName;
|
||||
} else if (nameValue instanceof QName) {
|
||||
QName qname = (QName)nameValue;
|
||||
uri = qname.uri();
|
||||
localName = qname.localName();
|
||||
} else if (nameValue instanceof Boolean
|
||||
|| nameValue instanceof Number
|
||||
|| nameValue == Undefined.instance
|
||||
|| nameValue == null)
|
||||
{
|
||||
throw badXMLName(nameValue);
|
||||
} else {
|
||||
uri = "";
|
||||
localName = ScriptRuntime.toString(nameValue);
|
||||
}
|
||||
XMLName xmlName = XMLName.formProperty(uri, localName);
|
||||
xmlName.setAttributeName();
|
||||
return xmlName;
|
||||
}
|
||||
|
||||
private static RuntimeException badXMLName(Object value)
|
||||
{
|
||||
String msg;
|
||||
if (value instanceof Number) {
|
||||
msg = "Can not construct XML name from number: ";
|
||||
} else if (value instanceof Boolean) {
|
||||
msg = "Can not construct XML name from boolean: ";
|
||||
} else if (value == Undefined.instance || value == null) {
|
||||
msg = "Can not construct XML name from ";
|
||||
} else {
|
||||
throw new IllegalArgumentException(value.toString());
|
||||
}
|
||||
return ScriptRuntime.typeError(msg+ScriptRuntime.toString(value));
|
||||
}
|
||||
|
||||
XMLName toXMLName(Context cx, Object nameValue)
|
||||
{
|
||||
XMLName result;
|
||||
|
||||
if (nameValue instanceof XMLName) {
|
||||
result = (XMLName)nameValue;
|
||||
} else if (nameValue instanceof QName) {
|
||||
QName qname = (QName)nameValue;
|
||||
result = XMLName.formProperty(qname.uri(), qname.localName());
|
||||
} else if (nameValue instanceof String) {
|
||||
result = toXMLNameFromString(cx, (String)nameValue);
|
||||
} else if (nameValue instanceof Boolean
|
||||
|| nameValue instanceof Number
|
||||
|| nameValue == Undefined.instance
|
||||
|| nameValue == null)
|
||||
{
|
||||
throw badXMLName(nameValue);
|
||||
} else {
|
||||
String name = ScriptRuntime.toString(nameValue);
|
||||
result = toXMLNameFromString(cx, name);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* If value represents Uint32 index, make it available through
|
||||
* ScriptRuntime.lastUint32Result(cx) and return null.
|
||||
* Otherwise return the same value as toXMLName(cx, value).
|
||||
*/
|
||||
XMLName toXMLNameOrIndex(Context cx, Object value)
|
||||
{
|
||||
XMLName result;
|
||||
|
||||
if (value instanceof XMLName) {
|
||||
result = (XMLName)value;
|
||||
} else if (value instanceof String) {
|
||||
String str = (String)value;
|
||||
long test = ScriptRuntime.testUint32String(str);
|
||||
if (test >= 0) {
|
||||
ScriptRuntime.storeUint32Result(cx, test);
|
||||
result = null;
|
||||
} else {
|
||||
result = toXMLNameFromString(cx, str);
|
||||
}
|
||||
} else if (value instanceof Number) {
|
||||
double d = ((Number)value).doubleValue();
|
||||
long l = (long)d;
|
||||
if (l == d && 0 <= l && l <= 0xFFFFFFFFL) {
|
||||
ScriptRuntime.storeUint32Result(cx, l);
|
||||
result = null;
|
||||
} else {
|
||||
throw badXMLName(value);
|
||||
}
|
||||
} else if (value instanceof QName) {
|
||||
QName qname = (QName)value;
|
||||
String uri = qname.uri();
|
||||
boolean number = false;
|
||||
result = null;
|
||||
if (uri != null && uri.length() == 0) {
|
||||
// Only in this case qname.toString() can resemble uint32
|
||||
long test = ScriptRuntime.testUint32String(uri);
|
||||
if (test >= 0) {
|
||||
ScriptRuntime.storeUint32Result(cx, test);
|
||||
number = true;
|
||||
}
|
||||
}
|
||||
if (!number) {
|
||||
result = XMLName.formProperty(uri, qname.localName());
|
||||
}
|
||||
} else if (value instanceof Boolean
|
||||
|| value == Undefined.instance
|
||||
|| value == null)
|
||||
{
|
||||
throw badXMLName(value);
|
||||
} else {
|
||||
String str = ScriptRuntime.toString(value);
|
||||
long test = ScriptRuntime.testUint32String(str);
|
||||
if (test >= 0) {
|
||||
ScriptRuntime.storeUint32Result(cx, test);
|
||||
result = null;
|
||||
} else {
|
||||
result = toXMLNameFromString(cx, str);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
XMLName toXMLNameFromString(Context cx, String name)
|
||||
{
|
||||
if (name == null)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
int l = name.length();
|
||||
if (l != 0) {
|
||||
char firstChar = name.charAt(0);
|
||||
if (firstChar == '*') {
|
||||
if (l == 1) {
|
||||
return XMLName.formStar();
|
||||
}
|
||||
} else if (firstChar == '@') {
|
||||
XMLName xmlName = XMLName.formProperty("", name.substring(1));
|
||||
xmlName.setAttributeName();
|
||||
return xmlName;
|
||||
}
|
||||
}
|
||||
|
||||
String uri = getDefaultNamespaceURI(cx);
|
||||
|
||||
return XMLName.formProperty(uri, name);
|
||||
}
|
||||
|
||||
Namespace constructNamespace(Context cx, Object uriValue)
|
||||
{
|
||||
String prefix;
|
||||
String uri;
|
||||
|
||||
if (uriValue instanceof Namespace) {
|
||||
Namespace ns = (Namespace)uriValue;
|
||||
prefix = ns.prefix();
|
||||
uri = ns.uri();
|
||||
} else if (uriValue instanceof QName) {
|
||||
QName qname = (QName)uriValue;
|
||||
uri = qname.uri();
|
||||
if (uri != null) {
|
||||
prefix = qname.prefix();
|
||||
} else {
|
||||
uri = qname.toString();
|
||||
prefix = null;
|
||||
}
|
||||
} else {
|
||||
uri = ScriptRuntime.toString(uriValue);
|
||||
prefix = (uri.length() == 0) ? "" : null;
|
||||
}
|
||||
|
||||
return new Namespace(this, prefix, uri);
|
||||
}
|
||||
|
||||
Namespace castToNamespace(Context cx, Object namescapeObj)
|
||||
{
|
||||
if (namescapeObj instanceof Namespace) {
|
||||
return (Namespace)namescapeObj;
|
||||
}
|
||||
return constructNamespace(cx, namescapeObj);
|
||||
}
|
||||
|
||||
Namespace constructNamespace(Context cx)
|
||||
{
|
||||
return new Namespace(this, "", "");
|
||||
}
|
||||
|
||||
public Namespace constructNamespace(Context cx, Object prefixValue,
|
||||
Object uriValue)
|
||||
{
|
||||
String prefix;
|
||||
String uri;
|
||||
|
||||
if (uriValue instanceof QName) {
|
||||
QName qname = (QName)uriValue;
|
||||
uri = qname.uri();
|
||||
if (uri == null) {
|
||||
uri = qname.toString();
|
||||
}
|
||||
} else {
|
||||
uri = ScriptRuntime.toString(uriValue);
|
||||
}
|
||||
|
||||
if (uri.length() == 0) {
|
||||
if (prefixValue == Undefined.instance) {
|
||||
prefix = "";
|
||||
} else {
|
||||
prefix = ScriptRuntime.toString(prefixValue);
|
||||
if (prefix.length() != 0) {
|
||||
throw ScriptRuntime.typeError(
|
||||
"Illegal prefix '"+prefix+"' for 'no namespace'.");
|
||||
}
|
||||
}
|
||||
} else if (prefixValue == Undefined.instance) {
|
||||
prefix = "";
|
||||
} else if (!isXMLName(cx, prefixValue)) {
|
||||
prefix = "";
|
||||
} else {
|
||||
prefix = ScriptRuntime.toString(prefixValue);
|
||||
}
|
||||
|
||||
return new Namespace(this, prefix, uri);
|
||||
}
|
||||
|
||||
String getDefaultNamespaceURI(Context cx)
|
||||
{
|
||||
String uri = "";
|
||||
if (cx == null) {
|
||||
cx = Context.getCurrentContext();
|
||||
}
|
||||
if (cx != null) {
|
||||
Object ns = ScriptRuntime.searchDefaultNamespace(cx);
|
||||
if (ns != null) {
|
||||
if (ns instanceof Namespace) {
|
||||
uri = ((Namespace)ns).uri();
|
||||
} else {
|
||||
// Should not happen but for now it could
|
||||
// due to bad searchDefaultNamespace implementation.
|
||||
}
|
||||
}
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
|
||||
Namespace getDefaultNamespace(Context cx)
|
||||
{
|
||||
if (cx == null) {
|
||||
cx = Context.getCurrentContext();
|
||||
if (cx == null) {
|
||||
return namespacePrototype;
|
||||
}
|
||||
}
|
||||
|
||||
Namespace result;
|
||||
Object ns = ScriptRuntime.searchDefaultNamespace(cx);
|
||||
if (ns == null) {
|
||||
result = namespacePrototype;
|
||||
} else {
|
||||
if (ns instanceof Namespace) {
|
||||
result = (Namespace)ns;
|
||||
} else {
|
||||
// Should not happen but for now it could
|
||||
// due to bad searchDefaultNamespace implementation.
|
||||
result = namespacePrototype;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QName castToQName(Context cx, Object qnameValue)
|
||||
{
|
||||
if (qnameValue instanceof QName) {
|
||||
return (QName)qnameValue;
|
||||
}
|
||||
return constructQName(cx, qnameValue);
|
||||
}
|
||||
|
||||
QName constructQName(Context cx, Object nameValue)
|
||||
{
|
||||
QName result;
|
||||
|
||||
if (nameValue instanceof QName) {
|
||||
QName qname = (QName)nameValue;
|
||||
result = new QName(this, qname.uri(), qname.localName(),
|
||||
qname.prefix());
|
||||
} else {
|
||||
String localName = ScriptRuntime.toString(nameValue);
|
||||
result = constructQNameFromString(cx, localName);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimized version of constructQName for String type
|
||||
*/
|
||||
QName constructQNameFromString(Context cx, String localName)
|
||||
{
|
||||
if (localName == null)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
String uri;
|
||||
String prefix;
|
||||
|
||||
if ("*".equals(localName)) {
|
||||
uri = null;
|
||||
prefix = null;
|
||||
} else {
|
||||
Namespace ns = getDefaultNamespace(cx);
|
||||
uri = ns.uri();
|
||||
prefix = ns.prefix();
|
||||
}
|
||||
|
||||
return new QName(this, uri, localName, prefix);
|
||||
}
|
||||
|
||||
QName constructQName(Context cx, Object namespaceValue, Object nameValue)
|
||||
{
|
||||
String uri;
|
||||
String localName;
|
||||
String prefix;
|
||||
|
||||
if (nameValue instanceof QName) {
|
||||
QName qname = (QName)nameValue;
|
||||
localName = qname.localName();
|
||||
} else {
|
||||
localName = ScriptRuntime.toString(nameValue);
|
||||
}
|
||||
|
||||
Namespace ns;
|
||||
if (namespaceValue == Undefined.instance) {
|
||||
if ("*".equals(localName)) {
|
||||
ns = null;
|
||||
} else {
|
||||
ns = getDefaultNamespace(cx);
|
||||
}
|
||||
} else if (namespaceValue == null) {
|
||||
ns = null;
|
||||
} else if (namespaceValue instanceof Namespace) {
|
||||
ns = (Namespace)namespaceValue;
|
||||
} else {
|
||||
ns = constructNamespace(cx, namespaceValue);
|
||||
}
|
||||
|
||||
if (ns == null) {
|
||||
uri = null;
|
||||
prefix = null;
|
||||
} else {
|
||||
uri = ns.uri();
|
||||
prefix = ns.prefix();
|
||||
}
|
||||
|
||||
return new QName(this, uri, localName, prefix);
|
||||
}
|
||||
|
||||
Object addXMLObjects(Context cx, XMLObject obj1, XMLObject obj2)
|
||||
{
|
||||
XMLList listToAdd = new XMLList(this);
|
||||
|
||||
if (obj1 instanceof XMLList) {
|
||||
XMLList list1 = (XMLList)obj1;
|
||||
if (list1.length() == 1) {
|
||||
listToAdd.addToList(list1.item(0));
|
||||
} else {
|
||||
// Might be xmlFragment + xmlFragment + xmlFragment + ...;
|
||||
// then the result will be an XMLList which we want to be an
|
||||
// rValue and allow it to be assigned to an lvalue.
|
||||
listToAdd = new XMLList(this, obj1);
|
||||
}
|
||||
} else {
|
||||
listToAdd.addToList(obj1);
|
||||
}
|
||||
|
||||
if (obj2 instanceof XMLList) {
|
||||
XMLList list2 = (XMLList)obj2;
|
||||
for (int i = 0; i < list2.length(); i++) {
|
||||
listToAdd.addToList(list2.item(i));
|
||||
}
|
||||
} else if (obj2 instanceof XML) {
|
||||
listToAdd.addToList(obj2);
|
||||
}
|
||||
|
||||
return listToAdd;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// Overriding XMLLib methods
|
||||
//
|
||||
//
|
||||
|
||||
/**
|
||||
* See E4X 13.1.2.1.
|
||||
*/
|
||||
public boolean isXMLName(Context cx, Object nameObj)
|
||||
{
|
||||
String name;
|
||||
try {
|
||||
name = ScriptRuntime.toString(nameObj);
|
||||
} catch (EcmaError ee) {
|
||||
if ("TypeError".equals(ee.getName())) {
|
||||
return false;
|
||||
}
|
||||
throw ee;
|
||||
}
|
||||
|
||||
// See http://w3.org/TR/xml-names11/#NT-NCName
|
||||
int length = name.length();
|
||||
if (length != 0) {
|
||||
if (isNCNameStartChar(name.charAt(0))) {
|
||||
for (int i = 1; i != length; ++i) {
|
||||
if (!isNCNameChar(name.charAt(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isNCNameStartChar(int c)
|
||||
{
|
||||
if ((c & ~0x7F) == 0) {
|
||||
// Optimize for ASCII and use A..Z < _ < a..z
|
||||
if (c >= 'a') {
|
||||
return c <= 'z';
|
||||
} else if (c >= 'A') {
|
||||
if (c <= 'Z') {
|
||||
return true;
|
||||
}
|
||||
return c == '_';
|
||||
}
|
||||
} else if ((c & ~0x1FFF) == 0) {
|
||||
return (0xC0 <= c && c <= 0xD6)
|
||||
|| (0xD8 <= c && c <= 0xF6)
|
||||
|| (0xF8 <= c && c <= 0x2FF)
|
||||
|| (0x370 <= c && c <= 0x37D)
|
||||
|| 0x37F <= c;
|
||||
}
|
||||
return (0x200C <= c && c <= 0x200D)
|
||||
|| (0x2070 <= c && c <= 0x218F)
|
||||
|| (0x2C00 <= c && c <= 0x2FEF)
|
||||
|| (0x3001 <= c && c <= 0xD7FF)
|
||||
|| (0xF900 <= c && c <= 0xFDCF)
|
||||
|| (0xFDF0 <= c && c <= 0xFFFD)
|
||||
|| (0x10000 <= c && c <= 0xEFFFF);
|
||||
}
|
||||
|
||||
private static boolean isNCNameChar(int c)
|
||||
{
|
||||
if ((c & ~0x7F) == 0) {
|
||||
// Optimize for ASCII and use - < . < 0..9 < A..Z < _ < a..z
|
||||
if (c >= 'a') {
|
||||
return c <= 'z';
|
||||
} else if (c >= 'A') {
|
||||
if (c <= 'Z') {
|
||||
return true;
|
||||
}
|
||||
return c == '_';
|
||||
} else if (c >= '0') {
|
||||
return c <= '9';
|
||||
} else {
|
||||
return c == '-' || c == '.';
|
||||
}
|
||||
} else if ((c & ~0x1FFF) == 0) {
|
||||
return isNCNameStartChar(c) || c == 0xB7
|
||||
|| (0x300 <= c && c <= 0x36F);
|
||||
}
|
||||
return isNCNameStartChar(c) || (0x203F <= c && c <= 0x2040);
|
||||
}
|
||||
|
||||
XMLName toQualifiedName(Context cx, Object namespaceValue,
|
||||
Object nameValue)
|
||||
{
|
||||
// This is duplication of constructQName(cx, namespaceValue, nameValue)
|
||||
// but for XMLName
|
||||
|
||||
String uri;
|
||||
String localName;
|
||||
|
||||
if (nameValue instanceof QName) {
|
||||
QName qname = (QName)nameValue;
|
||||
localName = qname.localName();
|
||||
} else {
|
||||
localName = ScriptRuntime.toString(nameValue);
|
||||
}
|
||||
|
||||
Namespace ns;
|
||||
if (namespaceValue == Undefined.instance) {
|
||||
if ("*".equals(localName)) {
|
||||
ns = null;
|
||||
} else {
|
||||
ns = getDefaultNamespace(cx);
|
||||
}
|
||||
} else if (namespaceValue == null) {
|
||||
ns = null;
|
||||
} else if (namespaceValue instanceof Namespace) {
|
||||
ns = (Namespace)namespaceValue;
|
||||
} else {
|
||||
ns = constructNamespace(cx, namespaceValue);
|
||||
}
|
||||
|
||||
if (ns == null) {
|
||||
uri = null;
|
||||
} else {
|
||||
uri = ns.uri();
|
||||
}
|
||||
|
||||
return XMLName.formProperty(uri, localName);
|
||||
}
|
||||
|
||||
public Ref nameRef(Context cx, Object name,
|
||||
Scriptable scope, int memberTypeFlags)
|
||||
{
|
||||
if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) == 0) {
|
||||
// should only be called foir cases like @name or @[expr]
|
||||
throw Kit.codeBug();
|
||||
}
|
||||
XMLName xmlName = toAttributeName(cx, name);
|
||||
return xmlPrimaryReference(cx, xmlName, scope);
|
||||
}
|
||||
|
||||
public Ref nameRef(Context cx, Object namespace, Object name,
|
||||
Scriptable scope, int memberTypeFlags)
|
||||
{
|
||||
XMLName xmlName = toQualifiedName(cx, namespace, name);
|
||||
if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) != 0) {
|
||||
if (!xmlName.isAttributeName()) {
|
||||
xmlName.setAttributeName();
|
||||
}
|
||||
}
|
||||
return xmlPrimaryReference(cx, xmlName, scope);
|
||||
}
|
||||
|
||||
private Ref xmlPrimaryReference(Context cx, XMLName xmlName,
|
||||
Scriptable scope)
|
||||
{
|
||||
XMLObjectImpl xmlObj;
|
||||
XMLObjectImpl firstXmlObject = null;
|
||||
for (;;) {
|
||||
// XML object can only present on scope chain as a wrapper
|
||||
// of XMLWithScope
|
||||
if (scope instanceof XMLWithScope) {
|
||||
xmlObj = (XMLObjectImpl)scope.getPrototype();
|
||||
if (xmlObj.hasXMLProperty(xmlName)) {
|
||||
break;
|
||||
}
|
||||
if (firstXmlObject == null) {
|
||||
firstXmlObject = xmlObj;
|
||||
}
|
||||
}
|
||||
scope = scope.getParentScope();
|
||||
if (scope == null) {
|
||||
xmlObj = firstXmlObject;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// xmlObj == null corresponds to undefined as the target of
|
||||
// the reference
|
||||
if (xmlObj != null) {
|
||||
xmlName.initXMLObject(xmlObj);
|
||||
}
|
||||
return xmlName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes the reserved characters in a value of an attribute
|
||||
*
|
||||
* @param value Unescaped text
|
||||
* @return The escaped text
|
||||
*/
|
||||
public String escapeAttributeValue(Object value)
|
||||
{
|
||||
String text = ScriptRuntime.toString(value);
|
||||
|
||||
if (text.length() == 0) return "";
|
||||
|
||||
XmlObject xo = XmlObject.Factory.newInstance();
|
||||
|
||||
XmlCursor cursor = xo.newCursor();
|
||||
cursor.toNextToken();
|
||||
cursor.beginElement("a");
|
||||
cursor.insertAttributeWithValue("a", text);
|
||||
cursor.dispose();
|
||||
|
||||
String elementText = xo.toString();
|
||||
int begin = elementText.indexOf('"');
|
||||
int end = elementText.lastIndexOf('"');
|
||||
return elementText.substring(begin + 1, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes the reserved characters in a value of a text node
|
||||
*
|
||||
* @param value Unescaped text
|
||||
* @return The escaped text
|
||||
*/
|
||||
public String escapeTextValue(Object value)
|
||||
{
|
||||
if (value instanceof XMLObjectImpl) {
|
||||
return ((XMLObjectImpl)value).toXMLString(0);
|
||||
}
|
||||
|
||||
String text = ScriptRuntime.toString(value);
|
||||
|
||||
if (text.length() == 0) return text;
|
||||
|
||||
XmlObject xo = XmlObject.Factory.newInstance();
|
||||
|
||||
XmlCursor cursor = xo.newCursor();
|
||||
cursor.toNextToken();
|
||||
cursor.beginElement("a");
|
||||
cursor.insertChars(text);
|
||||
cursor.dispose();
|
||||
|
||||
String elementText = xo.toString();
|
||||
int begin = elementText.indexOf('>') + 1;
|
||||
int end = elementText.lastIndexOf('<');
|
||||
return (begin < end) ? elementText.substring(begin, end) : "";
|
||||
}
|
||||
|
||||
public Object toDefaultXmlNamespace(Context cx, Object uriValue)
|
||||
{
|
||||
return constructNamespace(cx, uriValue);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,171 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov
|
||||
* Milen Nankov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript.xml.impl.xmlbeans;
|
||||
|
||||
import org.mozilla.javascript.Context;
|
||||
import org.mozilla.javascript.Kit;
|
||||
import org.mozilla.javascript.Ref;
|
||||
import org.mozilla.javascript.ScriptRuntime;
|
||||
import org.mozilla.javascript.Undefined;
|
||||
|
||||
class XMLName extends Ref
|
||||
{
|
||||
static final long serialVersionUID = 3832176310755686977L;
|
||||
|
||||
private String uri;
|
||||
private String localName;
|
||||
private boolean isAttributeName;
|
||||
private boolean isDescendants;
|
||||
private XMLObjectImpl xmlObject;
|
||||
|
||||
private XMLName(String uri, String localName)
|
||||
{
|
||||
this.uri = uri;
|
||||
this.localName = localName;
|
||||
}
|
||||
|
||||
static XMLName formStar()
|
||||
{
|
||||
return new XMLName(null, "*");
|
||||
}
|
||||
|
||||
static XMLName formProperty(String uri, String localName)
|
||||
{
|
||||
return new XMLName(uri, localName);
|
||||
}
|
||||
|
||||
void initXMLObject(XMLObjectImpl xmlObject)
|
||||
{
|
||||
if (xmlObject == null) throw new IllegalArgumentException();
|
||||
if (this.xmlObject != null) throw new IllegalStateException();
|
||||
this.xmlObject = xmlObject;
|
||||
}
|
||||
|
||||
String uri()
|
||||
{
|
||||
return uri;
|
||||
}
|
||||
|
||||
String localName()
|
||||
{
|
||||
return localName;
|
||||
}
|
||||
|
||||
boolean isAttributeName()
|
||||
{
|
||||
return isAttributeName;
|
||||
}
|
||||
|
||||
void setAttributeName()
|
||||
{
|
||||
if (isAttributeName) throw new IllegalStateException();
|
||||
isAttributeName = true;
|
||||
}
|
||||
|
||||
boolean isDescendants()
|
||||
{
|
||||
return isDescendants;
|
||||
}
|
||||
|
||||
void setIsDescendants()
|
||||
{
|
||||
if (isDescendants) throw new IllegalStateException();
|
||||
isDescendants = true;
|
||||
}
|
||||
|
||||
public boolean has(Context cx)
|
||||
{
|
||||
if (xmlObject == null) {
|
||||
return false;
|
||||
}
|
||||
return xmlObject.hasXMLProperty(this);
|
||||
}
|
||||
|
||||
public Object get(Context cx)
|
||||
{
|
||||
if (xmlObject == null) {
|
||||
throw ScriptRuntime.undefReadError(Undefined.instance,
|
||||
toString());
|
||||
}
|
||||
return xmlObject.getXMLProperty(this);
|
||||
}
|
||||
|
||||
public Object set(Context cx, Object value)
|
||||
{
|
||||
if (xmlObject == null) {
|
||||
throw ScriptRuntime.undefWriteError(Undefined.instance,
|
||||
toString(),
|
||||
value);
|
||||
}
|
||||
// Assignment to descendants causes parse error on bad reference
|
||||
// and this should not be called
|
||||
if (isDescendants) throw Kit.codeBug();
|
||||
xmlObject.putXMLProperty(this, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean delete(Context cx)
|
||||
{
|
||||
if (xmlObject == null) {
|
||||
return true;
|
||||
}
|
||||
xmlObject.deleteXMLProperty(this);
|
||||
return !xmlObject.hasXMLProperty(this);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
//return qname.localName();
|
||||
StringBuffer buff = new StringBuffer();
|
||||
if (isDescendants) buff.append("..");
|
||||
if (isAttributeName) buff.append('@');
|
||||
if (uri == null) {
|
||||
buff.append('*');
|
||||
if(localName().equals("*")) {
|
||||
return buff.toString();
|
||||
}
|
||||
} else {
|
||||
buff.append('"').append(uri()).append('"');
|
||||
}
|
||||
buff.append(':').append(localName());
|
||||
return buff.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,724 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov
|
||||
* Ethan Hugg
|
||||
* Terry Lucas
|
||||
* Milen Nankov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript.xml.impl.xmlbeans;
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
import org.mozilla.javascript.xml.*;
|
||||
|
||||
/**
|
||||
* This abstract class describes what all XML objects (XML, XMLList) should have in common.
|
||||
*
|
||||
* @see XML
|
||||
*/
|
||||
abstract class XMLObjectImpl extends XMLObject
|
||||
{
|
||||
private static final Object XMLOBJECT_TAG = "XMLObject";
|
||||
|
||||
protected final XMLLibImpl lib;
|
||||
protected boolean prototypeFlag;
|
||||
|
||||
protected XMLObjectImpl(XMLLibImpl lib, XMLObject prototype)
|
||||
{
|
||||
super(lib.globalScope(), prototype);
|
||||
this.lib = lib;
|
||||
}
|
||||
|
||||
/**
|
||||
* ecmaHas(cx, id) calls this after resolving when id to XMLName
|
||||
* and checking it is not Uint32 index.
|
||||
*/
|
||||
abstract boolean hasXMLProperty(XMLName name);
|
||||
|
||||
/**
|
||||
* ecmaGet(cx, id) calls this after resolving when id to XMLName
|
||||
* and checking it is not Uint32 index.
|
||||
*/
|
||||
abstract Object getXMLProperty(XMLName name);
|
||||
|
||||
/**
|
||||
* ecmaPut(cx, id, value) calls this after resolving when id to XMLName
|
||||
* and checking it is not Uint32 index.
|
||||
*/
|
||||
abstract void putXMLProperty(XMLName name, Object value);
|
||||
|
||||
/**
|
||||
* ecmaDelete(cx, id) calls this after resolving when id to XMLName
|
||||
* and checking it is not Uint32 index.
|
||||
*/
|
||||
abstract void deleteXMLProperty(XMLName name);
|
||||
|
||||
/**
|
||||
* Test XML equality with target the target.
|
||||
*/
|
||||
abstract boolean equivalentXml(Object target);
|
||||
|
||||
// Methods from section 12.4.4 in the spec
|
||||
abstract XML addNamespace(Namespace ns);
|
||||
abstract XML appendChild(Object xml);
|
||||
abstract XMLList attribute(XMLName xmlName);
|
||||
abstract XMLList attributes();
|
||||
abstract XMLList child(long index);
|
||||
abstract XMLList child(XMLName xmlName);
|
||||
abstract int childIndex();
|
||||
abstract XMLList children();
|
||||
abstract XMLList comments();
|
||||
abstract boolean contains(Object xml);
|
||||
abstract Object copy();
|
||||
abstract XMLList descendants(XMLName xmlName);
|
||||
abstract Object[] inScopeNamespaces();
|
||||
abstract XML insertChildAfter(Object child, Object xml);
|
||||
abstract XML insertChildBefore(Object child, Object xml);
|
||||
abstract boolean hasOwnProperty(XMLName xmlName);
|
||||
abstract boolean hasComplexContent();
|
||||
abstract boolean hasSimpleContent();
|
||||
abstract int length();
|
||||
abstract String localName();
|
||||
abstract QName name();
|
||||
abstract Object namespace(String prefix);
|
||||
abstract Object[] namespaceDeclarations();
|
||||
abstract Object nodeKind();
|
||||
abstract void normalize();
|
||||
abstract Object parent();
|
||||
abstract XML prependChild(Object xml);
|
||||
abstract Object processingInstructions(XMLName xmlName);
|
||||
abstract boolean propertyIsEnumerable(Object member);
|
||||
abstract XML removeNamespace(Namespace ns);
|
||||
abstract XML replace(long index, Object xml);
|
||||
abstract XML replace(XMLName name, Object xml);
|
||||
abstract XML setChildren(Object xml);
|
||||
abstract void setLocalName(String name);
|
||||
abstract void setName(QName xmlName);
|
||||
abstract void setNamespace(Namespace ns);
|
||||
abstract XMLList text();
|
||||
public abstract String toString();
|
||||
abstract String toSource(int indent);
|
||||
abstract String toXMLString(int indent);
|
||||
abstract Object valueOf();
|
||||
|
||||
/**
|
||||
* Extension to access native implementation from scripts
|
||||
*/
|
||||
abstract org.apache.xmlbeans.XmlObject getXmlObject();
|
||||
|
||||
protected abstract Object jsConstructor(Context cx, boolean inNewExpr,
|
||||
Object[] args);
|
||||
|
||||
|
||||
final Object getMethod(String id)
|
||||
{
|
||||
return super.get(id, this);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// Methods overriding ScriptableObject
|
||||
//
|
||||
//
|
||||
|
||||
public final Object getDefaultValue(Class hint)
|
||||
{
|
||||
return toString();
|
||||
}
|
||||
|
||||
public void delete(String name)
|
||||
{
|
||||
throw new IllegalArgumentException("String: [" + name + "]");
|
||||
}
|
||||
|
||||
/**
|
||||
* XMLObject always compare with any value and equivalentValues
|
||||
* never returns {@link Scriptable#NOT_FOUND} for them but rather
|
||||
* calls equivalentXml(value) and wrap the result as Boolean.
|
||||
*/
|
||||
protected final Object equivalentValues(Object value)
|
||||
{
|
||||
boolean result = equivalentXml(value);
|
||||
return result ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// Methods overriding XMLObject
|
||||
//
|
||||
//
|
||||
|
||||
public final XMLLib lib()
|
||||
{
|
||||
return lib;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ECMAScript [[Has]]
|
||||
*/
|
||||
public final boolean ecmaHas(Context cx, Object id)
|
||||
{
|
||||
if (cx == null) cx = Context.getCurrentContext();
|
||||
XMLName xmlName = lib.toXMLNameOrIndex(cx, id);
|
||||
if (xmlName == null) {
|
||||
long index = ScriptRuntime.lastUint32Result(cx);
|
||||
// XXX Fix this cast
|
||||
return has((int)index, this);
|
||||
}
|
||||
return hasXMLProperty(xmlName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ECMAScript [[Get]]
|
||||
*/
|
||||
public final Object ecmaGet(Context cx, Object id)
|
||||
{
|
||||
if (cx == null) cx = Context.getCurrentContext();
|
||||
XMLName xmlName = lib.toXMLNameOrIndex(cx, id);
|
||||
if (xmlName == null) {
|
||||
long index = ScriptRuntime.lastUint32Result(cx);
|
||||
// XXX Fix this cast
|
||||
Object result = get((int)index, this);
|
||||
if (result == Scriptable.NOT_FOUND) {
|
||||
result = Undefined.instance;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return getXMLProperty(xmlName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ECMAScript [[Put]]
|
||||
*/
|
||||
public final void ecmaPut(Context cx, Object id, Object value)
|
||||
{
|
||||
if (cx == null) cx = Context.getCurrentContext();
|
||||
XMLName xmlName = lib.toXMLNameOrIndex(cx, id);
|
||||
if (xmlName == null) {
|
||||
long index = ScriptRuntime.lastUint32Result(cx);
|
||||
// XXX Fix this cast
|
||||
put((int)index, this, value);
|
||||
return;
|
||||
}
|
||||
putXMLProperty(xmlName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ECMAScript [[Delete]].
|
||||
*/
|
||||
public final boolean ecmaDelete(Context cx, Object id)
|
||||
{
|
||||
if (cx == null) cx = Context.getCurrentContext();
|
||||
XMLName xmlName = lib.toXMLNameOrIndex(cx, id);
|
||||
if (xmlName == null) {
|
||||
long index = ScriptRuntime.lastUint32Result(cx);
|
||||
// XXX Fix this
|
||||
delete((int)index);
|
||||
return true;
|
||||
}
|
||||
deleteXMLProperty(xmlName);
|
||||
return true;
|
||||
}
|
||||
|
||||
public Ref memberRef(Context cx, Object elem, int memberTypeFlags)
|
||||
{
|
||||
XMLName xmlName;
|
||||
if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) != 0) {
|
||||
xmlName = lib.toAttributeName(cx, elem);
|
||||
} else {
|
||||
if ((memberTypeFlags & Node.DESCENDANTS_FLAG) == 0) {
|
||||
// Code generation would use ecma(Get|Has|Delete|Set) for
|
||||
// normal name idenrifiers so one ATTRIBUTE_FLAG
|
||||
// or DESCENDANTS_FLAG has to be set
|
||||
throw Kit.codeBug();
|
||||
}
|
||||
xmlName = lib.toXMLName(cx, elem);
|
||||
}
|
||||
if ((memberTypeFlags & Node.DESCENDANTS_FLAG) != 0) {
|
||||
xmlName.setIsDescendants();
|
||||
}
|
||||
xmlName.initXMLObject(this);
|
||||
return xmlName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic reference to implement x::ns, x.@ns::y, x..@ns::y etc.
|
||||
*/
|
||||
public Ref memberRef(Context cx, Object namespace, Object elem,
|
||||
int memberTypeFlags)
|
||||
{
|
||||
XMLName xmlName = lib.toQualifiedName(cx, namespace, elem);
|
||||
if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) != 0) {
|
||||
if (!xmlName.isAttributeName()) {
|
||||
xmlName.setAttributeName();
|
||||
}
|
||||
}
|
||||
if ((memberTypeFlags & Node.DESCENDANTS_FLAG) != 0) {
|
||||
xmlName.setIsDescendants();
|
||||
}
|
||||
xmlName.initXMLObject(this);
|
||||
return xmlName;
|
||||
}
|
||||
|
||||
public NativeWith enterWith(Scriptable scope)
|
||||
{
|
||||
return new XMLWithScope(lib, scope, this);
|
||||
}
|
||||
|
||||
public NativeWith enterDotQuery(Scriptable scope)
|
||||
{
|
||||
XMLWithScope xws = new XMLWithScope(lib, scope, this);
|
||||
xws.initAsDotQuery();
|
||||
return xws;
|
||||
}
|
||||
|
||||
public final Object addValues(Context cx, boolean thisIsLeft,
|
||||
Object value)
|
||||
{
|
||||
if (value instanceof XMLObject) {
|
||||
XMLObject v1, v2;
|
||||
if (thisIsLeft) {
|
||||
v1 = this;
|
||||
v2 = (XMLObject)value;
|
||||
} else {
|
||||
v1 = (XMLObject)value;
|
||||
v2 = this;
|
||||
}
|
||||
return lib.addXMLObjects(cx, v1, v2);
|
||||
}
|
||||
if (value == Undefined.instance) {
|
||||
// both "xml + undefined" and "undefined + xml" gives String(xml)
|
||||
return ScriptRuntime.toString(this);
|
||||
}
|
||||
|
||||
return super.addValues(cx, thisIsLeft, value);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// IdScriptableObject machinery
|
||||
//
|
||||
//
|
||||
|
||||
final void exportAsJSClass(boolean sealed)
|
||||
{
|
||||
prototypeFlag = true;
|
||||
exportAsJSClass(MAX_PROTOTYPE_ID, lib.globalScope(), sealed);
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
private final static int
|
||||
Id_constructor = 1,
|
||||
|
||||
Id_addNamespace = 2,
|
||||
Id_appendChild = 3,
|
||||
Id_attribute = 4,
|
||||
Id_attributes = 5,
|
||||
Id_child = 6,
|
||||
Id_childIndex = 7,
|
||||
Id_children = 8,
|
||||
Id_comments = 9,
|
||||
Id_contains = 10,
|
||||
Id_copy = 11,
|
||||
Id_descendants = 12,
|
||||
Id_inScopeNamespaces = 13,
|
||||
Id_insertChildAfter = 14,
|
||||
Id_insertChildBefore = 15,
|
||||
Id_hasOwnProperty = 16,
|
||||
Id_hasComplexContent = 17,
|
||||
Id_hasSimpleContent = 18,
|
||||
Id_length = 19,
|
||||
Id_localName = 20,
|
||||
Id_name = 21,
|
||||
Id_namespace = 22,
|
||||
Id_namespaceDeclarations = 23,
|
||||
Id_nodeKind = 24,
|
||||
Id_normalize = 25,
|
||||
Id_parent = 26,
|
||||
Id_prependChild = 27,
|
||||
Id_processingInstructions = 28,
|
||||
Id_propertyIsEnumerable = 29,
|
||||
Id_removeNamespace = 30,
|
||||
Id_replace = 31,
|
||||
Id_setChildren = 32,
|
||||
Id_setLocalName = 33,
|
||||
Id_setName = 34,
|
||||
Id_setNamespace = 35,
|
||||
Id_text = 36,
|
||||
Id_toString = 37,
|
||||
Id_toSource = 38,
|
||||
Id_toXMLString = 39,
|
||||
Id_valueOf = 40,
|
||||
|
||||
Id_getXmlObject = 41,
|
||||
|
||||
MAX_PROTOTYPE_ID = 41;
|
||||
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2004-11-10 15:38:11 CET
|
||||
L0: { id = 0; String X = null; int c;
|
||||
L: switch (s.length()) {
|
||||
case 4: c=s.charAt(0);
|
||||
if (c=='c') { X="copy";id=Id_copy; }
|
||||
else if (c=='n') { X="name";id=Id_name; }
|
||||
else if (c=='t') { X="text";id=Id_text; }
|
||||
break L;
|
||||
case 5: X="child";id=Id_child; break L;
|
||||
case 6: c=s.charAt(0);
|
||||
if (c=='l') { X="length";id=Id_length; }
|
||||
else if (c=='p') { X="parent";id=Id_parent; }
|
||||
break L;
|
||||
case 7: c=s.charAt(0);
|
||||
if (c=='r') { X="replace";id=Id_replace; }
|
||||
else if (c=='s') { X="setName";id=Id_setName; }
|
||||
else if (c=='v') { X="valueOf";id=Id_valueOf; }
|
||||
break L;
|
||||
case 8: switch (s.charAt(4)) {
|
||||
case 'K': X="nodeKind";id=Id_nodeKind; break L;
|
||||
case 'a': X="contains";id=Id_contains; break L;
|
||||
case 'd': X="children";id=Id_children; break L;
|
||||
case 'e': X="comments";id=Id_comments; break L;
|
||||
case 'r': X="toString";id=Id_toString; break L;
|
||||
case 'u': X="toSource";id=Id_toSource; break L;
|
||||
} break L;
|
||||
case 9: switch (s.charAt(2)) {
|
||||
case 'c': X="localName";id=Id_localName; break L;
|
||||
case 'm': X="namespace";id=Id_namespace; break L;
|
||||
case 'r': X="normalize";id=Id_normalize; break L;
|
||||
case 't': X="attribute";id=Id_attribute; break L;
|
||||
} break L;
|
||||
case 10: c=s.charAt(0);
|
||||
if (c=='a') { X="attributes";id=Id_attributes; }
|
||||
else if (c=='c') { X="childIndex";id=Id_childIndex; }
|
||||
break L;
|
||||
case 11: switch (s.charAt(0)) {
|
||||
case 'a': X="appendChild";id=Id_appendChild; break L;
|
||||
case 'c': X="constructor";id=Id_constructor; break L;
|
||||
case 'd': X="descendants";id=Id_descendants; break L;
|
||||
case 's': X="setChildren";id=Id_setChildren; break L;
|
||||
case 't': X="toXMLString";id=Id_toXMLString; break L;
|
||||
} break L;
|
||||
case 12: switch (s.charAt(0)) {
|
||||
case 'a': X="addNamespace";id=Id_addNamespace; break L;
|
||||
case 'g': X="getXmlObject";id=Id_getXmlObject; break L;
|
||||
case 'p': X="prependChild";id=Id_prependChild; break L;
|
||||
case 's': c=s.charAt(3);
|
||||
if (c=='L') { X="setLocalName";id=Id_setLocalName; }
|
||||
else if (c=='N') { X="setNamespace";id=Id_setNamespace; }
|
||||
break L;
|
||||
} break L;
|
||||
case 14: X="hasOwnProperty";id=Id_hasOwnProperty; break L;
|
||||
case 15: X="removeNamespace";id=Id_removeNamespace; break L;
|
||||
case 16: c=s.charAt(0);
|
||||
if (c=='h') { X="hasSimpleContent";id=Id_hasSimpleContent; }
|
||||
else if (c=='i') { X="insertChildAfter";id=Id_insertChildAfter; }
|
||||
break L;
|
||||
case 17: c=s.charAt(3);
|
||||
if (c=='C') { X="hasComplexContent";id=Id_hasComplexContent; }
|
||||
else if (c=='c') { X="inScopeNamespaces";id=Id_inScopeNamespaces; }
|
||||
else if (c=='e') { X="insertChildBefore";id=Id_insertChildBefore; }
|
||||
break L;
|
||||
case 20: X="propertyIsEnumerable";id=Id_propertyIsEnumerable; break L;
|
||||
case 21: X="namespaceDeclarations";id=Id_namespaceDeclarations; break L;
|
||||
case 22: X="processingInstructions";id=Id_processingInstructions; break L;
|
||||
}
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
}
|
||||
// #/generated#
|
||||
return id;
|
||||
}
|
||||
// #/string_id_map#
|
||||
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_constructor: {
|
||||
IdFunctionObject ctor;
|
||||
if (this instanceof XML) {
|
||||
ctor = new XMLCtor((XML)this, XMLOBJECT_TAG, id, 1);
|
||||
} else {
|
||||
ctor = new IdFunctionObject(this, XMLOBJECT_TAG, id, 1);
|
||||
}
|
||||
initPrototypeConstructor(ctor);
|
||||
return;
|
||||
}
|
||||
|
||||
case Id_addNamespace: arity=1; s="addNamespace"; break;
|
||||
case Id_appendChild: arity=1; s="appendChild"; break;
|
||||
case Id_attribute: arity=1; s="attribute"; break;
|
||||
case Id_attributes: arity=0; s="attributes"; break;
|
||||
case Id_child: arity=1; s="child"; break;
|
||||
case Id_childIndex: arity=0; s="childIndex"; break;
|
||||
case Id_children: arity=0; s="children"; break;
|
||||
case Id_comments: arity=0; s="comments"; break;
|
||||
case Id_contains: arity=1; s="contains"; break;
|
||||
case Id_copy: arity=0; s="copy"; break;
|
||||
case Id_descendants: arity=1; s="descendants"; break;
|
||||
case Id_hasComplexContent: arity=0; s="hasComplexContent"; break;
|
||||
case Id_hasOwnProperty: arity=1; s="hasOwnProperty"; break;
|
||||
case Id_hasSimpleContent: arity=0; s="hasSimpleContent"; break;
|
||||
case Id_inScopeNamespaces: arity=0; s="inScopeNamespaces"; break;
|
||||
case Id_insertChildAfter: arity=2; s="insertChildAfter"; break;
|
||||
case Id_insertChildBefore: arity=2; s="insertChildBefore"; break;
|
||||
case Id_length: arity=0; s="length"; break;
|
||||
case Id_localName: arity=0; s="localName"; break;
|
||||
case Id_name: arity=0; s="name"; break;
|
||||
case Id_namespace: arity=1; s="namespace"; break;
|
||||
case Id_namespaceDeclarations:
|
||||
arity=0; s="namespaceDeclarations"; break;
|
||||
case Id_nodeKind: arity=0; s="nodeKind"; break;
|
||||
case Id_normalize: arity=0; s="normalize"; break;
|
||||
case Id_parent: arity=0; s="parent"; break;
|
||||
case Id_prependChild: arity=1; s="prependChild"; break;
|
||||
case Id_processingInstructions:
|
||||
arity=1; s="processingInstructions"; break;
|
||||
case Id_propertyIsEnumerable:
|
||||
arity=1; s="propertyIsEnumerable"; break;
|
||||
case Id_removeNamespace: arity=1; s="removeNamespace"; break;
|
||||
case Id_replace: arity=2; s="replace"; break;
|
||||
case Id_setChildren: arity=1; s="setChildren"; break;
|
||||
case Id_setLocalName: arity=1; s="setLocalName"; break;
|
||||
case Id_setName: arity=1; s="setName"; break;
|
||||
case Id_setNamespace: arity=1; s="setNamespace"; break;
|
||||
case Id_text: arity=0; s="text"; break;
|
||||
case Id_toString: arity=0; s="toString"; break;
|
||||
case Id_toSource: arity=1; s="toSource"; break;
|
||||
case Id_toXMLString: arity=1; s="toXMLString"; break;
|
||||
case Id_valueOf: arity=0; s="valueOf"; break;
|
||||
|
||||
case Id_getXmlObject: arity=0; s="getXmlObject"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(XMLOBJECT_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param f
|
||||
* @param cx
|
||||
* @param scope
|
||||
* @param thisObj
|
||||
* @param args
|
||||
* @return
|
||||
*/
|
||||
public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (!f.hasTag(XMLOBJECT_TAG)) {
|
||||
return super.execIdCall(f, cx, scope, thisObj, args);
|
||||
}
|
||||
int id = f.methodId();
|
||||
if (id == Id_constructor) {
|
||||
return jsConstructor(cx, thisObj == null, args);
|
||||
}
|
||||
|
||||
// All (XML|XMLList).prototype methods require thisObj to be XML
|
||||
if (!(thisObj instanceof XMLObjectImpl))
|
||||
throw incompatibleCallError(f);
|
||||
XMLObjectImpl realThis = (XMLObjectImpl)thisObj;
|
||||
|
||||
switch (id) {
|
||||
case Id_addNamespace: {
|
||||
Namespace ns = lib.castToNamespace(cx, arg(args, 0));
|
||||
return realThis.addNamespace(ns);
|
||||
}
|
||||
case Id_appendChild:
|
||||
return realThis.appendChild(arg(args, 0));
|
||||
case Id_attribute: {
|
||||
XMLName xmlName = lib.toAttributeName(cx, arg(args, 0));
|
||||
return realThis.attribute(xmlName);
|
||||
}
|
||||
case Id_attributes:
|
||||
return realThis.attributes();
|
||||
case Id_child: {
|
||||
XMLName xmlName = lib.toXMLNameOrIndex(cx, arg(args, 0));
|
||||
if (xmlName == null) {
|
||||
long index = ScriptRuntime.lastUint32Result(cx);
|
||||
return realThis.child(index);
|
||||
} else {
|
||||
return realThis.child(xmlName);
|
||||
}
|
||||
}
|
||||
case Id_childIndex:
|
||||
return ScriptRuntime.wrapInt(realThis.childIndex());
|
||||
case Id_children:
|
||||
return realThis.children();
|
||||
case Id_comments:
|
||||
return realThis.comments();
|
||||
case Id_contains:
|
||||
return ScriptRuntime.wrapBoolean(
|
||||
realThis.contains(arg(args, 0)));
|
||||
case Id_copy:
|
||||
return realThis.copy();
|
||||
case Id_descendants: {
|
||||
XMLName xmlName = (args.length == 0)
|
||||
? XMLName.formStar()
|
||||
: lib.toXMLName(cx, args[0]);
|
||||
return realThis.descendants(xmlName);
|
||||
}
|
||||
case Id_inScopeNamespaces: {
|
||||
Object[] array = realThis.inScopeNamespaces();
|
||||
return cx.newArray(scope, array);
|
||||
}
|
||||
case Id_insertChildAfter:
|
||||
return realThis.insertChildAfter(arg(args, 0), arg(args, 1));
|
||||
case Id_insertChildBefore:
|
||||
return realThis.insertChildBefore(arg(args, 0), arg(args, 1));
|
||||
case Id_hasOwnProperty: {
|
||||
XMLName xmlName = lib.toXMLName(cx, arg(args, 0));
|
||||
return ScriptRuntime.wrapBoolean(
|
||||
realThis.hasOwnProperty(xmlName));
|
||||
}
|
||||
case Id_hasComplexContent:
|
||||
return ScriptRuntime.wrapBoolean(realThis.hasComplexContent());
|
||||
case Id_hasSimpleContent:
|
||||
return ScriptRuntime.wrapBoolean(realThis.hasSimpleContent());
|
||||
case Id_length:
|
||||
return ScriptRuntime.wrapInt(realThis.length());
|
||||
case Id_localName:
|
||||
return realThis.localName();
|
||||
case Id_name:
|
||||
return realThis.name();
|
||||
case Id_namespace: {
|
||||
String prefix = (args.length > 0)
|
||||
? ScriptRuntime.toString(args[0]) : null;
|
||||
return realThis.namespace(prefix);
|
||||
}
|
||||
case Id_namespaceDeclarations: {
|
||||
Object[] array = realThis.namespaceDeclarations();
|
||||
return cx.newArray(scope, array);
|
||||
}
|
||||
case Id_nodeKind:
|
||||
return realThis.nodeKind();
|
||||
case Id_normalize:
|
||||
realThis.normalize();
|
||||
return Undefined.instance;
|
||||
case Id_parent:
|
||||
return realThis.parent();
|
||||
case Id_prependChild:
|
||||
return realThis.prependChild(arg(args, 0));
|
||||
case Id_processingInstructions: {
|
||||
XMLName xmlName = (args.length > 0)
|
||||
? lib.toXMLName(cx, args[0])
|
||||
: XMLName.formStar();
|
||||
return realThis.processingInstructions(xmlName);
|
||||
}
|
||||
case Id_propertyIsEnumerable: {
|
||||
return ScriptRuntime.wrapBoolean(
|
||||
realThis.propertyIsEnumerable(arg(args, 0)));
|
||||
}
|
||||
case Id_removeNamespace: {
|
||||
Namespace ns = lib.castToNamespace(cx, arg(args, 0));
|
||||
return realThis.removeNamespace(ns);
|
||||
}
|
||||
case Id_replace: {
|
||||
XMLName xmlName = lib.toXMLNameOrIndex(cx, arg(args, 0));
|
||||
Object arg1 = arg(args, 1);
|
||||
if (xmlName == null) {
|
||||
long index = ScriptRuntime.lastUint32Result(cx);
|
||||
return realThis.replace(index, arg1);
|
||||
} else {
|
||||
return realThis.replace(xmlName, arg1);
|
||||
}
|
||||
}
|
||||
case Id_setChildren:
|
||||
return realThis.setChildren(arg(args, 0));
|
||||
case Id_setLocalName: {
|
||||
String localName;
|
||||
Object arg = arg(args, 0);
|
||||
if (arg instanceof QName) {
|
||||
localName = ((QName)arg).localName();
|
||||
} else {
|
||||
localName = ScriptRuntime.toString(arg);
|
||||
}
|
||||
realThis.setLocalName(localName);
|
||||
return Undefined.instance;
|
||||
}
|
||||
case Id_setName: {
|
||||
Object arg = (args.length != 0) ? args[0] : Undefined.instance;
|
||||
QName qname;
|
||||
if (arg instanceof QName) {
|
||||
qname = (QName)arg;
|
||||
if (qname.uri() == null) {
|
||||
qname = lib.constructQNameFromString(cx, qname.localName());
|
||||
} else {
|
||||
// E4X 13.4.4.35 requires to always construct QName
|
||||
qname = lib.constructQName(cx, qname);
|
||||
}
|
||||
} else {
|
||||
qname = lib.constructQName(cx, arg);
|
||||
}
|
||||
realThis.setName(qname);
|
||||
return Undefined.instance;
|
||||
}
|
||||
case Id_setNamespace: {
|
||||
Namespace ns = lib.castToNamespace(cx, arg(args, 0));
|
||||
realThis.setNamespace(ns);
|
||||
return Undefined.instance;
|
||||
}
|
||||
case Id_text:
|
||||
return realThis.text();
|
||||
case Id_toString:
|
||||
return realThis.toString();
|
||||
case Id_toSource: {
|
||||
int indent = ScriptRuntime.toInt32(args, 0);
|
||||
return realThis.toSource(indent);
|
||||
}
|
||||
case Id_toXMLString: {
|
||||
int indent = ScriptRuntime.toInt32(args, 0);
|
||||
return realThis.toXMLString(indent);
|
||||
}
|
||||
case Id_valueOf:
|
||||
return realThis.valueOf();
|
||||
|
||||
case Id_getXmlObject: {
|
||||
org.apache.xmlbeans.XmlObject xmlObject = realThis.getXmlObject();
|
||||
return Context.javaToJS(xmlObject, scope);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
private static Object arg(Object[] args, int i)
|
||||
{
|
||||
return (i < args.length) ? args[i] : Undefined.instance;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Ethan Hugg
|
||||
* Terry Lucas
|
||||
* Milen Nankov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript.xml.impl.xmlbeans;
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
import org.mozilla.javascript.xml.*;
|
||||
|
||||
final class XMLWithScope extends NativeWith
|
||||
{
|
||||
private static final long serialVersionUID = -696429282095170887L;
|
||||
|
||||
private XMLLibImpl lib;
|
||||
private int _currIndex;
|
||||
private XMLList _xmlList;
|
||||
private XMLObject _dqPrototype;
|
||||
|
||||
XMLWithScope(XMLLibImpl lib, Scriptable parent, XMLObject prototype)
|
||||
{
|
||||
super(parent, prototype);
|
||||
this.lib = lib;
|
||||
}
|
||||
|
||||
void initAsDotQuery()
|
||||
{
|
||||
XMLObject prototype = (XMLObject)getPrototype();
|
||||
// XMLWithScope also handles the .(xxx) DotQuery for XML
|
||||
// basically DotQuery is a for/in/with statement and in
|
||||
// the following 3 statements we setup to signal it's
|
||||
// DotQuery,
|
||||
// the index and the object being looped over. The
|
||||
// xws.setPrototype is the scope of the object which is
|
||||
// is a element of the lhs (XMLList).
|
||||
_currIndex = 0;
|
||||
_dqPrototype = prototype;
|
||||
if (prototype instanceof XMLList) {
|
||||
XMLList xl = (XMLList)prototype;
|
||||
if (xl.length() > 0) {
|
||||
setPrototype((Scriptable)(xl.get(0, null)));
|
||||
}
|
||||
}
|
||||
// Always return the outer-most type of XML lValue of
|
||||
// XML to left of dotQuery.
|
||||
_xmlList = new XMLList(lib);
|
||||
}
|
||||
|
||||
protected Object updateDotQuery(boolean value)
|
||||
{
|
||||
// Return null to continue looping
|
||||
|
||||
XMLObject seed = _dqPrototype;
|
||||
XMLList xmlL = _xmlList;
|
||||
|
||||
if (seed instanceof XMLList) {
|
||||
// We're a list so keep testing each element of the list if the
|
||||
// result on the top of stack is true then that element is added
|
||||
// to our result list. If false, we try the next element.
|
||||
XMLList orgXmlL = (XMLList)seed;
|
||||
|
||||
int idx = _currIndex;
|
||||
|
||||
if (value) {
|
||||
xmlL.addToList(orgXmlL.get(idx, null));
|
||||
}
|
||||
|
||||
// More elements to test?
|
||||
if (++idx < orgXmlL.length()) {
|
||||
// Yes, set our new index, get the next element and
|
||||
// reset the expression to run with this object as
|
||||
// the WITH selector.
|
||||
_currIndex = idx;
|
||||
setPrototype((Scriptable)(orgXmlL.get(idx, null)));
|
||||
|
||||
// continue looping
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
// If we're not a XMLList then there's no looping
|
||||
// just return DQPrototype if the result is true.
|
||||
if (value) {
|
||||
xmlL.addToList(seed);
|
||||
}
|
||||
}
|
||||
|
||||
return xmlL;
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
|
||||
/**
|
||||
* Example of controlling the JavaScript execution engine.
|
||||
*
|
||||
* We evaluate a script and then manipulate the result.
|
||||
*
|
||||
*/
|
||||
public class Control {
|
||||
|
||||
/**
|
||||
* Main entry point.
|
||||
*
|
||||
* Process arguments as would a normal Java program. Also
|
||||
* create a new Context and associate it with the current thread.
|
||||
* Then set up the execution environment and begin to
|
||||
* execute scripts.
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Context cx = Context.enter();
|
||||
try {
|
||||
// Set version to JavaScript1.2 so that we get object-literal style
|
||||
// printing instead of "[object Object]"
|
||||
cx.setLanguageVersion(Context.VERSION_1_2);
|
||||
|
||||
// Initialize the standard objects (Object, Function, etc.)
|
||||
// This must be done before scripts can be executed.
|
||||
Scriptable scope = cx.initStandardObjects();
|
||||
|
||||
// Now we can evaluate a script. Let's create a new object
|
||||
// using the object literal notation.
|
||||
Object result = cx.evaluateString(scope, "obj = {a:1, b:['x','y']}",
|
||||
"MySource", 1, null);
|
||||
|
||||
Scriptable obj = (Scriptable) scope.get("obj", scope);
|
||||
|
||||
// Should print "obj == result" (Since the result of an assignment
|
||||
// expression is the value that was assigned)
|
||||
System.out.println("obj " + (obj == result ? "==" : "!=") +
|
||||
" result");
|
||||
|
||||
// Should print "obj.a == 1"
|
||||
System.out.println("obj.a == " + obj.get("a", obj));
|
||||
|
||||
Scriptable b = (Scriptable) obj.get("b", obj);
|
||||
|
||||
// Should print "obj.b[0] == x"
|
||||
System.out.println("obj.b[0] == " + b.get(0, b));
|
||||
|
||||
// Should print "obj.b[1] == y"
|
||||
System.out.println("obj.b[1] == " + b.get(1, b));
|
||||
|
||||
// Should print {a:1, b:["x", "y"]}
|
||||
Function fn = (Function) ScriptableObject.getProperty(obj, "toString");
|
||||
System.out.println(fn.call(cx, scope, obj, new Object[0]));
|
||||
} finally {
|
||||
Context.exit();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
|
||||
public class Counter extends ScriptableObject {
|
||||
private static final long serialVersionUID = 438270592527335642L;
|
||||
|
||||
// The zero-argument constructor used by Rhino runtime to create instances
|
||||
public Counter() { }
|
||||
|
||||
// Method jsConstructor defines the JavaScript constructor
|
||||
public void jsConstructor(int a) { count = a; }
|
||||
|
||||
// The class name is defined by the getClassName method
|
||||
@Override
|
||||
public String getClassName() { return "Counter"; }
|
||||
|
||||
// The method jsGet_count defines the count property.
|
||||
public int jsGet_count() { return count++; }
|
||||
|
||||
// Methods can be defined using the jsFunction_ prefix. Here we define
|
||||
// resetCount for JavaScript.
|
||||
public void jsFunction_resetCount() { count = 0; }
|
||||
|
||||
private int count;
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
|
||||
/**
|
||||
* An example illustrating how to create a JavaScript object and retrieve
|
||||
* properties and call methods.
|
||||
* <p>
|
||||
* Output should be:
|
||||
* <pre>
|
||||
* count = 0
|
||||
* count = 1
|
||||
* resetCount
|
||||
* count = 0
|
||||
* </pre>
|
||||
*/
|
||||
public class CounterTest {
|
||||
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
Context cx = Context.enter();
|
||||
try {
|
||||
Scriptable scope = cx.initStandardObjects();
|
||||
ScriptableObject.defineClass(scope, Counter.class);
|
||||
|
||||
Scriptable testCounter = cx.newObject(scope, "Counter");
|
||||
|
||||
Object count = ScriptableObject.getProperty(testCounter, "count");
|
||||
System.out.println("count = " + count);
|
||||
|
||||
count = ScriptableObject.getProperty(testCounter, "count");
|
||||
System.out.println("count = " + count);
|
||||
|
||||
ScriptableObject.callMethod(testCounter,
|
||||
"resetCount",
|
||||
new Object[0]);
|
||||
System.out.println("resetCount");
|
||||
|
||||
count = ScriptableObject.getProperty(testCounter, "count");
|
||||
System.out.println("count = " + count);
|
||||
} finally {
|
||||
Context.exit();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,205 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
|
||||
/**
|
||||
* Example of controlling the JavaScript with multiple scopes and threads.
|
||||
*/
|
||||
public class DynamicScopes {
|
||||
|
||||
static boolean useDynamicScope;
|
||||
|
||||
static class MyFactory extends ContextFactory
|
||||
{
|
||||
@Override
|
||||
protected boolean hasFeature(Context cx, int featureIndex)
|
||||
{
|
||||
if (featureIndex == Context.FEATURE_DYNAMIC_SCOPE) {
|
||||
return useDynamicScope;
|
||||
}
|
||||
return super.hasFeature(cx, featureIndex);
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
ContextFactory.initGlobal(new MyFactory());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Main entry point.
|
||||
*
|
||||
* Set up the shared scope and then spawn new threads that execute
|
||||
* relative to that shared scope. Try to run functions with and
|
||||
* without dynamic scope to see the effect.
|
||||
*
|
||||
* The expected output is
|
||||
* <pre>
|
||||
* sharedScope
|
||||
* nested:sharedScope
|
||||
* sharedScope
|
||||
* nested:sharedScope
|
||||
* sharedScope
|
||||
* nested:sharedScope
|
||||
* thread0
|
||||
* nested:thread0
|
||||
* thread1
|
||||
* nested:thread1
|
||||
* thread2
|
||||
* nested:thread2
|
||||
* </pre>
|
||||
* The final three lines may be permuted in any order depending on
|
||||
* thread scheduling.
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Context cx = Context.enter();
|
||||
try {
|
||||
// Precompile source only once
|
||||
String source = ""
|
||||
+"var x = 'sharedScope';\n"
|
||||
+"function f() { return x; }\n"
|
||||
// Dynamic scope works with nested function too
|
||||
+"function initClosure(prefix) {\n"
|
||||
+" return function test() { return prefix+x; }\n"
|
||||
+"}\n"
|
||||
+"var closure = initClosure('nested:');\n"
|
||||
+"";
|
||||
Script script = cx.compileString(source, "sharedScript", 1, null);
|
||||
|
||||
useDynamicScope = false;
|
||||
runScripts(cx, script);
|
||||
useDynamicScope = true;
|
||||
runScripts(cx, script);
|
||||
} finally {
|
||||
Context.exit();
|
||||
}
|
||||
}
|
||||
|
||||
static void runScripts(Context cx, Script script)
|
||||
{
|
||||
// Initialize the standard objects (Object, Function, etc.)
|
||||
// This must be done before scripts can be executed. The call
|
||||
// returns a new scope that we will share.
|
||||
ScriptableObject sharedScope = cx.initStandardObjects(null, true);
|
||||
|
||||
// Now we can execute the precompiled script against the scope
|
||||
// to define x variable and f function in the shared scope.
|
||||
script.exec(cx, sharedScope);
|
||||
|
||||
// Now we spawn some threads that execute a script that calls the
|
||||
// function 'f'. The scope chain looks like this:
|
||||
// <pre>
|
||||
// ------------------ ------------------
|
||||
// | per-thread scope | -prototype-> | shared scope |
|
||||
// ------------------ ------------------
|
||||
// ^
|
||||
// |
|
||||
// parentScope
|
||||
// |
|
||||
// ------------------
|
||||
// | f's activation |
|
||||
// ------------------
|
||||
// </pre>
|
||||
// Both the shared scope and the per-thread scope have variables 'x'
|
||||
// defined in them. If 'f' is compiled with dynamic scope enabled,
|
||||
// the 'x' from the per-thread scope will be used. Otherwise, the 'x'
|
||||
// from the shared scope will be used. The 'x' defined in 'g' (which
|
||||
// calls 'f') should not be seen by 'f'.
|
||||
final int threadCount = 3;
|
||||
Thread[] t = new Thread[threadCount];
|
||||
for (int i=0; i < threadCount; i++) {
|
||||
String source2 = ""
|
||||
+"function g() { var x = 'local'; return f(); }\n"
|
||||
+"java.lang.System.out.println(g());\n"
|
||||
+"function g2() { var x = 'local'; return closure(); }\n"
|
||||
+"java.lang.System.out.println(g2());\n"
|
||||
+"";
|
||||
t[i] = new Thread(new PerThread(sharedScope, source2,
|
||||
"thread" + i));
|
||||
}
|
||||
for (int i=0; i < threadCount; i++)
|
||||
t[i].start();
|
||||
// Don't return in this thread until all the spawned threads have
|
||||
// completed.
|
||||
for (int i=0; i < threadCount; i++) {
|
||||
try {
|
||||
t[i].join();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class PerThread implements Runnable {
|
||||
|
||||
PerThread(Scriptable sharedScope, String source, String x) {
|
||||
this.sharedScope = sharedScope;
|
||||
this.source = source;
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
// We need a new Context for this thread.
|
||||
Context cx = Context.enter();
|
||||
try {
|
||||
// We can share the scope.
|
||||
Scriptable threadScope = cx.newObject(sharedScope);
|
||||
threadScope.setPrototype(sharedScope);
|
||||
|
||||
// We want "threadScope" to be a new top-level
|
||||
// scope, so set its parent scope to null. This
|
||||
// means that any variables created by assignments
|
||||
// will be properties of "threadScope".
|
||||
threadScope.setParentScope(null);
|
||||
|
||||
// Create a JavaScript property of the thread scope named
|
||||
// 'x' and save a value for it.
|
||||
threadScope.put("x", threadScope, x);
|
||||
cx.evaluateString(threadScope, source, "threadScript", 1, null);
|
||||
} finally {
|
||||
Context.exit();
|
||||
}
|
||||
}
|
||||
private Scriptable sharedScope;
|
||||
private String source;
|
||||
private String x;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,223 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* John Schneider
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
print("----------------------------------------");
|
||||
|
||||
// Use the XML constructor to parse an string into an XML object
|
||||
var John = "<employee><name>John</name><age>25</age></employee>";
|
||||
var Sue ="<employee><name>Sue</name><age>32</age></employee>";
|
||||
var tagName = "employees";
|
||||
var employees = new XML("<" + tagName +">" + John + Sue + "</" + tagName +">");
|
||||
print("The employees XML object constructed from a string is:\n" + employees);
|
||||
|
||||
print("----------------------------------------");
|
||||
|
||||
// Use an XML literal to create an XML object
|
||||
var order = <order>
|
||||
<customer>
|
||||
<firstname>John</firstname>
|
||||
<lastname>Doe</lastname>
|
||||
</customer>
|
||||
<item>
|
||||
<description>Big Screen Television</description>
|
||||
<price>1299.99</price>
|
||||
<quantity>1</quantity>
|
||||
</item>
|
||||
</order>
|
||||
|
||||
// Construct the full customer name
|
||||
var name = order.customer.firstname + " " + order.customer.lastname;
|
||||
|
||||
// Calculate the total price
|
||||
var total = order.item.price * order.item.quantity;
|
||||
|
||||
print("The order XML object constructed using a literal is:\n" + order);
|
||||
print("The total price of " + name + "'s order is " + total);
|
||||
|
||||
print("----------------------------------------");
|
||||
|
||||
// construct a new XML object using expando and super-expando properties
|
||||
var order = <order/>;
|
||||
order.customer.name = "Fred Jones";
|
||||
order.customer.address.street = "123 Long Lang";
|
||||
order.customer.address.city = "Underwood";
|
||||
order.customer.address.state = "CA";
|
||||
order.item[0] = "";
|
||||
order.item[0].description = "Small Rodents";
|
||||
order.item[0].quantity = 10;
|
||||
order.item[0].price = 6.95;
|
||||
|
||||
print("The order custructed using expandos and super-expandos is:\n" + order);
|
||||
|
||||
// append a new item to the order
|
||||
order.item += <item><description>Catapult</description><price>139.95</price></item>;
|
||||
|
||||
print("----------------------------------------");
|
||||
|
||||
print("The order after appending a new item is:\n" + order);
|
||||
|
||||
print("----------------------------------------");
|
||||
|
||||
// dynamically construct an XML element using embedded expressions
|
||||
var tagname = "name";
|
||||
var attributename = "id";
|
||||
var attributevalue = 5;
|
||||
var content = "Fred";
|
||||
|
||||
var x = <{tagname} {attributename}={attributevalue}>{content}</{tagname}>;
|
||||
|
||||
print("The dynamically computed element value is:\n" + x.toXMLString());
|
||||
|
||||
print("----------------------------------------");
|
||||
|
||||
// Create a SOAP message
|
||||
var message = <soap:Envelope
|
||||
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<soap:Body>
|
||||
<m:GetLastTradePrice xmlns:m="http://mycompany.com/stocks">
|
||||
<symbol>DIS</symbol>
|
||||
</m:GetLastTradePrice>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
||||
|
||||
// declare the SOAP and stocks namespaces
|
||||
var soap = new Namespace("http://schemas.xmlsoap.org/soap/envelope/");
|
||||
var stock = new Namespace ("http://mycompany.com/stocks");
|
||||
|
||||
// extract the soap encoding style and body from the soap message
|
||||
var encodingStyle = message.@soap::encodingStyle;
|
||||
|
||||
print("The encoding style of the soap message is specified by:\n" + encodingStyle);
|
||||
|
||||
// change the stock symbol
|
||||
message.soap::Body.stock::GetLastTradePrice.symbol = "MYCO";
|
||||
|
||||
var body = message.soap::Body;
|
||||
|
||||
print("The body of the soap message is:\n" + body);
|
||||
|
||||
print("----------------------------------------");
|
||||
|
||||
// create an manipulate an XML object using the default xml namespace
|
||||
|
||||
default xml namespace = "http://default.namespace.com";
|
||||
var x = <x/>;
|
||||
x.a = "one";
|
||||
x.b = "two";
|
||||
x.c = <c xmlns="http://some.other.namespace.com">three</c>;
|
||||
|
||||
print("XML object constructed using the default xml namespace:\n" + x);
|
||||
|
||||
default xml namespace="";
|
||||
|
||||
print("----------------------------------------");
|
||||
|
||||
var order = <order id = "123456" timestamp="Mon Mar 10 2003 16:03:25 GMT-0800 (PST)">
|
||||
<customer>
|
||||
<firstname>John</firstname>
|
||||
<lastname>Doe</lastname>
|
||||
</customer>
|
||||
<item id="3456">
|
||||
<description>Big Screen Television</description>
|
||||
<price>1299.99</price>
|
||||
<quantity>1</quantity>
|
||||
</item>
|
||||
<item id = "56789">
|
||||
<description>DVD Player</description>
|
||||
<price>399.99</price>
|
||||
<quantity>1</quantity>
|
||||
</item>
|
||||
</order>;
|
||||
|
||||
|
||||
// get the customer element from the orderprint("The customer is:\n" + order.customer);
|
||||
|
||||
// get the id attribute from the order
|
||||
print("The order id is:" + order.@id);
|
||||
|
||||
// get all the child elements from the order element
|
||||
print("The children of the order are:\n" + order.*);
|
||||
|
||||
// get the list of all item descriptions
|
||||
print("The order descriptions are:\n" + order.item.description);
|
||||
|
||||
|
||||
// get second item by numeric index
|
||||
print("The second item is:\n" + order.item[1]);
|
||||
|
||||
// get the list of all child elements in all item elements
|
||||
print("The children of the items are:\n" + order.item.*);
|
||||
|
||||
// get the second child element from the order by index
|
||||
print("The second child of the order is:\n" + order.*[1]);
|
||||
|
||||
// calculate the total price of the order
|
||||
var totalprice = 0;
|
||||
for each (i in order.item) {
|
||||
totalprice += i.price * i.quantity;
|
||||
}
|
||||
print("The total price of the order is: " + totalprice);
|
||||
|
||||
print("----------------------------------------");
|
||||
|
||||
var e = <employees>
|
||||
<employee id="1"><name>Joe</name><age>20</age></employee>
|
||||
<employee id="2"><name>Sue</name><age>30</age></employee>
|
||||
</employees>;
|
||||
|
||||
// get all the names in e
|
||||
print("All the employee names are:\n" + e..name);
|
||||
|
||||
// employees with name Joe
|
||||
print("The employee named Joe is:\n" + e.employee.(name == "Joe"));
|
||||
|
||||
// employees with id's 1 & 2
|
||||
print("Employees with ids 1 & 2:\n" + e.employee.(@id == 1 || @id == 2));
|
||||
|
||||
// name of employee with id 1
|
||||
print("Name of the the employee with ID=1: " + e.employee.(@id == 1).name);
|
||||
|
||||
print("----------------------------------------");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,353 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
import java.io.*;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Define a simple JavaScript File object.
|
||||
*
|
||||
* This isn't intended to be any sort of definitive attempt at a
|
||||
* standard File object for JavaScript, but instead is an example
|
||||
* of a more involved definition of a host object.
|
||||
*
|
||||
* Example of use of the File object:
|
||||
* <pre>
|
||||
* js> defineClass("File")
|
||||
* js> file = new File("myfile.txt");
|
||||
* [object File]
|
||||
* js> file.writeLine("one"); <i>only now is file actually opened</i>
|
||||
* js> file.writeLine("two");
|
||||
* js> file.writeLine("thr", "ee");
|
||||
* js> file.close(); <i>must close file before we can reopen for reading</i>
|
||||
* js> var a = file.readLines(); <i>creates and fills an array with the contents of the file</i>
|
||||
* js> a;
|
||||
* one,two,three
|
||||
* js>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* File errors or end-of-file signaled by thrown Java exceptions will
|
||||
* be wrapped as JavaScript exceptions when called from JavaScript,
|
||||
* and may be caught within JavaScript.
|
||||
*
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
public class File extends ScriptableObject {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 2549960399774237828L;
|
||||
/**
|
||||
* The zero-parameter constructor.
|
||||
*
|
||||
* When Context.defineClass is called with this class, it will
|
||||
* construct File.prototype using this constructor.
|
||||
*/
|
||||
public File() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The Java method defining the JavaScript File constructor.
|
||||
*
|
||||
* If the constructor has one or more arguments, and the
|
||||
* first argument is not undefined, the argument is converted
|
||||
* to a string as used as the filename.<p>
|
||||
*
|
||||
* Otherwise System.in or System.out is assumed as appropriate
|
||||
* to the use.
|
||||
*/
|
||||
public static Scriptable jsConstructor(Context cx, Object[] args,
|
||||
Function ctorObj,
|
||||
boolean inNewExpr)
|
||||
{
|
||||
File result = new File();
|
||||
if (args.length == 0 || args[0] == Context.getUndefinedValue()) {
|
||||
result.name = "";
|
||||
result.file = null;
|
||||
} else {
|
||||
result.name = Context.toString(args[0]);
|
||||
result.file = new java.io.File(result.name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this JavaScript class, "File".
|
||||
*/
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return "File";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the file.
|
||||
*
|
||||
* Used to define the "name" property.
|
||||
*/
|
||||
public String jsGet_name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the remaining lines in the file and return them in an array.
|
||||
*
|
||||
* Implements a JavaScript function.<p>
|
||||
*
|
||||
* This is a good example of creating a new array and setting
|
||||
* elements in that array.
|
||||
*
|
||||
* @exception IOException if an error occurred while accessing the file
|
||||
* associated with this object
|
||||
*/
|
||||
public Object jsFunction_readLines()
|
||||
throws IOException
|
||||
{
|
||||
List<String> list = new ArrayList<String>();
|
||||
String s;
|
||||
while ((s = jsFunction_readLine()) != null) {
|
||||
list.add(s);
|
||||
}
|
||||
String[] lines = list.toArray(new String[list.size()]);
|
||||
Scriptable scope = ScriptableObject.getTopLevelScope(this);
|
||||
Context cx = Context.getCurrentContext();
|
||||
return cx.newObject(scope, "Array", lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a line.
|
||||
*
|
||||
* Implements a JavaScript function.
|
||||
* @exception IOException if an error occurred while accessing the file
|
||||
* associated with this object, or EOFException if the object
|
||||
* reached the end of the file
|
||||
*/
|
||||
public String jsFunction_readLine() throws IOException {
|
||||
return getReader().readLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a character.
|
||||
*
|
||||
* @exception IOException if an error occurred while accessing the file
|
||||
* associated with this object, or EOFException if the object
|
||||
* reached the end of the file
|
||||
*/
|
||||
public String jsFunction_readChar() throws IOException {
|
||||
int i = getReader().read();
|
||||
if (i == -1)
|
||||
return null;
|
||||
char[] charArray = { (char) i };
|
||||
return new String(charArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write strings.
|
||||
*
|
||||
* Implements a JavaScript function. <p>
|
||||
*
|
||||
* This function takes a variable number of arguments, converts
|
||||
* each argument to a string, and writes that string to the file.
|
||||
* @exception IOException if an error occurred while accessing the file
|
||||
* associated with this object
|
||||
*/
|
||||
public static void jsFunction_write(Context cx, Scriptable thisObj,
|
||||
Object[] args, Function funObj)
|
||||
throws IOException
|
||||
{
|
||||
write0(thisObj, args, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write strings and a newline.
|
||||
*
|
||||
* Implements a JavaScript function.
|
||||
* @exception IOException if an error occurred while accessing the file
|
||||
* associated with this object
|
||||
*
|
||||
*/
|
||||
public static void jsFunction_writeLine(Context cx, Scriptable thisObj,
|
||||
Object[] args, Function funObj)
|
||||
throws IOException
|
||||
{
|
||||
write0(thisObj, args, true);
|
||||
}
|
||||
|
||||
public int jsGet_lineNumber()
|
||||
throws FileNotFoundException
|
||||
{
|
||||
return getReader().getLineNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the file. It may be reopened.
|
||||
*
|
||||
* Implements a JavaScript function.
|
||||
* @exception IOException if an error occurred while accessing the file
|
||||
* associated with this object
|
||||
*/
|
||||
public void jsFunction_close() throws IOException {
|
||||
if (reader != null) {
|
||||
reader.close();
|
||||
reader = null;
|
||||
} else if (writer != null) {
|
||||
writer.close();
|
||||
writer = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalizer.
|
||||
*
|
||||
* Close the file when this object is collected.
|
||||
*/
|
||||
@Override
|
||||
protected void finalize() {
|
||||
try {
|
||||
jsFunction_close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Java reader.
|
||||
*/
|
||||
public Object jsFunction_getReader() {
|
||||
if (reader == null)
|
||||
return null;
|
||||
// Here we use toObject() to "wrap" the BufferedReader object
|
||||
// in a Scriptable object so that it can be manipulated by
|
||||
// JavaScript.
|
||||
Scriptable parent = ScriptableObject.getTopLevelScope(this);
|
||||
return Context.javaToJS(reader, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Java writer.
|
||||
*
|
||||
* @see File#jsFunction_getReader
|
||||
*
|
||||
*/
|
||||
public Object jsFunction_getWriter() {
|
||||
if (writer == null)
|
||||
return null;
|
||||
Scriptable parent = ScriptableObject.getTopLevelScope(this);
|
||||
return Context.javaToJS(writer, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the reader, checking that we're not already writing this file.
|
||||
*/
|
||||
private LineNumberReader getReader() throws FileNotFoundException {
|
||||
if (writer != null) {
|
||||
throw Context.reportRuntimeError("already writing file \""
|
||||
+ name
|
||||
+ "\"");
|
||||
}
|
||||
if (reader == null)
|
||||
reader = new LineNumberReader(file == null
|
||||
? new InputStreamReader(System.in)
|
||||
: new FileReader(file));
|
||||
return reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the guts of write and writeLine.
|
||||
*
|
||||
* Since the two functions differ only in whether they write a
|
||||
* newline character, move the code into a common subroutine.
|
||||
*
|
||||
*/
|
||||
private static void write0(Scriptable thisObj, Object[] args, boolean eol)
|
||||
throws IOException
|
||||
{
|
||||
File thisFile = checkInstance(thisObj);
|
||||
if (thisFile.reader != null) {
|
||||
throw Context.reportRuntimeError("already writing file \""
|
||||
+ thisFile.name
|
||||
+ "\"");
|
||||
}
|
||||
if (thisFile.writer == null)
|
||||
thisFile.writer = new BufferedWriter(
|
||||
thisFile.file == null ? new OutputStreamWriter(System.out)
|
||||
: new FileWriter(thisFile.file));
|
||||
for (int i=0; i < args.length; i++) {
|
||||
String s = Context.toString(args[i]);
|
||||
thisFile.writer.write(s, 0, s.length());
|
||||
}
|
||||
if (eol)
|
||||
thisFile.writer.newLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the instanceof check and return the downcasted File object.
|
||||
*
|
||||
* This is necessary since methods may reside in the File.prototype
|
||||
* object and scripts can dynamically alter prototype chains. For example:
|
||||
* <pre>
|
||||
* js> defineClass("File");
|
||||
* js> o = {};
|
||||
* [object Object]
|
||||
* js> o.__proto__ = File.prototype;
|
||||
* [object File]
|
||||
* js> o.write("hi");
|
||||
* js: called on incompatible object
|
||||
* </pre>
|
||||
* The runtime will take care of such checks when non-static Java methods
|
||||
* are defined as JavaScript functions.
|
||||
*/
|
||||
private static File checkInstance(Scriptable obj) {
|
||||
if (obj == null || !(obj instanceof File)) {
|
||||
throw Context.reportRuntimeError("called on incompatible object");
|
||||
}
|
||||
return (File) obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Some private data for this class.
|
||||
*/
|
||||
private String name;
|
||||
private java.io.File file; // may be null, meaning to use System.out or .in
|
||||
private LineNumberReader reader;
|
||||
private BufferedWriter writer;
|
||||
}
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
|
||||
/**
|
||||
* An example host object class.
|
||||
*
|
||||
* Here's a shell session showing the Foo object in action:
|
||||
* <pre>
|
||||
* js> defineClass("Foo")
|
||||
* js> foo = new Foo(); <i>A constructor call, see <a href="#Foo">Foo</a> below.</i>
|
||||
* [object Foo] <i>The "Foo" here comes from <a href"#getClassName">getClassName</a>.</i>
|
||||
* js> foo.counter; <i>The counter property is defined by the <code>defineProperty</code></i>
|
||||
* 0 <i>call below and implemented by the <a href="#getCounter">getCounter</a></i>
|
||||
* js> foo.counter; <i>method below.</i>
|
||||
* 1
|
||||
* js> foo.counter;
|
||||
* 2
|
||||
* js> foo.resetCounter(); <i>Results in a call to <a href="#resetCounter">resetCounter</a>.</i>
|
||||
* js> foo.counter; <i>Now the counter has been reset.</i>
|
||||
* 0
|
||||
* js> foo.counter;
|
||||
* 1
|
||||
* js> bar = new Foo(37); <i>Create a new instance.</i>
|
||||
* [object Foo]
|
||||
* js> bar.counter; <i>This instance's counter is distinct from</i>
|
||||
* 37 <i>the other instance's counter.</i>
|
||||
* js> foo.varargs(3, "hi"); <i>Calls <a href="#varargs">varargs</a>.</i>
|
||||
* this = [object Foo]; args = [3, hi]
|
||||
* js> foo[7] = 34; <i>Since we extended ScriptableObject, we get</i>
|
||||
* 34 <i>all the behavior of a JavaScript object</i>
|
||||
* js> foo.a = 23; <i>for free.</i>
|
||||
* 23
|
||||
* js> foo.a + foo[7];
|
||||
* 57
|
||||
* js>
|
||||
* </pre>
|
||||
*
|
||||
* @see org.mozilla.javascript.Context
|
||||
* @see org.mozilla.javascript.Scriptable
|
||||
* @see org.mozilla.javascript.ScriptableObject
|
||||
*
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
|
||||
public class Foo extends ScriptableObject {
|
||||
private static final long serialVersionUID = -3833489808933339159L;
|
||||
|
||||
/**
|
||||
* The zero-parameter constructor.
|
||||
*
|
||||
* When Context.defineClass is called with this class, it will
|
||||
* construct Foo.prototype using this constructor.
|
||||
*/
|
||||
public Foo() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The Java method defining the JavaScript Foo constructor.
|
||||
*
|
||||
* Takes an initial value for the counter property.
|
||||
* Note that in the example Shell session above, we didn't
|
||||
* supply a argument to the Foo constructor. This means that
|
||||
* the Undefined value is used as the value of the argument,
|
||||
* and when the argument is converted to an integer, Undefined
|
||||
* becomes 0.
|
||||
*/
|
||||
public Foo(int counterStart) {
|
||||
counter = counterStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this JavaScript class, "Foo".
|
||||
*/
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return "Foo";
|
||||
}
|
||||
|
||||
/**
|
||||
* The Java method defining the JavaScript resetCounter function.
|
||||
*
|
||||
* Resets the counter to 0.
|
||||
*/
|
||||
public void jsFunction_resetCounter() {
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Java method implementing the getter for the counter property.
|
||||
* <p>
|
||||
* If "setCounter" had been defined in this class, the runtime would
|
||||
* call the setter when the property is assigned to.
|
||||
*/
|
||||
public int jsGet_counter() {
|
||||
return counter++;
|
||||
}
|
||||
|
||||
/**
|
||||
* An example of a variable-arguments method.
|
||||
*
|
||||
* All variable arguments methods must have the same number and
|
||||
* types of parameters, and must be static. <p>
|
||||
* @param cx the Context of the current thread
|
||||
* @param thisObj the JavaScript 'this' value.
|
||||
* @param args the array of arguments for this call
|
||||
* @param funObj the function object of the invoked JavaScript function
|
||||
* This value is useful to compute a scope using
|
||||
* Context.getTopLevelScope().
|
||||
* @return computes the string values and types of 'this' and
|
||||
* of each of the supplied arguments and returns them in a string.
|
||||
*
|
||||
* @see org.mozilla.javascript.ScriptableObject#getTopLevelScope
|
||||
*/
|
||||
public static Object jsFunction_varargs(Context cx, Scriptable thisObj,
|
||||
Object[] args, Function funObj)
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("this = ");
|
||||
buf.append(Context.toString(thisObj));
|
||||
buf.append("; args = [");
|
||||
for (int i=0; i < args.length; i++) {
|
||||
buf.append(Context.toString(args[i]));
|
||||
if (i+1 != args.length)
|
||||
buf.append(", ");
|
||||
}
|
||||
buf.append("]");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* A piece of private data for this class.
|
||||
*/
|
||||
private int counter;
|
||||
}
|
||||
|
||||
@@ -1,280 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Matrix: An example host object class that implements the Scriptable interface.
|
||||
*
|
||||
* Built-in JavaScript arrays don't handle multiple dimensions gracefully: the
|
||||
* script writer must create every array in an array of arrays. The Matrix class
|
||||
* takes care of that by automatically allocating arrays for every index that
|
||||
* is accessed. What's more, the Matrix constructor takes a integer argument
|
||||
* that specifies the dimension of the Matrix. If m is a Matrix with dimension 3,
|
||||
* then m[0] will be a Matrix with dimension 1, and m[0][0] will be an Array.
|
||||
*
|
||||
* Here's a shell session showing the Matrix object in action:
|
||||
* <pre>
|
||||
* js> defineClass("Matrix")
|
||||
* js> var m = new Matrix(2); // A constructor call, see "Matrix(int dimension)"
|
||||
* js> m // Object.toString will call "Matrix.getClassName()"
|
||||
* [object Matrix]
|
||||
* js> m[0][0] = 3;
|
||||
* 3
|
||||
* js> uneval(m[0]); // an array was created automatically!
|
||||
* [3]
|
||||
* js> uneval(m[1]); // array is created even if we don't set a value
|
||||
* []
|
||||
* js> m.dim; // we can access the "dim" property
|
||||
* 2
|
||||
* js> m.dim = 3;
|
||||
* 3
|
||||
* js> m.dim; // but not modify the "dim" property
|
||||
* 2
|
||||
* </pre>
|
||||
*
|
||||
* @see org.mozilla.javascript.Context
|
||||
* @see org.mozilla.javascript.Scriptable
|
||||
*
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
public class Matrix implements Scriptable {
|
||||
|
||||
/**
|
||||
* The zero-parameter constructor.
|
||||
*
|
||||
* When ScriptableObject.defineClass is called with this class, it will
|
||||
* construct Matrix.prototype using this constructor.
|
||||
*/
|
||||
public Matrix() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The Java constructor, also used to define the JavaScript constructor.
|
||||
*/
|
||||
public Matrix(int dimension) {
|
||||
if (dimension <= 0) {
|
||||
throw Context.reportRuntimeError(
|
||||
"Dimension of Matrix must be greater than zero");
|
||||
}
|
||||
dim = dimension;
|
||||
list = new ArrayList<Object>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this JavaScript class, "Matrix".
|
||||
*/
|
||||
public String getClassName() {
|
||||
return "Matrix";
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the "dim" property by returning true if name is
|
||||
* equal to "dim".
|
||||
* <p>
|
||||
* Defines no other properties, i.e., returns false for
|
||||
* all other names.
|
||||
*
|
||||
* @param name the name of the property
|
||||
* @param start the object where lookup began
|
||||
*/
|
||||
public boolean has(String name, Scriptable start) {
|
||||
return name.equals("dim");
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines all numeric properties by returning true.
|
||||
*
|
||||
* @param index the index of the property
|
||||
* @param start the object where lookup began
|
||||
*/
|
||||
public boolean has(int index, Scriptable start) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the named property.
|
||||
* <p>
|
||||
* Handles the "dim" property and returns NOT_FOUND for all
|
||||
* other names.
|
||||
* @param name the property name
|
||||
* @param start the object where the lookup began
|
||||
*/
|
||||
public Object get(String name, Scriptable start) {
|
||||
if (name.equals("dim"))
|
||||
return new Integer(dim);
|
||||
|
||||
return NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the indexed property.
|
||||
* <p>
|
||||
* Look up the element in the associated list and return
|
||||
* it if it exists. If it doesn't exist, create it.<p>
|
||||
* @param index the index of the integral property
|
||||
* @param start the object where the lookup began
|
||||
*/
|
||||
public Object get(int index, Scriptable start) {
|
||||
while (index >= list.size()) {
|
||||
list.add(null);
|
||||
}
|
||||
Object result = list.get(index);
|
||||
if (result != null)
|
||||
return result;
|
||||
if (dim > 2) {
|
||||
Matrix m = new Matrix(dim-1);
|
||||
m.setParentScope(getParentScope());
|
||||
m.setPrototype(getPrototype());
|
||||
result = m;
|
||||
} else {
|
||||
Context cx = Context.getCurrentContext();
|
||||
Scriptable scope = ScriptableObject.getTopLevelScope(start);
|
||||
result = cx.newArray(scope, 0);
|
||||
}
|
||||
list.set(index, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a named property.
|
||||
*
|
||||
* We do nothing here, so all properties are effectively read-only.
|
||||
*/
|
||||
public void put(String name, Scriptable start, Object value) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an indexed property.
|
||||
*
|
||||
* We do nothing here, so all properties are effectively read-only.
|
||||
*/
|
||||
public void put(int index, Scriptable start, Object value) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a named property.
|
||||
*
|
||||
* This method shouldn't even be called since we define all properties
|
||||
* as PERMANENT.
|
||||
*/
|
||||
public void delete(String id) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an indexed property.
|
||||
*
|
||||
* This method shouldn't even be called since we define all properties
|
||||
* as PERMANENT.
|
||||
*/
|
||||
public void delete(int index) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get prototype.
|
||||
*/
|
||||
public Scriptable getPrototype() {
|
||||
return prototype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set prototype.
|
||||
*/
|
||||
public void setPrototype(Scriptable prototype) {
|
||||
this.prototype = prototype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parent.
|
||||
*/
|
||||
public Scriptable getParentScope() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set parent.
|
||||
*/
|
||||
public void setParentScope(Scriptable parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get properties.
|
||||
*
|
||||
* We return an empty array since we define all properties to be DONTENUM.
|
||||
*/
|
||||
public Object[] getIds() {
|
||||
return new Object[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Default value.
|
||||
*
|
||||
* Use the convenience method from Context that takes care of calling
|
||||
* toString, etc.
|
||||
*/
|
||||
public Object getDefaultValue(Class<?> typeHint) {
|
||||
return "[object Matrix]";
|
||||
}
|
||||
|
||||
/**
|
||||
* instanceof operator.
|
||||
*
|
||||
* We mimick the normal JavaScript instanceof semantics, returning
|
||||
* true if <code>this</code> appears in <code>value</code>'s prototype
|
||||
* chain.
|
||||
*/
|
||||
public boolean hasInstance(Scriptable value) {
|
||||
Scriptable proto = value.getPrototype();
|
||||
while (proto != null) {
|
||||
if (proto.equals(this))
|
||||
return true;
|
||||
proto = proto.getPrototype();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Some private data for this class.
|
||||
*/
|
||||
private int dim;
|
||||
private List<Object> list;
|
||||
private Scriptable prototype, parent;
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License Version
|
||||
- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
- the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is Rhino code, released May 6, 1999.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Netscape Communications Corporation.
|
||||
- Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
- case the provisions of the GPL are applicable instead of those above. If
|
||||
- you wish to allow use of your version of this file only under the terms of
|
||||
- the GPL and not to allow others to use your version of this file under the
|
||||
- MPL, indicate your decision by deleting the provisions above and replacing
|
||||
- them with the notice and other provisions required by the GPL. If you do
|
||||
- not delete the provisions above, a recipient may use your version of this
|
||||
- file under either the MPL or the GPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
This is the NervousText applet in javascript:
|
||||
<applet archive="js.jar" code=NervousText width=200 height=50 >
|
||||
</applet>
|
||||
|
||||
<hr>
|
||||
The test assumes that applet code is generated with:
|
||||
<pre>
|
||||
java -classpath js.jar org.mozilla.javascript.tools.jsc.Main \
|
||||
-extends java.applet.Applet \
|
||||
-implements java.lang.Runnable \
|
||||
NervousText.js
|
||||
</pre>
|
||||
and the resulting 2 classes, NervousText.class extending java.applet.Applet and implementing java.lang.Runnable and NervousText1.class which represents compiled JavaScript code, are placed in the same directory as NervousText.html.
|
||||
<p>
|
||||
The test also assumes that js.jar from Rhino distribution is available in the same directory.
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,109 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// The Java "NervousText" example ported to JavaScript.
|
||||
// Compile using java org.mozilla.javascript.tools.jsc.Main -extends java.applet.Applet -implements java.lang.Runnable NervousText.js
|
||||
/*
|
||||
Adapted from Java code by
|
||||
Daniel Wyszynski
|
||||
Center for Applied Large-Scale Computing (CALC)
|
||||
04-12-95
|
||||
|
||||
Test of text animation.
|
||||
|
||||
kwalrath: Changed string; added thread suspension. 5-9-95
|
||||
*/
|
||||
var Font = java.awt.Font;
|
||||
var Thread = java.lang.Thread;
|
||||
var separated;
|
||||
var s = null;
|
||||
var killme = null;
|
||||
var i;
|
||||
var x_coord = 0, y_coord = 0;
|
||||
var num;
|
||||
var speed=35;
|
||||
var counter =0;
|
||||
var threadSuspended = false; //added by kwalrath
|
||||
|
||||
function init() {
|
||||
this.resize(150,50);
|
||||
this.setFont(new Font("TimesRoman",Font.BOLD,36));
|
||||
s = this.getParameter("text");
|
||||
if (s == null) {
|
||||
s = "Rhino";
|
||||
}
|
||||
separated = s.split('');
|
||||
}
|
||||
|
||||
function start() {
|
||||
if(killme == null)
|
||||
{
|
||||
killme = new java.lang.Thread(java.lang.Runnable(this));
|
||||
killme.start();
|
||||
}
|
||||
}
|
||||
|
||||
function stop() {
|
||||
killme = null;
|
||||
}
|
||||
|
||||
function run() {
|
||||
while (killme != null) {
|
||||
try {Thread.sleep(100);} catch (e){}
|
||||
this.repaint();
|
||||
}
|
||||
killme = null;
|
||||
}
|
||||
|
||||
function paint(g) {
|
||||
for(i=0;i<separated.length;i++)
|
||||
{
|
||||
x_coord = Math.random()*10+15*i;
|
||||
y_coord = Math.random()*10+36;
|
||||
g.drawChars(separated, i,1,x_coord,y_coord);
|
||||
}
|
||||
}
|
||||
|
||||
/* Added by kwalrath. */
|
||||
function mouseDown(evt, x, y) {
|
||||
if (threadSuspended) {
|
||||
killme.resume();
|
||||
}
|
||||
else {
|
||||
killme.suspend();
|
||||
}
|
||||
threadSuspended = !threadSuspended;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
|
||||
/**
|
||||
* An example WrapFactory that can be used to avoid wrapping of Java types
|
||||
* that can be converted to ECMA primitive values.
|
||||
* So java.lang.String is mapped to ECMA string, all java.lang.Numbers are
|
||||
* mapped to ECMA numbers, and java.lang.Booleans are mapped to ECMA booleans
|
||||
* instead of being wrapped as objects. Additionally java.lang.Character is
|
||||
* converted to ECMA string with length 1.
|
||||
* Other types have the default behavior.
|
||||
* <p>
|
||||
* Note that calling "new java.lang.String('foo')" in JavaScript with this
|
||||
* wrap factory enabled will still produce a wrapped Java object since the
|
||||
* WrapFactory.wrapNewObject method is not overridden.
|
||||
* <p>
|
||||
* The PrimitiveWrapFactory is enabled on a Context by calling setWrapFactory
|
||||
* on that context.
|
||||
*/
|
||||
public class PrimitiveWrapFactory extends WrapFactory {
|
||||
@Override
|
||||
public Object wrap(Context cx, Scriptable scope, Object obj,
|
||||
Class<?> staticType)
|
||||
{
|
||||
if (obj instanceof String || obj instanceof Number ||
|
||||
obj instanceof Boolean)
|
||||
{
|
||||
return obj;
|
||||
} else if (obj instanceof Character) {
|
||||
char[] a = { ((Character)obj).charValue() };
|
||||
return new String(a);
|
||||
}
|
||||
return super.wrap(cx, scope, obj, staticType);
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
|
||||
/**
|
||||
* RunScript: simplest example of controlling execution of Rhino.
|
||||
*
|
||||
* Collects its arguments from the command line, executes the
|
||||
* script, and prints the result.
|
||||
*
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
public class RunScript {
|
||||
public static void main(String args[])
|
||||
{
|
||||
// Creates and enters a Context. The Context stores information
|
||||
// about the execution environment of a script.
|
||||
Context cx = Context.enter();
|
||||
try {
|
||||
// Initialize the standard objects (Object, Function, etc.)
|
||||
// This must be done before scripts can be executed. Returns
|
||||
// a scope object that we use in later calls.
|
||||
Scriptable scope = cx.initStandardObjects();
|
||||
|
||||
// Collect the arguments into a single string.
|
||||
String s = "";
|
||||
for (int i=0; i < args.length; i++) {
|
||||
s += args[i];
|
||||
}
|
||||
|
||||
// Now evaluate the string we've colected.
|
||||
Object result = cx.evaluateString(scope, s, "<cmd>", 1, null);
|
||||
|
||||
// Convert the result to a string and print it.
|
||||
System.err.println(Context.toString(result));
|
||||
|
||||
} finally {
|
||||
// Exit from the context.
|
||||
Context.exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
|
||||
/**
|
||||
* RunScript2: Like RunScript, but reflects the System.out into JavaScript.
|
||||
*
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
public class RunScript2 {
|
||||
public static void main(String args[])
|
||||
{
|
||||
Context cx = Context.enter();
|
||||
try {
|
||||
Scriptable scope = cx.initStandardObjects();
|
||||
|
||||
// Add a global variable "out" that is a JavaScript reflection
|
||||
// of System.out
|
||||
Object jsOut = Context.javaToJS(System.out, scope);
|
||||
ScriptableObject.putProperty(scope, "out", jsOut);
|
||||
|
||||
String s = "";
|
||||
for (int i=0; i < args.length; i++) {
|
||||
s += args[i];
|
||||
}
|
||||
Object result = cx.evaluateString(scope, s, "<cmd>", 1, null);
|
||||
System.err.println(Context.toString(result));
|
||||
} finally {
|
||||
Context.exit();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
|
||||
/**
|
||||
* RunScript3: Example of using JavaScript objects
|
||||
*
|
||||
* Collects its arguments from the command line, executes the
|
||||
* script, and then ...
|
||||
*
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
public class RunScript3 {
|
||||
public static void main(String args[])
|
||||
{
|
||||
Context cx = Context.enter();
|
||||
try {
|
||||
Scriptable scope = cx.initStandardObjects();
|
||||
|
||||
// Collect the arguments into a single string.
|
||||
String s = "";
|
||||
for (int i=0; i < args.length; i++) {
|
||||
s += args[i];
|
||||
}
|
||||
|
||||
// Now evaluate the string we've collected. We'll ignore the result.
|
||||
cx.evaluateString(scope, s, "<cmd>", 1, null);
|
||||
|
||||
// Print the value of variable "x"
|
||||
Object x = scope.get("x", scope);
|
||||
if (x == Scriptable.NOT_FOUND) {
|
||||
System.out.println("x is not defined.");
|
||||
} else {
|
||||
System.out.println("x = " + Context.toString(x));
|
||||
}
|
||||
|
||||
// Call function "f('my arg')" and print its result.
|
||||
Object fObj = scope.get("f", scope);
|
||||
if (!(fObj instanceof Function)) {
|
||||
System.out.println("f is undefined or not a function.");
|
||||
} else {
|
||||
Object functionArgs[] = { "my arg" };
|
||||
Function f = (Function)fObj;
|
||||
Object result = f.call(cx, scope, scope, functionArgs);
|
||||
String report = "f('my args') = " + Context.toString(result);
|
||||
System.out.println(report);
|
||||
}
|
||||
} finally {
|
||||
Context.exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
|
||||
/**
|
||||
* RunScript4: Execute scripts in an environment that includes the
|
||||
* example Counter class.
|
||||
*
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
public class RunScript4 {
|
||||
public static void main(String args[])
|
||||
throws Exception
|
||||
{
|
||||
Context cx = Context.enter();
|
||||
try {
|
||||
Scriptable scope = cx.initStandardObjects();
|
||||
|
||||
// Use the Counter class to define a Counter constructor
|
||||
// and prototype in JavaScript.
|
||||
ScriptableObject.defineClass(scope, Counter.class);
|
||||
|
||||
// Create an instance of Counter and assign it to
|
||||
// the top-level variable "myCounter". This is
|
||||
// equivalent to the JavaScript code
|
||||
// myCounter = new Counter(7);
|
||||
Object[] arg = { new Integer(7) };
|
||||
Scriptable myCounter = cx.newObject(scope, "Counter", arg);
|
||||
scope.put("myCounter", scope, myCounter);
|
||||
|
||||
String s = "";
|
||||
for (int i=0; i < args.length; i++) {
|
||||
s += args[i];
|
||||
}
|
||||
Object result = cx.evaluateString(scope, s, "<cmd>", 1, null);
|
||||
System.err.println(Context.toString(result));
|
||||
} finally {
|
||||
Context.exit();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,348 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* The shell program.
|
||||
*
|
||||
* Can execute scripts interactively or in batch mode at the command line.
|
||||
* An example of controlling the JavaScript engine.
|
||||
*
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
public class Shell extends ScriptableObject
|
||||
{
|
||||
private static final long serialVersionUID = -5638074146250193112L;
|
||||
|
||||
@Override
|
||||
public String getClassName()
|
||||
{
|
||||
return "global";
|
||||
}
|
||||
|
||||
/**
|
||||
* Main entry point.
|
||||
*
|
||||
* Process arguments as would a normal Java program. Also
|
||||
* create a new Context and associate it with the current thread.
|
||||
* Then set up the execution environment and begin to
|
||||
* execute scripts.
|
||||
*/
|
||||
public static void main(String args[]) {
|
||||
// Associate a new Context with this thread
|
||||
Context cx = Context.enter();
|
||||
try {
|
||||
// Initialize the standard objects (Object, Function, etc.)
|
||||
// This must be done before scripts can be executed.
|
||||
Shell shell = new Shell();
|
||||
cx.initStandardObjects(shell);
|
||||
|
||||
// Define some global functions particular to the shell. Note
|
||||
// that these functions are not part of ECMA.
|
||||
String[] names = { "print", "quit", "version", "load", "help" };
|
||||
shell.defineFunctionProperties(names, Shell.class,
|
||||
ScriptableObject.DONTENUM);
|
||||
|
||||
args = processOptions(cx, args);
|
||||
|
||||
// Set up "arguments" in the global scope to contain the command
|
||||
// line arguments after the name of the script to execute
|
||||
Object[] array;
|
||||
if (args.length == 0) {
|
||||
array = new Object[0];
|
||||
} else {
|
||||
int length = args.length - 1;
|
||||
array = new Object[length];
|
||||
System.arraycopy(args, 1, array, 0, length);
|
||||
}
|
||||
Scriptable argsObj = cx.newArray(shell, array);
|
||||
shell.defineProperty("arguments", argsObj,
|
||||
ScriptableObject.DONTENUM);
|
||||
|
||||
shell.processSource(cx, args.length == 0 ? null : args[0]);
|
||||
} finally {
|
||||
Context.exit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse arguments.
|
||||
*/
|
||||
public static String[] processOptions(Context cx, String args[]) {
|
||||
for (int i=0; i < args.length; i++) {
|
||||
String arg = args[i];
|
||||
if (!arg.startsWith("-")) {
|
||||
String[] result = new String[args.length - i];
|
||||
for (int j=i; j < args.length; j++)
|
||||
result[j-i] = args[j];
|
||||
return result;
|
||||
}
|
||||
if (arg.equals("-version")) {
|
||||
if (++i == args.length)
|
||||
usage(arg);
|
||||
double d = Context.toNumber(args[i]);
|
||||
if (d != d)
|
||||
usage(arg);
|
||||
cx.setLanguageVersion((int) d);
|
||||
continue;
|
||||
}
|
||||
usage(arg);
|
||||
}
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a usage message.
|
||||
*/
|
||||
private static void usage(String s) {
|
||||
p("Didn't understand \"" + s + "\".");
|
||||
p("Valid arguments are:");
|
||||
p("-version 100|110|120|130|140|150|160|170");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a help message.
|
||||
*
|
||||
* This method is defined as a JavaScript function.
|
||||
*/
|
||||
public void help() {
|
||||
p("");
|
||||
p("Command Description");
|
||||
p("======= ===========");
|
||||
p("help() Display usage and help messages. ");
|
||||
p("defineClass(className) Define an extension using the Java class");
|
||||
p(" named with the string argument. ");
|
||||
p(" Uses ScriptableObject.defineClass(). ");
|
||||
p("load(['foo.js', ...]) Load JavaScript source files named by ");
|
||||
p(" string arguments. ");
|
||||
p("loadClass(className) Load a class named by a string argument.");
|
||||
p(" The class must be a script compiled to a");
|
||||
p(" class file. ");
|
||||
p("print([expr ...]) Evaluate and print expressions. ");
|
||||
p("quit() Quit the shell. ");
|
||||
p("version([number]) Get or set the JavaScript version number.");
|
||||
p("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the string values of its arguments.
|
||||
*
|
||||
* This method is defined as a JavaScript function.
|
||||
* Note that its arguments are of the "varargs" form, which
|
||||
* allows it to handle an arbitrary number of arguments
|
||||
* supplied to the JavaScript function.
|
||||
*
|
||||
*/
|
||||
public static void print(Context cx, Scriptable thisObj,
|
||||
Object[] args, Function funObj)
|
||||
{
|
||||
for (int i=0; i < args.length; i++) {
|
||||
if (i > 0)
|
||||
System.out.print(" ");
|
||||
|
||||
// Convert the arbitrary JavaScript value into a string form.
|
||||
String s = Context.toString(args[i]);
|
||||
|
||||
System.out.print(s);
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Quit the shell.
|
||||
*
|
||||
* This only affects the interactive mode.
|
||||
*
|
||||
* This method is defined as a JavaScript function.
|
||||
*/
|
||||
public void quit()
|
||||
{
|
||||
quitting = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and set the language version.
|
||||
*
|
||||
* This method is defined as a JavaScript function.
|
||||
*/
|
||||
public static double version(Context cx, Scriptable thisObj,
|
||||
Object[] args, Function funObj)
|
||||
{
|
||||
double result = cx.getLanguageVersion();
|
||||
if (args.length > 0) {
|
||||
double d = Context.toNumber(args[0]);
|
||||
cx.setLanguageVersion((int) d);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and execute a set of JavaScript source files.
|
||||
*
|
||||
* This method is defined as a JavaScript function.
|
||||
*
|
||||
*/
|
||||
public static void load(Context cx, Scriptable thisObj,
|
||||
Object[] args, Function funObj)
|
||||
{
|
||||
Shell shell = (Shell)getTopLevelScope(thisObj);
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
shell.processSource(cx, Context.toString(args[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Evaluate JavaScript source.
|
||||
*
|
||||
* @param cx the current context
|
||||
* @param filename the name of the file to compile, or null
|
||||
* for interactive mode.
|
||||
*/
|
||||
private void processSource(Context cx, String filename)
|
||||
{
|
||||
if (filename == null) {
|
||||
BufferedReader in = new BufferedReader
|
||||
(new InputStreamReader(System.in));
|
||||
String sourceName = "<stdin>";
|
||||
int lineno = 1;
|
||||
boolean hitEOF = false;
|
||||
do {
|
||||
int startline = lineno;
|
||||
System.err.print("js> ");
|
||||
System.err.flush();
|
||||
try {
|
||||
String source = "";
|
||||
// Collect lines of source to compile.
|
||||
while(true) {
|
||||
String newline;
|
||||
newline = in.readLine();
|
||||
if (newline == null) {
|
||||
hitEOF = true;
|
||||
break;
|
||||
}
|
||||
source = source + newline + "\n";
|
||||
lineno++;
|
||||
// Continue collecting as long as more lines
|
||||
// are needed to complete the current
|
||||
// statement. stringIsCompilableUnit is also
|
||||
// true if the source statement will result in
|
||||
// any error other than one that might be
|
||||
// resolved by appending more source.
|
||||
if (cx.stringIsCompilableUnit(source))
|
||||
break;
|
||||
}
|
||||
Object result = cx.evaluateString(this, source,
|
||||
sourceName, startline,
|
||||
null);
|
||||
if (result != Context.getUndefinedValue()) {
|
||||
System.err.println(Context.toString(result));
|
||||
}
|
||||
}
|
||||
catch (WrappedException we) {
|
||||
// Some form of exception was caught by JavaScript and
|
||||
// propagated up.
|
||||
System.err.println(we.getWrappedException().toString());
|
||||
we.printStackTrace();
|
||||
}
|
||||
catch (EvaluatorException ee) {
|
||||
// Some form of JavaScript error.
|
||||
System.err.println("js: " + ee.getMessage());
|
||||
}
|
||||
catch (JavaScriptException jse) {
|
||||
// Some form of JavaScript error.
|
||||
System.err.println("js: " + jse.getMessage());
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
System.err.println(ioe.toString());
|
||||
}
|
||||
if (quitting) {
|
||||
// The user executed the quit() function.
|
||||
break;
|
||||
}
|
||||
} while (!hitEOF);
|
||||
System.err.println();
|
||||
} else {
|
||||
FileReader in = null;
|
||||
try {
|
||||
in = new FileReader(filename);
|
||||
}
|
||||
catch (FileNotFoundException ex) {
|
||||
Context.reportError("Couldn't open file \"" + filename + "\".");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Here we evalute the entire contents of the file as
|
||||
// a script. Text is printed only if the print() function
|
||||
// is called.
|
||||
cx.evaluateReader(this, in, filename, 1, null);
|
||||
}
|
||||
catch (WrappedException we) {
|
||||
System.err.println(we.getWrappedException().toString());
|
||||
we.printStackTrace();
|
||||
}
|
||||
catch (EvaluatorException ee) {
|
||||
System.err.println("js: " + ee.getMessage());
|
||||
}
|
||||
catch (JavaScriptException jse) {
|
||||
System.err.println("js: " + jse.getMessage());
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
System.err.println(ioe.toString());
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
in.close();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
System.err.println(ioe.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void p(String s) {
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
private boolean quitting;
|
||||
}
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
* SwingApplication.js - a translation into JavaScript of
|
||||
* SwingApplication.java, a java.sun.com Swing example.
|
||||
*
|
||||
* @author Roger E Critchlow, Jr.
|
||||
*/
|
||||
|
||||
var swingNames = JavaImporter();
|
||||
|
||||
swingNames.importPackage(Packages.javax.swing);
|
||||
swingNames.importPackage(Packages.java.awt);
|
||||
swingNames.importPackage(Packages.java.awt.event);
|
||||
|
||||
function createComponents()
|
||||
{
|
||||
with (swingNames) {
|
||||
var labelPrefix = "Number of button clicks: ";
|
||||
var numClicks = 0;
|
||||
var label = new JLabel(labelPrefix + numClicks);
|
||||
var button = new JButton("I'm a Swing button!");
|
||||
button.mnemonic = KeyEvent.VK_I;
|
||||
// Since Rhino 1.5R5 JS functions can be passed to Java method if
|
||||
// corresponding argument type is Java interface with single method
|
||||
// or all its methods have the same number of arguments and the
|
||||
// corresponding arguments has the same type. See also comments for
|
||||
// frame.addWindowListener bellow
|
||||
button.addActionListener(function() {
|
||||
numClicks += 1;
|
||||
label.setText(labelPrefix + numClicks);
|
||||
});
|
||||
label.setLabelFor(button);
|
||||
|
||||
/*
|
||||
* An easy way to put space between a top-level container
|
||||
* and its contents is to put the contents in a JPanel
|
||||
* that has an "empty" border.
|
||||
*/
|
||||
var pane = new JPanel();
|
||||
pane.border = BorderFactory.createEmptyBorder(30, //top
|
||||
30, //left
|
||||
10, //bottom
|
||||
30); //right
|
||||
pane.setLayout(new GridLayout(0, 1));
|
||||
pane.add(button);
|
||||
pane.add(label);
|
||||
|
||||
return pane;
|
||||
}
|
||||
}
|
||||
|
||||
with (swingNames) {
|
||||
try {
|
||||
UIManager.
|
||||
setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
|
||||
} catch (e) { }
|
||||
|
||||
//Create the top-level container and add contents to it.
|
||||
var frame = new swingNames.JFrame("SwingApplication");
|
||||
frame.getContentPane().add(createComponents(), BorderLayout.CENTER);
|
||||
|
||||
// Pass JS function as implementation of WindowListener. It is allowed since
|
||||
// all methods in WindowListener have the same signature. To distinguish
|
||||
// between methods Rhino passes to JS function the name of corresponding
|
||||
// method as the last argument
|
||||
frame.addWindowListener(function(event, methodName) {
|
||||
if (methodName == "windowClosing") {
|
||||
java.lang.System.exit(0);
|
||||
}
|
||||
});
|
||||
|
||||
//Finish setting up the frame, and show it.
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* checkParam.js
|
||||
*
|
||||
* The files given as arguments on the command line are assumed to be
|
||||
* Java source code files. This program checks to see that the @param
|
||||
* tags in the documentation comments match with the parameters for
|
||||
* the associated Java methods.
|
||||
* <p>
|
||||
* Any errors found are reported.
|
||||
*
|
||||
*/
|
||||
defineClass("File")
|
||||
|
||||
// Return true if "str" ends with "suffix".
|
||||
function stringEndsWith(str, suffix) {
|
||||
return str.substring(str.length - suffix.length) == suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform processing once the end of a documentation comment is seen.
|
||||
*
|
||||
* Look for a parameter list following the end of the comment and
|
||||
* collect the parameters and compare to the @param entries.
|
||||
* Report any discrepancies.
|
||||
* @param f the current file
|
||||
* @param a an array of parameters from @param comments
|
||||
* @param line the string containing the comment end (in case the
|
||||
* parameters are on the same line)
|
||||
*/
|
||||
function processCommentEnd(f, a, line) {
|
||||
while (line != null && !line.match(/\(/))
|
||||
line = f.readLine();
|
||||
while (line != null && !line.match(/\)/))
|
||||
line += f.readLine();
|
||||
if (line === null)
|
||||
return;
|
||||
var m = line.match(/\(([^\)]+)\)/);
|
||||
var args = m ? m[1].split(",") : [];
|
||||
if (a.length != args.length) {
|
||||
print('"' + f.name +
|
||||
'"; line ' + f.lineNumber +
|
||||
' mismatch: had a different number' +
|
||||
' of @param entries and parameters.');
|
||||
} else {
|
||||
for (var i=0; i < a.length; i++) {
|
||||
if (!stringEndsWith(args[i], a[i])) {
|
||||
print('"' + f.name +
|
||||
'"; line ' + f.lineNumber +
|
||||
' mismatch: had "' + a[i] +
|
||||
'" and "' + args[i] + '".');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the given file, looking for mismatched @param lists and
|
||||
* parameter lists.
|
||||
* @param f the file to process
|
||||
*/
|
||||
function processFile(f) {
|
||||
var line;
|
||||
var m;
|
||||
var i = 0;
|
||||
var a = [];
|
||||
outer:
|
||||
while ((line = f.readLine()) != null) {
|
||||
if (line.match(/@param/)) {
|
||||
while (m = line.match(/@param[ ]+([^ ]+)/)) {
|
||||
a[i++] = m[1];
|
||||
line = f.readLine();
|
||||
if (line == null)
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
if (i != 0 && line.match(/\*\//)) {
|
||||
processCommentEnd(f, a, line);
|
||||
i = 0;
|
||||
a = [];
|
||||
}
|
||||
}
|
||||
if (i != 0) {
|
||||
print('"' + f.name +
|
||||
'"; line ' + f.lineNumber +
|
||||
' missing parameters at end of file.');
|
||||
}
|
||||
}
|
||||
|
||||
// main script: process each file in arguments list
|
||||
|
||||
for (var i=0; i < arguments.length; i++) {
|
||||
var filename = String(arguments[i]);
|
||||
print("Checking " + filename + "...");
|
||||
var f = new File(filename);
|
||||
processFile(f);
|
||||
}
|
||||
print("done.");
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/* -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Patrick Beard
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
Implementing the interface java.util.Enumeration passing the object
|
||||
with JavaScript implementation directly to the constructor.
|
||||
This is a shorthand for JavaAdapter constructor:
|
||||
|
||||
elements = new JavaAdapter(java.util.Enumeration, {
|
||||
index: 0,
|
||||
elements: array,
|
||||
hasMoreElements: function ...
|
||||
nextElement: function ...
|
||||
});
|
||||
*/
|
||||
|
||||
// an array to enumerate.
|
||||
var array = [0, 1, 2];
|
||||
|
||||
// create an array enumeration.
|
||||
var elements = new java.util.Enumeration({
|
||||
index: 0,
|
||||
elements: array,
|
||||
hasMoreElements: function() {
|
||||
return (this.index < this.elements.length);
|
||||
},
|
||||
nextElement: function() {
|
||||
return this.elements[this.index++];
|
||||
}
|
||||
});
|
||||
|
||||
// now print out the array by enumerating through the Enumeration
|
||||
while (elements.hasMoreElements())
|
||||
print(elements.nextElement());
|
||||
@@ -1,556 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Roland Pennings
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* Process a JavaScript source file and process special comments
|
||||
* to produce an HTML file of documentation, similar to javadoc.
|
||||
* @author Norris Boyd
|
||||
* @see rhinotip.jar
|
||||
* @lastmodified xx
|
||||
* @version 1.2 Roland Pennings: Allow multiple files for a function.
|
||||
* @version 1.3 Roland Pennings: Removes ../.. from the input directory name
|
||||
*/
|
||||
defineClass("File")
|
||||
|
||||
var functionDocArray = [];
|
||||
var inputDirName = "";
|
||||
var indexFileArray = [];
|
||||
var indexFile = "";
|
||||
var indexFileName = "index_files";
|
||||
var indexFunctionArray = [];
|
||||
var indexFunction = "";
|
||||
var indexFunctionName = "index_functions";
|
||||
var FileList = [];
|
||||
var DirList = [];
|
||||
var outputdir = null;
|
||||
var debug = 0;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Process JavaScript source file <code>f</code>, writing jsdoc to
|
||||
* file <code>out</code>.
|
||||
* @param f input file
|
||||
* @param fname name of the input file (without the path)
|
||||
* @param inputdir directory of the input file
|
||||
* @param out output file
|
||||
*/
|
||||
function processFile(f, fname, inputdir, out) {
|
||||
var s;
|
||||
var firstLine = true;
|
||||
indexFileArray[fname] = "";
|
||||
|
||||
// write the header of the output file
|
||||
out.writeLine('<HTML><HEADER><TITLE>' + fname + '</TITLE><BODY>');
|
||||
if (inputdir != null) {
|
||||
outstr = '<a name=\"_top_\"></a><pre><a href=\"' + indexFile + '\">Index Files</a> ';
|
||||
outstr += '<a href=\"' + indexFunction + '\">Index Functions</a></pre><hr>';
|
||||
out.writeLine(outstr);
|
||||
}
|
||||
|
||||
// process the input file
|
||||
var comment = "";
|
||||
while ((s = f.readLine()) != null) {
|
||||
var m = s.match(/\/\*\*(.*)/);
|
||||
if (m != null) {
|
||||
// Found a comment start.
|
||||
s = "*" + m[1];
|
||||
do {
|
||||
m = s.match(/(.*)\*\//);
|
||||
if (m != null) {
|
||||
// Found end of comment.
|
||||
comment += m[1];
|
||||
break;
|
||||
}
|
||||
// Strip leading whitespace and "*".
|
||||
comment += s.replace(/^\s*\*/, "");
|
||||
s = f.readLine();
|
||||
} while (s != null);
|
||||
|
||||
if (debug)
|
||||
print("Found comment " + comment);
|
||||
|
||||
if (firstLine) {
|
||||
// We have a comment for the whole file.
|
||||
out.writeLine('<H1>File ' + fname + '</H1>');
|
||||
out.writeLine(processComment(comment,firstLine,fname));
|
||||
out.writeLine('<HR>');
|
||||
firstLine = false;
|
||||
comment = "";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// match the beginning of the function
|
||||
// NB we also match functions without a comment!
|
||||
// if we have two comments one after another only the last one will be taken
|
||||
m = s.match(/^\s*function\s+((\w+)|(\w+)(\s+))\(([^)]*)\)/);
|
||||
if (m != null)
|
||||
{
|
||||
// Found a function start
|
||||
var htmlText = processFunction(m[1], m[5], comment); // sjm changed from 2nd to 5th arg
|
||||
|
||||
// Save the text in a global variable, so we
|
||||
// can write out a table of contents first.
|
||||
functionDocArray[functionDocArray.length] = {name:m[1], text:htmlText};
|
||||
|
||||
// Store the function also in the indexFunctionArray
|
||||
// so we can have a separate file with the function table of contents
|
||||
if (indexFunctionArray[m[1]]) {
|
||||
// print("ERROR: function: " + m[1] + " is defined more than once!");
|
||||
// Allow multiple files for a function
|
||||
with (indexFunctionArray[m[1]]) {
|
||||
filename = filename + "|" + fname;
|
||||
// print("filename = " + filename);
|
||||
}
|
||||
}
|
||||
else {
|
||||
indexFunctionArray[m[1]] = {filename:fname};
|
||||
}
|
||||
//reset comment
|
||||
comment = "";
|
||||
}
|
||||
// match a method being bound to a prototype
|
||||
m = s.match(/^\s*(\w*)\.prototype\.(\w*)\s*=\s*function\s*\(([^)]*)\)/);
|
||||
if (m != null)
|
||||
{
|
||||
// Found a method being bound to a prototype.
|
||||
var htmlText = processPrototypeMethod(m[1], m[2], m[3], comment);
|
||||
|
||||
// Save the text in a global variable, so we
|
||||
// can write out a table of contents first.
|
||||
functionDocArray[functionDocArray.length] = {name:m[1]+".prototype."+m[2], text:htmlText};
|
||||
|
||||
// Store the function also in the indexFunctionArray
|
||||
// so we can have a separate file with the function table of contents
|
||||
if (indexFunctionArray[m[1]]) {
|
||||
// print("ERROR: function: " + m[1] + " is defined more than once!");
|
||||
// Allow multiple files for a function
|
||||
with (indexFunctionArray[m[1]]) {
|
||||
filename = filename + "|" + fname;
|
||||
// print("filename = " + filename);
|
||||
}
|
||||
}
|
||||
else {
|
||||
indexFunctionArray[m[1]] = {filename:fname};
|
||||
}
|
||||
//reset comment
|
||||
comment = "";
|
||||
}
|
||||
|
||||
|
||||
firstLine = false;
|
||||
}
|
||||
|
||||
// Write table of contents.
|
||||
for (var i=0; i < functionDocArray.length; i++) {
|
||||
with (functionDocArray[i]) {
|
||||
out.writeLine('function <A HREF=#' + name +
|
||||
'>' + name + '</A><BR>');
|
||||
}
|
||||
}
|
||||
out.writeLine('<HR>');
|
||||
|
||||
// Now write the saved function documentation.
|
||||
for (i=0; i < functionDocArray.length; i++) {
|
||||
with (functionDocArray[i]) {
|
||||
out.writeLine('<A NAME=' + name + '>');
|
||||
out.writeLine(text);
|
||||
}
|
||||
}
|
||||
out.writeLine('</BODY></HTML>');
|
||||
|
||||
// Now clean up the doc array
|
||||
functionDocArray = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Process function and associated comment.
|
||||
* @param name the name of the function
|
||||
* @param args the args of the function as a single string
|
||||
* @param comment the text of the comment
|
||||
* @return a string for the HTML text of the documentation
|
||||
*/
|
||||
function processFunction(name, args, comment) {
|
||||
if (debug)
|
||||
print("Processing " + name + " " + args + " " + comment);
|
||||
return "<H2>Function " + name + "</H2>" +
|
||||
"<PRE>" +
|
||||
"function " + name + "(" + args + ")" +
|
||||
"</PRE>" +
|
||||
processComment(comment,0,name) +
|
||||
"<P><BR><BR>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a method being bound to a prototype.
|
||||
* @param proto the name of the prototype
|
||||
* @param name the name of the function
|
||||
* @param args the args of the function as a single string
|
||||
* @param comment the text of the comment
|
||||
* @return a string for the HTML text of the documentation
|
||||
*/
|
||||
function processPrototypeMethod(proto, name, args, comment) {
|
||||
if (debug)
|
||||
print("Processing " + proto + ".prototype." + name + " " + args + " " + comment);
|
||||
return "<H2> Method " + proto + ".prototype." + name + "</H2>" +
|
||||
"<PRE>" +
|
||||
proto + ".prototype." + name + " = function(" + args + ")" +
|
||||
"</PRE>" +
|
||||
processComment(comment,0,name) +
|
||||
"<P><BR><BR>";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process comment.
|
||||
* @param comment the text of the comment
|
||||
* @param firstLine shows if comment is at the beginning of the file
|
||||
* @param fname name of the file (without path)
|
||||
* @return a string for the HTML text of the documentation
|
||||
*/
|
||||
function processComment(comment,firstLine,fname) {
|
||||
var tags = {};
|
||||
// Use the "lambda" form of regular expression replace,
|
||||
// where the replacement object is a function rather
|
||||
// than a string. The function is called with the
|
||||
// matched text and any parenthetical matches as
|
||||
// arguments, and the result of the function used as the
|
||||
// replacement text.
|
||||
// Here we use the function to build up the "tags" object,
|
||||
// which has a property for each "@" tag that is the name
|
||||
// of the tag, and whose value is an array of the
|
||||
// text following that tag.
|
||||
comment = comment.replace(/@(\w+)\s+([^@]*)/g,
|
||||
function (s, name, text) {
|
||||
var a = tags[name] || [];
|
||||
a.push(text);
|
||||
tags[name] = a;
|
||||
return "";
|
||||
});
|
||||
|
||||
// if we have a comment at the beginning of a file
|
||||
// store the comment for the index file
|
||||
if (firstLine) {
|
||||
indexFileArray[fname] = comment;
|
||||
}
|
||||
|
||||
var out = comment + '<P>';
|
||||
if (tags["param"]) {
|
||||
// Create a table of parameters and their descriptions.
|
||||
var array = tags["param"];
|
||||
var params = "";
|
||||
for (var i=0; i < array.length; i++) {
|
||||
var m = array[i].match(/(\w+)\s+(.*)/);
|
||||
params += '<TR><TD><I>'+m[1]+'</I></TD>' +
|
||||
'<TD>'+m[2]+'</TD></TR>';
|
||||
}
|
||||
out += '<TABLE WIDTH="90%" BORDER=1>';
|
||||
out += '<TR BGCOLOR=0xdddddddd>';
|
||||
out += '<TD><B>Parameter</B></TD>';
|
||||
out += '<TD><B>Description</B></TD></TR>';
|
||||
out += params;
|
||||
out += '</TABLE><P>';
|
||||
}
|
||||
if (tags["return"]) {
|
||||
out += "<DT><B>Returns:</B><DD>";
|
||||
out += tags["return"][0] + "</DL><P>";
|
||||
}
|
||||
if (tags["author"]) {
|
||||
// List the authors together, separated by commas.
|
||||
out += '<DT><B>Author:</B><DD>';
|
||||
var array = tags["author"];
|
||||
for (var i=0; i < array.length; i++) {
|
||||
out += array[i];
|
||||
if (i+1 < array.length)
|
||||
out += ", ";
|
||||
}
|
||||
out += '</DL><P>';
|
||||
}
|
||||
if (tags["version"]) {
|
||||
// Show the version.
|
||||
out += '<DT><B>Version:</B><DD>';
|
||||
var array = tags["version"];
|
||||
for (var i=0; i < array.length; i++) {
|
||||
out += array[i];
|
||||
if (i+1 < array.length)
|
||||
out += "<BR><DD>";
|
||||
}
|
||||
out += '</DL><P>';
|
||||
}
|
||||
if (tags["see"]) {
|
||||
// List the see modules together, separated by <BR>.
|
||||
out += '<DT><B>Dependencies:</B><DD>';
|
||||
var array = tags["see"];
|
||||
for (var i=0; i < array.length; i++) {
|
||||
out += array[i];
|
||||
if (i+1 < array.length)
|
||||
out += "<BR><DD>";
|
||||
}
|
||||
out += '</DL><P>';
|
||||
}
|
||||
if (tags["lastmodified"]) {
|
||||
// Shows a last modified description with client-side js.
|
||||
out += '<DT><B>Last modified:</B><DD>';
|
||||
out += '<script><!--\n';
|
||||
out += 'document.writeln(document.lastModified);\n';
|
||||
out += '// ---></script>\n';
|
||||
out += '</DL><P>';
|
||||
}
|
||||
|
||||
// additional tags can be added here (i.e., "if (tags["see"])...")
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an html output file
|
||||
* @param outputdir directory to put the file
|
||||
* @param htmlfile name of the file
|
||||
*/
|
||||
function CreateOutputFile(outputdir,htmlfile)
|
||||
{
|
||||
if (outputdir==null)
|
||||
{
|
||||
var outname = htmlfile;
|
||||
}
|
||||
else
|
||||
{
|
||||
var separator = Packages.java.io.File.separator;
|
||||
var outname = outputdir + separator + htmlfile.substring(htmlfile.lastIndexOf(separator),htmlfile.length);
|
||||
}
|
||||
print("output file: " + outname);
|
||||
return new File(outname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a javascript file. Puts the generated HTML file in the outdir
|
||||
* @param filename name of the javascript file
|
||||
* @inputdir input directory of the file (default null)
|
||||
*/
|
||||
function processJSFile(filename,inputdir)
|
||||
{
|
||||
if (debug) print("filename = " + filename + " inputdir = " + inputdir);
|
||||
|
||||
if (!filename.match(/\.js$/)) {
|
||||
print("Expected filename to end in '.js'; had instead " +
|
||||
filename + ". I don't treat the file.");
|
||||
} else {
|
||||
if (inputdir==null)
|
||||
{
|
||||
var inname = filename;
|
||||
}
|
||||
else
|
||||
{
|
||||
var separator = Packages.java.io.File.separator;
|
||||
var inname = inputdir + separator + filename;
|
||||
}
|
||||
print("Processing file " + inname);
|
||||
|
||||
var f = new File(inname);
|
||||
|
||||
// create the output file
|
||||
var htmlfile = filename.replace(/\.js$/, ".html");
|
||||
|
||||
var out = CreateOutputFile(outputdir,htmlfile);
|
||||
|
||||
processFile(f, filename, inputdir, out);
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate index files containing links to the processed javascript files
|
||||
* and the generated functions
|
||||
*/
|
||||
function GenerateIndex(dirname)
|
||||
{
|
||||
// construct the files index file
|
||||
var out = CreateOutputFile(outputdir,indexFile);
|
||||
|
||||
// write the beginning of the file
|
||||
out.writeLine('<HTML><HEADER><TITLE>File Index - directory: ' + dirname + '</TITLE><BODY>');
|
||||
out.writeLine('<H1>File Index - directory: ' + dirname + '</H1>\n');
|
||||
out.writeLine('<TABLE WIDTH="90%" BORDER=1>');
|
||||
out.writeLine('<TR BGCOLOR=0xdddddddd>');
|
||||
out.writeLine('<TD><B>File</B></TD>');
|
||||
out.writeLine('<TD><B>Description</B></TD></TR>');
|
||||
|
||||
var separator = Packages.java.io.File.separator;
|
||||
|
||||
// sort the index file array
|
||||
var SortedFileArray = [];
|
||||
for (var fname in indexFileArray)
|
||||
SortedFileArray.push(fname);
|
||||
SortedFileArray.sort();
|
||||
|
||||
for (var i=0; i < SortedFileArray.length; i++) {
|
||||
var fname = SortedFileArray[i];
|
||||
var htmlfile = fname.replace(/\.js$/, ".html");
|
||||
out.writeLine('<TR><TD><A HREF=\"' + htmlfile + '\">' + fname + '</A></TD></TD><TD>');
|
||||
if (indexFileArray[fname])
|
||||
out.writeLine(indexFileArray[fname]);
|
||||
else
|
||||
out.writeLine('No comments');
|
||||
out.writeLine('</TD></TR>\n');
|
||||
}
|
||||
out.writeLine('</TABLE></BODY></HTML>');
|
||||
out.close();
|
||||
|
||||
// construct the functions index file
|
||||
var out = CreateOutputFile(outputdir,indexFunction);
|
||||
|
||||
// write the beginning of the file
|
||||
out.writeLine('<HTML><HEADER><TITLE>Function Index - directory: ' + dirname + '</TITLE><BODY>');
|
||||
out.writeLine('<H1>Function Index - directory: ' + dirname + '</H1>\n');
|
||||
out.writeLine('<TABLE WIDTH="90%" BORDER=1>');
|
||||
out.writeLine('<TR BGCOLOR=0xdddddddd>');
|
||||
out.writeLine('<TD><B>Function</B></TD>');
|
||||
out.writeLine('<TD><B>Files</B></TD></TR>');
|
||||
|
||||
// sort the function array
|
||||
var SortedFunctionArray = [];
|
||||
for (var functionname in indexFunctionArray)
|
||||
SortedFunctionArray.push(functionname);
|
||||
SortedFunctionArray.sort();
|
||||
|
||||
for (var j=0; j < SortedFunctionArray.length; j++) {
|
||||
var funcname = SortedFunctionArray[j];
|
||||
with (indexFunctionArray[funcname]) {
|
||||
var outstr = '<TR><TD>' + funcname + '</TD><TD>';
|
||||
var filelst = filename.split("|");
|
||||
for (var i in filelst) {
|
||||
var htmlfile = filelst[i].replace(/\.js$/, ".html");
|
||||
outstr += '<A HREF=\"' + htmlfile + '#' + funcname + '\">' + filelst[i] + '</A> ';
|
||||
}
|
||||
outstr += '</TD></TR>';
|
||||
out.writeLine(outstr);
|
||||
}
|
||||
}
|
||||
out.writeLine('</TABLE></BODY></HTML>');
|
||||
out.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* prints the options for JSDoc
|
||||
*/
|
||||
function PrintOptions()
|
||||
{
|
||||
print("You can use the following options:\n");
|
||||
print("-d: specify an output directory for the generated html files\n");
|
||||
print("-i: processes all files in an input directory (you can specify several directories)\n");
|
||||
quit();
|
||||
}
|
||||
|
||||
|
||||
// Main Script
|
||||
// first read the arguments
|
||||
if (! arguments)
|
||||
PrintOptions();
|
||||
|
||||
for (var i=0; i < arguments.length; i++) {
|
||||
if (debug) print("argument: + \'" + arguments[i] + "\'");
|
||||
if (arguments[i].match(/^\-/)) {
|
||||
if (String(arguments[i])=="-d"){
|
||||
// output directory for the generated html files
|
||||
|
||||
outputdir = String(arguments[i+1]);
|
||||
if (debug) print("outputdir: + \'" + outputdir + "\'");
|
||||
|
||||
i++;
|
||||
}
|
||||
else if (String(arguments[i])=="-i"){
|
||||
// process all files in an input directory
|
||||
|
||||
DirList.push(String(arguments[i+1]));
|
||||
if (debug) print("inputdir: + \'" + arguments[i+1] + "\'");
|
||||
i++;
|
||||
}
|
||||
else {
|
||||
print("Unknown option: " + arguments[i] + "\n");
|
||||
PrintOptions();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have a single file
|
||||
if (debug) print("file: + \'" + arguments[i] + "\'");
|
||||
|
||||
FileList.push(String(arguments[i]));
|
||||
}
|
||||
}
|
||||
|
||||
// first handle the single files
|
||||
for (var i in FileList)
|
||||
processJSFile(FileList[i],null);
|
||||
|
||||
// then handle the input directories
|
||||
for (var j in DirList) {
|
||||
var inputdir = String(DirList[j]);
|
||||
|
||||
print("Process input directory: " + inputdir);
|
||||
|
||||
// clean up index arrays
|
||||
var indexFileArray = [];
|
||||
var indexFunctionArray = [];
|
||||
|
||||
// for the directory name get rid of ../../ or ..\..\
|
||||
inputDirName = inputdir.replace(/\.\.\/|\.\.\\/g,"");
|
||||
|
||||
indexFile = indexFileName + "_" + inputDirName + ".html";
|
||||
indexFunction = indexFunctionName + "_" + inputDirName + ".html";
|
||||
|
||||
print("indexFile = " + indexFile);
|
||||
print("indexFunction = " + indexFunction);
|
||||
|
||||
// read the files in the directory
|
||||
var DirFile = new java.io.File(inputdir);
|
||||
var lst = DirFile.list();
|
||||
var separator = Packages.java.io.File.separator;
|
||||
|
||||
for (var i=0; i < lst.length; i++)
|
||||
{
|
||||
processJSFile(String(lst[i]),inputdir);
|
||||
}
|
||||
|
||||
// generate the index files for the input directory
|
||||
GenerateIndex(inputDirName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* liveConnect.js: a simple demonstration of JavaScript-to-Java connectivity
|
||||
*/
|
||||
|
||||
// Create a new StringBuffer. Note that the class name must be fully qualified
|
||||
// by its package. Packages other than "java" must start with "Packages", i.e.,
|
||||
// "Packages.javax.servlet...".
|
||||
var sb = new java.lang.StringBuffer();
|
||||
|
||||
// Now add some stuff to the buffer.
|
||||
sb.append("hi, mom");
|
||||
sb.append(3); // this will add "3.0" to the buffer since all JS numbers
|
||||
// are doubles by default
|
||||
sb.append(true);
|
||||
|
||||
// Now print it out. (The toString() method of sb is automatically called
|
||||
// to convert the buffer to a string.)
|
||||
// Should print "hi, mom3.0true".
|
||||
print(sb);
|
||||
@@ -1,56 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// unique.js: read the contents of a file and print out the unique lines
|
||||
|
||||
defineClass("File")
|
||||
|
||||
// "arguments[0]" refers to the first argument at the command line to the
|
||||
// script, if present. If not present, "arguments[0]" will be undefined,
|
||||
// which will cause f to read from System.in.
|
||||
var f = new File(arguments[0]);
|
||||
var o = {}
|
||||
var line;
|
||||
while ((line = f.readLine()) != null) {
|
||||
// Use JavaScript objects' inherent nature as an associative
|
||||
// array to provide uniqueness
|
||||
o[line] = true;
|
||||
}
|
||||
for (i in o) {
|
||||
print(i);
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License Version
|
||||
- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
- the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is Rhino code, released May 6, 1999.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Netscape Communications Corporation.
|
||||
- Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
- case the provisions of the GPL are applicable instead of those above. If
|
||||
- you wish to allow use of your version of this file only under the terms of
|
||||
- the GPL and not to allow others to use your version of this file under the
|
||||
- MPL, indicate your decision by deleting the provisions above and replacing
|
||||
- them with the notice and other provisions required by the GPL. If you do
|
||||
- not delete the provisions above, a recipient may use your version of this
|
||||
- file under either the MPL or the GPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
|
||||
|
||||
<!--
|
||||
Build file for Rhino using Ant (see http://jakarta.apache.org/ant/index.html)
|
||||
Requires Ant version 1.2
|
||||
-->
|
||||
<project name="src" default="compile" basedir="..">
|
||||
|
||||
<property file="build.properties"/>
|
||||
|
||||
<available property="jdk15"
|
||||
classname="java.lang.reflect.ParameterizedType" />
|
||||
|
||||
<target name="compile" depends="compile-most,compile-jdk15">
|
||||
</target>
|
||||
|
||||
<target name="shell" depends="compile">
|
||||
<java classname="org.mozilla.javascript.tools.shell.Main"
|
||||
classpath="${classes}"
|
||||
fork="true">
|
||||
<arg line="-version 170"/>
|
||||
</java>
|
||||
</target>
|
||||
|
||||
<target name="compile-most">
|
||||
<javac srcdir="src"
|
||||
destdir="${classes}"
|
||||
includes="org/**/*.java"
|
||||
excludes="org/**/jdk15/*.java"
|
||||
deprecation="on"
|
||||
debug="${debug}"
|
||||
target="${target-jvm}"
|
||||
source="${source-level}"
|
||||
>
|
||||
</javac>
|
||||
<copy todir="${classes}">
|
||||
<fileset dir="src" includes="org/**/*.properties" />
|
||||
<filterset>
|
||||
<filter token="IMPLEMENTATION.VERSION"
|
||||
value="${implementation.version}"/>
|
||||
</filterset>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="compile-jdk15" if="jdk15">
|
||||
<javac srcdir="src"
|
||||
destdir="${classes}"
|
||||
includes="org/**/jdk15/*.java"
|
||||
deprecation="on"
|
||||
debug="${debug}"
|
||||
target="${target-jvm}"
|
||||
source="${source-level}"
|
||||
>
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<target name="copy-source">
|
||||
<mkdir dir="${dist.dir}/src"/>
|
||||
<copy todir="${dist.dir}/src">
|
||||
<fileset dir="src"
|
||||
includes="**/*.java,**/*.properties,**/*.xml,manifest"/>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="clean">
|
||||
<delete includeEmptyDirs="true">
|
||||
<fileset dir="${classes}"
|
||||
excludes="org/mozilla/javascript/tools/**"/>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
@@ -1,3 +0,0 @@
|
||||
Manifest-Version: 1.0
|
||||
Main-Class: org.mozilla.javascript.tools.shell.Main
|
||||
Class-Path: xbean.jar
|
||||
@@ -1,274 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Roger Lawrence
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.classfile;
|
||||
|
||||
/**
|
||||
* This class provides opcode values expected by the JVM in Java class files.
|
||||
*
|
||||
* It also provides tables for internal use by the ClassFileWriter.
|
||||
*
|
||||
* @author Roger Lawrence
|
||||
*/
|
||||
public class ByteCode {
|
||||
|
||||
/**
|
||||
* The byte opcodes defined by the Java Virtual Machine.
|
||||
*/
|
||||
public static final int
|
||||
NOP = 0x00,
|
||||
ACONST_NULL = 0x01,
|
||||
ICONST_M1 = 0x02,
|
||||
ICONST_0 = 0x03,
|
||||
ICONST_1 = 0x04,
|
||||
ICONST_2 = 0x05,
|
||||
ICONST_3 = 0x06,
|
||||
ICONST_4 = 0x07,
|
||||
ICONST_5 = 0x08,
|
||||
LCONST_0 = 0x09,
|
||||
LCONST_1 = 0x0A,
|
||||
FCONST_0 = 0x0B,
|
||||
FCONST_1 = 0x0C,
|
||||
FCONST_2 = 0x0D,
|
||||
DCONST_0 = 0x0E,
|
||||
DCONST_1 = 0x0F,
|
||||
BIPUSH = 0x10,
|
||||
SIPUSH = 0x11,
|
||||
LDC = 0x12,
|
||||
LDC_W = 0x13,
|
||||
LDC2_W = 0x14,
|
||||
ILOAD = 0x15,
|
||||
LLOAD = 0x16,
|
||||
FLOAD = 0x17,
|
||||
DLOAD = 0x18,
|
||||
ALOAD = 0x19,
|
||||
ILOAD_0 = 0x1A,
|
||||
ILOAD_1 = 0x1B,
|
||||
ILOAD_2 = 0x1C,
|
||||
ILOAD_3 = 0x1D,
|
||||
LLOAD_0 = 0x1E,
|
||||
LLOAD_1 = 0x1F,
|
||||
LLOAD_2 = 0x20,
|
||||
LLOAD_3 = 0x21,
|
||||
FLOAD_0 = 0x22,
|
||||
FLOAD_1 = 0x23,
|
||||
FLOAD_2 = 0x24,
|
||||
FLOAD_3 = 0x25,
|
||||
DLOAD_0 = 0x26,
|
||||
DLOAD_1 = 0x27,
|
||||
DLOAD_2 = 0x28,
|
||||
DLOAD_3 = 0x29,
|
||||
ALOAD_0 = 0x2A,
|
||||
ALOAD_1 = 0x2B,
|
||||
ALOAD_2 = 0x2C,
|
||||
ALOAD_3 = 0x2D,
|
||||
IALOAD = 0x2E,
|
||||
LALOAD = 0x2F,
|
||||
FALOAD = 0x30,
|
||||
DALOAD = 0x31,
|
||||
AALOAD = 0x32,
|
||||
BALOAD = 0x33,
|
||||
CALOAD = 0x34,
|
||||
SALOAD = 0x35,
|
||||
ISTORE = 0x36,
|
||||
LSTORE = 0x37,
|
||||
FSTORE = 0x38,
|
||||
DSTORE = 0x39,
|
||||
ASTORE = 0x3A,
|
||||
ISTORE_0 = 0x3B,
|
||||
ISTORE_1 = 0x3C,
|
||||
ISTORE_2 = 0x3D,
|
||||
ISTORE_3 = 0x3E,
|
||||
LSTORE_0 = 0x3F,
|
||||
LSTORE_1 = 0x40,
|
||||
LSTORE_2 = 0x41,
|
||||
LSTORE_3 = 0x42,
|
||||
FSTORE_0 = 0x43,
|
||||
FSTORE_1 = 0x44,
|
||||
FSTORE_2 = 0x45,
|
||||
FSTORE_3 = 0x46,
|
||||
DSTORE_0 = 0x47,
|
||||
DSTORE_1 = 0x48,
|
||||
DSTORE_2 = 0x49,
|
||||
DSTORE_3 = 0x4A,
|
||||
ASTORE_0 = 0x4B,
|
||||
ASTORE_1 = 0x4C,
|
||||
ASTORE_2 = 0x4D,
|
||||
ASTORE_3 = 0x4E,
|
||||
IASTORE = 0x4F,
|
||||
LASTORE = 0x50,
|
||||
FASTORE = 0x51,
|
||||
DASTORE = 0x52,
|
||||
AASTORE = 0x53,
|
||||
BASTORE = 0x54,
|
||||
CASTORE = 0x55,
|
||||
SASTORE = 0x56,
|
||||
POP = 0x57,
|
||||
POP2 = 0x58,
|
||||
DUP = 0x59,
|
||||
DUP_X1 = 0x5A,
|
||||
DUP_X2 = 0x5B,
|
||||
DUP2 = 0x5C,
|
||||
DUP2_X1 = 0x5D,
|
||||
DUP2_X2 = 0x5E,
|
||||
SWAP = 0x5F,
|
||||
IADD = 0x60,
|
||||
LADD = 0x61,
|
||||
FADD = 0x62,
|
||||
DADD = 0x63,
|
||||
ISUB = 0x64,
|
||||
LSUB = 0x65,
|
||||
FSUB = 0x66,
|
||||
DSUB = 0x67,
|
||||
IMUL = 0x68,
|
||||
LMUL = 0x69,
|
||||
FMUL = 0x6A,
|
||||
DMUL = 0x6B,
|
||||
IDIV = 0x6C,
|
||||
LDIV = 0x6D,
|
||||
FDIV = 0x6E,
|
||||
DDIV = 0x6F,
|
||||
IREM = 0x70,
|
||||
LREM = 0x71,
|
||||
FREM = 0x72,
|
||||
DREM = 0x73,
|
||||
INEG = 0x74,
|
||||
LNEG = 0x75,
|
||||
FNEG = 0x76,
|
||||
DNEG = 0x77,
|
||||
ISHL = 0x78,
|
||||
LSHL = 0x79,
|
||||
ISHR = 0x7A,
|
||||
LSHR = 0x7B,
|
||||
IUSHR = 0x7C,
|
||||
LUSHR = 0x7D,
|
||||
IAND = 0x7E,
|
||||
LAND = 0x7F,
|
||||
IOR = 0x80,
|
||||
LOR = 0x81,
|
||||
IXOR = 0x82,
|
||||
LXOR = 0x83,
|
||||
IINC = 0x84,
|
||||
I2L = 0x85,
|
||||
I2F = 0x86,
|
||||
I2D = 0x87,
|
||||
L2I = 0x88,
|
||||
L2F = 0x89,
|
||||
L2D = 0x8A,
|
||||
F2I = 0x8B,
|
||||
F2L = 0x8C,
|
||||
F2D = 0x8D,
|
||||
D2I = 0x8E,
|
||||
D2L = 0x8F,
|
||||
D2F = 0x90,
|
||||
I2B = 0x91,
|
||||
I2C = 0x92,
|
||||
I2S = 0x93,
|
||||
LCMP = 0x94,
|
||||
FCMPL = 0x95,
|
||||
FCMPG = 0x96,
|
||||
DCMPL = 0x97,
|
||||
DCMPG = 0x98,
|
||||
IFEQ = 0x99,
|
||||
IFNE = 0x9A,
|
||||
IFLT = 0x9B,
|
||||
IFGE = 0x9C,
|
||||
IFGT = 0x9D,
|
||||
IFLE = 0x9E,
|
||||
IF_ICMPEQ = 0x9F,
|
||||
IF_ICMPNE = 0xA0,
|
||||
IF_ICMPLT = 0xA1,
|
||||
IF_ICMPGE = 0xA2,
|
||||
IF_ICMPGT = 0xA3,
|
||||
IF_ICMPLE = 0xA4,
|
||||
IF_ACMPEQ = 0xA5,
|
||||
IF_ACMPNE = 0xA6,
|
||||
GOTO = 0xA7,
|
||||
JSR = 0xA8,
|
||||
RET = 0xA9,
|
||||
TABLESWITCH = 0xAA,
|
||||
LOOKUPSWITCH = 0xAB,
|
||||
IRETURN = 0xAC,
|
||||
LRETURN = 0xAD,
|
||||
FRETURN = 0xAE,
|
||||
DRETURN = 0xAF,
|
||||
ARETURN = 0xB0,
|
||||
RETURN = 0xB1,
|
||||
GETSTATIC = 0xB2,
|
||||
PUTSTATIC = 0xB3,
|
||||
GETFIELD = 0xB4,
|
||||
PUTFIELD = 0xB5,
|
||||
INVOKEVIRTUAL = 0xB6,
|
||||
INVOKESPECIAL = 0xB7,
|
||||
INVOKESTATIC = 0xB8,
|
||||
INVOKEINTERFACE = 0xB9,
|
||||
NEW = 0xBB,
|
||||
NEWARRAY = 0xBC,
|
||||
ANEWARRAY = 0xBD,
|
||||
ARRAYLENGTH = 0xBE,
|
||||
ATHROW = 0xBF,
|
||||
CHECKCAST = 0xC0,
|
||||
INSTANCEOF = 0xC1,
|
||||
MONITORENTER = 0xC2,
|
||||
MONITOREXIT = 0xC3,
|
||||
WIDE = 0xC4,
|
||||
MULTIANEWARRAY = 0xC5,
|
||||
IFNULL = 0xC6,
|
||||
IFNONNULL = 0xC7,
|
||||
GOTO_W = 0xC8,
|
||||
JSR_W = 0xC9,
|
||||
BREAKPOINT = 0xCA,
|
||||
|
||||
IMPDEP1 = 0xFE,
|
||||
IMPDEP2 = 0xFF;
|
||||
|
||||
/**
|
||||
* Types for the NEWARRAY opcode.
|
||||
*/
|
||||
public static final byte
|
||||
T_BOOLEAN = 4,
|
||||
T_CHAR = 5,
|
||||
T_FLOAT = 6,
|
||||
T_DOUBLE = 7,
|
||||
T_BYTE = 8,
|
||||
T_SHORT = 9,
|
||||
T_INT = 10,
|
||||
T_LONG = 11;
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,322 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Igor Bukanov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* This class implements the "arguments" object.
|
||||
*
|
||||
* See ECMA 10.1.8
|
||||
*
|
||||
* @see org.mozilla.javascript.NativeCall
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
final class Arguments extends IdScriptableObject
|
||||
{
|
||||
static final long serialVersionUID = 4275508002492040609L;
|
||||
|
||||
public Arguments(NativeCall activation)
|
||||
{
|
||||
this.activation = activation;
|
||||
|
||||
Scriptable parent = activation.getParentScope();
|
||||
setParentScope(parent);
|
||||
setPrototype(ScriptableObject.getObjectPrototype(parent));
|
||||
|
||||
args = activation.originalArgs;
|
||||
lengthObj = Integer.valueOf(args.length);
|
||||
|
||||
NativeFunction f = activation.function;
|
||||
calleeObj = f;
|
||||
|
||||
int version = f.getLanguageVersion();
|
||||
if (version <= Context.VERSION_1_3
|
||||
&& version != Context.VERSION_DEFAULT)
|
||||
{
|
||||
callerObj = null;
|
||||
} else {
|
||||
callerObj = NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName()
|
||||
{
|
||||
return "Object";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(int index, Scriptable start)
|
||||
{
|
||||
if (0 <= index && index < args.length) {
|
||||
if (args[index] != NOT_FOUND) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.has(index, start);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(int index, Scriptable start)
|
||||
{
|
||||
if (0 <= index && index < args.length) {
|
||||
Object value = args[index];
|
||||
if (value != NOT_FOUND) {
|
||||
if (sharedWithActivation(index)) {
|
||||
NativeFunction f = activation.function;
|
||||
String argName = f.getParamOrVarName(index);
|
||||
value = activation.get(argName, activation);
|
||||
if (value == NOT_FOUND) Kit.codeBug();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return super.get(index, start);
|
||||
}
|
||||
|
||||
private boolean sharedWithActivation(int index)
|
||||
{
|
||||
NativeFunction f = activation.function;
|
||||
int definedCount = f.getParamCount();
|
||||
if (index < definedCount) {
|
||||
// Check if argument is not hidden by later argument with the same
|
||||
// name as hidden arguments are not shared with activation
|
||||
if (index < definedCount - 1) {
|
||||
String argName = f.getParamOrVarName(index);
|
||||
for (int i = index + 1; i < definedCount; i++) {
|
||||
if (argName.equals(f.getParamOrVarName(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(int index, Scriptable start, Object value)
|
||||
{
|
||||
if (0 <= index && index < args.length) {
|
||||
if (args[index] != NOT_FOUND) {
|
||||
if (sharedWithActivation(index)) {
|
||||
String argName;
|
||||
argName = activation.function.getParamOrVarName(index);
|
||||
activation.put(argName, activation, value);
|
||||
return;
|
||||
}
|
||||
synchronized (this) {
|
||||
if (args[index] != NOT_FOUND) {
|
||||
if (args == activation.originalArgs) {
|
||||
args = args.clone();
|
||||
}
|
||||
args[index] = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
super.put(index, start, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(int index)
|
||||
{
|
||||
if (0 <= index && index < args.length) {
|
||||
synchronized (this) {
|
||||
if (args[index] != NOT_FOUND) {
|
||||
if (args == activation.originalArgs) {
|
||||
args = args.clone();
|
||||
}
|
||||
args[index] = NOT_FOUND;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
super.delete(index);
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
private static final int
|
||||
Id_callee = 1,
|
||||
Id_length = 2,
|
||||
Id_caller = 3,
|
||||
|
||||
MAX_INSTANCE_ID = 3;
|
||||
|
||||
@Override
|
||||
protected int getMaxInstanceId()
|
||||
{
|
||||
return MAX_INSTANCE_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int findInstanceIdInfo(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2007-05-09 08:15:04 EDT
|
||||
L0: { id = 0; String X = null; int c;
|
||||
if (s.length()==6) {
|
||||
c=s.charAt(5);
|
||||
if (c=='e') { X="callee";id=Id_callee; }
|
||||
else if (c=='h') { X="length";id=Id_length; }
|
||||
else if (c=='r') { X="caller";id=Id_caller; }
|
||||
}
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
break L0;
|
||||
}
|
||||
// #/generated#
|
||||
|
||||
if (id == 0) return super.findInstanceIdInfo(s);
|
||||
|
||||
int attr;
|
||||
switch (id) {
|
||||
case Id_callee:
|
||||
case Id_caller:
|
||||
case Id_length:
|
||||
attr = DONTENUM;
|
||||
break;
|
||||
default: throw new IllegalStateException();
|
||||
}
|
||||
return instanceIdInfo(attr, id);
|
||||
}
|
||||
|
||||
// #/string_id_map#
|
||||
|
||||
@Override
|
||||
protected String getInstanceIdName(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_callee: return "callee";
|
||||
case Id_length: return "length";
|
||||
case Id_caller: return "caller";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getInstanceIdValue(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_callee: return calleeObj;
|
||||
case Id_length: return lengthObj;
|
||||
case Id_caller: {
|
||||
Object value = callerObj;
|
||||
if (value == UniqueTag.NULL_VALUE) { value = null; }
|
||||
else if (value == null) {
|
||||
NativeCall caller = activation.parentActivationCall;
|
||||
if (caller != null) {
|
||||
value = caller.get("arguments", caller);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return super.getInstanceIdValue(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setInstanceIdValue(int id, Object value)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_callee: calleeObj = value; return;
|
||||
case Id_length: lengthObj = value; return;
|
||||
case Id_caller:
|
||||
callerObj = (value != null) ? value : UniqueTag.NULL_VALUE;
|
||||
return;
|
||||
}
|
||||
super.setInstanceIdValue(id, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
Object[] getIds(boolean getAll)
|
||||
{
|
||||
Object[] ids = super.getIds(getAll);
|
||||
if (getAll && args.length != 0) {
|
||||
boolean[] present = null;
|
||||
int extraCount = args.length;
|
||||
for (int i = 0; i != ids.length; ++i) {
|
||||
Object id = ids[i];
|
||||
if (id instanceof Integer) {
|
||||
int index = ((Integer)id).intValue();
|
||||
if (0 <= index && index < args.length) {
|
||||
if (present == null) {
|
||||
present = new boolean[args.length];
|
||||
}
|
||||
if (!present[index]) {
|
||||
present[index] = true;
|
||||
extraCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (extraCount != 0) {
|
||||
Object[] tmp = new Object[extraCount + ids.length];
|
||||
System.arraycopy(ids, 0, tmp, extraCount, ids.length);
|
||||
ids = tmp;
|
||||
int offset = 0;
|
||||
for (int i = 0; i != args.length; ++i) {
|
||||
if (present == null || !present[i]) {
|
||||
ids[offset] = Integer.valueOf(i);
|
||||
++offset;
|
||||
}
|
||||
}
|
||||
if (offset != extraCount) Kit.codeBug();
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
// Fields to hold caller, callee and length properties,
|
||||
// where NOT_FOUND value tags deleted properties.
|
||||
// In addition if callerObj == NULL_VALUE, it tags null for scripts, as
|
||||
// initial callerObj == null means access to caller arguments available
|
||||
// only in JS <= 1.3 scripts
|
||||
private Object callerObj;
|
||||
private Object calleeObj;
|
||||
private Object lengthObj;
|
||||
|
||||
private NativeCall activation;
|
||||
|
||||
// Initially args holds activation.getOriginalArgs(), but any modification
|
||||
// of its elements triggers creation of a copy. If its element holds NOT_FOUND,
|
||||
// it indicates deleted index, in which case super class is queried.
|
||||
private Object[] args;
|
||||
}
|
||||
@@ -1,564 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Igor Bukanov
|
||||
* Roger Lawrence
|
||||
* Mike McCabe
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* The base class for Function objects
|
||||
* See ECMA 15.3.
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
public class BaseFunction extends IdScriptableObject implements Function
|
||||
{
|
||||
|
||||
static final long serialVersionUID = 5311394446546053859L;
|
||||
|
||||
private static final Object FUNCTION_TAG = "Function";
|
||||
|
||||
static void init(Scriptable scope, boolean sealed)
|
||||
{
|
||||
BaseFunction obj = new BaseFunction();
|
||||
// Function.prototype attributes: see ECMA 15.3.3.1
|
||||
obj.prototypePropertyAttributes = DONTENUM | READONLY | PERMANENT;
|
||||
obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
|
||||
}
|
||||
|
||||
public BaseFunction()
|
||||
{
|
||||
}
|
||||
|
||||
public BaseFunction(Scriptable scope, Scriptable prototype)
|
||||
{
|
||||
super(scope, prototype);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return "Function";
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the instanceof operator for JavaScript Function objects.
|
||||
* <p>
|
||||
* <code>
|
||||
* foo = new Foo();<br>
|
||||
* foo instanceof Foo; // true<br>
|
||||
* </code>
|
||||
*
|
||||
* @param instance The value that appeared on the LHS of the instanceof
|
||||
* operator
|
||||
* @return true if the "prototype" property of "this" appears in
|
||||
* value's prototype chain
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public boolean hasInstance(Scriptable instance)
|
||||
{
|
||||
Object protoProp = ScriptableObject.getProperty(this, "prototype");
|
||||
if (protoProp instanceof Scriptable) {
|
||||
return ScriptRuntime.jsDelegatesTo(instance, (Scriptable)protoProp);
|
||||
}
|
||||
throw ScriptRuntime.typeError1("msg.instanceof.bad.prototype",
|
||||
getFunctionName());
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
private static final int
|
||||
Id_length = 1,
|
||||
Id_arity = 2,
|
||||
Id_name = 3,
|
||||
Id_prototype = 4,
|
||||
Id_arguments = 5,
|
||||
|
||||
MAX_INSTANCE_ID = 5;
|
||||
|
||||
@Override
|
||||
protected int getMaxInstanceId()
|
||||
{
|
||||
return MAX_INSTANCE_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int findInstanceIdInfo(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2007-05-09 08:15:15 EDT
|
||||
L0: { id = 0; String X = null; int c;
|
||||
L: switch (s.length()) {
|
||||
case 4: X="name";id=Id_name; break L;
|
||||
case 5: X="arity";id=Id_arity; break L;
|
||||
case 6: X="length";id=Id_length; break L;
|
||||
case 9: c=s.charAt(0);
|
||||
if (c=='a') { X="arguments";id=Id_arguments; }
|
||||
else if (c=='p') { X="prototype";id=Id_prototype; }
|
||||
break L;
|
||||
}
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
break L0;
|
||||
}
|
||||
// #/generated#
|
||||
// #/string_id_map#
|
||||
|
||||
if (id == 0) return super.findInstanceIdInfo(s);
|
||||
|
||||
int attr;
|
||||
switch (id) {
|
||||
case Id_length:
|
||||
case Id_arity:
|
||||
case Id_name:
|
||||
attr = DONTENUM | READONLY | PERMANENT;
|
||||
break;
|
||||
case Id_prototype:
|
||||
attr = prototypePropertyAttributes;
|
||||
break;
|
||||
case Id_arguments:
|
||||
attr = DONTENUM | PERMANENT;
|
||||
break;
|
||||
default: throw new IllegalStateException();
|
||||
}
|
||||
return instanceIdInfo(attr, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getInstanceIdName(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_length: return "length";
|
||||
case Id_arity: return "arity";
|
||||
case Id_name: return "name";
|
||||
case Id_prototype: return "prototype";
|
||||
case Id_arguments: return "arguments";
|
||||
}
|
||||
return super.getInstanceIdName(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getInstanceIdValue(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_length: return ScriptRuntime.wrapInt(getLength());
|
||||
case Id_arity: return ScriptRuntime.wrapInt(getArity());
|
||||
case Id_name: return getFunctionName();
|
||||
case Id_prototype: return getPrototypeProperty();
|
||||
case Id_arguments: return getArguments();
|
||||
}
|
||||
return super.getInstanceIdValue(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setInstanceIdValue(int id, Object value)
|
||||
{
|
||||
if (id == Id_prototype) {
|
||||
if ((prototypePropertyAttributes & READONLY) == 0) {
|
||||
prototypeProperty = (value != null)
|
||||
? value : UniqueTag.NULL_VALUE;
|
||||
}
|
||||
return;
|
||||
} else if (id == Id_arguments) {
|
||||
if (value == NOT_FOUND) {
|
||||
// This should not be called since "arguments" is PERMANENT
|
||||
Kit.codeBug();
|
||||
}
|
||||
defaultPut("arguments", value);
|
||||
}
|
||||
super.setInstanceIdValue(id, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillConstructorProperties(IdFunctionObject ctor)
|
||||
{
|
||||
// Fix up bootstrapping problem: getPrototype of the IdFunctionObject
|
||||
// can not return Function.prototype because Function object is not
|
||||
// yet defined.
|
||||
ctor.setPrototype(this);
|
||||
super.fillConstructorProperties(ctor);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_constructor: arity=1; s="constructor"; break;
|
||||
case Id_toString: arity=1; s="toString"; break;
|
||||
case Id_toSource: arity=1; s="toSource"; break;
|
||||
case Id_apply: arity=2; s="apply"; break;
|
||||
case Id_call: arity=1; s="call"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(FUNCTION_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
static boolean isApply(IdFunctionObject f) {
|
||||
return f.hasTag(FUNCTION_TAG) && f.methodId() == Id_apply;
|
||||
}
|
||||
|
||||
static boolean isApplyOrCall(IdFunctionObject f) {
|
||||
if(f.hasTag(FUNCTION_TAG)) {
|
||||
switch(f.methodId()) {
|
||||
case Id_apply:
|
||||
case Id_call:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (!f.hasTag(FUNCTION_TAG)) {
|
||||
return super.execIdCall(f, cx, scope, thisObj, args);
|
||||
}
|
||||
int id = f.methodId();
|
||||
switch (id) {
|
||||
case Id_constructor:
|
||||
return jsConstructor(cx, scope, args);
|
||||
|
||||
case Id_toString: {
|
||||
BaseFunction realf = realFunction(thisObj, f);
|
||||
int indent = ScriptRuntime.toInt32(args, 0);
|
||||
return realf.decompile(indent, 0);
|
||||
}
|
||||
|
||||
case Id_toSource: {
|
||||
BaseFunction realf = realFunction(thisObj, f);
|
||||
int indent = 0;
|
||||
int flags = Decompiler.TO_SOURCE_FLAG;
|
||||
if (args.length != 0) {
|
||||
indent = ScriptRuntime.toInt32(args[0]);
|
||||
if (indent >= 0) {
|
||||
flags = 0;
|
||||
} else {
|
||||
indent = 0;
|
||||
}
|
||||
}
|
||||
return realf.decompile(indent, flags);
|
||||
}
|
||||
|
||||
case Id_apply:
|
||||
case Id_call:
|
||||
return ScriptRuntime.applyOrCall(id == Id_apply,
|
||||
cx, scope, thisObj, args);
|
||||
}
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
private BaseFunction realFunction(Scriptable thisObj, IdFunctionObject f)
|
||||
{
|
||||
Object x = thisObj.getDefaultValue(ScriptRuntime.FunctionClass);
|
||||
if (x instanceof BaseFunction) {
|
||||
return (BaseFunction)x;
|
||||
}
|
||||
throw ScriptRuntime.typeError1("msg.incompat.call",
|
||||
f.getFunctionName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Make value as DontEnum, DontDelete, ReadOnly
|
||||
* prototype property of this Function object
|
||||
*/
|
||||
public void setImmunePrototypeProperty(Object value)
|
||||
{
|
||||
if ((prototypePropertyAttributes & READONLY) != 0) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
prototypeProperty = (value != null) ? value : UniqueTag.NULL_VALUE;
|
||||
prototypePropertyAttributes = DONTENUM | PERMANENT | READONLY;
|
||||
}
|
||||
|
||||
protected Scriptable getClassPrototype()
|
||||
{
|
||||
Object protoVal = getPrototypeProperty();
|
||||
if (protoVal instanceof Scriptable) {
|
||||
return (Scriptable) protoVal;
|
||||
}
|
||||
return getClassPrototype(this, "Object");
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be overridden.
|
||||
*/
|
||||
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
|
||||
Object[] args)
|
||||
{
|
||||
return Undefined.instance;
|
||||
}
|
||||
|
||||
public Scriptable construct(Context cx, Scriptable scope, Object[] args)
|
||||
{
|
||||
Scriptable result = createObject(cx, scope);
|
||||
if (result != null) {
|
||||
Object val = call(cx, scope, result, args);
|
||||
if (val instanceof Scriptable) {
|
||||
result = (Scriptable)val;
|
||||
}
|
||||
} else {
|
||||
Object val = call(cx, scope, null, args);
|
||||
if (!(val instanceof Scriptable)) {
|
||||
// It is program error not to return Scriptable from
|
||||
// the call method if createObject returns null.
|
||||
throw new IllegalStateException(
|
||||
"Bad implementaion of call as constructor, name="
|
||||
+getFunctionName()+" in "+getClass().getName());
|
||||
}
|
||||
result = (Scriptable)val;
|
||||
if (result.getPrototype() == null) {
|
||||
result.setPrototype(getClassPrototype());
|
||||
}
|
||||
if (result.getParentScope() == null) {
|
||||
Scriptable parent = getParentScope();
|
||||
if (result != parent) {
|
||||
result.setParentScope(parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new script object.
|
||||
* The default implementation of {@link #construct} uses the method to
|
||||
* to get the value for <tt>thisObj</tt> argument when invoking
|
||||
* {@link #call}.
|
||||
* The methos is allowed to return <tt>null</tt> to indicate that
|
||||
* {@link #call} will create a new object itself. In this case
|
||||
* {@link #construct} will set scope and prototype on the result
|
||||
* {@link #call} unless they are already set.
|
||||
*/
|
||||
public Scriptable createObject(Context cx, Scriptable scope)
|
||||
{
|
||||
Scriptable newInstance = new NativeObject();
|
||||
newInstance.setPrototype(getClassPrototype());
|
||||
newInstance.setParentScope(getParentScope());
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompile the source information associated with this js
|
||||
* function/script back into a string.
|
||||
*
|
||||
* @param indent How much to indent the decompiled result.
|
||||
*
|
||||
* @param flags Flags specifying format of decompilation output.
|
||||
*/
|
||||
String decompile(int indent, int flags)
|
||||
{
|
||||
StringBuffer sb = new StringBuffer();
|
||||
boolean justbody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
|
||||
if (!justbody) {
|
||||
sb.append("function ");
|
||||
sb.append(getFunctionName());
|
||||
sb.append("() {\n\t");
|
||||
}
|
||||
sb.append("[native code, arity=");
|
||||
sb.append(getArity());
|
||||
sb.append("]\n");
|
||||
if (!justbody) {
|
||||
sb.append("}\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public int getArity() { return 0; }
|
||||
|
||||
public int getLength() { return 0; }
|
||||
|
||||
public String getFunctionName()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
final Object getPrototypeProperty() {
|
||||
Object result = prototypeProperty;
|
||||
if (result == null) {
|
||||
synchronized (this) {
|
||||
result = prototypeProperty;
|
||||
if (result == null) {
|
||||
setupDefaultPrototype();
|
||||
result = prototypeProperty;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (result == UniqueTag.NULL_VALUE) { result = null; }
|
||||
return result;
|
||||
}
|
||||
|
||||
private void setupDefaultPrototype()
|
||||
{
|
||||
NativeObject obj = new NativeObject();
|
||||
final int attr = ScriptableObject.DONTENUM;
|
||||
obj.defineProperty("constructor", this, attr);
|
||||
// put the prototype property into the object now, then in the
|
||||
// wacky case of a user defining a function Object(), we don't
|
||||
// get an infinite loop trying to find the prototype.
|
||||
prototypeProperty = obj;
|
||||
Scriptable proto = getObjectPrototype(this);
|
||||
if (proto != obj) {
|
||||
// not the one we just made, it must remain grounded
|
||||
obj.setPrototype(proto);
|
||||
}
|
||||
}
|
||||
|
||||
private Object getArguments()
|
||||
{
|
||||
// <Function name>.arguments is deprecated, so we use a slow
|
||||
// way of getting it that doesn't add to the invocation cost.
|
||||
// TODO: add warning, error based on version
|
||||
Object value = defaultGet("arguments");
|
||||
if (value != NOT_FOUND) {
|
||||
// Should after changing <Function name>.arguments its
|
||||
// activation still be available during Function call?
|
||||
// This code assumes it should not:
|
||||
// defaultGet("arguments") != NOT_FOUND
|
||||
// means assigned arguments
|
||||
return value;
|
||||
}
|
||||
Context cx = Context.getContext();
|
||||
NativeCall activation = ScriptRuntime.findFunctionActivation(cx, this);
|
||||
return (activation == null)
|
||||
? null
|
||||
: activation.get("arguments", activation);
|
||||
}
|
||||
|
||||
private static Object jsConstructor(Context cx, Scriptable scope,
|
||||
Object[] args)
|
||||
{
|
||||
int arglen = args.length;
|
||||
StringBuffer sourceBuf = new StringBuffer();
|
||||
|
||||
sourceBuf.append("function ");
|
||||
/* version != 1.2 Function constructor behavior -
|
||||
* print 'anonymous' as the function name if the
|
||||
* version (under which the function was compiled) is
|
||||
* less than 1.2... or if it's greater than 1.2, because
|
||||
* we need to be closer to ECMA.
|
||||
*/
|
||||
if (cx.getLanguageVersion() != Context.VERSION_1_2) {
|
||||
sourceBuf.append("anonymous");
|
||||
}
|
||||
sourceBuf.append('(');
|
||||
|
||||
// Append arguments as coma separated strings
|
||||
for (int i = 0; i < arglen - 1; i++) {
|
||||
if (i > 0) {
|
||||
sourceBuf.append(',');
|
||||
}
|
||||
sourceBuf.append(ScriptRuntime.toString(args[i]));
|
||||
}
|
||||
sourceBuf.append(") {");
|
||||
if (arglen != 0) {
|
||||
// append function body
|
||||
String funBody = ScriptRuntime.toString(args[arglen - 1]);
|
||||
sourceBuf.append(funBody);
|
||||
}
|
||||
sourceBuf.append('}');
|
||||
String source = sourceBuf.toString();
|
||||
|
||||
int[] linep = new int[1];
|
||||
String filename = Context.getSourcePositionFromStack(linep);
|
||||
if (filename == null) {
|
||||
filename = "<eval'ed string>";
|
||||
linep[0] = 1;
|
||||
}
|
||||
|
||||
String sourceURI = ScriptRuntime.
|
||||
makeUrlForGeneratedScript(false, filename, linep[0]);
|
||||
|
||||
Scriptable global = ScriptableObject.getTopLevelScope(scope);
|
||||
|
||||
ErrorReporter reporter;
|
||||
reporter = DefaultErrorReporter.forEval(cx.getErrorReporter());
|
||||
|
||||
Evaluator evaluator = Context.createInterpreter();
|
||||
if (evaluator == null) {
|
||||
throw new JavaScriptException("Interpreter not present",
|
||||
filename, linep[0]);
|
||||
}
|
||||
|
||||
// Compile with explicit interpreter instance to force interpreter
|
||||
// mode.
|
||||
return cx.compileFunction(global, source, evaluator, reporter,
|
||||
sourceURI, 1, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
// #string_id_map#
|
||||
// #generated# Last update: 2007-05-09 08:15:15 EDT
|
||||
L0: { id = 0; String X = null; int c;
|
||||
L: switch (s.length()) {
|
||||
case 4: X="call";id=Id_call; break L;
|
||||
case 5: X="apply";id=Id_apply; break L;
|
||||
case 8: c=s.charAt(3);
|
||||
if (c=='o') { X="toSource";id=Id_toSource; }
|
||||
else if (c=='t') { X="toString";id=Id_toString; }
|
||||
break L;
|
||||
case 11: X="constructor";id=Id_constructor; break L;
|
||||
}
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
break L0;
|
||||
}
|
||||
// #/generated#
|
||||
return id;
|
||||
}
|
||||
|
||||
private static final int
|
||||
Id_constructor = 1,
|
||||
Id_toString = 2,
|
||||
Id_toSource = 3,
|
||||
Id_apply = 4,
|
||||
Id_call = 5,
|
||||
|
||||
MAX_PROTOTYPE_ID = 5;
|
||||
|
||||
// #/string_id_map#
|
||||
|
||||
private Object prototypeProperty;
|
||||
// For function object instances, attribute is PERMANENT; see ECMA 15.3.5.2
|
||||
private int prototypePropertyAttributes = PERMANENT;
|
||||
}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov, igor@fastmail.fm
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* Generic notion of callable object that can execute some script-related code
|
||||
* upon request with specified values for script scope and this objects.
|
||||
*/
|
||||
public interface Callable
|
||||
{
|
||||
/**
|
||||
* Perform the call.
|
||||
*
|
||||
* @param cx the current Context for this thread
|
||||
* @param scope the scope to use to resolve properties.
|
||||
* @param thisObj the JavaScript <code>this</code> object
|
||||
* @param args the array of arguments
|
||||
* @return the result of the call
|
||||
*/
|
||||
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
|
||||
Object[] args);
|
||||
}
|
||||
|
||||
@@ -1,223 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov, igor@fastmail.fm
|
||||
* Norris Boyd
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Cache of generated classes and data structures to access Java runtime
|
||||
* from JavaScript.
|
||||
*
|
||||
* @author Igor Bukanov
|
||||
*
|
||||
* @since Rhino 1.5 Release 5
|
||||
*/
|
||||
public class ClassCache implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -8866246036237312215L;
|
||||
private static final Object AKEY = "ClassCache";
|
||||
private volatile boolean cachingIsEnabled = true;
|
||||
private transient HashMap<Class<?>,JavaMembers> classTable;
|
||||
private transient HashMap<JavaAdapter.JavaAdapterSignature,Class<?>> classAdapterCache;
|
||||
private transient HashMap<Class<?>,Object> interfaceAdapterCache;
|
||||
private int generatedClassSerial;
|
||||
|
||||
/**
|
||||
* Search for ClassCache object in the given scope.
|
||||
* The method first calls
|
||||
* {@link ScriptableObject#getTopLevelScope(Scriptable scope)}
|
||||
* to get the top most scope and then tries to locate associated
|
||||
* ClassCache object in the prototype chain of the top scope.
|
||||
*
|
||||
* @param scope scope to search for ClassCache object.
|
||||
* @return previously associated ClassCache object or a new instance of
|
||||
* ClassCache if no ClassCache object was found.
|
||||
*
|
||||
* @see #associate(ScriptableObject topScope)
|
||||
*/
|
||||
public static ClassCache get(Scriptable scope)
|
||||
{
|
||||
ClassCache cache = (ClassCache)
|
||||
ScriptableObject.getTopScopeValue(scope, AKEY);
|
||||
if (cache == null) {
|
||||
throw new RuntimeException("Can't find top level scope for " +
|
||||
"ClassCache.get");
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate ClassCache object with the given top-level scope.
|
||||
* The ClassCache object can only be associated with the given scope once.
|
||||
*
|
||||
* @param topScope scope to associate this ClassCache object with.
|
||||
* @return true if no previous ClassCache objects were embedded into
|
||||
* the scope and this ClassCache were successfully associated
|
||||
* or false otherwise.
|
||||
*
|
||||
* @see #get(Scriptable scope)
|
||||
*/
|
||||
public boolean associate(ScriptableObject topScope)
|
||||
{
|
||||
if (topScope.getParentScope() != null) {
|
||||
// Can only associate cache with top level scope
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (this == topScope.associateValue(AKEY, this)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty caches of generated Java classes and Java reflection information.
|
||||
*/
|
||||
public synchronized void clearCaches()
|
||||
{
|
||||
classTable = null;
|
||||
classAdapterCache = null;
|
||||
interfaceAdapterCache = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if generated Java classes and Java reflection information
|
||||
* is cached.
|
||||
*/
|
||||
public final boolean isCachingEnabled()
|
||||
{
|
||||
return cachingIsEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to cache some values.
|
||||
* <p>
|
||||
* By default, the engine will cache the results of
|
||||
* <tt>Class.getMethods()</tt> and similar calls.
|
||||
* This can speed execution dramatically, but increases the memory
|
||||
* footprint. Also, with caching enabled, references may be held to
|
||||
* objects past the lifetime of any real usage.
|
||||
* <p>
|
||||
* If caching is enabled and this method is called with a
|
||||
* <code>false</code> argument, the caches will be emptied.
|
||||
* <p>
|
||||
* Caching is enabled by default.
|
||||
*
|
||||
* @param enabled if true, caching is enabled
|
||||
*
|
||||
* @see #clearCaches()
|
||||
*/
|
||||
public synchronized void setCachingEnabled(boolean enabled)
|
||||
{
|
||||
if (enabled == cachingIsEnabled)
|
||||
return;
|
||||
if (!enabled)
|
||||
clearCaches();
|
||||
cachingIsEnabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a map from classes to associated JavaMembers objects
|
||||
*/
|
||||
Map<Class<?>,JavaMembers> getClassCacheMap() {
|
||||
if (classTable == null) {
|
||||
classTable = new HashMap<Class<?>,JavaMembers>();
|
||||
}
|
||||
return classTable;
|
||||
}
|
||||
|
||||
Map<JavaAdapter.JavaAdapterSignature,Class<?>> getInterfaceAdapterCacheMap()
|
||||
{
|
||||
if (classAdapterCache == null) {
|
||||
classAdapterCache = new HashMap<JavaAdapter.JavaAdapterSignature,Class<?>>();
|
||||
}
|
||||
return classAdapterCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* The method always returns false.
|
||||
* @see #setInvokerOptimizationEnabled(boolean enabled)
|
||||
*/
|
||||
public boolean isInvokerOptimizationEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* The method does nothing.
|
||||
* Invoker optimization is no longer used by Rhino.
|
||||
* On modern JDK like 1.4 or 1.5 the disadvantages of the optimization
|
||||
* like increased memory usage or longer initialization time overweight
|
||||
* small speed increase that can be gained using generated proxy class
|
||||
* to replace reflection.
|
||||
*/
|
||||
public synchronized void setInvokerOptimizationEnabled(boolean enabled)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal engine method to return serial number for generated classes
|
||||
* to ensure name uniqueness.
|
||||
*/
|
||||
public final synchronized int newClassSerialNumber()
|
||||
{
|
||||
return ++generatedClassSerial;
|
||||
}
|
||||
|
||||
Object getInterfaceAdapter(Class<?> cl)
|
||||
{
|
||||
return interfaceAdapterCache == null
|
||||
? null
|
||||
: interfaceAdapterCache.get(cl);
|
||||
}
|
||||
|
||||
synchronized void cacheInterfaceAdapter(Class<?> cl, Object iadapter)
|
||||
{
|
||||
if (cachingIsEnabled) {
|
||||
if (interfaceAdapterCache == null) {
|
||||
interfaceAdapterCache = new HashMap<Class<?>,Object>();
|
||||
}
|
||||
interfaceAdapterCache.put(cl, iadapter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Igor Bukanov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// API class
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
Embeddings that wish to filter Java classes that are visible to scripts
|
||||
through the LiveConnect, should implement this interface.
|
||||
|
||||
@see Context#setClassShutter(ClassShutter)
|
||||
@since 1.5 Release 4
|
||||
@author Norris Boyd
|
||||
*/
|
||||
|
||||
public interface ClassShutter {
|
||||
|
||||
/**
|
||||
* Return true iff the Java class with the given name should be exposed
|
||||
* to scripts.
|
||||
* <p>
|
||||
* An embedding may filter which Java classes are exposed through
|
||||
* LiveConnect to JavaScript scripts.
|
||||
* <p>
|
||||
* Due to the fact that there is no package reflection in Java,
|
||||
* this method will also be called with package names. There
|
||||
* is no way for Rhino to tell if "Packages.a.b" is a package name
|
||||
* or a class that doesn't exist. What Rhino does is attempt
|
||||
* to load each segment of "Packages.a.b.c": It first attempts to
|
||||
* load class "a", then attempts to load class "a.b", then
|
||||
* finally attempts to load class "a.b.c". On a Rhino installation
|
||||
* without any ClassShutter set, and without any of the
|
||||
* above classes, the expression "Packages.a.b.c" will result in
|
||||
* a [JavaPackage a.b.c] and not an error.
|
||||
* <p>
|
||||
* With ClassShutter supplied, Rhino will first call
|
||||
* visibleToScripts before attempting to look up the class name. If
|
||||
* visibleToScripts returns false, the class name lookup is not
|
||||
* performed and subsequent Rhino execution assumes the class is
|
||||
* not present. So for "java.lang.System.out.println" the lookup
|
||||
* of "java.lang.System" is skipped and thus Rhino assumes that
|
||||
* "java.lang.System" doesn't exist. So then for "java.lang.System.out",
|
||||
* Rhino attempts to load the class "java.lang.System.out" because
|
||||
* it assumes that "java.lang.System" is a package name.
|
||||
* <p>
|
||||
* @param fullClassName the full name of the class (including the package
|
||||
* name, with '.' as a delimiter). For example the
|
||||
* standard string class is "java.lang.String"
|
||||
* @return whether or not to reveal this class to scripts
|
||||
*/
|
||||
public boolean visibleToScripts(String fullClassName);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,328 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov, igor@fastmail.fm
|
||||
* Bob Jervis
|
||||
* Steve Yegge
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.mozilla.javascript.ast.ErrorCollector;
|
||||
|
||||
public class CompilerEnvirons
|
||||
{
|
||||
public CompilerEnvirons()
|
||||
{
|
||||
errorReporter = DefaultErrorReporter.instance;
|
||||
languageVersion = Context.VERSION_DEFAULT;
|
||||
generateDebugInfo = true;
|
||||
useDynamicScope = false;
|
||||
reservedKeywordAsIdentifier = false;
|
||||
allowMemberExprAsFunctionName = false;
|
||||
xmlAvailable = true;
|
||||
optimizationLevel = 0;
|
||||
generatingSource = true;
|
||||
strictMode = false;
|
||||
warningAsError = false;
|
||||
generateObserverCount = false;
|
||||
allowSharpComments = false;
|
||||
}
|
||||
|
||||
public void initFromContext(Context cx)
|
||||
{
|
||||
setErrorReporter(cx.getErrorReporter());
|
||||
this.languageVersion = cx.getLanguageVersion();
|
||||
useDynamicScope = cx.compileFunctionsWithDynamicScopeFlag;
|
||||
generateDebugInfo = (!cx.isGeneratingDebugChanged()
|
||||
|| cx.isGeneratingDebug());
|
||||
reservedKeywordAsIdentifier
|
||||
= cx.hasFeature(Context.FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER);
|
||||
allowMemberExprAsFunctionName
|
||||
= cx.hasFeature(Context.FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME);
|
||||
strictMode
|
||||
= cx.hasFeature(Context.FEATURE_STRICT_MODE);
|
||||
warningAsError = cx.hasFeature(Context.FEATURE_WARNING_AS_ERROR);
|
||||
xmlAvailable
|
||||
= cx.hasFeature(Context.FEATURE_E4X);
|
||||
|
||||
optimizationLevel = cx.getOptimizationLevel();
|
||||
|
||||
generatingSource = cx.isGeneratingSource();
|
||||
activationNames = cx.activationNames;
|
||||
|
||||
// Observer code generation in compiled code :
|
||||
generateObserverCount = cx.generateObserverCount;
|
||||
}
|
||||
|
||||
public final ErrorReporter getErrorReporter()
|
||||
{
|
||||
return errorReporter;
|
||||
}
|
||||
|
||||
public void setErrorReporter(ErrorReporter errorReporter)
|
||||
{
|
||||
if (errorReporter == null) throw new IllegalArgumentException();
|
||||
this.errorReporter = errorReporter;
|
||||
}
|
||||
|
||||
public final int getLanguageVersion()
|
||||
{
|
||||
return languageVersion;
|
||||
}
|
||||
|
||||
public void setLanguageVersion(int languageVersion)
|
||||
{
|
||||
Context.checkLanguageVersion(languageVersion);
|
||||
this.languageVersion = languageVersion;
|
||||
}
|
||||
|
||||
public final boolean isGenerateDebugInfo()
|
||||
{
|
||||
return generateDebugInfo;
|
||||
}
|
||||
|
||||
public void setGenerateDebugInfo(boolean flag)
|
||||
{
|
||||
this.generateDebugInfo = flag;
|
||||
}
|
||||
|
||||
public final boolean isUseDynamicScope()
|
||||
{
|
||||
return useDynamicScope;
|
||||
}
|
||||
|
||||
public final boolean isReservedKeywordAsIdentifier()
|
||||
{
|
||||
return reservedKeywordAsIdentifier;
|
||||
}
|
||||
|
||||
public void setReservedKeywordAsIdentifier(boolean flag)
|
||||
{
|
||||
reservedKeywordAsIdentifier = flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extension to ECMA: if 'function <name>' is not followed
|
||||
* by '(', assume <name> starts a {@code memberExpr}
|
||||
*/
|
||||
public final boolean isAllowMemberExprAsFunctionName()
|
||||
{
|
||||
return allowMemberExprAsFunctionName;
|
||||
}
|
||||
|
||||
public void setAllowMemberExprAsFunctionName(boolean flag)
|
||||
{
|
||||
allowMemberExprAsFunctionName = flag;
|
||||
}
|
||||
|
||||
public final boolean isXmlAvailable()
|
||||
{
|
||||
return xmlAvailable;
|
||||
}
|
||||
|
||||
public void setXmlAvailable(boolean flag)
|
||||
{
|
||||
xmlAvailable = flag;
|
||||
}
|
||||
|
||||
public final int getOptimizationLevel()
|
||||
{
|
||||
return optimizationLevel;
|
||||
}
|
||||
|
||||
public void setOptimizationLevel(int level)
|
||||
{
|
||||
Context.checkOptimizationLevel(level);
|
||||
this.optimizationLevel = level;
|
||||
}
|
||||
|
||||
public final boolean isGeneratingSource()
|
||||
{
|
||||
return generatingSource;
|
||||
}
|
||||
|
||||
public boolean getWarnTrailingComma() {
|
||||
return warnTrailingComma;
|
||||
}
|
||||
|
||||
public void setWarnTrailingComma(boolean warn) {
|
||||
warnTrailingComma = warn;
|
||||
}
|
||||
|
||||
public final boolean isStrictMode()
|
||||
{
|
||||
return strictMode;
|
||||
}
|
||||
|
||||
public void setStrictMode(boolean strict)
|
||||
{
|
||||
strictMode = strict;
|
||||
}
|
||||
|
||||
public final boolean reportWarningAsError()
|
||||
{
|
||||
return warningAsError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether or not source information should be generated.
|
||||
* <p>
|
||||
* Without source information, evaluating the "toString" method
|
||||
* on JavaScript functions produces only "[native code]" for
|
||||
* the body of the function.
|
||||
* Note that code generated without source is not fully ECMA
|
||||
* conformant.
|
||||
*/
|
||||
public void setGeneratingSource(boolean generatingSource)
|
||||
{
|
||||
this.generatingSource = generatingSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true iff code will be generated with callbacks to enable
|
||||
* instruction thresholds
|
||||
*/
|
||||
public boolean isGenerateObserverCount() {
|
||||
return generateObserverCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn on or off generation of code with callbacks to
|
||||
* track the count of executed instructions.
|
||||
* Currently only affects JVM byte code generation: this slows down the
|
||||
* generated code, but code generated without the callbacks will not
|
||||
* be counted toward instruction thresholds. Rhino's interpretive
|
||||
* mode does instruction counting without inserting callbacks, so
|
||||
* there is no requirement to compile code differently.
|
||||
* @param generateObserverCount if true, generated code will contain
|
||||
* calls to accumulate an estimate of the instructions executed.
|
||||
*/
|
||||
public void setGenerateObserverCount(boolean generateObserverCount) {
|
||||
this.generateObserverCount = generateObserverCount;
|
||||
}
|
||||
|
||||
public boolean isRecordingComments() {
|
||||
return recordingComments;
|
||||
}
|
||||
|
||||
public void setRecordingComments(boolean record) {
|
||||
recordingComments = record;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn on or off full error recovery. In this mode, parse errors do not
|
||||
* throw an exception, and the parser attempts to build a full syntax tree
|
||||
* from the input. Useful for IDEs and other frontends.
|
||||
*/
|
||||
public void setRecoverFromErrors(boolean recover) {
|
||||
recoverFromErrors = recover;
|
||||
}
|
||||
|
||||
public boolean recoverFromErrors() {
|
||||
return recoverFromErrors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the parser in "IDE" mode. This enables some slightly more expensive
|
||||
* computations, such as figuring out helpful error bounds.
|
||||
*/
|
||||
public void setIdeMode(boolean ide) {
|
||||
ideMode = ide;
|
||||
}
|
||||
|
||||
public boolean isIdeMode() {
|
||||
return ideMode;
|
||||
}
|
||||
|
||||
public Set<String> getActivationNames() {
|
||||
return activationNames;
|
||||
}
|
||||
|
||||
public void setActivationNames(Set<String> activationNames) {
|
||||
this.activationNames = activationNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mozilla sources use the C preprocessor.
|
||||
*/
|
||||
public void setAllowSharpComments(boolean allow) {
|
||||
allowSharpComments = allow;
|
||||
}
|
||||
|
||||
public boolean getAllowSharpComments() {
|
||||
return allowSharpComments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code CompilerEnvirons} suitable for using Rhino
|
||||
* in an IDE environment. Most features are enabled by default.
|
||||
* The {@link ErrorReporter} is set to an {@link ErrorCollector}.
|
||||
*/
|
||||
public static CompilerEnvirons ideEnvirons() {
|
||||
CompilerEnvirons env = new CompilerEnvirons();
|
||||
env.setRecoverFromErrors(true);
|
||||
env.setRecordingComments(true);
|
||||
env.setStrictMode(true);
|
||||
env.setWarnTrailingComma(true);
|
||||
env.setLanguageVersion(170);
|
||||
env.setReservedKeywordAsIdentifier(true);
|
||||
env.setIdeMode(true);
|
||||
env.setErrorReporter(new ErrorCollector());
|
||||
return env;
|
||||
}
|
||||
|
||||
private ErrorReporter errorReporter;
|
||||
|
||||
private int languageVersion;
|
||||
private boolean generateDebugInfo;
|
||||
private boolean useDynamicScope;
|
||||
private boolean reservedKeywordAsIdentifier;
|
||||
private boolean allowMemberExprAsFunctionName;
|
||||
private boolean xmlAvailable;
|
||||
private int optimizationLevel;
|
||||
private boolean generatingSource;
|
||||
private boolean strictMode;
|
||||
private boolean warningAsError;
|
||||
private boolean generateObserverCount;
|
||||
private boolean recordingComments;
|
||||
private boolean recoverFromErrors;
|
||||
private boolean warnTrailingComma;
|
||||
private boolean ideMode;
|
||||
private boolean allowSharpComments;
|
||||
Set<String> activationNames;
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Bob Jervis
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// API class
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
public interface ConstProperties {
|
||||
/**
|
||||
* Sets a named const property in this object.
|
||||
* <p>
|
||||
* The property is specified by a string name
|
||||
* as defined for <code>Scriptable.get</code>.
|
||||
* <p>
|
||||
* The possible values that may be passed in are as defined for
|
||||
* <code>Scriptable.get</code>. A class that implements this method may choose
|
||||
* to ignore calls to set certain properties, in which case those
|
||||
* properties are effectively read-only.<p>
|
||||
* For properties defined in a prototype chain,
|
||||
* use <code>putProperty</code> in ScriptableObject. <p>
|
||||
* Note that if a property <i>a</i> is defined in the prototype <i>p</i>
|
||||
* of an object <i>o</i>, then evaluating <code>o.a = 23</code> will cause
|
||||
* <code>set</code> to be called on the prototype <i>p</i> with
|
||||
* <i>o</i> as the <i>start</i> parameter.
|
||||
* To preserve JavaScript semantics, it is the Scriptable
|
||||
* object's responsibility to modify <i>o</i>. <p>
|
||||
* This design allows properties to be defined in prototypes and implemented
|
||||
* in terms of getters and setters of Java values without consuming slots
|
||||
* in each instance.<p>
|
||||
* <p>
|
||||
* The values that may be set are limited to the following:
|
||||
* <UL>
|
||||
* <LI>java.lang.Boolean objects</LI>
|
||||
* <LI>java.lang.String objects</LI>
|
||||
* <LI>java.lang.Number objects</LI>
|
||||
* <LI>org.mozilla.javascript.Scriptable objects</LI>
|
||||
* <LI>null</LI>
|
||||
* <LI>The value returned by Context.getUndefinedValue()</LI>
|
||||
* </UL><p>
|
||||
* Arbitrary Java objects may be wrapped in a Scriptable by first calling
|
||||
* <code>Context.toObject</code>. This allows the property of a JavaScript
|
||||
* object to contain an arbitrary Java object as a value.<p>
|
||||
* Note that <code>has</code> will be called by the runtime first before
|
||||
* <code>set</code> is called to determine in which object the
|
||||
* property is defined.
|
||||
* Note that this method is not expected to traverse the prototype chain,
|
||||
* which is different from the ECMA [[Put]] operation.
|
||||
* @param name the name of the property
|
||||
* @param start the object whose property is being set
|
||||
* @param value value to set the property to
|
||||
* @see org.mozilla.javascript.Scriptable#has(String, Scriptable)
|
||||
* @see org.mozilla.javascript.Scriptable#get(String, Scriptable)
|
||||
* @see org.mozilla.javascript.ScriptableObject#putProperty(Scriptable, String, Object)
|
||||
* @see org.mozilla.javascript.Context#toObject(Object, Scriptable)
|
||||
*/
|
||||
public void putConst(String name, Scriptable start, Object value);
|
||||
|
||||
/**
|
||||
* Reserves a definition spot for a const. This will set up a definition
|
||||
* of the const property, but set its value to undefined. The semantics of
|
||||
* the start parameter is the same as for putConst.
|
||||
* @param name The name of the property.
|
||||
* @param start The object whose property is being reserved.
|
||||
*/
|
||||
public void defineConst(String name, Scriptable start);
|
||||
|
||||
/**
|
||||
* Returns true if the named property is defined as a const on this object.
|
||||
* @param name
|
||||
* @return true if the named property is defined as a const, false
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean isConst(String name);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,58 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov, igor@fastmail.fm
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// API class
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* Interface to represent arbitrary action that requires to have Context
|
||||
* object associated with the current thread for its execution.
|
||||
*/
|
||||
public interface ContextAction
|
||||
{
|
||||
/**
|
||||
* Execute action using the supplied Context instance.
|
||||
* When Rhino runtime calls the method, <tt>cx</tt> will be associated
|
||||
* with the current thread as active context.
|
||||
*
|
||||
* @see ContextFactory#call(ContextAction)
|
||||
*/
|
||||
public Object run(Context cx);
|
||||
}
|
||||
|
||||
@@ -1,597 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov, igor@fastmail.fm
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// API class
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/**
|
||||
* Factory class that Rhino runtime uses to create new {@link Context}
|
||||
* instances. A <code>ContextFactory</code> can also notify listeners
|
||||
* about context creation and release.
|
||||
* <p>
|
||||
* When the Rhino runtime needs to create new {@link Context} instance during
|
||||
* execution of {@link Context#enter()} or {@link Context}, it will call
|
||||
* {@link #makeContext()} of the current global ContextFactory.
|
||||
* See {@link #getGlobal()} and {@link #initGlobal(ContextFactory)}.
|
||||
* <p>
|
||||
* It is also possible to use explicit ContextFactory instances for Context
|
||||
* creation. This is useful to have a set of independent Rhino runtime
|
||||
* instances under single JVM. See {@link #call(ContextAction)}.
|
||||
* <p>
|
||||
* The following example demonstrates Context customization to terminate
|
||||
* scripts running more then 10 seconds and to provide better compatibility
|
||||
* with JavaScript code using MSIE-specific features.
|
||||
* <pre>
|
||||
* import org.mozilla.javascript.*;
|
||||
*
|
||||
* class MyFactory extends ContextFactory
|
||||
* {
|
||||
*
|
||||
* // Custom {@link Context} to store execution time.
|
||||
* private static class MyContext extends Context
|
||||
* {
|
||||
* long startTime;
|
||||
* }
|
||||
*
|
||||
* static {
|
||||
* // Initialize GlobalFactory with custom factory
|
||||
* ContextFactory.initGlobal(new MyFactory());
|
||||
* }
|
||||
*
|
||||
* // Override {@link #makeContext()}
|
||||
* protected Context makeContext()
|
||||
* {
|
||||
* MyContext cx = new MyContext();
|
||||
* // Make Rhino runtime to call observeInstructionCount
|
||||
* // each 10000 bytecode instructions
|
||||
* cx.setInstructionObserverThreshold(10000);
|
||||
* return cx;
|
||||
* }
|
||||
*
|
||||
* // Override {@link #hasFeature(Context, int)}
|
||||
* public boolean hasFeature(Context cx, int featureIndex)
|
||||
* {
|
||||
* // Turn on maximum compatibility with MSIE scripts
|
||||
* switch (featureIndex) {
|
||||
* case {@link Context#FEATURE_NON_ECMA_GET_YEAR}:
|
||||
* return true;
|
||||
*
|
||||
* case {@link Context#FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME}:
|
||||
* return true;
|
||||
*
|
||||
* case {@link Context#FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER}:
|
||||
* return true;
|
||||
*
|
||||
* case {@link Context#FEATURE_PARENT_PROTO_PROPERTIES}:
|
||||
* return false;
|
||||
* }
|
||||
* return super.hasFeature(cx, featureIndex);
|
||||
* }
|
||||
*
|
||||
* // Override {@link #observeInstructionCount(Context, int)}
|
||||
* protected void observeInstructionCount(Context cx, int instructionCount)
|
||||
* {
|
||||
* MyContext mcx = (MyContext)cx;
|
||||
* long currentTime = System.currentTimeMillis();
|
||||
* if (currentTime - mcx.startTime > 10*1000) {
|
||||
* // More then 10 seconds from Context creation time:
|
||||
* // it is time to stop the script.
|
||||
* // Throw Error instance to ensure that script will never
|
||||
* // get control back through catch or finally.
|
||||
* throw new Error();
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // Override {@link #doTopCall(Callable,
|
||||
Context, Scriptable,
|
||||
Scriptable, Object[])}
|
||||
* protected Object doTopCall(Callable callable,
|
||||
* Context cx, Scriptable scope,
|
||||
* Scriptable thisObj, Object[] args)
|
||||
* {
|
||||
* MyContext mcx = (MyContext)cx;
|
||||
* mcx.startTime = System.currentTimeMillis();
|
||||
*
|
||||
* return super.doTopCall(callable, cx, scope, thisObj, args);
|
||||
* }
|
||||
*
|
||||
* }
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class ContextFactory
|
||||
{
|
||||
private static volatile boolean hasCustomGlobal;
|
||||
private static ContextFactory global = new ContextFactory();
|
||||
|
||||
private volatile boolean sealed;
|
||||
|
||||
private final Object listenersLock = new Object();
|
||||
private volatile Object listeners;
|
||||
private boolean disabledListening;
|
||||
private ClassLoader applicationClassLoader;
|
||||
|
||||
/**
|
||||
* Listener of {@link Context} creation and release events.
|
||||
*/
|
||||
public interface Listener
|
||||
{
|
||||
/**
|
||||
* Notify about newly created {@link Context} object.
|
||||
*/
|
||||
public void contextCreated(Context cx);
|
||||
|
||||
/**
|
||||
* Notify that the specified {@link Context} instance is no longer
|
||||
* associated with the current thread.
|
||||
*/
|
||||
public void contextReleased(Context cx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get global ContextFactory.
|
||||
*
|
||||
* @see #hasExplicitGlobal()
|
||||
* @see #initGlobal(ContextFactory)
|
||||
*/
|
||||
public static ContextFactory getGlobal()
|
||||
{
|
||||
return global;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if global factory was set.
|
||||
* Return true to indicate that {@link #initGlobal(ContextFactory)} was
|
||||
* already called and false to indicate that the global factory was not
|
||||
* explicitly set.
|
||||
*
|
||||
* @see #getGlobal()
|
||||
* @see #initGlobal(ContextFactory)
|
||||
*/
|
||||
public static boolean hasExplicitGlobal()
|
||||
{
|
||||
return hasCustomGlobal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set global ContextFactory.
|
||||
* The method can only be called once.
|
||||
*
|
||||
* @see #getGlobal()
|
||||
* @see #hasExplicitGlobal()
|
||||
*/
|
||||
public synchronized static void initGlobal(ContextFactory factory)
|
||||
{
|
||||
if (factory == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (hasCustomGlobal) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
hasCustomGlobal = true;
|
||||
global = factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new {@link Context} instance to be associated with the current
|
||||
* thread.
|
||||
* This is a callback method used by Rhino to create {@link Context}
|
||||
* instance when it is necessary to associate one with the current
|
||||
* execution thread. <tt>makeContext()</tt> is allowed to call
|
||||
* {@link Context#seal(Object)} on the result to prevent
|
||||
* {@link Context} changes by hostile scripts or applets.
|
||||
*/
|
||||
protected Context makeContext()
|
||||
{
|
||||
return new Context(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of {@link Context#hasFeature(int featureIndex)}.
|
||||
* This can be used to customize {@link Context} without introducing
|
||||
* additional subclasses.
|
||||
*/
|
||||
protected boolean hasFeature(Context cx, int featureIndex)
|
||||
{
|
||||
int version;
|
||||
switch (featureIndex) {
|
||||
case Context.FEATURE_NON_ECMA_GET_YEAR:
|
||||
/*
|
||||
* During the great date rewrite of 1.3, we tried to track the
|
||||
* evolving ECMA standard, which then had a definition of
|
||||
* getYear which always subtracted 1900. Which we
|
||||
* implemented, not realizing that it was incompatible with
|
||||
* the old behavior... now, rather than thrash the behavior
|
||||
* yet again, we've decided to leave it with the - 1900
|
||||
* behavior and point people to the getFullYear method. But
|
||||
* we try to protect existing scripts that have specified a
|
||||
* version...
|
||||
*/
|
||||
version = cx.getLanguageVersion();
|
||||
return (version == Context.VERSION_1_0
|
||||
|| version == Context.VERSION_1_1
|
||||
|| version == Context.VERSION_1_2);
|
||||
|
||||
case Context.FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME:
|
||||
return false;
|
||||
|
||||
case Context.FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER:
|
||||
return false;
|
||||
|
||||
case Context.FEATURE_TO_STRING_AS_SOURCE:
|
||||
version = cx.getLanguageVersion();
|
||||
return version == Context.VERSION_1_2;
|
||||
|
||||
case Context.FEATURE_PARENT_PROTO_PROPERTIES:
|
||||
return true;
|
||||
|
||||
case Context.FEATURE_E4X:
|
||||
version = cx.getLanguageVersion();
|
||||
return (version == Context.VERSION_DEFAULT
|
||||
|| version >= Context.VERSION_1_6);
|
||||
|
||||
case Context.FEATURE_DYNAMIC_SCOPE:
|
||||
return false;
|
||||
|
||||
case Context.FEATURE_STRICT_VARS:
|
||||
return false;
|
||||
|
||||
case Context.FEATURE_STRICT_EVAL:
|
||||
return false;
|
||||
|
||||
case Context.FEATURE_LOCATION_INFORMATION_IN_ERROR:
|
||||
return false;
|
||||
|
||||
case Context.FEATURE_STRICT_MODE:
|
||||
return false;
|
||||
|
||||
case Context.FEATURE_WARNING_AS_ERROR:
|
||||
return false;
|
||||
|
||||
case Context.FEATURE_ENHANCED_JAVA_ACCESS:
|
||||
return false;
|
||||
}
|
||||
// It is a bug to call the method with unknown featureIndex
|
||||
throw new IllegalArgumentException(String.valueOf(featureIndex));
|
||||
}
|
||||
|
||||
private boolean isDom3Present() {
|
||||
Class<?> nodeClass = Kit.classOrNull("org.w3c.dom.Node");
|
||||
if (nodeClass == null) return false;
|
||||
// Check to see whether DOM3 is present; use a new method defined in
|
||||
// DOM3 that is vital to our implementation
|
||||
try {
|
||||
nodeClass.getMethod("getUserData", new Class<?>[] { String.class });
|
||||
return true;
|
||||
} catch (NoSuchMethodException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a default
|
||||
* {@link org.mozilla.javascript.xml.XMLLib.Factory XMLLib.Factory}
|
||||
* to be used by the <code>Context</code> instances produced by this
|
||||
* factory. See {@link Context#getE4xImplementationFactory} for details.
|
||||
*
|
||||
* May return null, in which case E4X functionality is not supported in
|
||||
* Rhino.
|
||||
*
|
||||
* The default implementation now prefers the DOM3 E4X implementation.
|
||||
*/
|
||||
protected org.mozilla.javascript.xml.XMLLib.Factory
|
||||
getE4xImplementationFactory()
|
||||
{
|
||||
// Must provide default implementation, rather than abstract method,
|
||||
// so that past implementors of ContextFactory do not fail at runtime
|
||||
// upon invocation of this method.
|
||||
// Note that the default implementation returns null if we
|
||||
// neither have XMLBeans nor a DOM3 implementation present.
|
||||
|
||||
if (isDom3Present()) {
|
||||
return org.mozilla.javascript.xml.XMLLib.Factory.create(
|
||||
"org.mozilla.javascript.xmlimpl.XMLLibImpl"
|
||||
);
|
||||
} else if (Kit.classOrNull("org.apache.xmlbeans.XmlCursor") != null) {
|
||||
return org.mozilla.javascript.xml.XMLLib.Factory.create(
|
||||
"org.mozilla.javascript.xml.impl.xmlbeans.XMLLibImpl"
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create class loader for generated classes.
|
||||
* This method creates an instance of the default implementation
|
||||
* of {@link GeneratedClassLoader}. Rhino uses this interface to load
|
||||
* generated JVM classes when no {@link SecurityController}
|
||||
* is installed.
|
||||
* Application can override the method to provide custom class loading.
|
||||
*/
|
||||
protected GeneratedClassLoader createClassLoader(final ClassLoader parent)
|
||||
{
|
||||
return AccessController.doPrivileged(new PrivilegedAction<DefiningClassLoader>() {
|
||||
public DefiningClassLoader run(){
|
||||
return new DefiningClassLoader(parent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ClassLoader to use when searching for Java classes.
|
||||
* Unless it was explicitly initialized with
|
||||
* {@link #initApplicationClassLoader(ClassLoader)} the method returns
|
||||
* null to indicate that Thread.getContextClassLoader() should be used.
|
||||
*/
|
||||
public final ClassLoader getApplicationClassLoader()
|
||||
{
|
||||
return applicationClassLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set explicit class loader to use when searching for Java classes.
|
||||
*
|
||||
* @see #getApplicationClassLoader()
|
||||
*/
|
||||
public final void initApplicationClassLoader(ClassLoader loader)
|
||||
{
|
||||
if (loader == null)
|
||||
throw new IllegalArgumentException("loader is null");
|
||||
if (!Kit.testIfCanLoadRhinoClasses(loader))
|
||||
throw new IllegalArgumentException(
|
||||
"Loader can not resolve Rhino classes");
|
||||
|
||||
if (this.applicationClassLoader != null)
|
||||
throw new IllegalStateException(
|
||||
"applicationClassLoader can only be set once");
|
||||
checkNotSealed();
|
||||
|
||||
this.applicationClassLoader = loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute top call to script or function.
|
||||
* When the runtime is about to execute a script or function that will
|
||||
* create the first stack frame with scriptable code, it calls this method
|
||||
* to perform the real call. In this way execution of any script
|
||||
* happens inside this function.
|
||||
*/
|
||||
protected Object doTopCall(Callable callable,
|
||||
Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
return callable.call(cx, scope, thisObj, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of
|
||||
* {@link Context#observeInstructionCount(int instructionCount)}.
|
||||
* This can be used to customize {@link Context} without introducing
|
||||
* additional subclasses.
|
||||
*/
|
||||
protected void observeInstructionCount(Context cx, int instructionCount) {
|
||||
}
|
||||
|
||||
protected void onContextCreated(Context cx)
|
||||
{
|
||||
Object listeners = this.listeners;
|
||||
for (int i = 0; ; ++i) {
|
||||
Listener l = (Listener)Kit.getListener(listeners, i);
|
||||
if (l == null)
|
||||
break;
|
||||
l.contextCreated(cx);
|
||||
}
|
||||
}
|
||||
|
||||
protected void onContextReleased(Context cx)
|
||||
{
|
||||
Object listeners = this.listeners;
|
||||
for (int i = 0; ; ++i) {
|
||||
Listener l = (Listener)Kit.getListener(listeners, i);
|
||||
if (l == null)
|
||||
break;
|
||||
l.contextReleased(cx);
|
||||
}
|
||||
}
|
||||
|
||||
public final void addListener(Listener listener)
|
||||
{
|
||||
checkNotSealed();
|
||||
synchronized (listenersLock) {
|
||||
if (disabledListening) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
listeners = Kit.addListener(listeners, listener);
|
||||
}
|
||||
}
|
||||
|
||||
public final void removeListener(Listener listener)
|
||||
{
|
||||
checkNotSealed();
|
||||
synchronized (listenersLock) {
|
||||
if (disabledListening) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
listeners = Kit.removeListener(listeners, listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The method is used only to implement
|
||||
* Context.disableStaticContextListening()
|
||||
*/
|
||||
final void disableContextListening()
|
||||
{
|
||||
checkNotSealed();
|
||||
synchronized (listenersLock) {
|
||||
disabledListening = true;
|
||||
listeners = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this is a sealed ContextFactory.
|
||||
* @see #seal()
|
||||
*/
|
||||
public final boolean isSealed()
|
||||
{
|
||||
return sealed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Seal this ContextFactory so any attempt to modify it like to add or
|
||||
* remove its listeners will throw an exception.
|
||||
* @see #isSealed()
|
||||
*/
|
||||
public final void seal()
|
||||
{
|
||||
checkNotSealed();
|
||||
sealed = true;
|
||||
}
|
||||
|
||||
protected final void checkNotSealed()
|
||||
{
|
||||
if (sealed) throw new IllegalStateException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call {@link ContextAction#run(Context cx)}
|
||||
* using the {@link Context} instance associated with the current thread.
|
||||
* If no Context is associated with the thread, then
|
||||
* {@link #makeContext()} will be called to construct
|
||||
* new Context instance. The instance will be temporary associated
|
||||
* with the thread during call to {@link ContextAction#run(Context)}.
|
||||
*
|
||||
* @see ContextFactory#call(ContextAction)
|
||||
* @see Context#call(ContextFactory factory, Callable callable,
|
||||
* Scriptable scope, Scriptable thisObj,
|
||||
* Object[] args)
|
||||
*/
|
||||
public final Object call(ContextAction action)
|
||||
{
|
||||
return Context.call(this, action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a context associated with the current thread, creating one if need
|
||||
* be. The Context stores the execution state of the JavaScript engine, so
|
||||
* it is required that the context be entered before execution may begin.
|
||||
* Once a thread has entered a Context, then getCurrentContext() may be
|
||||
* called to find the context that is associated with the current thread.
|
||||
* <p>
|
||||
* Calling <code>enterContext()</code> will return either the Context
|
||||
* currently associated with the thread, or will create a new context and
|
||||
* associate it with the current thread. Each call to
|
||||
* <code>enterContext()</code> must have a matching call to
|
||||
* {@link Context#exit()}.
|
||||
* <pre>
|
||||
* Context cx = contextFactory.enterContext();
|
||||
* try {
|
||||
* ...
|
||||
* cx.evaluateString(...);
|
||||
* } finally {
|
||||
* Context.exit();
|
||||
* }
|
||||
* </pre>
|
||||
* Instead of using <tt>enterContext()</tt>, <tt>exit()</tt> pair consider
|
||||
* using {@link #call(ContextAction)} which guarantees proper association
|
||||
* of Context instances with the current thread.
|
||||
* With this method the above example becomes:
|
||||
* <pre>
|
||||
* ContextFactory.call(new ContextAction() {
|
||||
* public Object run(Context cx) {
|
||||
* ...
|
||||
* cx.evaluateString(...);
|
||||
* return null;
|
||||
* }
|
||||
* });
|
||||
* </pre>
|
||||
* @return a Context associated with the current thread
|
||||
* @see Context#getCurrentContext()
|
||||
* @see Context#exit()
|
||||
* @see #call(ContextAction)
|
||||
*/
|
||||
public Context enterContext()
|
||||
{
|
||||
return enterContext(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #enterContext()} instead
|
||||
* @return a Context associated with the current thread
|
||||
*/
|
||||
public final Context enter()
|
||||
{
|
||||
return enterContext(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link Context#exit()} instead.
|
||||
*/
|
||||
public final void exit()
|
||||
{
|
||||
Context.exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Context associated with the current thread, using the given
|
||||
* Context if need be.
|
||||
* <p>
|
||||
* The same as <code>enterContext()</code> except that <code>cx</code>
|
||||
* is associated with the current thread and returned if the current thread
|
||||
* has no associated context and <code>cx</code> is not associated with any
|
||||
* other thread.
|
||||
* @param cx a Context to associate with the thread if possible
|
||||
* @return a Context associated with the current thread
|
||||
* @see #enterContext()
|
||||
* @see #call(ContextAction)
|
||||
* @throws IllegalStateException if <code>cx</code> is already associated
|
||||
* with a different thread
|
||||
*/
|
||||
public final Context enterContext(Context cx)
|
||||
{
|
||||
return Context.enter(cx, this);
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// API class
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* @deprecated Embeddings that wish to customize newly created
|
||||
* {@link Context} instances should implement
|
||||
* {@link ContextFactory.Listener}.
|
||||
*/
|
||||
public interface ContextListener extends ContextFactory.Listener
|
||||
{
|
||||
|
||||
/**
|
||||
* @deprecated Rhino runtime never calls the method.
|
||||
*/
|
||||
public void contextEntered(Context cx);
|
||||
|
||||
/**
|
||||
* @deprecated Rhino runtime never calls the method.
|
||||
*/
|
||||
public void contextExited(Context cx);
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package org.mozilla.javascript;
|
||||
|
||||
|
||||
/**
|
||||
* Exception thrown by
|
||||
* {@link org.mozilla.javascript.Context#executeScriptWithContinuations(Script, Scriptable)}
|
||||
* and {@link org.mozilla.javascript.Context#callFunctionWithContinuations(Callable, Scriptable, Object[])}
|
||||
* when execution encounters a continuation captured by
|
||||
* {@link org.mozilla.javascript.Context#captureContinuation()}.
|
||||
* Exception will contain the captured state needed to restart the continuation
|
||||
* with {@link org.mozilla.javascript.Context#resumeContinuation(Object, Scriptable, Object)}.
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
public class ContinuationPending extends RuntimeException {
|
||||
private static final long serialVersionUID = 4956008116771118856L;
|
||||
private NativeContinuation continuationState;
|
||||
private Object applicationState;
|
||||
|
||||
/**
|
||||
* Construct a ContinuationPending exception. Internal call only;
|
||||
* users of the API should get continuations created on their behalf by
|
||||
* calling {@link org.mozilla.javascript.Context#executeScriptWithContinuations(Script, Scriptable)}
|
||||
* and {@link org.mozilla.javascript.Context#callFunctionWithContinuations(Callable, Scriptable, Object[])}
|
||||
* @param continuationState Internal Continuation object
|
||||
*/
|
||||
ContinuationPending(NativeContinuation continuationState) {
|
||||
this.continuationState = continuationState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get continuation object. The only
|
||||
* use for this object is to be passed to
|
||||
* {@link org.mozilla.javascript.Context#resumeContinuation(Object, Scriptable, Object)}.
|
||||
* @return continuation object
|
||||
*/
|
||||
public Object getContinuation() {
|
||||
return continuationState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return internal continuation state
|
||||
*/
|
||||
NativeContinuation getContinuationState() {
|
||||
return continuationState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an arbitrary object that applications can use to associate
|
||||
* their state with the continuation.
|
||||
* @param applicationState arbitrary application state
|
||||
*/
|
||||
public void setApplicationState(Object applicationState) {
|
||||
this.applicationState = applicationState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return arbitrary application state
|
||||
*/
|
||||
public Object getApplicationState() {
|
||||
return applicationState;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,920 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mike Ang
|
||||
* Igor Bukanov
|
||||
* Bob Jervis
|
||||
* Mike McCabe
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import org.mozilla.javascript.ast.FunctionNode;
|
||||
|
||||
/**
|
||||
* The following class save decompilation information about the source.
|
||||
* Source information is returned from the parser as a String
|
||||
* associated with function nodes and with the toplevel script. When
|
||||
* saved in the constant pool of a class, this string will be UTF-8
|
||||
* encoded, and token values will occupy a single byte.
|
||||
|
||||
* Source is saved (mostly) as token numbers. The tokens saved pretty
|
||||
* much correspond to the token stream of a 'canonical' representation
|
||||
* of the input program, as directed by the parser. (There were a few
|
||||
* cases where tokens could have been left out where decompiler could
|
||||
* easily reconstruct them, but I left them in for clarity). (I also
|
||||
* looked adding source collection to TokenStream instead, where I
|
||||
* could have limited the changes to a few lines in getToken... but
|
||||
* this wouldn't have saved any space in the resulting source
|
||||
* representation, and would have meant that I'd have to duplicate
|
||||
* parser logic in the decompiler to disambiguate situations where
|
||||
* newlines are important.) The function decompile expands the
|
||||
* tokens back into their string representations, using simple
|
||||
* lookahead to correct spacing and indentation.
|
||||
*
|
||||
* Assignments are saved as two-token pairs (Token.ASSIGN, op). Number tokens
|
||||
* are stored inline, as a NUMBER token, a character representing the type, and
|
||||
* either 1 or 4 characters representing the bit-encoding of the number. String
|
||||
* types NAME, STRING and OBJECT are currently stored as a token type,
|
||||
* followed by a character giving the length of the string (assumed to
|
||||
* be less than 2^16), followed by the characters of the string
|
||||
* inlined into the source string. Changing this to some reference to
|
||||
* to the string in the compiled class' constant pool would probably
|
||||
* save a lot of space... but would require some method of deriving
|
||||
* the final constant pool entry from information available at parse
|
||||
* time.
|
||||
*/
|
||||
public class Decompiler
|
||||
{
|
||||
/**
|
||||
* Flag to indicate that the decompilation should omit the
|
||||
* function header and trailing brace.
|
||||
*/
|
||||
public static final int ONLY_BODY_FLAG = 1 << 0;
|
||||
|
||||
/**
|
||||
* Flag to indicate that the decompilation generates toSource result.
|
||||
*/
|
||||
public static final int TO_SOURCE_FLAG = 1 << 1;
|
||||
|
||||
/**
|
||||
* Decompilation property to specify initial ident value.
|
||||
*/
|
||||
public static final int INITIAL_INDENT_PROP = 1;
|
||||
|
||||
/**
|
||||
* Decompilation property to specify default identation offset.
|
||||
*/
|
||||
public static final int INDENT_GAP_PROP = 2;
|
||||
|
||||
/**
|
||||
* Decompilation property to specify identation offset for case labels.
|
||||
*/
|
||||
public static final int CASE_GAP_PROP = 3;
|
||||
|
||||
// Marker to denote the last RC of function so it can be distinguished from
|
||||
// the last RC of object literals in case of function expressions
|
||||
private static final int FUNCTION_END = Token.LAST_TOKEN + 1;
|
||||
|
||||
String getEncodedSource()
|
||||
{
|
||||
return sourceToString(0);
|
||||
}
|
||||
|
||||
int getCurrentOffset()
|
||||
{
|
||||
return sourceTop;
|
||||
}
|
||||
|
||||
int markFunctionStart(int functionType)
|
||||
{
|
||||
int savedOffset = getCurrentOffset();
|
||||
addToken(Token.FUNCTION);
|
||||
append((char)functionType);
|
||||
return savedOffset;
|
||||
}
|
||||
|
||||
int markFunctionEnd(int functionStart)
|
||||
{
|
||||
int offset = getCurrentOffset();
|
||||
append((char)FUNCTION_END);
|
||||
return offset;
|
||||
}
|
||||
|
||||
void addToken(int token)
|
||||
{
|
||||
if (!(0 <= token && token <= Token.LAST_TOKEN))
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
append((char)token);
|
||||
}
|
||||
|
||||
void addEOL(int token)
|
||||
{
|
||||
if (!(0 <= token && token <= Token.LAST_TOKEN))
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
append((char)token);
|
||||
append((char)Token.EOL);
|
||||
}
|
||||
|
||||
void addName(String str)
|
||||
{
|
||||
addToken(Token.NAME);
|
||||
appendString(str);
|
||||
}
|
||||
|
||||
void addString(String str)
|
||||
{
|
||||
addToken(Token.STRING);
|
||||
appendString(str);
|
||||
}
|
||||
|
||||
void addRegexp(String regexp, String flags)
|
||||
{
|
||||
addToken(Token.REGEXP);
|
||||
appendString('/' + regexp + '/' + flags);
|
||||
}
|
||||
|
||||
void addNumber(double n)
|
||||
{
|
||||
addToken(Token.NUMBER);
|
||||
|
||||
/* encode the number in the source stream.
|
||||
* Save as NUMBER type (char | char char char char)
|
||||
* where type is
|
||||
* 'D' - double, 'S' - short, 'J' - long.
|
||||
|
||||
* We need to retain float vs. integer type info to keep the
|
||||
* behavior of liveconnect type-guessing the same after
|
||||
* decompilation. (Liveconnect tries to present 1.0 to Java
|
||||
* as a float/double)
|
||||
* OPT: This is no longer true. We could compress the format.
|
||||
|
||||
* This may not be the most space-efficient encoding;
|
||||
* the chars created below may take up to 3 bytes in
|
||||
* constant pool UTF-8 encoding, so a Double could take
|
||||
* up to 12 bytes.
|
||||
*/
|
||||
|
||||
long lbits = (long)n;
|
||||
if (lbits != n) {
|
||||
// if it's floating point, save as a Double bit pattern.
|
||||
// (12/15/97 our scanner only returns Double for f.p.)
|
||||
lbits = Double.doubleToLongBits(n);
|
||||
append('D');
|
||||
append((char)(lbits >> 48));
|
||||
append((char)(lbits >> 32));
|
||||
append((char)(lbits >> 16));
|
||||
append((char)lbits);
|
||||
}
|
||||
else {
|
||||
// we can ignore negative values, bc they're already prefixed
|
||||
// by NEG
|
||||
if (lbits < 0) Kit.codeBug();
|
||||
|
||||
// will it fit in a char?
|
||||
// this gives a short encoding for integer values up to 2^16.
|
||||
if (lbits <= Character.MAX_VALUE) {
|
||||
append('S');
|
||||
append((char)lbits);
|
||||
}
|
||||
else { // Integral, but won't fit in a char. Store as a long.
|
||||
append('J');
|
||||
append((char)(lbits >> 48));
|
||||
append((char)(lbits >> 32));
|
||||
append((char)(lbits >> 16));
|
||||
append((char)lbits);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void appendString(String str)
|
||||
{
|
||||
int L = str.length();
|
||||
int lengthEncodingSize = 1;
|
||||
if (L >= 0x8000) {
|
||||
lengthEncodingSize = 2;
|
||||
}
|
||||
int nextTop = sourceTop + lengthEncodingSize + L;
|
||||
if (nextTop > sourceBuffer.length) {
|
||||
increaseSourceCapacity(nextTop);
|
||||
}
|
||||
if (L >= 0x8000) {
|
||||
// Use 2 chars to encode strings exceeding 32K, were the highest
|
||||
// bit in the first char indicates presence of the next byte
|
||||
sourceBuffer[sourceTop] = (char)(0x8000 | (L >>> 16));
|
||||
++sourceTop;
|
||||
}
|
||||
sourceBuffer[sourceTop] = (char)L;
|
||||
++sourceTop;
|
||||
str.getChars(0, L, sourceBuffer, sourceTop);
|
||||
sourceTop = nextTop;
|
||||
}
|
||||
|
||||
private void append(char c)
|
||||
{
|
||||
if (sourceTop == sourceBuffer.length) {
|
||||
increaseSourceCapacity(sourceTop + 1);
|
||||
}
|
||||
sourceBuffer[sourceTop] = c;
|
||||
++sourceTop;
|
||||
}
|
||||
|
||||
private void increaseSourceCapacity(int minimalCapacity)
|
||||
{
|
||||
// Call this only when capacity increase is must
|
||||
if (minimalCapacity <= sourceBuffer.length) Kit.codeBug();
|
||||
int newCapacity = sourceBuffer.length * 2;
|
||||
if (newCapacity < minimalCapacity) {
|
||||
newCapacity = minimalCapacity;
|
||||
}
|
||||
char[] tmp = new char[newCapacity];
|
||||
System.arraycopy(sourceBuffer, 0, tmp, 0, sourceTop);
|
||||
sourceBuffer = tmp;
|
||||
}
|
||||
|
||||
private String sourceToString(int offset)
|
||||
{
|
||||
if (offset < 0 || sourceTop < offset) Kit.codeBug();
|
||||
return new String(sourceBuffer, offset, sourceTop - offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompile the source information associated with this js
|
||||
* function/script back into a string. For the most part, this
|
||||
* just means translating tokens back to their string
|
||||
* representations; there's a little bit of lookahead logic to
|
||||
* decide the proper spacing/indentation. Most of the work in
|
||||
* mapping the original source to the prettyprinted decompiled
|
||||
* version is done by the parser.
|
||||
*
|
||||
* @param source encoded source tree presentation
|
||||
*
|
||||
* @param flags flags to select output format
|
||||
*
|
||||
* @param properties indentation properties
|
||||
*
|
||||
*/
|
||||
public static String decompile(String source, int flags,
|
||||
UintMap properties)
|
||||
{
|
||||
int length = source.length();
|
||||
if (length == 0) { return ""; }
|
||||
|
||||
int indent = properties.getInt(INITIAL_INDENT_PROP, 0);
|
||||
if (indent < 0) throw new IllegalArgumentException();
|
||||
int indentGap = properties.getInt(INDENT_GAP_PROP, 4);
|
||||
if (indentGap < 0) throw new IllegalArgumentException();
|
||||
int caseGap = properties.getInt(CASE_GAP_PROP, 2);
|
||||
if (caseGap < 0) throw new IllegalArgumentException();
|
||||
|
||||
StringBuffer result = new StringBuffer();
|
||||
boolean justFunctionBody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
|
||||
boolean toSource = (0 != (flags & Decompiler.TO_SOURCE_FLAG));
|
||||
|
||||
// Spew tokens in source, for debugging.
|
||||
// as TYPE number char
|
||||
if (printSource) {
|
||||
System.err.println("length:" + length);
|
||||
for (int i = 0; i < length; ++i) {
|
||||
// Note that tokenToName will fail unless Context.printTrees
|
||||
// is true.
|
||||
String tokenname = null;
|
||||
if (Token.printNames) {
|
||||
tokenname = Token.name(source.charAt(i));
|
||||
}
|
||||
if (tokenname == null) {
|
||||
tokenname = "---";
|
||||
}
|
||||
String pad = tokenname.length() > 7
|
||||
? "\t"
|
||||
: "\t\t";
|
||||
System.err.println
|
||||
(tokenname
|
||||
+ pad + (int)source.charAt(i)
|
||||
+ "\t'" + ScriptRuntime.escapeString
|
||||
(source.substring(i, i+1))
|
||||
+ "'");
|
||||
}
|
||||
System.err.println();
|
||||
}
|
||||
|
||||
int braceNesting = 0;
|
||||
boolean afterFirstEOL = false;
|
||||
int i = 0;
|
||||
int topFunctionType;
|
||||
if (source.charAt(i) == Token.SCRIPT) {
|
||||
++i;
|
||||
topFunctionType = -1;
|
||||
} else {
|
||||
topFunctionType = source.charAt(i + 1);
|
||||
}
|
||||
|
||||
if (!toSource) {
|
||||
// add an initial newline to exactly match js.
|
||||
result.append('\n');
|
||||
for (int j = 0; j < indent; j++)
|
||||
result.append(' ');
|
||||
} else {
|
||||
if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {
|
||||
result.append('(');
|
||||
}
|
||||
}
|
||||
|
||||
while (i < length) {
|
||||
switch(source.charAt(i)) {
|
||||
case Token.GET:
|
||||
case Token.SET:
|
||||
result.append(source.charAt(i) == Token.GET ? "get " : "set ");
|
||||
++i;
|
||||
i = printSourceString(source, i + 1, false, result);
|
||||
// Now increment one more to get past the FUNCTION token
|
||||
++i;
|
||||
break;
|
||||
|
||||
case Token.NAME:
|
||||
case Token.REGEXP: // re-wrapped in '/'s in parser...
|
||||
i = printSourceString(source, i + 1, false, result);
|
||||
continue;
|
||||
|
||||
case Token.STRING:
|
||||
i = printSourceString(source, i + 1, true, result);
|
||||
continue;
|
||||
|
||||
case Token.NUMBER:
|
||||
i = printSourceNumber(source, i + 1, result);
|
||||
continue;
|
||||
|
||||
case Token.TRUE:
|
||||
result.append("true");
|
||||
break;
|
||||
|
||||
case Token.FALSE:
|
||||
result.append("false");
|
||||
break;
|
||||
|
||||
case Token.NULL:
|
||||
result.append("null");
|
||||
break;
|
||||
|
||||
case Token.THIS:
|
||||
result.append("this");
|
||||
break;
|
||||
|
||||
case Token.FUNCTION:
|
||||
++i; // skip function type
|
||||
result.append("function ");
|
||||
break;
|
||||
|
||||
case FUNCTION_END:
|
||||
// Do nothing
|
||||
break;
|
||||
|
||||
case Token.COMMA:
|
||||
result.append(", ");
|
||||
break;
|
||||
|
||||
case Token.LC:
|
||||
++braceNesting;
|
||||
if (Token.EOL == getNext(source, length, i))
|
||||
indent += indentGap;
|
||||
result.append('{');
|
||||
break;
|
||||
|
||||
case Token.RC: {
|
||||
--braceNesting;
|
||||
/* don't print the closing RC if it closes the
|
||||
* toplevel function and we're called from
|
||||
* decompileFunctionBody.
|
||||
*/
|
||||
if (justFunctionBody && braceNesting == 0)
|
||||
break;
|
||||
|
||||
result.append('}');
|
||||
switch (getNext(source, length, i)) {
|
||||
case Token.EOL:
|
||||
case FUNCTION_END:
|
||||
indent -= indentGap;
|
||||
break;
|
||||
case Token.WHILE:
|
||||
case Token.ELSE:
|
||||
indent -= indentGap;
|
||||
result.append(' ');
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Token.LP:
|
||||
result.append('(');
|
||||
break;
|
||||
|
||||
case Token.RP:
|
||||
result.append(')');
|
||||
if (Token.LC == getNext(source, length, i))
|
||||
result.append(' ');
|
||||
break;
|
||||
|
||||
case Token.LB:
|
||||
result.append('[');
|
||||
break;
|
||||
|
||||
case Token.RB:
|
||||
result.append(']');
|
||||
break;
|
||||
|
||||
case Token.EOL: {
|
||||
if (toSource) break;
|
||||
boolean newLine = true;
|
||||
if (!afterFirstEOL) {
|
||||
afterFirstEOL = true;
|
||||
if (justFunctionBody) {
|
||||
/* throw away just added 'function name(...) {'
|
||||
* and restore the original indent
|
||||
*/
|
||||
result.setLength(0);
|
||||
indent -= indentGap;
|
||||
newLine = false;
|
||||
}
|
||||
}
|
||||
if (newLine) {
|
||||
result.append('\n');
|
||||
}
|
||||
|
||||
/* add indent if any tokens remain,
|
||||
* less setback if next token is
|
||||
* a label, case or default.
|
||||
*/
|
||||
if (i + 1 < length) {
|
||||
int less = 0;
|
||||
int nextToken = source.charAt(i + 1);
|
||||
if (nextToken == Token.CASE
|
||||
|| nextToken == Token.DEFAULT)
|
||||
{
|
||||
less = indentGap - caseGap;
|
||||
} else if (nextToken == Token.RC) {
|
||||
less = indentGap;
|
||||
}
|
||||
|
||||
/* elaborate check against label... skip past a
|
||||
* following inlined NAME and look for a COLON.
|
||||
*/
|
||||
else if (nextToken == Token.NAME) {
|
||||
int afterName = getSourceStringEnd(source, i + 2);
|
||||
if (source.charAt(afterName) == Token.COLON)
|
||||
less = indentGap;
|
||||
}
|
||||
|
||||
for (; less < indent; less++)
|
||||
result.append(' ');
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Token.DOT:
|
||||
result.append('.');
|
||||
break;
|
||||
|
||||
case Token.NEW:
|
||||
result.append("new ");
|
||||
break;
|
||||
|
||||
case Token.DELPROP:
|
||||
result.append("delete ");
|
||||
break;
|
||||
|
||||
case Token.IF:
|
||||
result.append("if ");
|
||||
break;
|
||||
|
||||
case Token.ELSE:
|
||||
result.append("else ");
|
||||
break;
|
||||
|
||||
case Token.FOR:
|
||||
result.append("for ");
|
||||
break;
|
||||
|
||||
case Token.IN:
|
||||
result.append(" in ");
|
||||
break;
|
||||
|
||||
case Token.WITH:
|
||||
result.append("with ");
|
||||
break;
|
||||
|
||||
case Token.WHILE:
|
||||
result.append("while ");
|
||||
break;
|
||||
|
||||
case Token.DO:
|
||||
result.append("do ");
|
||||
break;
|
||||
|
||||
case Token.TRY:
|
||||
result.append("try ");
|
||||
break;
|
||||
|
||||
case Token.CATCH:
|
||||
result.append("catch ");
|
||||
break;
|
||||
|
||||
case Token.FINALLY:
|
||||
result.append("finally ");
|
||||
break;
|
||||
|
||||
case Token.THROW:
|
||||
result.append("throw ");
|
||||
break;
|
||||
|
||||
case Token.SWITCH:
|
||||
result.append("switch ");
|
||||
break;
|
||||
|
||||
case Token.BREAK:
|
||||
result.append("break");
|
||||
if (Token.NAME == getNext(source, length, i))
|
||||
result.append(' ');
|
||||
break;
|
||||
|
||||
case Token.CONTINUE:
|
||||
result.append("continue");
|
||||
if (Token.NAME == getNext(source, length, i))
|
||||
result.append(' ');
|
||||
break;
|
||||
|
||||
case Token.CASE:
|
||||
result.append("case ");
|
||||
break;
|
||||
|
||||
case Token.DEFAULT:
|
||||
result.append("default");
|
||||
break;
|
||||
|
||||
case Token.RETURN:
|
||||
result.append("return");
|
||||
if (Token.SEMI != getNext(source, length, i))
|
||||
result.append(' ');
|
||||
break;
|
||||
|
||||
case Token.VAR:
|
||||
result.append("var ");
|
||||
break;
|
||||
|
||||
case Token.LET:
|
||||
result.append("let ");
|
||||
break;
|
||||
|
||||
case Token.SEMI:
|
||||
result.append(';');
|
||||
if (Token.EOL != getNext(source, length, i)) {
|
||||
// separators in FOR
|
||||
result.append(' ');
|
||||
}
|
||||
break;
|
||||
|
||||
case Token.ASSIGN:
|
||||
result.append(" = ");
|
||||
break;
|
||||
|
||||
case Token.ASSIGN_ADD:
|
||||
result.append(" += ");
|
||||
break;
|
||||
|
||||
case Token.ASSIGN_SUB:
|
||||
result.append(" -= ");
|
||||
break;
|
||||
|
||||
case Token.ASSIGN_MUL:
|
||||
result.append(" *= ");
|
||||
break;
|
||||
|
||||
case Token.ASSIGN_DIV:
|
||||
result.append(" /= ");
|
||||
break;
|
||||
|
||||
case Token.ASSIGN_MOD:
|
||||
result.append(" %= ");
|
||||
break;
|
||||
|
||||
case Token.ASSIGN_BITOR:
|
||||
result.append(" |= ");
|
||||
break;
|
||||
|
||||
case Token.ASSIGN_BITXOR:
|
||||
result.append(" ^= ");
|
||||
break;
|
||||
|
||||
case Token.ASSIGN_BITAND:
|
||||
result.append(" &= ");
|
||||
break;
|
||||
|
||||
case Token.ASSIGN_LSH:
|
||||
result.append(" <<= ");
|
||||
break;
|
||||
|
||||
case Token.ASSIGN_RSH:
|
||||
result.append(" >>= ");
|
||||
break;
|
||||
|
||||
case Token.ASSIGN_URSH:
|
||||
result.append(" >>>= ");
|
||||
break;
|
||||
|
||||
case Token.HOOK:
|
||||
result.append(" ? ");
|
||||
break;
|
||||
|
||||
case Token.OBJECTLIT:
|
||||
// pun OBJECTLIT to mean colon in objlit property
|
||||
// initialization.
|
||||
// This needs to be distinct from COLON in the general case
|
||||
// to distinguish from the colon in a ternary... which needs
|
||||
// different spacing.
|
||||
result.append(':');
|
||||
break;
|
||||
|
||||
case Token.COLON:
|
||||
if (Token.EOL == getNext(source, length, i))
|
||||
// it's the end of a label
|
||||
result.append(':');
|
||||
else
|
||||
// it's the middle part of a ternary
|
||||
result.append(" : ");
|
||||
break;
|
||||
|
||||
case Token.OR:
|
||||
result.append(" || ");
|
||||
break;
|
||||
|
||||
case Token.AND:
|
||||
result.append(" && ");
|
||||
break;
|
||||
|
||||
case Token.BITOR:
|
||||
result.append(" | ");
|
||||
break;
|
||||
|
||||
case Token.BITXOR:
|
||||
result.append(" ^ ");
|
||||
break;
|
||||
|
||||
case Token.BITAND:
|
||||
result.append(" & ");
|
||||
break;
|
||||
|
||||
case Token.SHEQ:
|
||||
result.append(" === ");
|
||||
break;
|
||||
|
||||
case Token.SHNE:
|
||||
result.append(" !== ");
|
||||
break;
|
||||
|
||||
case Token.EQ:
|
||||
result.append(" == ");
|
||||
break;
|
||||
|
||||
case Token.NE:
|
||||
result.append(" != ");
|
||||
break;
|
||||
|
||||
case Token.LE:
|
||||
result.append(" <= ");
|
||||
break;
|
||||
|
||||
case Token.LT:
|
||||
result.append(" < ");
|
||||
break;
|
||||
|
||||
case Token.GE:
|
||||
result.append(" >= ");
|
||||
break;
|
||||
|
||||
case Token.GT:
|
||||
result.append(" > ");
|
||||
break;
|
||||
|
||||
case Token.INSTANCEOF:
|
||||
result.append(" instanceof ");
|
||||
break;
|
||||
|
||||
case Token.LSH:
|
||||
result.append(" << ");
|
||||
break;
|
||||
|
||||
case Token.RSH:
|
||||
result.append(" >> ");
|
||||
break;
|
||||
|
||||
case Token.URSH:
|
||||
result.append(" >>> ");
|
||||
break;
|
||||
|
||||
case Token.TYPEOF:
|
||||
result.append("typeof ");
|
||||
break;
|
||||
|
||||
case Token.VOID:
|
||||
result.append("void ");
|
||||
break;
|
||||
|
||||
case Token.CONST:
|
||||
result.append("const ");
|
||||
break;
|
||||
|
||||
case Token.YIELD:
|
||||
result.append("yield ");
|
||||
break;
|
||||
|
||||
case Token.NOT:
|
||||
result.append('!');
|
||||
break;
|
||||
|
||||
case Token.BITNOT:
|
||||
result.append('~');
|
||||
break;
|
||||
|
||||
case Token.POS:
|
||||
result.append('+');
|
||||
break;
|
||||
|
||||
case Token.NEG:
|
||||
result.append('-');
|
||||
break;
|
||||
|
||||
case Token.INC:
|
||||
result.append("++");
|
||||
break;
|
||||
|
||||
case Token.DEC:
|
||||
result.append("--");
|
||||
break;
|
||||
|
||||
case Token.ADD:
|
||||
result.append(" + ");
|
||||
break;
|
||||
|
||||
case Token.SUB:
|
||||
result.append(" - ");
|
||||
break;
|
||||
|
||||
case Token.MUL:
|
||||
result.append(" * ");
|
||||
break;
|
||||
|
||||
case Token.DIV:
|
||||
result.append(" / ");
|
||||
break;
|
||||
|
||||
case Token.MOD:
|
||||
result.append(" % ");
|
||||
break;
|
||||
|
||||
case Token.COLONCOLON:
|
||||
result.append("::");
|
||||
break;
|
||||
|
||||
case Token.DOTDOT:
|
||||
result.append("..");
|
||||
break;
|
||||
|
||||
case Token.DOTQUERY:
|
||||
result.append(".(");
|
||||
break;
|
||||
|
||||
case Token.XMLATTR:
|
||||
result.append('@');
|
||||
break;
|
||||
|
||||
default:
|
||||
// If we don't know how to decompile it, raise an exception.
|
||||
throw new RuntimeException("Token: " +
|
||||
Token.name(source.charAt(i)));
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
if (!toSource) {
|
||||
// add that trailing newline if it's an outermost function.
|
||||
if (!justFunctionBody)
|
||||
result.append('\n');
|
||||
} else {
|
||||
if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {
|
||||
result.append(')');
|
||||
}
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private static int getNext(String source, int length, int i)
|
||||
{
|
||||
return (i + 1 < length) ? source.charAt(i + 1) : Token.EOF;
|
||||
}
|
||||
|
||||
private static int getSourceStringEnd(String source, int offset)
|
||||
{
|
||||
return printSourceString(source, offset, false, null);
|
||||
}
|
||||
|
||||
private static int printSourceString(String source, int offset,
|
||||
boolean asQuotedString,
|
||||
StringBuffer sb)
|
||||
{
|
||||
int length = source.charAt(offset);
|
||||
++offset;
|
||||
if ((0x8000 & length) != 0) {
|
||||
length = ((0x7FFF & length) << 16) | source.charAt(offset);
|
||||
++offset;
|
||||
}
|
||||
if (sb != null) {
|
||||
String str = source.substring(offset, offset + length);
|
||||
if (!asQuotedString) {
|
||||
sb.append(str);
|
||||
} else {
|
||||
sb.append('"');
|
||||
sb.append(ScriptRuntime.escapeString(str));
|
||||
sb.append('"');
|
||||
}
|
||||
}
|
||||
return offset + length;
|
||||
}
|
||||
|
||||
private static int printSourceNumber(String source, int offset,
|
||||
StringBuffer sb)
|
||||
{
|
||||
double number = 0.0;
|
||||
char type = source.charAt(offset);
|
||||
++offset;
|
||||
if (type == 'S') {
|
||||
if (sb != null) {
|
||||
int ival = source.charAt(offset);
|
||||
number = ival;
|
||||
}
|
||||
++offset;
|
||||
} else if (type == 'J' || type == 'D') {
|
||||
if (sb != null) {
|
||||
long lbits;
|
||||
lbits = (long)source.charAt(offset) << 48;
|
||||
lbits |= (long)source.charAt(offset + 1) << 32;
|
||||
lbits |= (long)source.charAt(offset + 2) << 16;
|
||||
lbits |= source.charAt(offset + 3);
|
||||
if (type == 'J') {
|
||||
number = lbits;
|
||||
} else {
|
||||
number = Double.longBitsToDouble(lbits);
|
||||
}
|
||||
}
|
||||
offset += 4;
|
||||
} else {
|
||||
// Bad source
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (sb != null) {
|
||||
sb.append(ScriptRuntime.numberToString(number, 10));
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
private char[] sourceBuffer = new char[128];
|
||||
|
||||
// Per script/function source buffer top: parent source does not include a
|
||||
// nested functions source and uses function index as a reference instead.
|
||||
private int sourceTop;
|
||||
|
||||
// whether to do a debug print of the source information, when decompiling.
|
||||
private static final boolean printSource = false;
|
||||
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* This is the default error reporter for JavaScript.
|
||||
*
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
class DefaultErrorReporter implements ErrorReporter
|
||||
{
|
||||
static final DefaultErrorReporter instance = new DefaultErrorReporter();
|
||||
|
||||
private boolean forEval;
|
||||
private ErrorReporter chainedReporter;
|
||||
|
||||
private DefaultErrorReporter() { }
|
||||
|
||||
static ErrorReporter forEval(ErrorReporter reporter)
|
||||
{
|
||||
DefaultErrorReporter r = new DefaultErrorReporter();
|
||||
r.forEval = true;
|
||||
r.chainedReporter = reporter;
|
||||
return r;
|
||||
}
|
||||
|
||||
public void warning(String message, String sourceURI, int line,
|
||||
String lineText, int lineOffset)
|
||||
{
|
||||
if (chainedReporter != null) {
|
||||
chainedReporter.warning(
|
||||
message, sourceURI, line, lineText, lineOffset);
|
||||
} else {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
public void error(String message, String sourceURI, int line,
|
||||
String lineText, int lineOffset)
|
||||
{
|
||||
if (forEval) {
|
||||
// Assume error message strings that start with "TypeError: "
|
||||
// should become TypeError exceptions. A bit of a hack, but we
|
||||
// don't want to change the ErrorReporter interface.
|
||||
String error = "SyntaxError";
|
||||
final String TYPE_ERROR_NAME = "TypeError";
|
||||
final String DELIMETER = ": ";
|
||||
final String prefix = TYPE_ERROR_NAME + DELIMETER;
|
||||
if (message.startsWith(prefix)) {
|
||||
error = TYPE_ERROR_NAME;
|
||||
message = message.substring(prefix.length());
|
||||
}
|
||||
throw ScriptRuntime.constructError(error, message, sourceURI,
|
||||
line, lineText, lineOffset);
|
||||
}
|
||||
if (chainedReporter != null) {
|
||||
chainedReporter.error(
|
||||
message, sourceURI, line, lineText, lineOffset);
|
||||
} else {
|
||||
throw runtimeError(
|
||||
message, sourceURI, line, lineText, lineOffset);
|
||||
}
|
||||
}
|
||||
|
||||
public EvaluatorException runtimeError(String message, String sourceURI,
|
||||
int line, String lineText,
|
||||
int lineOffset)
|
||||
{
|
||||
if (chainedReporter != null) {
|
||||
return chainedReporter.runtimeError(
|
||||
message, sourceURI, line, lineText, lineOffset);
|
||||
} else {
|
||||
return new EvaluatorException(
|
||||
message, sourceURI, line, lineText, lineOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Roger Lawrence
|
||||
* Patrick Beard
|
||||
* Igor Bukanov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* Load generated classes.
|
||||
*
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
public class DefiningClassLoader extends ClassLoader
|
||||
implements GeneratedClassLoader
|
||||
{
|
||||
public DefiningClassLoader() {
|
||||
this.parentLoader = getClass().getClassLoader();
|
||||
}
|
||||
|
||||
public DefiningClassLoader(ClassLoader parentLoader) {
|
||||
this.parentLoader = parentLoader;
|
||||
}
|
||||
|
||||
public Class<?> defineClass(String name, byte[] data) {
|
||||
// Use our own protection domain for the generated classes.
|
||||
// TODO: we might want to use a separate protection domain for classes
|
||||
// compiled from scripts, based on where the script was loaded from.
|
||||
return super.defineClass(name, data, 0, data.length,
|
||||
SecurityUtilities.getProtectionDomain(getClass()));
|
||||
}
|
||||
|
||||
public void linkClass(Class<?> cl) {
|
||||
resolveClass(cl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> loadClass(String name, boolean resolve)
|
||||
throws ClassNotFoundException
|
||||
{
|
||||
Class<?> cl = findLoadedClass(name);
|
||||
if (cl == null) {
|
||||
if (parentLoader != null) {
|
||||
cl = parentLoader.loadClass(name);
|
||||
} else {
|
||||
cl = findSystemClass(name);
|
||||
}
|
||||
}
|
||||
if (resolve) {
|
||||
resolveClass(cl);
|
||||
}
|
||||
return cl;
|
||||
}
|
||||
|
||||
private final ClassLoader parentLoader;
|
||||
}
|
||||
@@ -1,266 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Delegator.java, released
|
||||
* Sep 27, 2000.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Matthias Radestock. <matthias@sorted.org>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// API class
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* This is a helper class for implementing wrappers around Scriptable
|
||||
* objects. It implements the Function interface and delegates all
|
||||
* invocations to a delegee Scriptable object. The normal use of this
|
||||
* class involves creating a sub-class and overriding one or more of
|
||||
* the methods.
|
||||
*
|
||||
* A useful application is the implementation of interceptors,
|
||||
* pre/post conditions, debugging.
|
||||
*
|
||||
* @see Function
|
||||
* @see Scriptable
|
||||
* @author Matthias Radestock
|
||||
*/
|
||||
|
||||
public class Delegator implements Function {
|
||||
|
||||
protected Scriptable obj = null;
|
||||
|
||||
/**
|
||||
* Create a Delegator prototype.
|
||||
*
|
||||
* This constructor should only be used for creating prototype
|
||||
* objects of Delegator.
|
||||
*
|
||||
* @see org.mozilla.javascript.Delegator#construct
|
||||
*/
|
||||
public Delegator() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Delegator that forwards requests to a delegee
|
||||
* Scriptable object.
|
||||
*
|
||||
* @param obj the delegee
|
||||
* @see org.mozilla.javascript.Scriptable
|
||||
*/
|
||||
public Delegator(Scriptable obj) {
|
||||
this.obj = obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crete new Delegator instance.
|
||||
* The default implementation calls this.getClass().newInstance().
|
||||
*
|
||||
* @see #construct(Context cx, Scriptable scope, Object[] args)
|
||||
*/
|
||||
protected Delegator newInstance()
|
||||
{
|
||||
try {
|
||||
return this.getClass().newInstance();
|
||||
} catch (Exception ex) {
|
||||
throw Context.throwAsScriptRuntimeEx(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the delegee.
|
||||
*
|
||||
* @return the delegee
|
||||
*/
|
||||
public Scriptable getDelegee() {
|
||||
return obj;
|
||||
}
|
||||
/**
|
||||
* Set the delegee.
|
||||
*
|
||||
* @param obj the delegee
|
||||
* @see org.mozilla.javascript.Scriptable
|
||||
*/
|
||||
public void setDelegee(Scriptable obj) {
|
||||
this.obj = obj;
|
||||
}
|
||||
/**
|
||||
* @see org.mozilla.javascript.Scriptable#getClassName
|
||||
*/
|
||||
public String getClassName() {
|
||||
return obj.getClassName();
|
||||
}
|
||||
/**
|
||||
* @see org.mozilla.javascript.Scriptable#get(String, Scriptable)
|
||||
*/
|
||||
public Object get(String name, Scriptable start) {
|
||||
return obj.get(name,start);
|
||||
}
|
||||
/**
|
||||
* @see org.mozilla.javascript.Scriptable#get(int, Scriptable)
|
||||
*/
|
||||
public Object get(int index, Scriptable start) {
|
||||
return obj.get(index,start);
|
||||
}
|
||||
/**
|
||||
* @see org.mozilla.javascript.Scriptable#has(String, Scriptable)
|
||||
*/
|
||||
public boolean has(String name, Scriptable start) {
|
||||
return obj.has(name,start);
|
||||
}
|
||||
/**
|
||||
* @see org.mozilla.javascript.Scriptable#has(int, Scriptable)
|
||||
*/
|
||||
public boolean has(int index, Scriptable start) {
|
||||
return obj.has(index,start);
|
||||
}
|
||||
/**
|
||||
* @see org.mozilla.javascript.Scriptable#put(String, Scriptable, Object)
|
||||
*/
|
||||
public void put(String name, Scriptable start, Object value) {
|
||||
obj.put(name,start,value);
|
||||
}
|
||||
/**
|
||||
* @see org.mozilla.javascript.Scriptable#put(int, Scriptable, Object)
|
||||
*/
|
||||
public void put(int index, Scriptable start, Object value) {
|
||||
obj.put(index,start,value);
|
||||
}
|
||||
/**
|
||||
* @see org.mozilla.javascript.Scriptable#delete(String)
|
||||
*/
|
||||
public void delete(String name) {
|
||||
obj.delete(name);
|
||||
}
|
||||
/**
|
||||
* @see org.mozilla.javascript.Scriptable#delete(int)
|
||||
*/
|
||||
public void delete(int index) {
|
||||
obj.delete(index);
|
||||
}
|
||||
/**
|
||||
* @see org.mozilla.javascript.Scriptable#getPrototype
|
||||
*/
|
||||
public Scriptable getPrototype() {
|
||||
return obj.getPrototype();
|
||||
}
|
||||
/**
|
||||
* @see org.mozilla.javascript.Scriptable#setPrototype
|
||||
*/
|
||||
public void setPrototype(Scriptable prototype) {
|
||||
obj.setPrototype(prototype);
|
||||
}
|
||||
/**
|
||||
* @see org.mozilla.javascript.Scriptable#getParentScope
|
||||
*/
|
||||
public Scriptable getParentScope() {
|
||||
return obj.getParentScope();
|
||||
}
|
||||
/**
|
||||
* @see org.mozilla.javascript.Scriptable#setParentScope
|
||||
*/
|
||||
public void setParentScope(Scriptable parent) {
|
||||
obj.setParentScope(parent);
|
||||
}
|
||||
/**
|
||||
* @see org.mozilla.javascript.Scriptable#getIds
|
||||
*/
|
||||
public Object[] getIds() {
|
||||
return obj.getIds();
|
||||
}
|
||||
/**
|
||||
* Note that this method does not get forwarded to the delegee if
|
||||
* the <code>hint</code> parameter is null,
|
||||
* <code>ScriptRuntime.ScriptableClass</code> or
|
||||
* <code>ScriptRuntime.FunctionClass</code>. Instead the object
|
||||
* itself is returned.
|
||||
*
|
||||
* @param hint the type hint
|
||||
* @return the default value
|
||||
*
|
||||
* @see org.mozilla.javascript.Scriptable#getDefaultValue
|
||||
*/
|
||||
public Object getDefaultValue(Class<?> hint) {
|
||||
return (hint == null ||
|
||||
hint == ScriptRuntime.ScriptableClass ||
|
||||
hint == ScriptRuntime.FunctionClass) ?
|
||||
this : obj.getDefaultValue(hint);
|
||||
}
|
||||
/**
|
||||
* @see org.mozilla.javascript.Scriptable#hasInstance
|
||||
*/
|
||||
public boolean hasInstance(Scriptable instance) {
|
||||
return obj.hasInstance(instance);
|
||||
}
|
||||
/**
|
||||
* @see org.mozilla.javascript.Function#call
|
||||
*/
|
||||
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
|
||||
Object[] args)
|
||||
{
|
||||
return ((Function)obj).call(cx,scope,thisObj,args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that if the <code>delegee</code> is <code>null</code>,
|
||||
* this method creates a new instance of the Delegator itself
|
||||
* rathert than forwarding the call to the
|
||||
* <code>delegee</code>. This permits the use of Delegator
|
||||
* prototypes.
|
||||
*
|
||||
* @param cx the current Context for this thread
|
||||
* @param scope an enclosing scope of the caller except
|
||||
* when the function is called from a closure.
|
||||
* @param args the array of arguments
|
||||
* @return the allocated object
|
||||
*
|
||||
* @see Function#construct(Context, Scriptable, Object[])
|
||||
*/
|
||||
public Scriptable construct(Context cx, Scriptable scope, Object[] args)
|
||||
{
|
||||
if (obj == null) {
|
||||
//this little trick allows us to declare prototype objects for
|
||||
//Delegators
|
||||
Delegator n = newInstance();
|
||||
Scriptable delegee;
|
||||
if (args.length == 0) {
|
||||
delegee = new NativeObject();
|
||||
} else {
|
||||
delegee = ScriptRuntime.toObject(cx, scope, args[0]);
|
||||
}
|
||||
n.setDelegee(delegee);
|
||||
return n;
|
||||
}
|
||||
else {
|
||||
return ((Function)obj).construct(cx,scope,args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,161 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Roger Lawrence
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// API class
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* The class of exceptions raised by the engine as described in
|
||||
* ECMA edition 3. See section 15.11.6 in particular.
|
||||
*/
|
||||
public class EcmaError extends RhinoException
|
||||
{
|
||||
static final long serialVersionUID = -6261226256957286699L;
|
||||
|
||||
private String errorName;
|
||||
private String errorMessage;
|
||||
|
||||
/**
|
||||
* Create an exception with the specified detail message.
|
||||
*
|
||||
* Errors internal to the JavaScript engine will simply throw a
|
||||
* RuntimeException.
|
||||
*
|
||||
* @param sourceName the name of the source responsible for the error
|
||||
* @param lineNumber the line number of the source
|
||||
* @param columnNumber the columnNumber of the source (may be zero if
|
||||
* unknown)
|
||||
* @param lineSource the source of the line containing the error (may be
|
||||
* null if unknown)
|
||||
*/
|
||||
EcmaError(String errorName, String errorMessage,
|
||||
String sourceName, int lineNumber,
|
||||
String lineSource, int columnNumber)
|
||||
{
|
||||
recordErrorOrigin(sourceName, lineNumber, lineSource, columnNumber);
|
||||
this.errorName = errorName;
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated EcmaError error instances should not be constructed
|
||||
* explicitly since they are generated by the engine.
|
||||
*/
|
||||
public EcmaError(Scriptable nativeError, String sourceName,
|
||||
int lineNumber, int columnNumber, String lineSource)
|
||||
{
|
||||
this("InternalError", ScriptRuntime.toString(nativeError),
|
||||
sourceName, lineNumber, lineSource, columnNumber);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String details()
|
||||
{
|
||||
return errorName+": "+errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the error.
|
||||
*
|
||||
* ECMA edition 3 defines the following
|
||||
* errors: EvalError, RangeError, ReferenceError,
|
||||
* SyntaxError, TypeError, and URIError. Additional error names
|
||||
* may be added in the future.
|
||||
*
|
||||
* See ECMA edition 3, 15.11.7.9.
|
||||
*
|
||||
* @return the name of the error.
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return errorName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message corresponding to the error.
|
||||
*
|
||||
* See ECMA edition 3, 15.11.7.10.
|
||||
*
|
||||
* @return an implementation-defined string describing the error.
|
||||
*/
|
||||
public String getErrorMessage()
|
||||
{
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link RhinoException#sourceName()} from the super class.
|
||||
*/
|
||||
public String getSourceName()
|
||||
{
|
||||
return sourceName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link RhinoException#lineNumber()} from the super class.
|
||||
*/
|
||||
public int getLineNumber()
|
||||
{
|
||||
return lineNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link RhinoException#columnNumber()} from the super class.
|
||||
*/
|
||||
public int getColumnNumber() {
|
||||
return columnNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link RhinoException#lineSource()} from the super class.
|
||||
*/
|
||||
public String getLineSource() {
|
||||
return lineSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Always returns <b>null</b>.
|
||||
*/
|
||||
public Scriptable getErrorObject()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// API class
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* This is interface defines a protocol for the reporting of
|
||||
* errors during JavaScript translation or execution.
|
||||
*
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
|
||||
public interface ErrorReporter {
|
||||
|
||||
/**
|
||||
* Report a warning.
|
||||
*
|
||||
* The implementing class may choose to ignore the warning
|
||||
* if it desires.
|
||||
*
|
||||
* @param message a String describing the warning
|
||||
* @param sourceName a String describing the JavaScript source
|
||||
* where the warning occured; typically a filename or URL
|
||||
* @param line the line number associated with the warning
|
||||
* @param lineSource the text of the line (may be null)
|
||||
* @param lineOffset the offset into lineSource where problem was detected
|
||||
*/
|
||||
void warning(String message, String sourceName, int line,
|
||||
String lineSource, int lineOffset);
|
||||
|
||||
/**
|
||||
* Report an error.
|
||||
*
|
||||
* The implementing class is free to throw an exception if
|
||||
* it desires.
|
||||
*
|
||||
* If execution has not yet begun, the JavaScript engine is
|
||||
* free to find additional errors rather than terminating
|
||||
* the translation. It will not execute a script that had
|
||||
* errors, however.
|
||||
*
|
||||
* @param message a String describing the error
|
||||
* @param sourceName a String describing the JavaScript source
|
||||
* where the error occured; typically a filename or URL
|
||||
* @param line the line number associated with the error
|
||||
* @param lineSource the text of the line (may be null)
|
||||
* @param lineOffset the offset into lineSource where problem was detected
|
||||
*/
|
||||
void error(String message, String sourceName, int line,
|
||||
String lineSource, int lineOffset);
|
||||
|
||||
/**
|
||||
* Creates an EvaluatorException that may be thrown.
|
||||
*
|
||||
* runtimeErrors, unlike errors, will always terminate the
|
||||
* current script.
|
||||
*
|
||||
* @param message a String describing the error
|
||||
* @param sourceName a String describing the JavaScript source
|
||||
* where the error occured; typically a filename or URL
|
||||
* @param line the line number associated with the error
|
||||
* @param lineSource the text of the line (may be null)
|
||||
* @param lineOffset the offset into lineSource where problem was detected
|
||||
* @return an EvaluatorException that will be thrown.
|
||||
*/
|
||||
EvaluatorException runtimeError(String message, String sourceName,
|
||||
int line, String lineSource,
|
||||
int lineOffset);
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import org.mozilla.javascript.ast.ScriptNode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Abstraction of evaluation, which can be implemented either by an
|
||||
* interpreter or compiler.
|
||||
*/
|
||||
public interface Evaluator {
|
||||
|
||||
/**
|
||||
* Compile the script or function from intermediate representation
|
||||
* tree into an executable form.
|
||||
*
|
||||
* @param compilerEnv Compiler environment
|
||||
* @param tree parse tree
|
||||
* @param encodedSource encoding of the source code for decompilation
|
||||
* @param returnFunction if true, compiling a function
|
||||
* @return an opaque object that can be passed to either
|
||||
* createFunctionObject or createScriptObject, depending on the
|
||||
* value of returnFunction
|
||||
*/
|
||||
public Object compile(CompilerEnvirons compilerEnv,
|
||||
ScriptNode tree,
|
||||
String encodedSource,
|
||||
boolean returnFunction);
|
||||
|
||||
/**
|
||||
* Create a function object.
|
||||
*
|
||||
* @param cx Current context
|
||||
* @param scope scope of the function
|
||||
* @param bytecode opaque object returned by compile
|
||||
* @param staticSecurityDomain security domain
|
||||
* @return Function object that can be called
|
||||
*/
|
||||
public Function createFunctionObject(Context cx, Scriptable scope,
|
||||
Object bytecode, Object staticSecurityDomain);
|
||||
|
||||
/**
|
||||
* Create a script object.
|
||||
*
|
||||
* @param bytecode opaque object returned by compile
|
||||
* @param staticSecurityDomain security domain
|
||||
* @return Script object that can be evaluated
|
||||
*/
|
||||
public Script createScriptObject(Object bytecode,
|
||||
Object staticSecurityDomain);
|
||||
|
||||
/**
|
||||
* Capture stack information from the given exception.
|
||||
* @param ex an exception thrown during execution
|
||||
*/
|
||||
public void captureStackInfo(RhinoException ex);
|
||||
|
||||
/**
|
||||
* Get the source position information by examining the stack.
|
||||
* @param cx Context
|
||||
* @param linep Array object of length >= 1; getSourcePositionFromStack
|
||||
* will assign the line number to linep[0].
|
||||
* @return the name of the file or other source container
|
||||
*/
|
||||
public String getSourcePositionFromStack(Context cx, int[] linep);
|
||||
|
||||
/**
|
||||
* Given a native stack trace, patch it with script-specific source
|
||||
* and line information
|
||||
* @param ex exception
|
||||
* @param nativeStackTrace the native stack trace
|
||||
* @return patched stack trace
|
||||
*/
|
||||
public String getPatchedStack(RhinoException ex,
|
||||
String nativeStackTrace);
|
||||
|
||||
/**
|
||||
* Get the script stack for the given exception
|
||||
* @param ex exception from execution
|
||||
* @return list of strings for the stack trace
|
||||
*/
|
||||
public List<String> getScriptStack(RhinoException ex);
|
||||
|
||||
/**
|
||||
* Mark the given script to indicate it was created by a call to
|
||||
* eval() or to a Function constructor.
|
||||
* @param script script to mark as from eval
|
||||
*/
|
||||
public void setEvalScriptFlag(Script script);
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* The class of exceptions thrown by the JavaScript engine.
|
||||
*/
|
||||
public class EvaluatorException extends RhinoException
|
||||
{
|
||||
static final long serialVersionUID = -8743165779676009808L;
|
||||
|
||||
public EvaluatorException(String detail)
|
||||
{
|
||||
super(detail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an exception with the specified detail message.
|
||||
*
|
||||
* Errors internal to the JavaScript engine will simply throw a
|
||||
* RuntimeException.
|
||||
*
|
||||
* @param detail the error message
|
||||
* @param sourceName the name of the source reponsible for the error
|
||||
* @param lineNumber the line number of the source
|
||||
*/
|
||||
public EvaluatorException(String detail, String sourceName,
|
||||
int lineNumber)
|
||||
{
|
||||
this(detail, sourceName, lineNumber, null, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an exception with the specified detail message.
|
||||
*
|
||||
* Errors internal to the JavaScript engine will simply throw a
|
||||
* RuntimeException.
|
||||
*
|
||||
* @param detail the error message
|
||||
* @param sourceName the name of the source responsible for the error
|
||||
* @param lineNumber the line number of the source
|
||||
* @param columnNumber the columnNumber of the source (may be zero if
|
||||
* unknown)
|
||||
* @param lineSource the source of the line containing the error (may be
|
||||
* null if unknown)
|
||||
*/
|
||||
public EvaluatorException(String detail, String sourceName, int lineNumber,
|
||||
String lineSource, int columnNumber)
|
||||
{
|
||||
super(detail);
|
||||
recordErrorOrigin(sourceName, lineNumber, lineSource, columnNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link RhinoException#sourceName()} from the super class.
|
||||
*/
|
||||
public String getSourceName()
|
||||
{
|
||||
return sourceName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link RhinoException#lineNumber()} from the super class.
|
||||
*/
|
||||
public int getLineNumber()
|
||||
{
|
||||
return lineNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link RhinoException#columnNumber()} from the super class.
|
||||
*/
|
||||
public int getColumnNumber()
|
||||
{
|
||||
return columnNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link RhinoException#lineSource()} from the super class.
|
||||
*/
|
||||
public String getLineSource()
|
||||
{
|
||||
return lineSource();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// API class
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* This is interface that all functions in JavaScript must implement.
|
||||
* The interface provides for calling functions and constructors.
|
||||
*
|
||||
* @see org.mozilla.javascript.Scriptable
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
|
||||
public interface Function extends Scriptable, Callable
|
||||
{
|
||||
/**
|
||||
* Call the function.
|
||||
*
|
||||
* Note that the array of arguments is not guaranteed to have
|
||||
* length greater than 0.
|
||||
*
|
||||
* @param cx the current Context for this thread
|
||||
* @param scope the scope to execute the function relative to. This is
|
||||
* set to the value returned by getParentScope() except
|
||||
* when the function is called from a closure.
|
||||
* @param thisObj the JavaScript <code>this</code> object
|
||||
* @param args the array of arguments
|
||||
* @return the result of the call
|
||||
*/
|
||||
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
|
||||
Object[] args);
|
||||
|
||||
/**
|
||||
* Call the function as a constructor.
|
||||
*
|
||||
* This method is invoked by the runtime in order to satisfy a use
|
||||
* of the JavaScript <code>new</code> operator. This method is
|
||||
* expected to create a new object and return it.
|
||||
*
|
||||
* @param cx the current Context for this thread
|
||||
* @param scope an enclosing scope of the caller except
|
||||
* when the function is called from a closure.
|
||||
* @param args the array of arguments
|
||||
* @return the allocated object
|
||||
*/
|
||||
public Scriptable construct(Context cx, Scriptable scope, Object[] args);
|
||||
}
|
||||
@@ -1,572 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Igor Bukanov
|
||||
* David C. Navas
|
||||
* Ted Neward
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// API class
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.io.*;
|
||||
|
||||
public class FunctionObject extends BaseFunction
|
||||
{
|
||||
static final long serialVersionUID = -5332312783643935019L;
|
||||
|
||||
/**
|
||||
* Create a JavaScript function object from a Java method.
|
||||
*
|
||||
* <p>The <code>member</code> argument must be either a java.lang.reflect.Method
|
||||
* or a java.lang.reflect.Constructor and must match one of two forms.<p>
|
||||
*
|
||||
* The first form is a member with zero or more parameters
|
||||
* of the following types: Object, String, boolean, Scriptable,
|
||||
* int, or double. The Long type is not supported
|
||||
* because the double representation of a long (which is the
|
||||
* EMCA-mandated storage type for Numbers) may lose precision.
|
||||
* If the member is a Method, the return value must be void or one
|
||||
* of the types allowed for parameters.<p>
|
||||
*
|
||||
* The runtime will perform appropriate conversions based
|
||||
* upon the type of the parameter. A parameter type of
|
||||
* Object specifies that no conversions are to be done. A parameter
|
||||
* of type String will use Context.toString to convert arguments.
|
||||
* Similarly, parameters of type double, boolean, and Scriptable
|
||||
* will cause Context.toNumber, Context.toBoolean, and
|
||||
* Context.toObject, respectively, to be called.<p>
|
||||
*
|
||||
* If the method is not static, the Java 'this' value will
|
||||
* correspond to the JavaScript 'this' value. Any attempt
|
||||
* to call the function with a 'this' value that is not
|
||||
* of the right Java type will result in an error.<p>
|
||||
*
|
||||
* The second form is the variable arguments (or "varargs")
|
||||
* form. If the FunctionObject will be used as a constructor,
|
||||
* the member must have the following parameters
|
||||
* <pre>
|
||||
* (Context cx, Object[] args, Function ctorObj,
|
||||
* boolean inNewExpr)</pre>
|
||||
* and if it is a Method, be static and return an Object result.<p>
|
||||
*
|
||||
* Otherwise, if the FunctionObject will <i>not</i> be used to define a
|
||||
* constructor, the member must be a static Method with parameters
|
||||
* (Context cx, Scriptable thisObj, Object[] args,
|
||||
* Function funObj) </pre>
|
||||
* <pre>
|
||||
* and an Object result.<p>
|
||||
*
|
||||
* When the function varargs form is called as part of a function call,
|
||||
* the <code>args</code> parameter contains the
|
||||
* arguments, with <code>thisObj</code>
|
||||
* set to the JavaScript 'this' value. <code>funObj</code>
|
||||
* is the function object for the invoked function.<p>
|
||||
*
|
||||
* When the constructor varargs form is called or invoked while evaluating
|
||||
* a <code>new</code> expression, <code>args</code> contains the
|
||||
* arguments, <code>ctorObj</code> refers to this FunctionObject, and
|
||||
* <code>inNewExpr</code> is true if and only if a <code>new</code>
|
||||
* expression caused the call. This supports defining a function that
|
||||
* has different behavior when called as a constructor than when
|
||||
* invoked as a normal function call. (For example, the Boolean
|
||||
* constructor, when called as a function,
|
||||
* will convert to boolean rather than creating a new object.)<p>
|
||||
*
|
||||
* @param name the name of the function
|
||||
* @param methodOrConstructor a java.lang.reflect.Method or a java.lang.reflect.Constructor
|
||||
* that defines the object
|
||||
* @param scope enclosing scope of function
|
||||
* @see org.mozilla.javascript.Scriptable
|
||||
*/
|
||||
public FunctionObject(String name, Member methodOrConstructor,
|
||||
Scriptable scope)
|
||||
{
|
||||
if (methodOrConstructor instanceof Constructor) {
|
||||
member = new MemberBox((Constructor<?>) methodOrConstructor);
|
||||
isStatic = true; // well, doesn't take a 'this'
|
||||
} else {
|
||||
member = new MemberBox((Method) methodOrConstructor);
|
||||
isStatic = member.isStatic();
|
||||
}
|
||||
String methodName = member.getName();
|
||||
this.functionName = name;
|
||||
Class<?>[] types = member.argTypes;
|
||||
int arity = types.length;
|
||||
if (arity == 4 && (types[1].isArray() || types[2].isArray())) {
|
||||
// Either variable args or an error.
|
||||
if (types[1].isArray()) {
|
||||
if (!isStatic ||
|
||||
types[0] != ScriptRuntime.ContextClass ||
|
||||
types[1].getComponentType() != ScriptRuntime.ObjectClass ||
|
||||
types[2] != ScriptRuntime.FunctionClass ||
|
||||
types[3] != Boolean.TYPE)
|
||||
{
|
||||
throw Context.reportRuntimeError1(
|
||||
"msg.varargs.ctor", methodName);
|
||||
}
|
||||
parmsLength = VARARGS_CTOR;
|
||||
} else {
|
||||
if (!isStatic ||
|
||||
types[0] != ScriptRuntime.ContextClass ||
|
||||
types[1] != ScriptRuntime.ScriptableClass ||
|
||||
types[2].getComponentType() != ScriptRuntime.ObjectClass ||
|
||||
types[3] != ScriptRuntime.FunctionClass)
|
||||
{
|
||||
throw Context.reportRuntimeError1(
|
||||
"msg.varargs.fun", methodName);
|
||||
}
|
||||
parmsLength = VARARGS_METHOD;
|
||||
}
|
||||
} else {
|
||||
parmsLength = arity;
|
||||
if (arity > 0) {
|
||||
typeTags = new byte[arity];
|
||||
for (int i = 0; i != arity; ++i) {
|
||||
int tag = getTypeTag(types[i]);
|
||||
if (tag == JAVA_UNSUPPORTED_TYPE) {
|
||||
throw Context.reportRuntimeError2(
|
||||
"msg.bad.parms", types[i].getName(), methodName);
|
||||
}
|
||||
typeTags[i] = (byte)tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (member.isMethod()) {
|
||||
Method method = member.method();
|
||||
Class<?> returnType = method.getReturnType();
|
||||
if (returnType == Void.TYPE) {
|
||||
hasVoidReturn = true;
|
||||
} else {
|
||||
returnTypeTag = getTypeTag(returnType);
|
||||
}
|
||||
} else {
|
||||
Class<?> ctorType = member.getDeclaringClass();
|
||||
if (!ScriptRuntime.ScriptableClass.isAssignableFrom(ctorType)) {
|
||||
throw Context.reportRuntimeError1(
|
||||
"msg.bad.ctor.return", ctorType.getName());
|
||||
}
|
||||
}
|
||||
|
||||
ScriptRuntime.setFunctionProtoAndParent(this, scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return One of <tt>JAVA_*_TYPE</tt> constants to indicate desired type
|
||||
* or {@link #JAVA_UNSUPPORTED_TYPE} if the convertion is not
|
||||
* possible
|
||||
*/
|
||||
public static int getTypeTag(Class<?> type)
|
||||
{
|
||||
if (type == ScriptRuntime.StringClass)
|
||||
return JAVA_STRING_TYPE;
|
||||
if (type == ScriptRuntime.IntegerClass || type == Integer.TYPE)
|
||||
return JAVA_INT_TYPE;
|
||||
if (type == ScriptRuntime.BooleanClass || type == Boolean.TYPE)
|
||||
return JAVA_BOOLEAN_TYPE;
|
||||
if (type == ScriptRuntime.DoubleClass || type == Double.TYPE)
|
||||
return JAVA_DOUBLE_TYPE;
|
||||
if (ScriptRuntime.ScriptableClass.isAssignableFrom(type))
|
||||
return JAVA_SCRIPTABLE_TYPE;
|
||||
if (type == ScriptRuntime.ObjectClass)
|
||||
return JAVA_OBJECT_TYPE;
|
||||
|
||||
// Note that the long type is not supported; see the javadoc for
|
||||
// the constructor for this class
|
||||
|
||||
return JAVA_UNSUPPORTED_TYPE;
|
||||
}
|
||||
|
||||
public static Object convertArg(Context cx, Scriptable scope,
|
||||
Object arg, int typeTag)
|
||||
{
|
||||
switch (typeTag) {
|
||||
case JAVA_STRING_TYPE:
|
||||
if (arg instanceof String)
|
||||
return arg;
|
||||
return ScriptRuntime.toString(arg);
|
||||
case JAVA_INT_TYPE:
|
||||
if (arg instanceof Integer)
|
||||
return arg;
|
||||
return Integer.valueOf(ScriptRuntime.toInt32(arg));
|
||||
case JAVA_BOOLEAN_TYPE:
|
||||
if (arg instanceof Boolean)
|
||||
return arg;
|
||||
return ScriptRuntime.toBoolean(arg) ? Boolean.TRUE
|
||||
: Boolean.FALSE;
|
||||
case JAVA_DOUBLE_TYPE:
|
||||
if (arg instanceof Double)
|
||||
return arg;
|
||||
return new Double(ScriptRuntime.toNumber(arg));
|
||||
case JAVA_SCRIPTABLE_TYPE:
|
||||
return ScriptRuntime.toObjectOrNull(cx, arg, scope);
|
||||
case JAVA_OBJECT_TYPE:
|
||||
return arg;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value defined by the method used to construct the object
|
||||
* (number of parameters of the method, or 1 if the method is a "varargs"
|
||||
* form).
|
||||
*/
|
||||
@Override
|
||||
public int getArity() {
|
||||
return parmsLength < 0 ? 1 : parmsLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the same value as {@link #getArity()}.
|
||||
*/
|
||||
@Override
|
||||
public int getLength() {
|
||||
return getArity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFunctionName()
|
||||
{
|
||||
return (functionName == null) ? "" : functionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Java method or constructor this function represent.
|
||||
*/
|
||||
public Member getMethodOrConstructor()
|
||||
{
|
||||
if (member.isMethod()) {
|
||||
return member.method();
|
||||
} else {
|
||||
return member.ctor();
|
||||
}
|
||||
}
|
||||
|
||||
static Method findSingleMethod(Method[] methods, String name)
|
||||
{
|
||||
Method found = null;
|
||||
for (int i = 0, N = methods.length; i != N; ++i) {
|
||||
Method method = methods[i];
|
||||
if (method != null && name.equals(method.getName())) {
|
||||
if (found != null) {
|
||||
throw Context.reportRuntimeError2(
|
||||
"msg.no.overload", name,
|
||||
method.getDeclaringClass().getName());
|
||||
}
|
||||
found = method;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all public methods declared by the specified class. This excludes
|
||||
* inherited methods.
|
||||
*
|
||||
* @param clazz the class from which to pull public declared methods
|
||||
* @return the public methods declared in the specified class
|
||||
* @see Class#getDeclaredMethods()
|
||||
*/
|
||||
static Method[] getMethodList(Class<?> clazz) {
|
||||
Method[] methods = null;
|
||||
try {
|
||||
// getDeclaredMethods may be rejected by the security manager
|
||||
// but getMethods is more expensive
|
||||
if (!sawSecurityException)
|
||||
methods = clazz.getDeclaredMethods();
|
||||
} catch (SecurityException e) {
|
||||
// If we get an exception once, give up on getDeclaredMethods
|
||||
sawSecurityException = true;
|
||||
}
|
||||
if (methods == null) {
|
||||
methods = clazz.getMethods();
|
||||
}
|
||||
int count = 0;
|
||||
for (int i=0; i < methods.length; i++) {
|
||||
if (sawSecurityException
|
||||
? methods[i].getDeclaringClass() != clazz
|
||||
: !Modifier.isPublic(methods[i].getModifiers()))
|
||||
{
|
||||
methods[i] = null;
|
||||
} else {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
Method[] result = new Method[count];
|
||||
int j=0;
|
||||
for (int i=0; i < methods.length; i++) {
|
||||
if (methods[i] != null)
|
||||
result[j++] = methods[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define this function as a JavaScript constructor.
|
||||
* <p>
|
||||
* Sets up the "prototype" and "constructor" properties. Also
|
||||
* calls setParent and setPrototype with appropriate values.
|
||||
* Then adds the function object as a property of the given scope, using
|
||||
* <code>prototype.getClassName()</code>
|
||||
* as the name of the property.
|
||||
*
|
||||
* @param scope the scope in which to define the constructor (typically
|
||||
* the global object)
|
||||
* @param prototype the prototype object
|
||||
* @see org.mozilla.javascript.Scriptable#setParentScope
|
||||
* @see org.mozilla.javascript.Scriptable#setPrototype
|
||||
* @see org.mozilla.javascript.Scriptable#getClassName
|
||||
*/
|
||||
public void addAsConstructor(Scriptable scope, Scriptable prototype)
|
||||
{
|
||||
initAsConstructor(scope, prototype);
|
||||
defineProperty(scope, prototype.getClassName(),
|
||||
this, ScriptableObject.DONTENUM);
|
||||
}
|
||||
|
||||
void initAsConstructor(Scriptable scope, Scriptable prototype)
|
||||
{
|
||||
ScriptRuntime.setFunctionProtoAndParent(this, scope);
|
||||
setImmunePrototypeProperty(prototype);
|
||||
|
||||
prototype.setParentScope(this);
|
||||
|
||||
defineProperty(prototype, "constructor", this,
|
||||
ScriptableObject.DONTENUM |
|
||||
ScriptableObject.PERMANENT |
|
||||
ScriptableObject.READONLY);
|
||||
setParentScope(scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getTypeTag(Class)}
|
||||
* and {@link #convertArg(Context, Scriptable, Object, int)}
|
||||
* for type conversion.
|
||||
*/
|
||||
public static Object convertArg(Context cx, Scriptable scope,
|
||||
Object arg, Class<?> desired)
|
||||
{
|
||||
int tag = getTypeTag(desired);
|
||||
if (tag == JAVA_UNSUPPORTED_TYPE) {
|
||||
throw Context.reportRuntimeError1
|
||||
("msg.cant.convert", desired.getName());
|
||||
}
|
||||
return convertArg(cx, scope, arg, tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs conversions on argument types if needed and
|
||||
* invokes the underlying Java method or constructor.
|
||||
* <p>
|
||||
* Implements Function.call.
|
||||
*
|
||||
* @see org.mozilla.javascript.Function#call(
|
||||
* Context, Scriptable, Scriptable, Object[])
|
||||
*/
|
||||
@Override
|
||||
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
|
||||
Object[] args)
|
||||
{
|
||||
Object result;
|
||||
boolean checkMethodResult = false;
|
||||
|
||||
if (parmsLength < 0) {
|
||||
if (parmsLength == VARARGS_METHOD) {
|
||||
Object[] invokeArgs = { cx, thisObj, args, this };
|
||||
result = member.invoke(null, invokeArgs);
|
||||
checkMethodResult = true;
|
||||
} else {
|
||||
boolean inNewExpr = (thisObj == null);
|
||||
Boolean b = inNewExpr ? Boolean.TRUE : Boolean.FALSE;
|
||||
Object[] invokeArgs = { cx, args, this, b };
|
||||
result = (member.isCtor())
|
||||
? member.newInstance(invokeArgs)
|
||||
: member.invoke(null, invokeArgs);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!isStatic) {
|
||||
Class<?> clazz = member.getDeclaringClass();
|
||||
if (!clazz.isInstance(thisObj)) {
|
||||
boolean compatible = false;
|
||||
if (thisObj == scope) {
|
||||
Scriptable parentScope = getParentScope();
|
||||
if (scope != parentScope) {
|
||||
// Call with dynamic scope for standalone function,
|
||||
// use parentScope as thisObj
|
||||
compatible = clazz.isInstance(parentScope);
|
||||
if (compatible) {
|
||||
thisObj = parentScope;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!compatible) {
|
||||
// Couldn't find an object to call this on.
|
||||
throw ScriptRuntime.typeError1("msg.incompat.call",
|
||||
functionName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object[] invokeArgs;
|
||||
if (parmsLength == args.length) {
|
||||
// Do not allocate new argument array if java arguments are
|
||||
// the same as the original js ones.
|
||||
invokeArgs = args;
|
||||
for (int i = 0; i != parmsLength; ++i) {
|
||||
Object arg = args[i];
|
||||
Object converted = convertArg(cx, scope, arg, typeTags[i]);
|
||||
if (arg != converted) {
|
||||
if (invokeArgs == args) {
|
||||
invokeArgs = args.clone();
|
||||
}
|
||||
invokeArgs[i] = converted;
|
||||
}
|
||||
}
|
||||
} else if (parmsLength == 0) {
|
||||
invokeArgs = ScriptRuntime.emptyArgs;
|
||||
} else {
|
||||
invokeArgs = new Object[parmsLength];
|
||||
for (int i = 0; i != parmsLength; ++i) {
|
||||
Object arg = (i < args.length)
|
||||
? args[i]
|
||||
: Undefined.instance;
|
||||
invokeArgs[i] = convertArg(cx, scope, arg, typeTags[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (member.isMethod()) {
|
||||
result = member.invoke(thisObj, invokeArgs);
|
||||
checkMethodResult = true;
|
||||
} else {
|
||||
result = member.newInstance(invokeArgs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (checkMethodResult) {
|
||||
if (hasVoidReturn) {
|
||||
result = Undefined.instance;
|
||||
} else if (returnTypeTag == JAVA_UNSUPPORTED_TYPE) {
|
||||
result = cx.getWrapFactory().wrap(cx, scope, result, null);
|
||||
}
|
||||
// XXX: the code assumes that if returnTypeTag == JAVA_OBJECT_TYPE
|
||||
// then the Java method did a proper job of converting the
|
||||
// result to JS primitive or Scriptable to avoid
|
||||
// potentially costly Context.javaToJS call.
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return new {@link Scriptable} instance using the default
|
||||
* constructor for the class of the underlying Java method.
|
||||
* Return null to indicate that the call method should be used to create
|
||||
* new objects.
|
||||
*/
|
||||
@Override
|
||||
public Scriptable createObject(Context cx, Scriptable scope) {
|
||||
if (member.isCtor() || parmsLength == VARARGS_CTOR) {
|
||||
return null;
|
||||
}
|
||||
Scriptable result;
|
||||
try {
|
||||
result = (Scriptable) member.getDeclaringClass().newInstance();
|
||||
} catch (Exception ex) {
|
||||
throw Context.throwAsScriptRuntimeEx(ex);
|
||||
}
|
||||
|
||||
result.setPrototype(getClassPrototype());
|
||||
result.setParentScope(getParentScope());
|
||||
return result;
|
||||
}
|
||||
|
||||
boolean isVarArgsMethod() {
|
||||
return parmsLength == VARARGS_METHOD;
|
||||
}
|
||||
|
||||
boolean isVarArgsConstructor() {
|
||||
return parmsLength == VARARGS_CTOR;
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
in.defaultReadObject();
|
||||
if (parmsLength > 0) {
|
||||
Class<?>[] types = member.argTypes;
|
||||
typeTags = new byte[parmsLength];
|
||||
for (int i = 0; i != parmsLength; ++i) {
|
||||
typeTags[i] = (byte)getTypeTag(types[i]);
|
||||
}
|
||||
}
|
||||
if (member.isMethod()) {
|
||||
Method method = member.method();
|
||||
Class<?> returnType = method.getReturnType();
|
||||
if (returnType == Void.TYPE) {
|
||||
hasVoidReturn = true;
|
||||
} else {
|
||||
returnTypeTag = getTypeTag(returnType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final short VARARGS_METHOD = -1;
|
||||
private static final short VARARGS_CTOR = -2;
|
||||
|
||||
private static boolean sawSecurityException;
|
||||
|
||||
public static final int JAVA_UNSUPPORTED_TYPE = 0;
|
||||
public static final int JAVA_STRING_TYPE = 1;
|
||||
public static final int JAVA_INT_TYPE = 2;
|
||||
public static final int JAVA_BOOLEAN_TYPE = 3;
|
||||
public static final int JAVA_DOUBLE_TYPE = 4;
|
||||
public static final int JAVA_SCRIPTABLE_TYPE = 5;
|
||||
public static final int JAVA_OBJECT_TYPE = 6;
|
||||
|
||||
MemberBox member;
|
||||
private String functionName;
|
||||
private transient byte[] typeTags;
|
||||
private int parmsLength;
|
||||
private transient boolean hasVoidReturn;
|
||||
private transient int returnTypeTag;
|
||||
private boolean isStatic;
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// API class
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* Interface to define classes from generated byte code.
|
||||
*/
|
||||
public interface GeneratedClassLoader {
|
||||
|
||||
/**
|
||||
* Define a new Java class.
|
||||
* Classes created via this method should have the same class loader.
|
||||
*
|
||||
* @param name fully qualified class name
|
||||
* @param data class byte code
|
||||
* @return new class object
|
||||
*/
|
||||
public Class<?> defineClass(String name, byte[] data);
|
||||
|
||||
/**
|
||||
* Link the given class.
|
||||
*
|
||||
* @param cl Class instance returned from the previous call to
|
||||
* {@link #defineClass(String, byte[])}
|
||||
* @see java.lang.ClassLoader
|
||||
*/
|
||||
public void linkClass(Class<?> cl);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,279 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mike Ang
|
||||
* Igor Bukanov
|
||||
* Yuh-Ruey Chen
|
||||
* Ethan Hugg
|
||||
* Bob Jervis
|
||||
* Terry Lucas
|
||||
* Mike McCabe
|
||||
* Milen Nankov
|
||||
* Norris Boyd
|
||||
* Steve Yegge
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* Additional interpreter-specific codes
|
||||
*/
|
||||
abstract class Icode {
|
||||
|
||||
static final int
|
||||
|
||||
// Stack: ... value1 -> ... value1 value1
|
||||
Icode_DUP = -1,
|
||||
|
||||
// Stack: ... value2 value1 -> ... value2 value1 value2 value1
|
||||
Icode_DUP2 = -2,
|
||||
|
||||
// Stack: ... value2 value1 -> ... value1 value2
|
||||
Icode_SWAP = -3,
|
||||
|
||||
// Stack: ... value1 -> ...
|
||||
Icode_POP = -4,
|
||||
|
||||
// Store stack top into return register and then pop it
|
||||
Icode_POP_RESULT = -5,
|
||||
|
||||
// To jump conditionally and pop additional stack value
|
||||
Icode_IFEQ_POP = -6,
|
||||
|
||||
// various types of ++/--
|
||||
Icode_VAR_INC_DEC = -7,
|
||||
Icode_NAME_INC_DEC = -8,
|
||||
Icode_PROP_INC_DEC = -9,
|
||||
Icode_ELEM_INC_DEC = -10,
|
||||
Icode_REF_INC_DEC = -11,
|
||||
|
||||
// load/save scope from/to local
|
||||
Icode_SCOPE_LOAD = -12,
|
||||
Icode_SCOPE_SAVE = -13,
|
||||
|
||||
Icode_TYPEOFNAME = -14,
|
||||
|
||||
// helper for function calls
|
||||
Icode_NAME_AND_THIS = -15,
|
||||
Icode_PROP_AND_THIS = -16,
|
||||
Icode_ELEM_AND_THIS = -17,
|
||||
Icode_VALUE_AND_THIS = -18,
|
||||
|
||||
// Create closure object for nested functions
|
||||
Icode_CLOSURE_EXPR = -19,
|
||||
Icode_CLOSURE_STMT = -20,
|
||||
|
||||
// Special calls
|
||||
Icode_CALLSPECIAL = -21,
|
||||
|
||||
// To return undefined value
|
||||
Icode_RETUNDEF = -22,
|
||||
|
||||
// Exception handling implementation
|
||||
Icode_GOSUB = -23,
|
||||
Icode_STARTSUB = -24,
|
||||
Icode_RETSUB = -25,
|
||||
|
||||
// To indicating a line number change in icodes.
|
||||
Icode_LINE = -26,
|
||||
|
||||
// To store shorts and ints inline
|
||||
Icode_SHORTNUMBER = -27,
|
||||
Icode_INTNUMBER = -28,
|
||||
|
||||
// To create and populate array to hold values for [] and {} literals
|
||||
Icode_LITERAL_NEW = -29,
|
||||
Icode_LITERAL_SET = -30,
|
||||
|
||||
// Array literal with skipped index like [1,,2]
|
||||
Icode_SPARE_ARRAYLIT = -31,
|
||||
|
||||
// Load index register to prepare for the following index operation
|
||||
Icode_REG_IND_C0 = -32,
|
||||
Icode_REG_IND_C1 = -33,
|
||||
Icode_REG_IND_C2 = -34,
|
||||
Icode_REG_IND_C3 = -35,
|
||||
Icode_REG_IND_C4 = -36,
|
||||
Icode_REG_IND_C5 = -37,
|
||||
Icode_REG_IND1 = -38,
|
||||
Icode_REG_IND2 = -39,
|
||||
Icode_REG_IND4 = -40,
|
||||
|
||||
// Load string register to prepare for the following string operation
|
||||
Icode_REG_STR_C0 = -41,
|
||||
Icode_REG_STR_C1 = -42,
|
||||
Icode_REG_STR_C2 = -43,
|
||||
Icode_REG_STR_C3 = -44,
|
||||
Icode_REG_STR1 = -45,
|
||||
Icode_REG_STR2 = -46,
|
||||
Icode_REG_STR4 = -47,
|
||||
|
||||
// Version of getvar/setvar that read var index directly from bytecode
|
||||
Icode_GETVAR1 = -48,
|
||||
Icode_SETVAR1 = -49,
|
||||
|
||||
// Load unefined
|
||||
Icode_UNDEF = -50,
|
||||
Icode_ZERO = -51,
|
||||
Icode_ONE = -52,
|
||||
|
||||
// entrance and exit from .()
|
||||
Icode_ENTERDQ = -53,
|
||||
Icode_LEAVEDQ = -54,
|
||||
|
||||
Icode_TAIL_CALL = -55,
|
||||
|
||||
// Clear local to allow GC its context
|
||||
Icode_LOCAL_CLEAR = -56,
|
||||
|
||||
// Literal get/set
|
||||
Icode_LITERAL_GETTER = -57,
|
||||
Icode_LITERAL_SETTER = -58,
|
||||
|
||||
// const
|
||||
Icode_SETCONST = -59,
|
||||
Icode_SETCONSTVAR = -60,
|
||||
Icode_SETCONSTVAR1 = -61,
|
||||
|
||||
// Generator opcodes (along with Token.YIELD)
|
||||
Icode_GENERATOR = -62,
|
||||
Icode_GENERATOR_END = -63,
|
||||
|
||||
Icode_DEBUGGER = -64,
|
||||
|
||||
// Last icode
|
||||
MIN_ICODE = -64;
|
||||
|
||||
static String bytecodeName(int bytecode)
|
||||
{
|
||||
if (!validBytecode(bytecode)) {
|
||||
throw new IllegalArgumentException(String.valueOf(bytecode));
|
||||
}
|
||||
|
||||
if (!Token.printICode) {
|
||||
return String.valueOf(bytecode);
|
||||
}
|
||||
|
||||
if (validTokenCode(bytecode)) {
|
||||
return Token.name(bytecode);
|
||||
}
|
||||
|
||||
switch (bytecode) {
|
||||
case Icode_DUP: return "DUP";
|
||||
case Icode_DUP2: return "DUP2";
|
||||
case Icode_SWAP: return "SWAP";
|
||||
case Icode_POP: return "POP";
|
||||
case Icode_POP_RESULT: return "POP_RESULT";
|
||||
case Icode_IFEQ_POP: return "IFEQ_POP";
|
||||
case Icode_VAR_INC_DEC: return "VAR_INC_DEC";
|
||||
case Icode_NAME_INC_DEC: return "NAME_INC_DEC";
|
||||
case Icode_PROP_INC_DEC: return "PROP_INC_DEC";
|
||||
case Icode_ELEM_INC_DEC: return "ELEM_INC_DEC";
|
||||
case Icode_REF_INC_DEC: return "REF_INC_DEC";
|
||||
case Icode_SCOPE_LOAD: return "SCOPE_LOAD";
|
||||
case Icode_SCOPE_SAVE: return "SCOPE_SAVE";
|
||||
case Icode_TYPEOFNAME: return "TYPEOFNAME";
|
||||
case Icode_NAME_AND_THIS: return "NAME_AND_THIS";
|
||||
case Icode_PROP_AND_THIS: return "PROP_AND_THIS";
|
||||
case Icode_ELEM_AND_THIS: return "ELEM_AND_THIS";
|
||||
case Icode_VALUE_AND_THIS: return "VALUE_AND_THIS";
|
||||
case Icode_CLOSURE_EXPR: return "CLOSURE_EXPR";
|
||||
case Icode_CLOSURE_STMT: return "CLOSURE_STMT";
|
||||
case Icode_CALLSPECIAL: return "CALLSPECIAL";
|
||||
case Icode_RETUNDEF: return "RETUNDEF";
|
||||
case Icode_GOSUB: return "GOSUB";
|
||||
case Icode_STARTSUB: return "STARTSUB";
|
||||
case Icode_RETSUB: return "RETSUB";
|
||||
case Icode_LINE: return "LINE";
|
||||
case Icode_SHORTNUMBER: return "SHORTNUMBER";
|
||||
case Icode_INTNUMBER: return "INTNUMBER";
|
||||
case Icode_LITERAL_NEW: return "LITERAL_NEW";
|
||||
case Icode_LITERAL_SET: return "LITERAL_SET";
|
||||
case Icode_SPARE_ARRAYLIT: return "SPARE_ARRAYLIT";
|
||||
case Icode_REG_IND_C0: return "REG_IND_C0";
|
||||
case Icode_REG_IND_C1: return "REG_IND_C1";
|
||||
case Icode_REG_IND_C2: return "REG_IND_C2";
|
||||
case Icode_REG_IND_C3: return "REG_IND_C3";
|
||||
case Icode_REG_IND_C4: return "REG_IND_C4";
|
||||
case Icode_REG_IND_C5: return "REG_IND_C5";
|
||||
case Icode_REG_IND1: return "LOAD_IND1";
|
||||
case Icode_REG_IND2: return "LOAD_IND2";
|
||||
case Icode_REG_IND4: return "LOAD_IND4";
|
||||
case Icode_REG_STR_C0: return "REG_STR_C0";
|
||||
case Icode_REG_STR_C1: return "REG_STR_C1";
|
||||
case Icode_REG_STR_C2: return "REG_STR_C2";
|
||||
case Icode_REG_STR_C3: return "REG_STR_C3";
|
||||
case Icode_REG_STR1: return "LOAD_STR1";
|
||||
case Icode_REG_STR2: return "LOAD_STR2";
|
||||
case Icode_REG_STR4: return "LOAD_STR4";
|
||||
case Icode_GETVAR1: return "GETVAR1";
|
||||
case Icode_SETVAR1: return "SETVAR1";
|
||||
case Icode_UNDEF: return "UNDEF";
|
||||
case Icode_ZERO: return "ZERO";
|
||||
case Icode_ONE: return "ONE";
|
||||
case Icode_ENTERDQ: return "ENTERDQ";
|
||||
case Icode_LEAVEDQ: return "LEAVEDQ";
|
||||
case Icode_TAIL_CALL: return "TAIL_CALL";
|
||||
case Icode_LOCAL_CLEAR: return "LOCAL_CLEAR";
|
||||
case Icode_LITERAL_GETTER: return "LITERAL_GETTER";
|
||||
case Icode_LITERAL_SETTER: return "LITERAL_SETTER";
|
||||
case Icode_SETCONST: return "SETCONST";
|
||||
case Icode_SETCONSTVAR: return "SETCONSTVAR";
|
||||
case Icode_SETCONSTVAR1: return "SETCONSTVAR1";
|
||||
case Icode_GENERATOR: return "GENERATOR";
|
||||
case Icode_GENERATOR_END: return "GENERATOR_END";
|
||||
case Icode_DEBUGGER: return "DEBUGGER";
|
||||
}
|
||||
|
||||
// icode without name
|
||||
throw new IllegalStateException(String.valueOf(bytecode));
|
||||
}
|
||||
|
||||
static boolean validIcode(int icode)
|
||||
{
|
||||
return MIN_ICODE <= icode && icode <= -1;
|
||||
}
|
||||
|
||||
static boolean validTokenCode(int token)
|
||||
{
|
||||
return Token.FIRST_BYTECODE_TOKEN <= token
|
||||
&& token <= Token.LAST_BYTECODE_TOKEN;
|
||||
}
|
||||
|
||||
static boolean validBytecode(int bytecode)
|
||||
{
|
||||
return validIcode(bytecode) || validTokenCode(bytecode);
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* Master for id-based functions that knows their properties and how to
|
||||
* execute them.
|
||||
*/
|
||||
public interface IdFunctionCall
|
||||
{
|
||||
/**
|
||||
* 'thisObj' will be null if invoked as constructor, in which case
|
||||
* instance of Scriptable should be returned
|
||||
*/
|
||||
public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// API class
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
public class IdFunctionObject extends BaseFunction
|
||||
{
|
||||
|
||||
static final long serialVersionUID = -5332312783643935019L;
|
||||
|
||||
public IdFunctionObject(IdFunctionCall idcall, Object tag, int id, int arity)
|
||||
{
|
||||
if (arity < 0)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.idcall = idcall;
|
||||
this.tag = tag;
|
||||
this.methodId = id;
|
||||
this.arity = arity;
|
||||
if (arity < 0) throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
public IdFunctionObject(IdFunctionCall idcall, Object tag, int id,
|
||||
String name, int arity, Scriptable scope)
|
||||
{
|
||||
super(scope, null);
|
||||
|
||||
if (arity < 0)
|
||||
throw new IllegalArgumentException();
|
||||
if (name == null)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.idcall = idcall;
|
||||
this.tag = tag;
|
||||
this.methodId = id;
|
||||
this.arity = arity;
|
||||
this.functionName = name;
|
||||
}
|
||||
|
||||
public void initFunction(String name, Scriptable scope)
|
||||
{
|
||||
if (name == null) throw new IllegalArgumentException();
|
||||
if (scope == null) throw new IllegalArgumentException();
|
||||
this.functionName = name;
|
||||
setParentScope(scope);
|
||||
}
|
||||
|
||||
public final boolean hasTag(Object tag)
|
||||
{
|
||||
return this.tag == tag;
|
||||
}
|
||||
|
||||
public final int methodId()
|
||||
{
|
||||
return methodId;
|
||||
}
|
||||
|
||||
public final void markAsConstructor(Scriptable prototypeProperty)
|
||||
{
|
||||
useCallAsConstructor = true;
|
||||
setImmunePrototypeProperty(prototypeProperty);
|
||||
}
|
||||
|
||||
public final void addAsProperty(Scriptable target)
|
||||
{
|
||||
ScriptableObject.defineProperty(target, functionName, this,
|
||||
ScriptableObject.DONTENUM);
|
||||
}
|
||||
|
||||
public void exportAsScopeProperty()
|
||||
{
|
||||
addAsProperty(getParentScope());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scriptable getPrototype()
|
||||
{
|
||||
// Lazy initialization of prototype: for native functions this
|
||||
// may not be called at all
|
||||
Scriptable proto = super.getPrototype();
|
||||
if (proto == null) {
|
||||
proto = getFunctionPrototype(getParentScope());
|
||||
setPrototype(proto);
|
||||
}
|
||||
return proto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
|
||||
Object[] args)
|
||||
{
|
||||
return idcall.execIdCall(this, cx, scope, thisObj, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scriptable createObject(Context cx, Scriptable scope)
|
||||
{
|
||||
if (useCallAsConstructor) {
|
||||
return null;
|
||||
}
|
||||
// Throw error if not explicitly coded to be used as constructor,
|
||||
// to satisfy ECMAScript standard (see bugzilla 202019).
|
||||
// To follow current (2003-05-01) SpiderMonkey behavior, change it to:
|
||||
// return super.createObject(cx, scope);
|
||||
throw ScriptRuntime.typeError1("msg.not.ctor", functionName);
|
||||
}
|
||||
|
||||
@Override
|
||||
String decompile(int indent, int flags)
|
||||
{
|
||||
StringBuffer sb = new StringBuffer();
|
||||
boolean justbody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
|
||||
if (!justbody) {
|
||||
sb.append("function ");
|
||||
sb.append(getFunctionName());
|
||||
sb.append("() { ");
|
||||
}
|
||||
sb.append("[native code for ");
|
||||
if (idcall instanceof Scriptable) {
|
||||
Scriptable sobj = (Scriptable)idcall;
|
||||
sb.append(sobj.getClassName());
|
||||
sb.append('.');
|
||||
}
|
||||
sb.append(getFunctionName());
|
||||
sb.append(", arity=");
|
||||
sb.append(getArity());
|
||||
sb.append(justbody ? "]\n" : "] }\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArity()
|
||||
{
|
||||
return arity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() { return getArity(); }
|
||||
|
||||
@Override
|
||||
public String getFunctionName()
|
||||
{
|
||||
return (functionName == null) ? "" : functionName;
|
||||
}
|
||||
|
||||
public final RuntimeException unknown()
|
||||
{
|
||||
// It is program error to call id-like methods for unknown function
|
||||
return new IllegalArgumentException(
|
||||
"BAD FUNCTION ID="+methodId+" MASTER="+idcall);
|
||||
}
|
||||
|
||||
private final IdFunctionCall idcall;
|
||||
private final Object tag;
|
||||
private final int methodId;
|
||||
private int arity;
|
||||
private boolean useCallAsConstructor;
|
||||
private String functionName;
|
||||
}
|
||||
@@ -1,741 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 4; indent-tabs-mode: 1; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
Base class for native object implementation that uses IdFunctionObject to export its methods to script via <class-name>.prototype object.
|
||||
|
||||
Any descendant should implement at least the following methods:
|
||||
findInstanceIdInfo
|
||||
getInstanceIdName
|
||||
execIdCall
|
||||
methodArity
|
||||
|
||||
To define non-function properties, the descendant should override
|
||||
getInstanceIdValue
|
||||
setInstanceIdValue
|
||||
to get/set property value and provide its default attributes.
|
||||
|
||||
|
||||
To customize initializition of constructor and protype objects, descendant
|
||||
may override scopeInit or fillConstructorProperties methods.
|
||||
|
||||
*/
|
||||
public abstract class IdScriptableObject extends ScriptableObject
|
||||
implements IdFunctionCall
|
||||
{
|
||||
private transient volatile PrototypeValues prototypeValues;
|
||||
|
||||
private static final class PrototypeValues implements Serializable
|
||||
{
|
||||
static final long serialVersionUID = 3038645279153854371L;
|
||||
|
||||
private static final int VALUE_SLOT = 0;
|
||||
private static final int NAME_SLOT = 1;
|
||||
private static final int SLOT_SPAN = 2;
|
||||
|
||||
private IdScriptableObject obj;
|
||||
private int maxId;
|
||||
private volatile Object[] valueArray;
|
||||
private volatile short[] attributeArray;
|
||||
private volatile int lastFoundId = 1;
|
||||
|
||||
// The following helps to avoid creation of valueArray during runtime
|
||||
// initialization for common case of "constructor" property
|
||||
int constructorId;
|
||||
private IdFunctionObject constructor;
|
||||
private short constructorAttrs;
|
||||
|
||||
PrototypeValues(IdScriptableObject obj, int maxId)
|
||||
{
|
||||
if (obj == null) throw new IllegalArgumentException();
|
||||
if (maxId < 1) throw new IllegalArgumentException();
|
||||
this.obj = obj;
|
||||
this.maxId = maxId;
|
||||
}
|
||||
|
||||
final int getMaxId()
|
||||
{
|
||||
return maxId;
|
||||
}
|
||||
|
||||
final void initValue(int id, String name, Object value, int attributes)
|
||||
{
|
||||
if (!(1 <= id && id <= maxId))
|
||||
throw new IllegalArgumentException();
|
||||
if (name == null)
|
||||
throw new IllegalArgumentException();
|
||||
if (value == NOT_FOUND)
|
||||
throw new IllegalArgumentException();
|
||||
ScriptableObject.checkValidAttributes(attributes);
|
||||
if (obj.findPrototypeId(name) != id)
|
||||
throw new IllegalArgumentException(name);
|
||||
|
||||
if (id == constructorId) {
|
||||
if (!(value instanceof IdFunctionObject)) {
|
||||
throw new IllegalArgumentException("consructor should be initialized with IdFunctionObject");
|
||||
}
|
||||
constructor = (IdFunctionObject)value;
|
||||
constructorAttrs = (short)attributes;
|
||||
return;
|
||||
}
|
||||
|
||||
initSlot(id, name, value, attributes);
|
||||
}
|
||||
|
||||
private void initSlot(int id, String name, Object value,
|
||||
int attributes)
|
||||
{
|
||||
Object[] array = valueArray;
|
||||
if (array == null)
|
||||
throw new IllegalStateException();
|
||||
|
||||
if (value == null) {
|
||||
value = UniqueTag.NULL_VALUE;
|
||||
}
|
||||
int index = (id - 1) * SLOT_SPAN;
|
||||
synchronized (this) {
|
||||
Object value2 = array[index + VALUE_SLOT];
|
||||
if (value2 == null) {
|
||||
array[index + VALUE_SLOT] = value;
|
||||
array[index + NAME_SLOT] = name;
|
||||
attributeArray[id - 1] = (short)attributes;
|
||||
} else {
|
||||
if (!name.equals(array[index + NAME_SLOT]))
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final IdFunctionObject createPrecachedConstructor()
|
||||
{
|
||||
if (constructorId != 0) throw new IllegalStateException();
|
||||
constructorId = obj.findPrototypeId("constructor");
|
||||
if (constructorId == 0) {
|
||||
throw new IllegalStateException(
|
||||
"No id for constructor property");
|
||||
}
|
||||
obj.initPrototypeId(constructorId);
|
||||
if (constructor == null) {
|
||||
throw new IllegalStateException(
|
||||
obj.getClass().getName()+".initPrototypeId() did not "
|
||||
+"initialize id="+constructorId);
|
||||
}
|
||||
constructor.initFunction(obj.getClassName(),
|
||||
ScriptableObject.getTopLevelScope(obj));
|
||||
constructor.markAsConstructor(obj);
|
||||
return constructor;
|
||||
}
|
||||
|
||||
final int findId(String name)
|
||||
{
|
||||
Object[] array = valueArray;
|
||||
if (array == null) {
|
||||
return obj.findPrototypeId(name);
|
||||
}
|
||||
int id = lastFoundId;
|
||||
if (name == array[(id - 1) * SLOT_SPAN + NAME_SLOT]) {
|
||||
return id;
|
||||
}
|
||||
id = obj.findPrototypeId(name);
|
||||
if (id != 0) {
|
||||
int nameSlot = (id - 1) * SLOT_SPAN + NAME_SLOT;
|
||||
// Make cache to work!
|
||||
array[nameSlot] = name;
|
||||
lastFoundId = id;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
final boolean has(int id)
|
||||
{
|
||||
Object[] array = valueArray;
|
||||
if (array == null) {
|
||||
// Not yet initialized, assume all exists
|
||||
return true;
|
||||
}
|
||||
int valueSlot = (id - 1) * SLOT_SPAN + VALUE_SLOT;
|
||||
Object value = array[valueSlot];
|
||||
if (value == null) {
|
||||
// The particular entry has not been yet initialized
|
||||
return true;
|
||||
}
|
||||
return value != NOT_FOUND;
|
||||
}
|
||||
|
||||
final Object get(int id)
|
||||
{
|
||||
Object value = ensureId(id);
|
||||
if (value == UniqueTag.NULL_VALUE) {
|
||||
value = null;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
final void set(int id, Scriptable start, Object value)
|
||||
{
|
||||
if (value == NOT_FOUND) throw new IllegalArgumentException();
|
||||
ensureId(id);
|
||||
int attr = attributeArray[id - 1];
|
||||
if ((attr & READONLY) == 0) {
|
||||
if (start == obj) {
|
||||
if (value == null) {
|
||||
value = UniqueTag.NULL_VALUE;
|
||||
}
|
||||
int valueSlot = (id - 1) * SLOT_SPAN + VALUE_SLOT;
|
||||
synchronized (this) {
|
||||
valueArray[valueSlot] = value;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int nameSlot = (id - 1) * SLOT_SPAN + NAME_SLOT;
|
||||
String name = (String)valueArray[nameSlot];
|
||||
start.put(name, start, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final void delete(int id)
|
||||
{
|
||||
ensureId(id);
|
||||
int attr = attributeArray[id - 1];
|
||||
if ((attr & PERMANENT) == 0) {
|
||||
int valueSlot = (id - 1) * SLOT_SPAN + VALUE_SLOT;
|
||||
synchronized (this) {
|
||||
valueArray[valueSlot] = NOT_FOUND;
|
||||
attributeArray[id - 1] = EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final int getAttributes(int id)
|
||||
{
|
||||
ensureId(id);
|
||||
return attributeArray[id - 1];
|
||||
}
|
||||
|
||||
final void setAttributes(int id, int attributes)
|
||||
{
|
||||
ScriptableObject.checkValidAttributes(attributes);
|
||||
ensureId(id);
|
||||
synchronized (this) {
|
||||
attributeArray[id - 1] = (short)attributes;
|
||||
}
|
||||
}
|
||||
|
||||
final Object[] getNames(boolean getAll, Object[] extraEntries)
|
||||
{
|
||||
Object[] names = null;
|
||||
int count = 0;
|
||||
for (int id = 1; id <= maxId; ++id) {
|
||||
Object value = ensureId(id);
|
||||
if (getAll || (attributeArray[id - 1] & DONTENUM) == 0) {
|
||||
if (value != NOT_FOUND) {
|
||||
int nameSlot = (id - 1) * SLOT_SPAN + NAME_SLOT;
|
||||
String name = (String)valueArray[nameSlot];
|
||||
if (names == null) {
|
||||
names = new Object[maxId];
|
||||
}
|
||||
names[count++] = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count == 0) {
|
||||
return extraEntries;
|
||||
} else if (extraEntries == null || extraEntries.length == 0) {
|
||||
if (count != names.length) {
|
||||
Object[] tmp = new Object[count];
|
||||
System.arraycopy(names, 0, tmp, 0, count);
|
||||
names = tmp;
|
||||
}
|
||||
return names;
|
||||
} else {
|
||||
int extra = extraEntries.length;
|
||||
Object[] tmp = new Object[extra + count];
|
||||
System.arraycopy(extraEntries, 0, tmp, 0, extra);
|
||||
System.arraycopy(names, 0, tmp, extra, count);
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
private Object ensureId(int id)
|
||||
{
|
||||
Object[] array = valueArray;
|
||||
if (array == null) {
|
||||
synchronized (this) {
|
||||
array = valueArray;
|
||||
if (array == null) {
|
||||
array = new Object[maxId * SLOT_SPAN];
|
||||
valueArray = array;
|
||||
attributeArray = new short[maxId];
|
||||
}
|
||||
}
|
||||
}
|
||||
int valueSlot = (id - 1) * SLOT_SPAN + VALUE_SLOT;
|
||||
Object value = array[valueSlot];
|
||||
if (value == null) {
|
||||
if (id == constructorId) {
|
||||
initSlot(constructorId, "constructor",
|
||||
constructor, constructorAttrs);
|
||||
constructor = null; // no need to refer it any longer
|
||||
} else {
|
||||
obj.initPrototypeId(id);
|
||||
}
|
||||
value = array[valueSlot];
|
||||
if (value == null) {
|
||||
throw new IllegalStateException(
|
||||
obj.getClass().getName()+".initPrototypeId(int id) "
|
||||
+"did not initialize id="+id);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public IdScriptableObject()
|
||||
{
|
||||
}
|
||||
|
||||
public IdScriptableObject(Scriptable scope, Scriptable prototype)
|
||||
{
|
||||
super(scope, prototype);
|
||||
}
|
||||
|
||||
protected final Object defaultGet(String name)
|
||||
{
|
||||
return super.get(name, this);
|
||||
}
|
||||
|
||||
protected final void defaultPut(String name, Object value)
|
||||
{
|
||||
super.put(name, this, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(String name, Scriptable start)
|
||||
{
|
||||
int info = findInstanceIdInfo(name);
|
||||
if (info != 0) {
|
||||
int attr = (info >>> 16);
|
||||
if ((attr & PERMANENT) != 0) {
|
||||
return true;
|
||||
}
|
||||
int id = (info & 0xFFFF);
|
||||
return NOT_FOUND != getInstanceIdValue(id);
|
||||
}
|
||||
if (prototypeValues != null) {
|
||||
int id = prototypeValues.findId(name);
|
||||
if (id != 0) {
|
||||
return prototypeValues.has(id);
|
||||
}
|
||||
}
|
||||
return super.has(name, start);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String name, Scriptable start)
|
||||
{
|
||||
int info = findInstanceIdInfo(name);
|
||||
if (info != 0) {
|
||||
int id = (info & 0xFFFF);
|
||||
return getInstanceIdValue(id);
|
||||
}
|
||||
if (prototypeValues != null) {
|
||||
int id = prototypeValues.findId(name);
|
||||
if (id != 0) {
|
||||
return prototypeValues.get(id);
|
||||
}
|
||||
}
|
||||
return super.get(name, start);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(String name, Scriptable start, Object value)
|
||||
{
|
||||
int info = findInstanceIdInfo(name);
|
||||
if (info != 0) {
|
||||
if (start == this && isSealed()) {
|
||||
throw Context.reportRuntimeError1("msg.modify.sealed",
|
||||
name);
|
||||
}
|
||||
int attr = (info >>> 16);
|
||||
if ((attr & READONLY) == 0) {
|
||||
if (start == this) {
|
||||
int id = (info & 0xFFFF);
|
||||
setInstanceIdValue(id, value);
|
||||
}
|
||||
else {
|
||||
start.put(name, start, value);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (prototypeValues != null) {
|
||||
int id = prototypeValues.findId(name);
|
||||
if (id != 0) {
|
||||
if (start == this && isSealed()) {
|
||||
throw Context.reportRuntimeError1("msg.modify.sealed",
|
||||
name);
|
||||
}
|
||||
prototypeValues.set(id, start, value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.put(name, start, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String name)
|
||||
{
|
||||
int info = findInstanceIdInfo(name);
|
||||
if (info != 0) {
|
||||
// Let the super class to throw exceptions for sealed objects
|
||||
if (!isSealed()) {
|
||||
int attr = (info >>> 16);
|
||||
if ((attr & PERMANENT) == 0) {
|
||||
int id = (info & 0xFFFF);
|
||||
setInstanceIdValue(id, NOT_FOUND);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (prototypeValues != null) {
|
||||
int id = prototypeValues.findId(name);
|
||||
if (id != 0) {
|
||||
if (!isSealed()) {
|
||||
prototypeValues.delete(id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.delete(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAttributes(String name)
|
||||
{
|
||||
int info = findInstanceIdInfo(name);
|
||||
if (info != 0) {
|
||||
int attr = (info >>> 16);
|
||||
return attr;
|
||||
}
|
||||
if (prototypeValues != null) {
|
||||
int id = prototypeValues.findId(name);
|
||||
if (id != 0) {
|
||||
return prototypeValues.getAttributes(id);
|
||||
}
|
||||
}
|
||||
return super.getAttributes(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttributes(String name, int attributes)
|
||||
{
|
||||
ScriptableObject.checkValidAttributes(attributes);
|
||||
int info = findInstanceIdInfo(name);
|
||||
if (info != 0) {
|
||||
int currentAttributes = (info >>> 16);
|
||||
if (attributes != currentAttributes) {
|
||||
throw new RuntimeException(
|
||||
"Change of attributes for this id is not supported");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (prototypeValues != null) {
|
||||
int id = prototypeValues.findId(name);
|
||||
if (id != 0) {
|
||||
prototypeValues.setAttributes(id, attributes);
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.setAttributes(name, attributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
Object[] getIds(boolean getAll)
|
||||
{
|
||||
Object[] result = super.getIds(getAll);
|
||||
|
||||
if (prototypeValues != null) {
|
||||
result = prototypeValues.getNames(getAll, result);
|
||||
}
|
||||
|
||||
int maxInstanceId = getMaxInstanceId();
|
||||
if (maxInstanceId != 0) {
|
||||
Object[] ids = null;
|
||||
int count = 0;
|
||||
|
||||
for (int id = maxInstanceId; id != 0; --id) {
|
||||
String name = getInstanceIdName(id);
|
||||
int info = findInstanceIdInfo(name);
|
||||
if (info != 0) {
|
||||
int attr = (info >>> 16);
|
||||
if ((attr & PERMANENT) == 0) {
|
||||
if (NOT_FOUND == getInstanceIdValue(id)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (getAll || (attr & DONTENUM) == 0) {
|
||||
if (count == 0) {
|
||||
// Need extra room for no more then [1..id] names
|
||||
ids = new Object[id];
|
||||
}
|
||||
ids[count++] = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count != 0) {
|
||||
if (result.length == 0 && ids.length == count) {
|
||||
result = ids;
|
||||
}
|
||||
else {
|
||||
Object[] tmp = new Object[result.length + count];
|
||||
System.arraycopy(result, 0, tmp, 0, result.length);
|
||||
System.arraycopy(ids, 0, tmp, result.length, count);
|
||||
result = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get maximum id findInstanceIdInfo can generate.
|
||||
*/
|
||||
protected int getMaxInstanceId()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected static int instanceIdInfo(int attributes, int id)
|
||||
{
|
||||
return (attributes << 16) | id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map name to id of instance property.
|
||||
* Should return 0 if not found or the result of
|
||||
* {@link #instanceIdInfo(int, int)}.
|
||||
*/
|
||||
protected int findInstanceIdInfo(String name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Map id back to property name it defines.
|
||||
*/
|
||||
protected String getInstanceIdName(int id)
|
||||
{
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
/** Get id value.
|
||||
** If id value is constant, descendant can call cacheIdValue to store
|
||||
** value in the permanent cache.
|
||||
** Default implementation creates IdFunctionObject instance for given id
|
||||
** and cache its value
|
||||
*/
|
||||
protected Object getInstanceIdValue(int id)
|
||||
{
|
||||
throw new IllegalStateException(String.valueOf(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or delete id value. If value == NOT_FOUND , the implementation
|
||||
* should make sure that the following getInstanceIdValue return NOT_FOUND.
|
||||
*/
|
||||
protected void setInstanceIdValue(int id, Object value)
|
||||
{
|
||||
throw new IllegalStateException(String.valueOf(id));
|
||||
}
|
||||
|
||||
/** 'thisObj' will be null if invoked as constructor, in which case
|
||||
** instance of Scriptable should be returned. */
|
||||
public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
throw f.unknown();
|
||||
}
|
||||
|
||||
public final IdFunctionObject exportAsJSClass(int maxPrototypeId,
|
||||
Scriptable scope,
|
||||
boolean sealed)
|
||||
{
|
||||
// Set scope and prototype unless this is top level scope itself
|
||||
if (scope != this && scope != null) {
|
||||
setParentScope(scope);
|
||||
setPrototype(getObjectPrototype(scope));
|
||||
}
|
||||
|
||||
activatePrototypeMap(maxPrototypeId);
|
||||
IdFunctionObject ctor = prototypeValues.createPrecachedConstructor();
|
||||
if (sealed) {
|
||||
sealObject();
|
||||
}
|
||||
fillConstructorProperties(ctor);
|
||||
if (sealed) {
|
||||
ctor.sealObject();
|
||||
}
|
||||
ctor.exportAsScopeProperty();
|
||||
return ctor;
|
||||
}
|
||||
|
||||
public final boolean hasPrototypeMap()
|
||||
{
|
||||
return prototypeValues != null;
|
||||
}
|
||||
|
||||
public final void activatePrototypeMap(int maxPrototypeId)
|
||||
{
|
||||
PrototypeValues values = new PrototypeValues(this, maxPrototypeId);
|
||||
synchronized (this) {
|
||||
if (prototypeValues != null)
|
||||
throw new IllegalStateException();
|
||||
prototypeValues = values;
|
||||
}
|
||||
}
|
||||
|
||||
public final void initPrototypeMethod(Object tag, int id, String name,
|
||||
int arity)
|
||||
{
|
||||
Scriptable scope = ScriptableObject.getTopLevelScope(this);
|
||||
IdFunctionObject f = newIdFunction(tag, id, name, arity, scope);
|
||||
prototypeValues.initValue(id, name, f, DONTENUM);
|
||||
}
|
||||
|
||||
public final void initPrototypeConstructor(IdFunctionObject f)
|
||||
{
|
||||
int id = prototypeValues.constructorId;
|
||||
if (id == 0)
|
||||
throw new IllegalStateException();
|
||||
if (f.methodId() != id)
|
||||
throw new IllegalArgumentException();
|
||||
if (isSealed()) { f.sealObject(); }
|
||||
prototypeValues.initValue(id, "constructor", f, DONTENUM);
|
||||
}
|
||||
|
||||
public final void initPrototypeValue(int id, String name, Object value,
|
||||
int attributes)
|
||||
{
|
||||
prototypeValues.initValue(id, name, value, attributes);
|
||||
}
|
||||
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
throw new IllegalStateException(String.valueOf(id));
|
||||
}
|
||||
|
||||
protected int findPrototypeId(String name)
|
||||
{
|
||||
throw new IllegalStateException(name);
|
||||
}
|
||||
|
||||
protected void fillConstructorProperties(IdFunctionObject ctor)
|
||||
{
|
||||
}
|
||||
|
||||
protected void addIdFunctionProperty(Scriptable obj, Object tag, int id,
|
||||
String name, int arity)
|
||||
{
|
||||
Scriptable scope = ScriptableObject.getTopLevelScope(obj);
|
||||
IdFunctionObject f = newIdFunction(tag, id, name, arity, scope);
|
||||
f.addAsProperty(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to construct type error to indicate incompatible call
|
||||
* when converting script thisObj to a particular type is not possible.
|
||||
* Possible usage would be to have a private function like realThis:
|
||||
* <pre>
|
||||
* private static NativeSomething realThis(Scriptable thisObj,
|
||||
* IdFunctionObject f)
|
||||
* {
|
||||
* if (!(thisObj instanceof NativeSomething))
|
||||
* throw incompatibleCallError(f);
|
||||
* return (NativeSomething)thisObj;
|
||||
* }
|
||||
* </pre>
|
||||
* Note that although such function can be implemented universally via
|
||||
* java.lang.Class.isInstance(), it would be much more slower.
|
||||
* @param f function that is attempting to convert 'this'
|
||||
* object.
|
||||
* @return Scriptable object suitable for a check by the instanceof
|
||||
* operator.
|
||||
* @throws RuntimeException if no more instanceof target can be found
|
||||
*/
|
||||
protected static EcmaError incompatibleCallError(IdFunctionObject f)
|
||||
{
|
||||
throw ScriptRuntime.typeError1("msg.incompat.call",
|
||||
f.getFunctionName());
|
||||
}
|
||||
|
||||
private IdFunctionObject newIdFunction(Object tag, int id, String name,
|
||||
int arity, Scriptable scope)
|
||||
{
|
||||
IdFunctionObject f = new IdFunctionObject(this, tag, id, name, arity,
|
||||
scope);
|
||||
if (isSealed()) { f.sealObject(); }
|
||||
return f;
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream stream)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
stream.defaultReadObject();
|
||||
int maxPrototypeId = stream.readInt();
|
||||
if (maxPrototypeId != 0) {
|
||||
activatePrototypeMap(maxPrototypeId);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream stream)
|
||||
throws IOException
|
||||
{
|
||||
stream.defaultWriteObject();
|
||||
int maxPrototypeId = 0;
|
||||
if (prototypeValues != null) {
|
||||
maxPrototypeId = prototypeValues.getMaxId();
|
||||
}
|
||||
stream.writeInt(maxPrototypeId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,324 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Igor Bukanov
|
||||
* Matthias Radestock
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// API class
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* Class ImporterTopLevel
|
||||
*
|
||||
* This class defines a ScriptableObject that can be instantiated
|
||||
* as a top-level ("global") object to provide functionality similar
|
||||
* to Java's "import" statement.
|
||||
* <p>
|
||||
* This class can be used to create a top-level scope using the following code:
|
||||
* <pre>
|
||||
* Scriptable scope = new ImporterTopLevel(cx);
|
||||
* </pre>
|
||||
* Then JavaScript code will have access to the following methods:
|
||||
* <ul>
|
||||
* <li>importClass - will "import" a class by making its unqualified name
|
||||
* available as a property of the top-level scope
|
||||
* <li>importPackage - will "import" all the classes of the package by
|
||||
* searching for unqualified names as classes qualified
|
||||
* by the given package.
|
||||
* </ul>
|
||||
* The following code from the shell illustrates this use:
|
||||
* <pre>
|
||||
* js> importClass(java.io.File)
|
||||
* js> f = new File('help.txt')
|
||||
* help.txt
|
||||
* js> importPackage(java.util)
|
||||
* js> v = new Vector()
|
||||
* []
|
||||
*
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
public class ImporterTopLevel extends IdScriptableObject
|
||||
{
|
||||
static final long serialVersionUID = -9095380847465315412L;
|
||||
|
||||
private static final Object IMPORTER_TAG = "Importer";
|
||||
|
||||
public ImporterTopLevel() { }
|
||||
|
||||
public ImporterTopLevel(Context cx) {
|
||||
this(cx, false);
|
||||
}
|
||||
|
||||
public ImporterTopLevel(Context cx, boolean sealed)
|
||||
{
|
||||
initStandardObjects(cx, sealed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName()
|
||||
{
|
||||
return (topScopeFlag) ? "global" : "JavaImporter";
|
||||
}
|
||||
|
||||
public static void init(Context cx, Scriptable scope, boolean sealed)
|
||||
{
|
||||
ImporterTopLevel obj = new ImporterTopLevel();
|
||||
obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
|
||||
}
|
||||
|
||||
public void initStandardObjects(Context cx, boolean sealed)
|
||||
{
|
||||
// Assume that Context.initStandardObjects initialize JavaImporter
|
||||
// property lazily so the above init call is not yet called
|
||||
cx.initStandardObjects(this, sealed);
|
||||
topScopeFlag = true;
|
||||
// If seal is true then exportAsJSClass(cx, seal) would seal
|
||||
// this obj. Since this is scope as well, it would not allow
|
||||
// to add variables.
|
||||
IdFunctionObject ctor = exportAsJSClass(MAX_PROTOTYPE_ID, this, false);
|
||||
if (sealed) {
|
||||
ctor.sealObject();
|
||||
}
|
||||
// delete "constructor" defined by exportAsJSClass so "constructor"
|
||||
// name would refer to Object.constructor
|
||||
// and not to JavaImporter.prototype.constructor.
|
||||
delete("constructor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(String name, Scriptable start) {
|
||||
return super.has(name, start)
|
||||
|| getPackageProperty(name, start) != NOT_FOUND;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String name, Scriptable start) {
|
||||
Object result = super.get(name, start);
|
||||
if (result != NOT_FOUND)
|
||||
return result;
|
||||
result = getPackageProperty(name, start);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Object getPackageProperty(String name, Scriptable start) {
|
||||
Object result = NOT_FOUND;
|
||||
Object[] elements;
|
||||
synchronized (importedPackages) {
|
||||
elements = importedPackages.toArray();
|
||||
}
|
||||
for (int i=0; i < elements.length; i++) {
|
||||
NativeJavaPackage p = (NativeJavaPackage) elements[i];
|
||||
Object v = p.getPkgProperty(name, start, false);
|
||||
if (v != null && !(v instanceof NativeJavaPackage)) {
|
||||
if (result == NOT_FOUND) {
|
||||
result = v;
|
||||
} else {
|
||||
throw Context.reportRuntimeError2(
|
||||
"msg.ambig.import", result.toString(), v.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Kept only for compatibility.
|
||||
*/
|
||||
public void importPackage(Context cx, Scriptable thisObj, Object[] args,
|
||||
Function funObj)
|
||||
{
|
||||
js_importPackage(args);
|
||||
}
|
||||
|
||||
private Object js_construct(Scriptable scope, Object[] args)
|
||||
{
|
||||
ImporterTopLevel result = new ImporterTopLevel();
|
||||
for (int i = 0; i != args.length; ++i) {
|
||||
Object arg = args[i];
|
||||
if (arg instanceof NativeJavaClass) {
|
||||
result.importClass((NativeJavaClass)arg);
|
||||
} else if (arg instanceof NativeJavaPackage) {
|
||||
result.importPackage((NativeJavaPackage)arg);
|
||||
} else {
|
||||
throw Context.reportRuntimeError1(
|
||||
"msg.not.class.not.pkg", Context.toString(arg));
|
||||
}
|
||||
}
|
||||
// set explicitly prototype and scope
|
||||
// as otherwise in top scope mode BaseFunction.construct
|
||||
// would keep them set to null. It also allow to use
|
||||
// JavaImporter without new and still get properly
|
||||
// initialized object.
|
||||
result.setParentScope(scope);
|
||||
result.setPrototype(this);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Object js_importClass(Object[] args)
|
||||
{
|
||||
for (int i = 0; i != args.length; i++) {
|
||||
Object arg = args[i];
|
||||
if (!(arg instanceof NativeJavaClass)) {
|
||||
throw Context.reportRuntimeError1(
|
||||
"msg.not.class", Context.toString(arg));
|
||||
}
|
||||
importClass((NativeJavaClass)arg);
|
||||
}
|
||||
return Undefined.instance;
|
||||
}
|
||||
|
||||
private Object js_importPackage(Object[] args)
|
||||
{
|
||||
for (int i = 0; i != args.length; i++) {
|
||||
Object arg = args[i];
|
||||
if (!(arg instanceof NativeJavaPackage)) {
|
||||
throw Context.reportRuntimeError1(
|
||||
"msg.not.pkg", Context.toString(arg));
|
||||
}
|
||||
importPackage((NativeJavaPackage)arg);
|
||||
}
|
||||
return Undefined.instance;
|
||||
}
|
||||
|
||||
private void importPackage(NativeJavaPackage pkg)
|
||||
{
|
||||
if(pkg == null) {
|
||||
return;
|
||||
}
|
||||
synchronized (importedPackages) {
|
||||
for (int j = 0; j != importedPackages.size(); j++) {
|
||||
if (pkg.equals(importedPackages.get(j))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
importedPackages.add(pkg);
|
||||
}
|
||||
}
|
||||
|
||||
private void importClass(NativeJavaClass cl)
|
||||
{
|
||||
String s = cl.getClassObject().getName();
|
||||
String n = s.substring(s.lastIndexOf('.')+1);
|
||||
Object val = get(n, this);
|
||||
if (val != NOT_FOUND && val != cl) {
|
||||
throw Context.reportRuntimeError1("msg.prop.defined", n);
|
||||
}
|
||||
//defineProperty(n, cl, DONTENUM);
|
||||
put(n, this, cl);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_constructor: arity=0; s="constructor"; break;
|
||||
case Id_importClass: arity=1; s="importClass"; break;
|
||||
case Id_importPackage: arity=1; s="importPackage"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(IMPORTER_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (!f.hasTag(IMPORTER_TAG)) {
|
||||
return super.execIdCall(f, cx, scope, thisObj, args);
|
||||
}
|
||||
int id = f.methodId();
|
||||
switch (id) {
|
||||
case Id_constructor:
|
||||
return js_construct(scope, args);
|
||||
|
||||
case Id_importClass:
|
||||
return realThis(thisObj, f).js_importClass(args);
|
||||
|
||||
case Id_importPackage:
|
||||
return realThis(thisObj, f).js_importPackage(args);
|
||||
}
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
private ImporterTopLevel realThis(Scriptable thisObj, IdFunctionObject f)
|
||||
{
|
||||
if (topScopeFlag) {
|
||||
// when used as top scope importPackage and importClass are global
|
||||
// function that ignore thisObj
|
||||
return this;
|
||||
}
|
||||
if (!(thisObj instanceof ImporterTopLevel))
|
||||
throw incompatibleCallError(f);
|
||||
return (ImporterTopLevel)thisObj;
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
@Override
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2007-05-09 08:15:24 EDT
|
||||
L0: { id = 0; String X = null; int c;
|
||||
int s_length = s.length();
|
||||
if (s_length==11) {
|
||||
c=s.charAt(0);
|
||||
if (c=='c') { X="constructor";id=Id_constructor; }
|
||||
else if (c=='i') { X="importClass";id=Id_importClass; }
|
||||
}
|
||||
else if (s_length==13) { X="importPackage";id=Id_importPackage; }
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
break L0;
|
||||
}
|
||||
// #/generated#
|
||||
return id;
|
||||
}
|
||||
|
||||
private static final int
|
||||
Id_constructor = 1,
|
||||
Id_importClass = 2,
|
||||
Id_importPackage = 3,
|
||||
MAX_PROTOTYPE_ID = 3;
|
||||
|
||||
// #/string_id_map#
|
||||
|
||||
private ObjArray importedPackages = new ObjArray();
|
||||
private boolean topScopeFlag;
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Adapter to use JS function as implementation of Java interfaces with
|
||||
* single method or multiple methods with the same signature.
|
||||
*/
|
||||
public class InterfaceAdapter
|
||||
{
|
||||
private final Object proxyHelper;
|
||||
|
||||
/**
|
||||
* Make glue object implementing interface cl that will
|
||||
* call the supplied JS function when called.
|
||||
* Only interfaces were all methods have the same signature is supported.
|
||||
*
|
||||
* @return The glue object or null if <tt>cl</tt> is not interface or
|
||||
* has methods with different signatures.
|
||||
*/
|
||||
static Object create(Context cx, Class<?> cl, Callable function)
|
||||
{
|
||||
if (!cl.isInterface()) throw new IllegalArgumentException();
|
||||
|
||||
Scriptable topScope = ScriptRuntime.getTopCallScope(cx);
|
||||
ClassCache cache = ClassCache.get(topScope);
|
||||
InterfaceAdapter adapter;
|
||||
adapter = (InterfaceAdapter)cache.getInterfaceAdapter(cl);
|
||||
ContextFactory cf = cx.getFactory();
|
||||
if (adapter == null) {
|
||||
Method[] methods = cl.getMethods();
|
||||
if (methods.length == 0) {
|
||||
throw Context.reportRuntimeError2(
|
||||
"msg.no.empty.interface.conversion",
|
||||
String.valueOf(function),
|
||||
cl.getClass().getName());
|
||||
}
|
||||
boolean canCallFunction = false;
|
||||
canCallFunctionChecks: {
|
||||
Class<?>[] argTypes = methods[0].getParameterTypes();
|
||||
// check that the rest of methods has the same signature
|
||||
for (int i = 1; i != methods.length; ++i) {
|
||||
Class<?>[] types2 = methods[i].getParameterTypes();
|
||||
if (types2.length != argTypes.length) {
|
||||
break canCallFunctionChecks;
|
||||
}
|
||||
for (int j = 0; j != argTypes.length; ++j) {
|
||||
if (types2[j] != argTypes[j]) {
|
||||
break canCallFunctionChecks;
|
||||
}
|
||||
}
|
||||
}
|
||||
canCallFunction= true;
|
||||
}
|
||||
if (!canCallFunction) {
|
||||
throw Context.reportRuntimeError2(
|
||||
"msg.no.function.interface.conversion",
|
||||
String.valueOf(function),
|
||||
cl.getClass().getName());
|
||||
}
|
||||
adapter = new InterfaceAdapter(cf, cl);
|
||||
cache.cacheInterfaceAdapter(cl, adapter);
|
||||
}
|
||||
return VMBridge.instance.newInterfaceProxy(
|
||||
adapter.proxyHelper, cf, adapter, function, topScope);
|
||||
}
|
||||
|
||||
private InterfaceAdapter(ContextFactory cf, Class<?> cl)
|
||||
{
|
||||
this.proxyHelper
|
||||
= VMBridge.instance.getInterfaceProxyHelper(
|
||||
cf, new Class[] { cl });
|
||||
}
|
||||
|
||||
public Object invoke(ContextFactory cf,
|
||||
final Object target,
|
||||
final Scriptable topScope,
|
||||
final Method method,
|
||||
final Object[] args)
|
||||
{
|
||||
ContextAction action = new ContextAction() {
|
||||
public Object run(Context cx)
|
||||
{
|
||||
return invokeImpl(cx, target, topScope, method, args);
|
||||
}
|
||||
};
|
||||
return cf.call(action);
|
||||
}
|
||||
|
||||
Object invokeImpl(Context cx,
|
||||
Object target,
|
||||
Scriptable topScope,
|
||||
Method method,
|
||||
Object[] args)
|
||||
{
|
||||
int N = (args == null) ? 0 : args.length;
|
||||
|
||||
Callable function = (Callable)target;
|
||||
Scriptable thisObj = topScope;
|
||||
Object[] jsargs = new Object[N + 1];
|
||||
jsargs[N] = method.getName();
|
||||
if (N != 0) {
|
||||
WrapFactory wf = cx.getWrapFactory();
|
||||
for (int i = 0; i != N; ++i) {
|
||||
jsargs[i] = wf.wrap(cx, topScope, args[i], null);
|
||||
}
|
||||
}
|
||||
|
||||
Object result = function.call(cx, topScope, thisObj, jsargs);
|
||||
Class<?> javaResultType = method.getReturnType();
|
||||
if (javaResultType == Void.TYPE) {
|
||||
result = null;
|
||||
} else {
|
||||
result = Context.jsToJava(result, javaResultType);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,235 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov
|
||||
* Bob Jervis
|
||||
* Roger Lawrence
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import org.mozilla.javascript.debug.DebuggableScript;
|
||||
|
||||
final class InterpretedFunction extends NativeFunction implements Script
|
||||
{
|
||||
static final long serialVersionUID = 541475680333911468L;
|
||||
|
||||
InterpreterData idata;
|
||||
SecurityController securityController;
|
||||
Object securityDomain;
|
||||
Scriptable[] functionRegExps;
|
||||
|
||||
private InterpretedFunction(InterpreterData idata,
|
||||
Object staticSecurityDomain)
|
||||
{
|
||||
this.idata = idata;
|
||||
|
||||
// Always get Context from the current thread to
|
||||
// avoid security breaches via passing mangled Context instances
|
||||
// with bogus SecurityController
|
||||
Context cx = Context.getContext();
|
||||
SecurityController sc = cx.getSecurityController();
|
||||
Object dynamicDomain;
|
||||
if (sc != null) {
|
||||
dynamicDomain = sc.getDynamicSecurityDomain(staticSecurityDomain);
|
||||
} else {
|
||||
if (staticSecurityDomain != null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
dynamicDomain = null;
|
||||
}
|
||||
|
||||
this.securityController = sc;
|
||||
this.securityDomain = dynamicDomain;
|
||||
}
|
||||
|
||||
private InterpretedFunction(InterpretedFunction parent, int index)
|
||||
{
|
||||
this.idata = parent.idata.itsNestedFunctions[index];
|
||||
this.securityController = parent.securityController;
|
||||
this.securityDomain = parent.securityDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create script from compiled bytecode.
|
||||
*/
|
||||
static InterpretedFunction createScript(InterpreterData idata,
|
||||
Object staticSecurityDomain)
|
||||
{
|
||||
InterpretedFunction f;
|
||||
f = new InterpretedFunction(idata, staticSecurityDomain);
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create function compiled from Function(...) constructor.
|
||||
*/
|
||||
static InterpretedFunction createFunction(Context cx,Scriptable scope,
|
||||
InterpreterData idata,
|
||||
Object staticSecurityDomain)
|
||||
{
|
||||
InterpretedFunction f;
|
||||
f = new InterpretedFunction(idata, staticSecurityDomain);
|
||||
f.initInterpretedFunction(cx, scope);
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create function embedded in script or another function.
|
||||
*/
|
||||
static InterpretedFunction createFunction(Context cx, Scriptable scope,
|
||||
InterpretedFunction parent,
|
||||
int index)
|
||||
{
|
||||
InterpretedFunction f = new InterpretedFunction(parent, index);
|
||||
f.initInterpretedFunction(cx, scope);
|
||||
return f;
|
||||
}
|
||||
|
||||
Scriptable[] createRegExpWraps(Context cx, Scriptable scope)
|
||||
{
|
||||
if (idata.itsRegExpLiterals == null) Kit.codeBug();
|
||||
|
||||
RegExpProxy rep = ScriptRuntime.checkRegExpProxy(cx);
|
||||
int N = idata.itsRegExpLiterals.length;
|
||||
Scriptable[] array = new Scriptable[N];
|
||||
for (int i = 0; i != N; ++i) {
|
||||
array[i] = rep.wrapRegExp(cx, scope, idata.itsRegExpLiterals[i]);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
private void initInterpretedFunction(Context cx, Scriptable scope)
|
||||
{
|
||||
initScriptFunction(cx, scope);
|
||||
if (idata.itsRegExpLiterals != null) {
|
||||
functionRegExps = createRegExpWraps(cx, scope);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFunctionName()
|
||||
{
|
||||
return (idata.itsName == null) ? "" : idata.itsName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the function.
|
||||
* @param cx the current context
|
||||
* @param scope the scope used for the call
|
||||
* @param thisObj the value of "this"
|
||||
* @param args function arguments. Must not be null. You can use
|
||||
* {@link ScriptRuntime#emptyArgs} to pass empty arguments.
|
||||
* @return the result of the function call.
|
||||
*/
|
||||
@Override
|
||||
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
|
||||
Object[] args)
|
||||
{
|
||||
if (!ScriptRuntime.hasTopCall(cx)) {
|
||||
return ScriptRuntime.doTopCall(this, cx, scope, thisObj, args);
|
||||
}
|
||||
return Interpreter.interpret(this, cx, scope, thisObj, args);
|
||||
}
|
||||
|
||||
public Object exec(Context cx, Scriptable scope)
|
||||
{
|
||||
if (!isScript()) {
|
||||
// Can only be applied to scripts
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
if (!ScriptRuntime.hasTopCall(cx)) {
|
||||
// It will go through "call" path. but they are equivalent
|
||||
return ScriptRuntime.doTopCall(
|
||||
this, cx, scope, scope, ScriptRuntime.emptyArgs);
|
||||
}
|
||||
return Interpreter.interpret(
|
||||
this, cx, scope, scope, ScriptRuntime.emptyArgs);
|
||||
}
|
||||
|
||||
public boolean isScript() {
|
||||
return idata.itsFunctionType == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEncodedSource()
|
||||
{
|
||||
return Interpreter.getEncodedSource(idata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DebuggableScript getDebuggableView()
|
||||
{
|
||||
return idata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resumeGenerator(Context cx, Scriptable scope, int operation,
|
||||
Object state, Object value)
|
||||
{
|
||||
return Interpreter.resumeGenerator(cx, scope, operation, state, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLanguageVersion()
|
||||
{
|
||||
return idata.languageVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getParamCount()
|
||||
{
|
||||
return idata.argCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getParamAndVarCount()
|
||||
{
|
||||
return idata.argNames.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getParamOrVarName(int index)
|
||||
{
|
||||
return idata.argNames[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean getParamOrVarConst(int index)
|
||||
{
|
||||
return idata.argIsConst[index];
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,192 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Bob Jervis
|
||||
* Roger Lawrence
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.mozilla.javascript.debug.DebuggableScript;
|
||||
|
||||
final class InterpreterData implements Serializable, DebuggableScript
|
||||
{
|
||||
static final long serialVersionUID = 5067677351589230234L;
|
||||
|
||||
static final int INITIAL_MAX_ICODE_LENGTH = 1024;
|
||||
static final int INITIAL_STRINGTABLE_SIZE = 64;
|
||||
static final int INITIAL_NUMBERTABLE_SIZE = 64;
|
||||
|
||||
InterpreterData(int languageVersion,
|
||||
String sourceFile, String encodedSource)
|
||||
{
|
||||
this.languageVersion = languageVersion;
|
||||
this.itsSourceFile = sourceFile;
|
||||
this.encodedSource = encodedSource;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
InterpreterData(InterpreterData parent)
|
||||
{
|
||||
this.parentData = parent;
|
||||
this.languageVersion = parent.languageVersion;
|
||||
this.itsSourceFile = parent.itsSourceFile;
|
||||
this.encodedSource = parent.encodedSource;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
itsICode = new byte[INITIAL_MAX_ICODE_LENGTH];
|
||||
itsStringTable = new String[INITIAL_STRINGTABLE_SIZE];
|
||||
}
|
||||
|
||||
String itsName;
|
||||
String itsSourceFile;
|
||||
boolean itsNeedsActivation;
|
||||
int itsFunctionType;
|
||||
|
||||
String[] itsStringTable;
|
||||
double[] itsDoubleTable;
|
||||
InterpreterData[] itsNestedFunctions;
|
||||
Object[] itsRegExpLiterals;
|
||||
|
||||
byte[] itsICode;
|
||||
|
||||
int[] itsExceptionTable;
|
||||
|
||||
int itsMaxVars;
|
||||
int itsMaxLocals;
|
||||
int itsMaxStack;
|
||||
int itsMaxFrameArray;
|
||||
|
||||
// see comments in NativeFuncion for definition of argNames and argCount
|
||||
String[] argNames;
|
||||
boolean[] argIsConst;
|
||||
int argCount;
|
||||
|
||||
int itsMaxCalleeArgs;
|
||||
|
||||
String encodedSource;
|
||||
int encodedSourceStart;
|
||||
int encodedSourceEnd;
|
||||
|
||||
int languageVersion;
|
||||
|
||||
boolean useDynamicScope;
|
||||
|
||||
boolean topLevel;
|
||||
|
||||
Object[] literalIds;
|
||||
|
||||
UintMap longJumps;
|
||||
|
||||
int firstLinePC = -1; // PC for the first LINE icode
|
||||
|
||||
InterpreterData parentData;
|
||||
|
||||
boolean evalScriptFlag; // true if script corresponds to eval() code
|
||||
|
||||
public boolean isTopLevel()
|
||||
{
|
||||
return topLevel;
|
||||
}
|
||||
|
||||
public boolean isFunction()
|
||||
{
|
||||
return itsFunctionType != 0;
|
||||
}
|
||||
|
||||
public String getFunctionName()
|
||||
{
|
||||
return itsName;
|
||||
}
|
||||
|
||||
public int getParamCount()
|
||||
{
|
||||
return argCount;
|
||||
}
|
||||
|
||||
public int getParamAndVarCount()
|
||||
{
|
||||
return argNames.length;
|
||||
}
|
||||
|
||||
public String getParamOrVarName(int index)
|
||||
{
|
||||
return argNames[index];
|
||||
}
|
||||
|
||||
public boolean getParamOrVarConst(int index)
|
||||
{
|
||||
return argIsConst[index];
|
||||
}
|
||||
|
||||
public String getSourceName()
|
||||
{
|
||||
return itsSourceFile;
|
||||
}
|
||||
|
||||
public boolean isGeneratedScript()
|
||||
{
|
||||
return ScriptRuntime.isGeneratedScript(itsSourceFile);
|
||||
}
|
||||
|
||||
public int[] getLineNumbers()
|
||||
{
|
||||
return Interpreter.getLineNumbers(this);
|
||||
}
|
||||
|
||||
public int getFunctionCount()
|
||||
{
|
||||
return (itsNestedFunctions == null) ? 0 : itsNestedFunctions.length;
|
||||
}
|
||||
|
||||
public DebuggableScript getFunction(int index)
|
||||
{
|
||||
return itsNestedFunctions[index];
|
||||
}
|
||||
|
||||
public DebuggableScript getParent()
|
||||
{
|
||||
return parentData;
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,932 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Cameron McCormack
|
||||
* Frank Mitchell
|
||||
* Mike Shaver
|
||||
* Kurt Westerfeld
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Mike Shaver
|
||||
* @author Norris Boyd
|
||||
* @see NativeJavaObject
|
||||
* @see NativeJavaClass
|
||||
*/
|
||||
class JavaMembers
|
||||
{
|
||||
JavaMembers(Scriptable scope, Class<?> cl)
|
||||
{
|
||||
this(scope, cl, false);
|
||||
}
|
||||
|
||||
JavaMembers(Scriptable scope, Class<?> cl, boolean includeProtected)
|
||||
{
|
||||
try {
|
||||
Context cx = ContextFactory.getGlobal().enterContext();
|
||||
ClassShutter shutter = cx.getClassShutter();
|
||||
if (shutter != null && !shutter.visibleToScripts(cl.getName())) {
|
||||
throw Context.reportRuntimeError1("msg.access.prohibited",
|
||||
cl.getName());
|
||||
}
|
||||
this.includePrivate = cx.hasFeature(
|
||||
Context.FEATURE_ENHANCED_JAVA_ACCESS);
|
||||
this.members = new HashMap<String,Object>();
|
||||
this.staticMembers = new HashMap<String,Object>();
|
||||
this.cl = cl;
|
||||
reflect(scope, includeProtected);
|
||||
} finally {
|
||||
Context.exit();
|
||||
}
|
||||
}
|
||||
|
||||
boolean has(String name, boolean isStatic)
|
||||
{
|
||||
Map<String,Object> ht = isStatic ? staticMembers : members;
|
||||
Object obj = ht.get(name);
|
||||
if (obj != null) {
|
||||
return true;
|
||||
}
|
||||
return findExplicitFunction(name, isStatic) != null;
|
||||
}
|
||||
|
||||
Object get(Scriptable scope, String name, Object javaObject,
|
||||
boolean isStatic)
|
||||
{
|
||||
Map<String,Object> ht = isStatic ? staticMembers : members;
|
||||
Object member = ht.get(name);
|
||||
if (!isStatic && member == null) {
|
||||
// Try to get static member from instance (LC3)
|
||||
member = staticMembers.get(name);
|
||||
}
|
||||
if (member == null) {
|
||||
member = this.getExplicitFunction(scope, name,
|
||||
javaObject, isStatic);
|
||||
if (member == null)
|
||||
return Scriptable.NOT_FOUND;
|
||||
}
|
||||
if (member instanceof Scriptable) {
|
||||
return member;
|
||||
}
|
||||
Context cx = Context.getContext();
|
||||
Object rval;
|
||||
Class<?> type;
|
||||
try {
|
||||
if (member instanceof BeanProperty) {
|
||||
BeanProperty bp = (BeanProperty) member;
|
||||
if (bp.getter == null)
|
||||
return Scriptable.NOT_FOUND;
|
||||
rval = bp.getter.invoke(javaObject, Context.emptyArgs);
|
||||
type = bp.getter.method().getReturnType();
|
||||
} else {
|
||||
Field field = (Field) member;
|
||||
rval = field.get(isStatic ? null : javaObject);
|
||||
type = field.getType();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw Context.throwAsScriptRuntimeEx(ex);
|
||||
}
|
||||
// Need to wrap the object before we return it.
|
||||
scope = ScriptableObject.getTopLevelScope(scope);
|
||||
return cx.getWrapFactory().wrap(cx, scope, rval, type);
|
||||
}
|
||||
|
||||
void put(Scriptable scope, String name, Object javaObject,
|
||||
Object value, boolean isStatic)
|
||||
{
|
||||
Map<String,Object> ht = isStatic ? staticMembers : members;
|
||||
Object member = ht.get(name);
|
||||
if (!isStatic && member == null) {
|
||||
// Try to get static member from instance (LC3)
|
||||
member = staticMembers.get(name);
|
||||
}
|
||||
if (member == null)
|
||||
throw reportMemberNotFound(name);
|
||||
if (member instanceof FieldAndMethods) {
|
||||
FieldAndMethods fam = (FieldAndMethods) ht.get(name);
|
||||
member = fam.field;
|
||||
}
|
||||
|
||||
// Is this a bean property "set"?
|
||||
if (member instanceof BeanProperty) {
|
||||
BeanProperty bp = (BeanProperty)member;
|
||||
if (bp.setter == null) {
|
||||
throw reportMemberNotFound(name);
|
||||
}
|
||||
// If there's only one setter or if the value is null, use the
|
||||
// main setter. Otherwise, let the NativeJavaMethod decide which
|
||||
// setter to use:
|
||||
if (bp.setters == null || value == null) {
|
||||
Class<?> setType = bp.setter.argTypes[0];
|
||||
Object[] args = { Context.jsToJava(value, setType) };
|
||||
try {
|
||||
bp.setter.invoke(javaObject, args);
|
||||
} catch (Exception ex) {
|
||||
throw Context.throwAsScriptRuntimeEx(ex);
|
||||
}
|
||||
} else {
|
||||
Object[] args = { value };
|
||||
bp.setters.call(Context.getContext(),
|
||||
ScriptableObject.getTopLevelScope(scope),
|
||||
scope, args);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(member instanceof Field)) {
|
||||
String str = (member == null) ? "msg.java.internal.private"
|
||||
: "msg.java.method.assign";
|
||||
throw Context.reportRuntimeError1(str, name);
|
||||
}
|
||||
Field field = (Field)member;
|
||||
Object javaValue = Context.jsToJava(value, field.getType());
|
||||
try {
|
||||
field.set(javaObject, javaValue);
|
||||
} catch (IllegalAccessException accessEx) {
|
||||
if ((field.getModifiers() & Modifier.FINAL) != 0) {
|
||||
// treat Java final the same as JavaScript [[READONLY]]
|
||||
return;
|
||||
}
|
||||
throw Context.throwAsScriptRuntimeEx(accessEx);
|
||||
} catch (IllegalArgumentException argEx) {
|
||||
throw Context.reportRuntimeError3(
|
||||
"msg.java.internal.field.type",
|
||||
value.getClass().getName(), field,
|
||||
javaObject.getClass().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object[] getIds(boolean isStatic)
|
||||
{
|
||||
Map<String,Object> map = isStatic ? staticMembers : members;
|
||||
return map.keySet().toArray(new Object[map.size()]);
|
||||
}
|
||||
|
||||
static String javaSignature(Class<?> type)
|
||||
{
|
||||
if (!type.isArray()) {
|
||||
return type.getName();
|
||||
} else {
|
||||
int arrayDimension = 0;
|
||||
do {
|
||||
++arrayDimension;
|
||||
type = type.getComponentType();
|
||||
} while (type.isArray());
|
||||
String name = type.getName();
|
||||
String suffix = "[]";
|
||||
if (arrayDimension == 1) {
|
||||
return name.concat(suffix);
|
||||
} else {
|
||||
int length = name.length() + arrayDimension * suffix.length();
|
||||
StringBuffer sb = new StringBuffer(length);
|
||||
sb.append(name);
|
||||
while (arrayDimension != 0) {
|
||||
--arrayDimension;
|
||||
sb.append(suffix);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static String liveConnectSignature(Class<?>[] argTypes)
|
||||
{
|
||||
int N = argTypes.length;
|
||||
if (N == 0) { return "()"; }
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append('(');
|
||||
for (int i = 0; i != N; ++i) {
|
||||
if (i != 0) {
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(javaSignature(argTypes[i]));
|
||||
}
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private MemberBox findExplicitFunction(String name, boolean isStatic)
|
||||
{
|
||||
int sigStart = name.indexOf('(');
|
||||
if (sigStart < 0) { return null; }
|
||||
|
||||
Map<String,Object> ht = isStatic ? staticMembers : members;
|
||||
MemberBox[] methodsOrCtors = null;
|
||||
boolean isCtor = (isStatic && sigStart == 0);
|
||||
|
||||
if (isCtor) {
|
||||
// Explicit request for an overloaded constructor
|
||||
methodsOrCtors = ctors;
|
||||
} else {
|
||||
// Explicit request for an overloaded method
|
||||
String trueName = name.substring(0,sigStart);
|
||||
Object obj = ht.get(trueName);
|
||||
if (!isStatic && obj == null) {
|
||||
// Try to get static member from instance (LC3)
|
||||
obj = staticMembers.get(trueName);
|
||||
}
|
||||
if (obj instanceof NativeJavaMethod) {
|
||||
NativeJavaMethod njm = (NativeJavaMethod)obj;
|
||||
methodsOrCtors = njm.methods;
|
||||
}
|
||||
}
|
||||
|
||||
if (methodsOrCtors != null) {
|
||||
for (int i = 0; i < methodsOrCtors.length; i++) {
|
||||
Class<?>[] type = methodsOrCtors[i].argTypes;
|
||||
String sig = liveConnectSignature(type);
|
||||
if (sigStart + sig.length() == name.length()
|
||||
&& name.regionMatches(sigStart, sig, 0, sig.length()))
|
||||
{
|
||||
return methodsOrCtors[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Object getExplicitFunction(Scriptable scope, String name,
|
||||
Object javaObject, boolean isStatic)
|
||||
{
|
||||
Map<String,Object> ht = isStatic ? staticMembers : members;
|
||||
Object member = null;
|
||||
MemberBox methodOrCtor = findExplicitFunction(name, isStatic);
|
||||
|
||||
if (methodOrCtor != null) {
|
||||
Scriptable prototype =
|
||||
ScriptableObject.getFunctionPrototype(scope);
|
||||
|
||||
if (methodOrCtor.isCtor()) {
|
||||
NativeJavaConstructor fun =
|
||||
new NativeJavaConstructor(methodOrCtor);
|
||||
fun.setPrototype(prototype);
|
||||
member = fun;
|
||||
ht.put(name, fun);
|
||||
} else {
|
||||
String trueName = methodOrCtor.getName();
|
||||
member = ht.get(trueName);
|
||||
|
||||
if (member instanceof NativeJavaMethod &&
|
||||
((NativeJavaMethod)member).methods.length > 1 ) {
|
||||
NativeJavaMethod fun =
|
||||
new NativeJavaMethod(methodOrCtor, name);
|
||||
fun.setPrototype(prototype);
|
||||
ht.put(name, fun);
|
||||
member = fun;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return member;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves mapping of methods to accessible methods for a class.
|
||||
* In case the class is not public, retrieves methods with same
|
||||
* signature as its public methods from public superclasses and
|
||||
* interfaces (if they exist). Basically upcasts every method to the
|
||||
* nearest accessible method.
|
||||
*/
|
||||
private static Method[] discoverAccessibleMethods(Class<?> clazz,
|
||||
boolean includeProtected,
|
||||
boolean includePrivate)
|
||||
{
|
||||
Map<MethodSignature,Method> map = new HashMap<MethodSignature,Method>();
|
||||
discoverAccessibleMethods(clazz, map, includeProtected, includePrivate);
|
||||
return map.values().toArray(new Method[map.size()]);
|
||||
}
|
||||
|
||||
private static void discoverAccessibleMethods(Class<?> clazz,
|
||||
Map<MethodSignature,Method> map, boolean includeProtected,
|
||||
boolean includePrivate)
|
||||
{
|
||||
if (Modifier.isPublic(clazz.getModifiers()) || includePrivate) {
|
||||
try {
|
||||
if (includeProtected || includePrivate) {
|
||||
while (clazz != null) {
|
||||
try {
|
||||
Method[] methods = clazz.getDeclaredMethods();
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
Method method = methods[i];
|
||||
int mods = method.getModifiers();
|
||||
|
||||
if (Modifier.isPublic(mods) ||
|
||||
Modifier.isProtected(mods) ||
|
||||
includePrivate)
|
||||
{
|
||||
if (includePrivate)
|
||||
method.setAccessible(true);
|
||||
map.put(new MethodSignature(method), method);
|
||||
}
|
||||
}
|
||||
clazz = clazz.getSuperclass();
|
||||
} catch (SecurityException e) {
|
||||
// Some security settings (i.e., applets) disallow
|
||||
// access to Class.getDeclaredMethods. Fall back to
|
||||
// Class.getMethods.
|
||||
Method[] methods = clazz.getMethods();
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
Method method = methods[i];
|
||||
MethodSignature sig
|
||||
= new MethodSignature(method);
|
||||
if (map.get(sig) == null)
|
||||
map.put(sig, method);
|
||||
}
|
||||
break; // getMethods gets superclass methods, no
|
||||
// need to loop any more
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Method[] methods = clazz.getMethods();
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
Method method = methods[i];
|
||||
MethodSignature sig = new MethodSignature(method);
|
||||
map.put(sig, method);
|
||||
}
|
||||
}
|
||||
return;
|
||||
} catch (SecurityException e) {
|
||||
Context.reportWarning(
|
||||
"Could not discover accessible methods of class " +
|
||||
clazz.getName() + " due to lack of privileges, " +
|
||||
"attemping superclasses/interfaces.");
|
||||
// Fall through and attempt to discover superclass/interface
|
||||
// methods
|
||||
}
|
||||
}
|
||||
|
||||
Class<?>[] interfaces = clazz.getInterfaces();
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
discoverAccessibleMethods(interfaces[i], map, includeProtected,
|
||||
includePrivate);
|
||||
}
|
||||
Class<?> superclass = clazz.getSuperclass();
|
||||
if (superclass != null) {
|
||||
discoverAccessibleMethods(superclass, map, includeProtected,
|
||||
includePrivate);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class MethodSignature
|
||||
{
|
||||
private final String name;
|
||||
private final Class<?>[] args;
|
||||
|
||||
private MethodSignature(String name, Class<?>[] args)
|
||||
{
|
||||
this.name = name;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
MethodSignature(Method method)
|
||||
{
|
||||
this(method.getName(), method.getParameterTypes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if(o instanceof MethodSignature)
|
||||
{
|
||||
MethodSignature ms = (MethodSignature)o;
|
||||
return ms.name.equals(name) && Arrays.equals(args, ms.args);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return name.hashCode() ^ args.length;
|
||||
}
|
||||
}
|
||||
|
||||
private void reflect(Scriptable scope, boolean includeProtected)
|
||||
{
|
||||
// We reflect methods first, because we want overloaded field/method
|
||||
// names to be allocated to the NativeJavaMethod before the field
|
||||
// gets in the way.
|
||||
|
||||
Method[] methods = discoverAccessibleMethods(cl, includeProtected,
|
||||
includePrivate);
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
Method method = methods[i];
|
||||
int mods = method.getModifiers();
|
||||
boolean isStatic = Modifier.isStatic(mods);
|
||||
Map<String,Object> ht = isStatic ? staticMembers : members;
|
||||
String name = method.getName();
|
||||
Object value = ht.get(name);
|
||||
if (value == null) {
|
||||
ht.put(name, method);
|
||||
} else {
|
||||
ObjArray overloadedMethods;
|
||||
if (value instanceof ObjArray) {
|
||||
overloadedMethods = (ObjArray)value;
|
||||
} else {
|
||||
if (!(value instanceof Method)) Kit.codeBug();
|
||||
// value should be instance of Method as at this stage
|
||||
// staticMembers and members can only contain methods
|
||||
overloadedMethods = new ObjArray();
|
||||
overloadedMethods.add(value);
|
||||
ht.put(name, overloadedMethods);
|
||||
}
|
||||
overloadedMethods.add(method);
|
||||
}
|
||||
}
|
||||
|
||||
// replace Method instances by wrapped NativeJavaMethod objects
|
||||
// first in staticMembers and then in members
|
||||
for (int tableCursor = 0; tableCursor != 2; ++tableCursor) {
|
||||
boolean isStatic = (tableCursor == 0);
|
||||
Map<String,Object> ht = isStatic ? staticMembers : members;
|
||||
for (Map.Entry<String, Object> entry: ht.entrySet()) {
|
||||
MemberBox[] methodBoxes;
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof Method) {
|
||||
methodBoxes = new MemberBox[1];
|
||||
methodBoxes[0] = new MemberBox((Method)value);
|
||||
} else {
|
||||
ObjArray overloadedMethods = (ObjArray)value;
|
||||
int N = overloadedMethods.size();
|
||||
if (N < 2) Kit.codeBug();
|
||||
methodBoxes = new MemberBox[N];
|
||||
for (int i = 0; i != N; ++i) {
|
||||
Method method = (Method)overloadedMethods.get(i);
|
||||
methodBoxes[i] = new MemberBox(method);
|
||||
}
|
||||
}
|
||||
NativeJavaMethod fun = new NativeJavaMethod(methodBoxes);
|
||||
if (scope != null) {
|
||||
ScriptRuntime.setFunctionProtoAndParent(fun, scope);
|
||||
}
|
||||
ht.put(entry.getKey(), fun);
|
||||
}
|
||||
}
|
||||
|
||||
// Reflect fields.
|
||||
Field[] fields = getAccessibleFields();
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
String name = field.getName();
|
||||
int mods = field.getModifiers();
|
||||
if (!includePrivate && !Modifier.isPublic(mods)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
boolean isStatic = Modifier.isStatic(mods);
|
||||
Map<String,Object> ht = isStatic ? staticMembers : members;
|
||||
Object member = ht.get(name);
|
||||
if (member == null) {
|
||||
ht.put(name, field);
|
||||
} else if (member instanceof NativeJavaMethod) {
|
||||
NativeJavaMethod method = (NativeJavaMethod) member;
|
||||
FieldAndMethods fam
|
||||
= new FieldAndMethods(scope, method.methods, field);
|
||||
Map<String,FieldAndMethods> fmht = isStatic ? staticFieldAndMethods
|
||||
: fieldAndMethods;
|
||||
if (fmht == null) {
|
||||
fmht = new HashMap<String,FieldAndMethods>();
|
||||
if (isStatic) {
|
||||
staticFieldAndMethods = fmht;
|
||||
} else {
|
||||
fieldAndMethods = fmht;
|
||||
}
|
||||
}
|
||||
fmht.put(name, fam);
|
||||
ht.put(name, fam);
|
||||
} else if (member instanceof Field) {
|
||||
Field oldField = (Field) member;
|
||||
// If this newly reflected field shadows an inherited field,
|
||||
// then replace it. Otherwise, since access to the field
|
||||
// would be ambiguous from Java, no field should be
|
||||
// reflected.
|
||||
// For now, the first field found wins, unless another field
|
||||
// explicitly shadows it.
|
||||
if (oldField.getDeclaringClass().
|
||||
isAssignableFrom(field.getDeclaringClass()))
|
||||
{
|
||||
ht.put(name, field);
|
||||
}
|
||||
} else {
|
||||
// "unknown member type"
|
||||
Kit.codeBug();
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
// skip this field
|
||||
Context.reportWarning("Could not access field "
|
||||
+ name + " of class " + cl.getName() +
|
||||
" due to lack of privileges.");
|
||||
}
|
||||
}
|
||||
|
||||
// Create bean properties from corresponding get/set methods first for
|
||||
// static members and then for instance members
|
||||
for (int tableCursor = 0; tableCursor != 2; ++tableCursor) {
|
||||
boolean isStatic = (tableCursor == 0);
|
||||
Map<String,Object> ht = isStatic ? staticMembers : members;
|
||||
|
||||
Map<String,BeanProperty> toAdd = new HashMap<String,BeanProperty>();
|
||||
|
||||
// Now, For each member, make "bean" properties.
|
||||
for (String name: ht.keySet()) {
|
||||
// Is this a getter?
|
||||
boolean memberIsGetMethod = name.startsWith("get");
|
||||
boolean memberIsSetMethod = name.startsWith("set");
|
||||
boolean memberIsIsMethod = name.startsWith("is");
|
||||
if (memberIsGetMethod || memberIsIsMethod
|
||||
|| memberIsSetMethod) {
|
||||
// Double check name component.
|
||||
String nameComponent
|
||||
= name.substring(memberIsIsMethod ? 2 : 3);
|
||||
if (nameComponent.length() == 0)
|
||||
continue;
|
||||
|
||||
// Make the bean property name.
|
||||
String beanPropertyName = nameComponent;
|
||||
char ch0 = nameComponent.charAt(0);
|
||||
if (Character.isUpperCase(ch0)) {
|
||||
if (nameComponent.length() == 1) {
|
||||
beanPropertyName = nameComponent.toLowerCase();
|
||||
} else {
|
||||
char ch1 = nameComponent.charAt(1);
|
||||
if (!Character.isUpperCase(ch1)) {
|
||||
beanPropertyName = Character.toLowerCase(ch0)
|
||||
+nameComponent.substring(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we already have a member by this name, don't do this
|
||||
// property.
|
||||
if (toAdd.containsKey(beanPropertyName))
|
||||
continue;
|
||||
Object v = ht.get(beanPropertyName);
|
||||
if (v != null) {
|
||||
// A private field shouldn't mask a public getter/setter
|
||||
if (!includePrivate ||
|
||||
!Modifier.isPrivate(((Member)v).getModifiers()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Find the getter method, or if there is none, the is-
|
||||
// method.
|
||||
MemberBox getter = null;
|
||||
getter = findGetter(isStatic, ht, "get", nameComponent);
|
||||
// If there was no valid getter, check for an is- method.
|
||||
if (getter == null) {
|
||||
getter = findGetter(isStatic, ht, "is", nameComponent);
|
||||
}
|
||||
|
||||
// setter
|
||||
MemberBox setter = null;
|
||||
NativeJavaMethod setters = null;
|
||||
String setterName = "set".concat(nameComponent);
|
||||
|
||||
if (ht.containsKey(setterName)) {
|
||||
// Is this value a method?
|
||||
Object member = ht.get(setterName);
|
||||
if (member instanceof NativeJavaMethod) {
|
||||
NativeJavaMethod njmSet = (NativeJavaMethod)member;
|
||||
if (getter != null) {
|
||||
// We have a getter. Now, do we have a matching
|
||||
// setter?
|
||||
Class<?> type = getter.method().getReturnType();
|
||||
setter = extractSetMethod(type, njmSet.methods,
|
||||
isStatic);
|
||||
} else {
|
||||
// No getter, find any set method
|
||||
setter = extractSetMethod(njmSet.methods,
|
||||
isStatic);
|
||||
}
|
||||
if (njmSet.methods.length > 1) {
|
||||
setters = njmSet;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Make the property.
|
||||
BeanProperty bp = new BeanProperty(getter, setter,
|
||||
setters);
|
||||
toAdd.put(beanPropertyName, bp);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the new bean properties.
|
||||
for (String key: toAdd.keySet()) {
|
||||
Object value = toAdd.get(key);
|
||||
ht.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
// Reflect constructors
|
||||
Constructor<?>[] constructors = getAccessibleConstructors();
|
||||
ctors = new MemberBox[constructors.length];
|
||||
for (int i = 0; i != constructors.length; ++i) {
|
||||
ctors[i] = new MemberBox(constructors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private Constructor<?>[] getAccessibleConstructors()
|
||||
{
|
||||
// The JVM currently doesn't allow changing access on java.lang.Class
|
||||
// constructors, so don't try
|
||||
if (includePrivate && cl != ScriptRuntime.ClassClass) {
|
||||
try {
|
||||
Constructor<?>[] cons = cl.getDeclaredConstructors();
|
||||
AccessibleObject.setAccessible(cons, true);
|
||||
|
||||
return cons;
|
||||
} catch (SecurityException e) {
|
||||
// Fall through to !includePrivate case
|
||||
Context.reportWarning("Could not access constructor " +
|
||||
" of class " + cl.getName() +
|
||||
" due to lack of privileges.");
|
||||
}
|
||||
}
|
||||
return cl.getConstructors();
|
||||
}
|
||||
|
||||
private Field[] getAccessibleFields() {
|
||||
if (includePrivate) {
|
||||
try {
|
||||
List<Field> fieldsList = new ArrayList<Field>();
|
||||
Class<?> currentClass = cl;
|
||||
|
||||
while (currentClass != null) {
|
||||
// get all declared fields in this class, make them
|
||||
// accessible, and save
|
||||
Field[] declared = currentClass.getDeclaredFields();
|
||||
for (int i = 0; i < declared.length; i++) {
|
||||
declared[i].setAccessible(true);
|
||||
fieldsList.add(declared[i]);
|
||||
}
|
||||
// walk up superclass chain. no need to deal specially with
|
||||
// interfaces, since they can't have fields
|
||||
currentClass = currentClass.getSuperclass();
|
||||
}
|
||||
|
||||
return fieldsList.toArray(new Field[fieldsList.size()]);
|
||||
} catch (SecurityException e) {
|
||||
// fall through to !includePrivate case
|
||||
}
|
||||
}
|
||||
return cl.getFields();
|
||||
}
|
||||
|
||||
private MemberBox findGetter(boolean isStatic, Map<String,Object> ht, String prefix,
|
||||
String propertyName)
|
||||
{
|
||||
String getterName = prefix.concat(propertyName);
|
||||
if (ht.containsKey(getterName)) {
|
||||
// Check that the getter is a method.
|
||||
Object member = ht.get(getterName);
|
||||
if (member instanceof NativeJavaMethod) {
|
||||
NativeJavaMethod njmGet = (NativeJavaMethod) member;
|
||||
return extractGetMethod(njmGet.methods, isStatic);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static MemberBox extractGetMethod(MemberBox[] methods,
|
||||
boolean isStatic)
|
||||
{
|
||||
// Inspect the list of all MemberBox for the only one having no
|
||||
// parameters
|
||||
for (int methodIdx = 0; methodIdx < methods.length; methodIdx++) {
|
||||
MemberBox method = methods[methodIdx];
|
||||
// Does getter method have an empty parameter list with a return
|
||||
// value (eg. a getSomething() or isSomething())?
|
||||
if (method.argTypes.length == 0
|
||||
&& (!isStatic || method.isStatic()))
|
||||
{
|
||||
Class<?> type = method.method().getReturnType();
|
||||
if (type != Void.TYPE) {
|
||||
return method;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static MemberBox extractSetMethod(Class<?> type, MemberBox[] methods,
|
||||
boolean isStatic)
|
||||
{
|
||||
//
|
||||
// Note: it may be preferable to allow NativeJavaMethod.findFunction()
|
||||
// to find the appropriate setter; unfortunately, it requires an
|
||||
// instance of the target arg to determine that.
|
||||
//
|
||||
|
||||
// Make two passes: one to find a method with direct type assignment,
|
||||
// and one to find a widening conversion.
|
||||
for (int pass = 1; pass <= 2; ++pass) {
|
||||
for (int i = 0; i < methods.length; ++i) {
|
||||
MemberBox method = methods[i];
|
||||
if (!isStatic || method.isStatic()) {
|
||||
Class<?>[] params = method.argTypes;
|
||||
if (params.length == 1) {
|
||||
if (pass == 1) {
|
||||
if (params[0] == type) {
|
||||
return method;
|
||||
}
|
||||
} else {
|
||||
if (pass != 2) Kit.codeBug();
|
||||
if (params[0].isAssignableFrom(type)) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static MemberBox extractSetMethod(MemberBox[] methods,
|
||||
boolean isStatic)
|
||||
{
|
||||
|
||||
for (int i = 0; i < methods.length; ++i) {
|
||||
MemberBox method = methods[i];
|
||||
if (!isStatic || method.isStatic()) {
|
||||
if (method.method().getReturnType() == Void.TYPE) {
|
||||
if (method.argTypes.length == 1) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<String,FieldAndMethods> getFieldAndMethodsObjects(Scriptable scope,
|
||||
Object javaObject, boolean isStatic)
|
||||
{
|
||||
Map<String,FieldAndMethods> ht = isStatic ? staticFieldAndMethods : fieldAndMethods;
|
||||
if (ht == null)
|
||||
return null;
|
||||
int len = ht.size();
|
||||
Map<String,FieldAndMethods> result = new HashMap<String,FieldAndMethods>(len);
|
||||
for (FieldAndMethods fam: ht.values()) {
|
||||
FieldAndMethods famNew = new FieldAndMethods(scope, fam.methods,
|
||||
fam.field);
|
||||
famNew.javaObject = javaObject;
|
||||
result.put(fam.field.getName(), famNew);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static JavaMembers lookupClass(Scriptable scope, Class<?> dynamicType,
|
||||
Class<?> staticType, boolean includeProtected)
|
||||
{
|
||||
JavaMembers members;
|
||||
scope = ScriptableObject.getTopLevelScope(scope);
|
||||
ClassCache cache = ClassCache.get(scope);
|
||||
Map<Class<?>,JavaMembers> ct = cache.getClassCacheMap();
|
||||
|
||||
Class<?> cl = dynamicType;
|
||||
for (;;) {
|
||||
members = ct.get(cl);
|
||||
if (members != null) {
|
||||
return members;
|
||||
}
|
||||
try {
|
||||
members = new JavaMembers(scope, cl, includeProtected);
|
||||
break;
|
||||
} catch (SecurityException e) {
|
||||
// Reflection may fail for objects that are in a restricted
|
||||
// access package (e.g. sun.*). If we get a security
|
||||
// exception, try again with the static type if it is interface.
|
||||
// Otherwise, try superclass
|
||||
if (staticType != null && staticType.isInterface()) {
|
||||
cl = staticType;
|
||||
staticType = null; // try staticType only once
|
||||
} else {
|
||||
Class<?> parent = cl.getSuperclass();
|
||||
if (parent == null) {
|
||||
if (cl.isInterface()) {
|
||||
// last resort after failed staticType interface
|
||||
parent = ScriptRuntime.ObjectClass;
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
cl = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cache.isCachingEnabled())
|
||||
ct.put(cl, members);
|
||||
return members;
|
||||
}
|
||||
|
||||
RuntimeException reportMemberNotFound(String memberName)
|
||||
{
|
||||
return Context.reportRuntimeError2(
|
||||
"msg.java.member.not.found", cl.getName(), memberName);
|
||||
}
|
||||
|
||||
private Class<?> cl;
|
||||
private Map<String,Object> members;
|
||||
private Map<String,FieldAndMethods> fieldAndMethods;
|
||||
private Map<String,Object> staticMembers;
|
||||
private Map<String,FieldAndMethods> staticFieldAndMethods;
|
||||
MemberBox[] ctors;
|
||||
private boolean includePrivate;
|
||||
}
|
||||
|
||||
class BeanProperty
|
||||
{
|
||||
BeanProperty(MemberBox getter, MemberBox setter, NativeJavaMethod setters)
|
||||
{
|
||||
this.getter = getter;
|
||||
this.setter = setter;
|
||||
this.setters = setters;
|
||||
}
|
||||
|
||||
MemberBox getter;
|
||||
MemberBox setter;
|
||||
NativeJavaMethod setters;
|
||||
}
|
||||
|
||||
class FieldAndMethods extends NativeJavaMethod
|
||||
{
|
||||
static final long serialVersionUID = -9222428244284796755L;
|
||||
|
||||
FieldAndMethods(Scriptable scope, MemberBox[] methods, Field field)
|
||||
{
|
||||
super(methods);
|
||||
this.field = field;
|
||||
setParentScope(scope);
|
||||
setPrototype(ScriptableObject.getFunctionPrototype(scope));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDefaultValue(Class<?> hint)
|
||||
{
|
||||
if (hint == ScriptRuntime.FunctionClass)
|
||||
return this;
|
||||
Object rval;
|
||||
Class<?> type;
|
||||
try {
|
||||
rval = field.get(javaObject);
|
||||
type = field.getType();
|
||||
} catch (IllegalAccessException accEx) {
|
||||
throw Context.reportRuntimeError1(
|
||||
"msg.java.internal.private", field.getName());
|
||||
}
|
||||
Context cx = Context.getContext();
|
||||
rval = cx.getWrapFactory().wrap(cx, this, rval, type);
|
||||
if (rval instanceof Scriptable) {
|
||||
rval = ((Scriptable) rval).getDefaultValue(hint);
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
Field field;
|
||||
Object javaObject;
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Bojan Cekrlic
|
||||
* Hannes Wallnoefer
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// API class
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* Java reflection of JavaScript exceptions.
|
||||
* Instances of this class are thrown by the JavaScript 'throw' keyword.
|
||||
*
|
||||
* @author Mike McCabe
|
||||
*/
|
||||
public class JavaScriptException extends RhinoException
|
||||
{
|
||||
static final long serialVersionUID = -7666130513694669293L;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link WrappedException#WrappedException(Throwable)} to report
|
||||
* exceptions in Java code.
|
||||
*/
|
||||
public JavaScriptException(Object value)
|
||||
{
|
||||
this(value, "", 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a JavaScript exception wrapping the given JavaScript value
|
||||
*
|
||||
* @param value the JavaScript value thrown.
|
||||
*/
|
||||
public JavaScriptException(Object value, String sourceName, int lineNumber)
|
||||
{
|
||||
recordErrorOrigin(sourceName, lineNumber, null, 0);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String details()
|
||||
{
|
||||
try {
|
||||
return ScriptRuntime.toString(value);
|
||||
} catch (RuntimeException rte) {
|
||||
// ScriptRuntime.toString may throw a RuntimeException
|
||||
if (value == null) {
|
||||
return "null";
|
||||
} else if (value instanceof Scriptable) {
|
||||
return ScriptRuntime.defaultObjectToString((Scriptable)value);
|
||||
} else {
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value wrapped by this exception
|
||||
*/
|
||||
public Object getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link RhinoException#sourceName()} from the super class.
|
||||
*/
|
||||
public String getSourceName()
|
||||
{
|
||||
return sourceName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link RhinoException#lineNumber()} from the super class.
|
||||
*/
|
||||
public int getLineNumber()
|
||||
{
|
||||
return lineNumber();
|
||||
}
|
||||
|
||||
private Object value;
|
||||
}
|
||||
@@ -1,470 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov, igor@fastmail.fm
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Collection of utilities
|
||||
*/
|
||||
|
||||
public class Kit
|
||||
{
|
||||
/**
|
||||
* Reflection of Throwable.initCause(Throwable) from JDK 1.4
|
||||
* or nul if it is not available.
|
||||
*/
|
||||
private static Method Throwable_initCause = null;
|
||||
|
||||
static {
|
||||
// Are we running on a JDK 1.4 or later system?
|
||||
try {
|
||||
Class<?> ThrowableClass = Kit.classOrNull("java.lang.Throwable");
|
||||
Class<?>[] signature = { ThrowableClass };
|
||||
Throwable_initCause
|
||||
= ThrowableClass.getMethod("initCause", signature);
|
||||
} catch (Exception ex) {
|
||||
// Assume any exceptions means the method does not exist.
|
||||
}
|
||||
}
|
||||
|
||||
public static Class<?> classOrNull(String className)
|
||||
{
|
||||
try {
|
||||
return Class.forName(className);
|
||||
} catch (ClassNotFoundException ex) {
|
||||
} catch (SecurityException ex) {
|
||||
} catch (LinkageError ex) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Can be thrown if name has characters that a class name
|
||||
// can not contain
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to load the class of the given name. Note that the type parameter
|
||||
* isn't checked.
|
||||
*/
|
||||
public static Class<?> classOrNull(ClassLoader loader, String className)
|
||||
{
|
||||
try {
|
||||
return loader.loadClass(className);
|
||||
} catch (ClassNotFoundException ex) {
|
||||
} catch (SecurityException ex) {
|
||||
} catch (LinkageError ex) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Can be thrown if name has characters that a class name
|
||||
// can not contain
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static Object newInstanceOrNull(Class<?> cl)
|
||||
{
|
||||
try {
|
||||
return cl.newInstance();
|
||||
} catch (SecurityException x) {
|
||||
} catch (LinkageError ex) {
|
||||
} catch (InstantiationException x) {
|
||||
} catch (IllegalAccessException x) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that testClass is accessible from the given loader.
|
||||
*/
|
||||
static boolean testIfCanLoadRhinoClasses(ClassLoader loader)
|
||||
{
|
||||
Class<?> testClass = ScriptRuntime.ContextFactoryClass;
|
||||
Class<?> x = Kit.classOrNull(loader, testClass.getName());
|
||||
if (x != testClass) {
|
||||
// The check covers the case when x == null =>
|
||||
// loader does not know about testClass or the case
|
||||
// when x != null && x != testClass =>
|
||||
// loader loads a class unrelated to testClass
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* If initCause methods exists in Throwable, call
|
||||
* <tt>ex.initCause(cause)</tt> or otherwise do nothing.
|
||||
* @return The <tt>ex</tt> argument.
|
||||
*/
|
||||
public static RuntimeException initCause(RuntimeException ex,
|
||||
Throwable cause)
|
||||
{
|
||||
if (Throwable_initCause != null) {
|
||||
Object[] args = { cause };
|
||||
try {
|
||||
Throwable_initCause.invoke(ex, args);
|
||||
} catch (Exception e) {
|
||||
// Ignore any exceptions
|
||||
}
|
||||
}
|
||||
return ex;
|
||||
}
|
||||
|
||||
/**
|
||||
* If character <tt>c</tt> is a hexadecimal digit, return
|
||||
* <tt>accumulator</tt> * 16 plus corresponding
|
||||
* number. Otherise return -1.
|
||||
*/
|
||||
public static int xDigitToInt(int c, int accumulator)
|
||||
{
|
||||
check: {
|
||||
// Use 0..9 < A..Z < a..z
|
||||
if (c <= '9') {
|
||||
c -= '0';
|
||||
if (0 <= c) { break check; }
|
||||
} else if (c <= 'F') {
|
||||
if ('A' <= c) {
|
||||
c -= ('A' - 10);
|
||||
break check;
|
||||
}
|
||||
} else if (c <= 'f') {
|
||||
if ('a' <= c) {
|
||||
c -= ('a' - 10);
|
||||
break check;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return (accumulator << 4) | c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add <i>listener</i> to <i>bag</i> of listeners.
|
||||
* The function does not modify <i>bag</i> and return a new collection
|
||||
* containing <i>listener</i> and all listeners from <i>bag</i>.
|
||||
* Bag without listeners always represented as the null value.
|
||||
* <p>
|
||||
* Usage example:
|
||||
* <pre>
|
||||
* private volatile Object changeListeners;
|
||||
*
|
||||
* public void addMyListener(PropertyChangeListener l)
|
||||
* {
|
||||
* synchronized (this) {
|
||||
* changeListeners = Kit.addListener(changeListeners, l);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* public void removeTextListener(PropertyChangeListener l)
|
||||
* {
|
||||
* synchronized (this) {
|
||||
* changeListeners = Kit.removeListener(changeListeners, l);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* public void fireChangeEvent(Object oldValue, Object newValue)
|
||||
* {
|
||||
* // Get immune local copy
|
||||
* Object listeners = changeListeners;
|
||||
* if (listeners != null) {
|
||||
* PropertyChangeEvent e = new PropertyChangeEvent(
|
||||
* this, "someProperty" oldValue, newValue);
|
||||
* for (int i = 0; ; ++i) {
|
||||
* Object l = Kit.getListener(listeners, i);
|
||||
* if (l == null)
|
||||
* break;
|
||||
* ((PropertyChangeListener)l).propertyChange(e);
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param listener Listener to add to <i>bag</i>
|
||||
* @param bag Current collection of listeners.
|
||||
* @return A new bag containing all listeners from <i>bag</i> and
|
||||
* <i>listener</i>.
|
||||
* @see #removeListener(Object bag, Object listener)
|
||||
* @see #getListener(Object bag, int index)
|
||||
*/
|
||||
public static Object addListener(Object bag, Object listener)
|
||||
{
|
||||
if (listener == null) throw new IllegalArgumentException();
|
||||
if (listener instanceof Object[]) throw new IllegalArgumentException();
|
||||
|
||||
if (bag == null) {
|
||||
bag = listener;
|
||||
} else if (!(bag instanceof Object[])) {
|
||||
bag = new Object[] { bag, listener };
|
||||
} else {
|
||||
Object[] array = (Object[])bag;
|
||||
int L = array.length;
|
||||
// bag has at least 2 elements if it is array
|
||||
if (L < 2) throw new IllegalArgumentException();
|
||||
Object[] tmp = new Object[L + 1];
|
||||
System.arraycopy(array, 0, tmp, 0, L);
|
||||
tmp[L] = listener;
|
||||
bag = tmp;
|
||||
}
|
||||
|
||||
return bag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove <i>listener</i> from <i>bag</i> of listeners.
|
||||
* The function does not modify <i>bag</i> and return a new collection
|
||||
* containing all listeners from <i>bag</i> except <i>listener</i>.
|
||||
* If <i>bag</i> does not contain <i>listener</i>, the function returns
|
||||
* <i>bag</i>.
|
||||
* <p>
|
||||
* For usage example, see {@link #addListener(Object bag, Object listener)}.
|
||||
*
|
||||
* @param listener Listener to remove from <i>bag</i>
|
||||
* @param bag Current collection of listeners.
|
||||
* @return A new bag containing all listeners from <i>bag</i> except
|
||||
* <i>listener</i>.
|
||||
* @see #addListener(Object bag, Object listener)
|
||||
* @see #getListener(Object bag, int index)
|
||||
*/
|
||||
public static Object removeListener(Object bag, Object listener)
|
||||
{
|
||||
if (listener == null) throw new IllegalArgumentException();
|
||||
if (listener instanceof Object[]) throw new IllegalArgumentException();
|
||||
|
||||
if (bag == listener) {
|
||||
bag = null;
|
||||
} else if (bag instanceof Object[]) {
|
||||
Object[] array = (Object[])bag;
|
||||
int L = array.length;
|
||||
// bag has at least 2 elements if it is array
|
||||
if (L < 2) throw new IllegalArgumentException();
|
||||
if (L == 2) {
|
||||
if (array[1] == listener) {
|
||||
bag = array[0];
|
||||
} else if (array[0] == listener) {
|
||||
bag = array[1];
|
||||
}
|
||||
} else {
|
||||
int i = L;
|
||||
do {
|
||||
--i;
|
||||
if (array[i] == listener) {
|
||||
Object[] tmp = new Object[L - 1];
|
||||
System.arraycopy(array, 0, tmp, 0, i);
|
||||
System.arraycopy(array, i + 1, tmp, i, L - (i + 1));
|
||||
bag = tmp;
|
||||
break;
|
||||
}
|
||||
} while (i != 0);
|
||||
}
|
||||
}
|
||||
|
||||
return bag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get listener at <i>index</i> position in <i>bag</i> or null if
|
||||
* <i>index</i> equals to number of listeners in <i>bag</i>.
|
||||
* <p>
|
||||
* For usage example, see {@link #addListener(Object bag, Object listener)}.
|
||||
*
|
||||
* @param bag Current collection of listeners.
|
||||
* @param index Index of the listener to access.
|
||||
* @return Listener at the given index or null.
|
||||
* @see #addListener(Object bag, Object listener)
|
||||
* @see #removeListener(Object bag, Object listener)
|
||||
*/
|
||||
public static Object getListener(Object bag, int index)
|
||||
{
|
||||
if (index == 0) {
|
||||
if (bag == null)
|
||||
return null;
|
||||
if (!(bag instanceof Object[]))
|
||||
return bag;
|
||||
Object[] array = (Object[])bag;
|
||||
// bag has at least 2 elements if it is array
|
||||
if (array.length < 2) throw new IllegalArgumentException();
|
||||
return array[0];
|
||||
} else if (index == 1) {
|
||||
if (!(bag instanceof Object[])) {
|
||||
if (bag == null) throw new IllegalArgumentException();
|
||||
return null;
|
||||
}
|
||||
Object[] array = (Object[])bag;
|
||||
// the array access will check for index on its own
|
||||
return array[1];
|
||||
} else {
|
||||
// bag has to array
|
||||
Object[] array = (Object[])bag;
|
||||
int L = array.length;
|
||||
if (L < 2) throw new IllegalArgumentException();
|
||||
if (index == L)
|
||||
return null;
|
||||
return array[index];
|
||||
}
|
||||
}
|
||||
|
||||
static Object initHash(Map<Object,Object> h, Object key, Object initialValue)
|
||||
{
|
||||
synchronized (h) {
|
||||
Object current = h.get(key);
|
||||
if (current == null) {
|
||||
h.put(key, initialValue);
|
||||
} else {
|
||||
initialValue = current;
|
||||
}
|
||||
}
|
||||
return initialValue;
|
||||
}
|
||||
|
||||
private final static class ComplexKey
|
||||
{
|
||||
private Object key1;
|
||||
private Object key2;
|
||||
private int hash;
|
||||
|
||||
ComplexKey(Object key1, Object key2)
|
||||
{
|
||||
this.key1 = key1;
|
||||
this.key2 = key2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object anotherObj)
|
||||
{
|
||||
if (!(anotherObj instanceof ComplexKey))
|
||||
return false;
|
||||
ComplexKey another = (ComplexKey)anotherObj;
|
||||
return key1.equals(another.key1) && key2.equals(another.key2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
if (hash == 0) {
|
||||
hash = key1.hashCode() ^ key2.hashCode();
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
public static Object makeHashKeyFromPair(Object key1, Object key2)
|
||||
{
|
||||
if (key1 == null) throw new IllegalArgumentException();
|
||||
if (key2 == null) throw new IllegalArgumentException();
|
||||
return new ComplexKey(key1, key2);
|
||||
}
|
||||
|
||||
public static String readReader(Reader r)
|
||||
throws IOException
|
||||
{
|
||||
char[] buffer = new char[512];
|
||||
int cursor = 0;
|
||||
for (;;) {
|
||||
int n = r.read(buffer, cursor, buffer.length - cursor);
|
||||
if (n < 0) { break; }
|
||||
cursor += n;
|
||||
if (cursor == buffer.length) {
|
||||
char[] tmp = new char[buffer.length * 2];
|
||||
System.arraycopy(buffer, 0, tmp, 0, cursor);
|
||||
buffer = tmp;
|
||||
}
|
||||
}
|
||||
return new String(buffer, 0, cursor);
|
||||
}
|
||||
|
||||
public static byte[] readStream(InputStream is, int initialBufferCapacity)
|
||||
throws IOException
|
||||
{
|
||||
if (initialBufferCapacity <= 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Bad initialBufferCapacity: "+initialBufferCapacity);
|
||||
}
|
||||
byte[] buffer = new byte[initialBufferCapacity];
|
||||
int cursor = 0;
|
||||
for (;;) {
|
||||
int n = is.read(buffer, cursor, buffer.length - cursor);
|
||||
if (n < 0) { break; }
|
||||
cursor += n;
|
||||
if (cursor == buffer.length) {
|
||||
byte[] tmp = new byte[buffer.length * 2];
|
||||
System.arraycopy(buffer, 0, tmp, 0, cursor);
|
||||
buffer = tmp;
|
||||
}
|
||||
}
|
||||
if (cursor != buffer.length) {
|
||||
byte[] tmp = new byte[cursor];
|
||||
System.arraycopy(buffer, 0, tmp, 0, cursor);
|
||||
buffer = tmp;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws RuntimeException to indicate failed assertion.
|
||||
* The function never returns and its return type is RuntimeException
|
||||
* only to be able to write <tt>throw Kit.codeBug()</tt> if plain
|
||||
* <tt>Kit.codeBug()</tt> triggers unreachable code error.
|
||||
*/
|
||||
public static RuntimeException codeBug()
|
||||
throws RuntimeException
|
||||
{
|
||||
RuntimeException ex = new IllegalStateException("FAILED ASSERTION");
|
||||
// Print stack trace ASAP
|
||||
ex.printStackTrace(System.err);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws RuntimeException to indicate failed assertion.
|
||||
* The function never returns and its return type is RuntimeException
|
||||
* only to be able to write <tt>throw Kit.codeBug()</tt> if plain
|
||||
* <tt>Kit.codeBug()</tt> triggers unreachable code error.
|
||||
*/
|
||||
public static RuntimeException codeBug(String msg)
|
||||
throws RuntimeException
|
||||
{
|
||||
msg = "FAILED ASSERTION: " + msg;
|
||||
RuntimeException ex = new IllegalStateException(msg);
|
||||
// Print stack trace ASAP
|
||||
ex.printStackTrace(System.err);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Igor Bukanov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
|
||||
/**
|
||||
* Avoid loading classes unless they are used.
|
||||
*
|
||||
* <p> This improves startup time and average memory usage.
|
||||
*/
|
||||
public final class LazilyLoadedCtor implements java.io.Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final int STATE_BEFORE_INIT = 0;
|
||||
private static final int STATE_INITIALIZING = 1;
|
||||
private static final int STATE_WITH_VALUE = 2;
|
||||
|
||||
private final ScriptableObject scope;
|
||||
private final String propertyName;
|
||||
private final String className;
|
||||
private final boolean sealed;
|
||||
private Object initializedValue;
|
||||
private int state;
|
||||
|
||||
public LazilyLoadedCtor(ScriptableObject scope, String propertyName,
|
||||
String className, boolean sealed)
|
||||
{
|
||||
|
||||
this.scope = scope;
|
||||
this.propertyName = propertyName;
|
||||
this.className = className;
|
||||
this.sealed = sealed;
|
||||
this.state = STATE_BEFORE_INIT;
|
||||
|
||||
scope.addLazilyInitializedValue(propertyName, 0, this,
|
||||
ScriptableObject.DONTENUM);
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
synchronized (this) {
|
||||
if (state == STATE_INITIALIZING)
|
||||
throw new IllegalStateException(
|
||||
"Recursive initialization for "+propertyName);
|
||||
if (state == STATE_BEFORE_INIT) {
|
||||
state = STATE_INITIALIZING;
|
||||
// Set value now to have something to set in finally block if
|
||||
// buildValue throws.
|
||||
Object value = Scriptable.NOT_FOUND;
|
||||
try {
|
||||
value = buildValue();
|
||||
} finally {
|
||||
initializedValue = value;
|
||||
state = STATE_WITH_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object getValue()
|
||||
{
|
||||
if (state != STATE_WITH_VALUE)
|
||||
throw new IllegalStateException(propertyName);
|
||||
return initializedValue;
|
||||
}
|
||||
|
||||
private Object buildValue()
|
||||
{
|
||||
Class<? extends Scriptable> cl = cast(Kit.classOrNull(className));
|
||||
if (cl != null) {
|
||||
try {
|
||||
Object value = ScriptableObject.buildClassCtor(scope, cl,
|
||||
sealed, false);
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
else {
|
||||
// cl has own static initializer which is expected
|
||||
// to set the property on its own.
|
||||
value = scope.get(propertyName, scope);
|
||||
if (value != Scriptable.NOT_FOUND)
|
||||
return value;
|
||||
}
|
||||
} catch (InvocationTargetException ex) {
|
||||
Throwable target = ex.getTargetException();
|
||||
if (target instanceof RuntimeException) {
|
||||
throw (RuntimeException)target;
|
||||
}
|
||||
} catch (RhinoException ex) {
|
||||
} catch (InstantiationException ex) {
|
||||
} catch (IllegalAccessException ex) {
|
||||
} catch (SecurityException ex) {
|
||||
}
|
||||
}
|
||||
return Scriptable.NOT_FOUND;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
private Class<? extends Scriptable> cast(Class<?> cl) {
|
||||
return (Class<? extends Scriptable>)cl;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,372 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov
|
||||
* Felix Meschberger
|
||||
* Norris Boyd
|
||||
* Ulrike Mueller <umueller@demandware.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Wrappper class for Method and Constructor instances to cache
|
||||
* getParameterTypes() results, recover from IllegalAccessException
|
||||
* in some cases and provide serialization support.
|
||||
*
|
||||
* @author Igor Bukanov
|
||||
*/
|
||||
|
||||
final class MemberBox implements Serializable
|
||||
{
|
||||
static final long serialVersionUID = 6358550398665688245L;
|
||||
|
||||
private transient Member memberObject;
|
||||
transient Class<?>[] argTypes;
|
||||
transient Object delegateTo;
|
||||
transient boolean vararg;
|
||||
|
||||
|
||||
MemberBox(Method method)
|
||||
{
|
||||
init(method);
|
||||
}
|
||||
|
||||
MemberBox(Constructor<?> constructor)
|
||||
{
|
||||
init(constructor);
|
||||
}
|
||||
|
||||
private void init(Method method)
|
||||
{
|
||||
this.memberObject = method;
|
||||
this.argTypes = method.getParameterTypes();
|
||||
this.vararg = VMBridge.instance.isVarArgs(method);
|
||||
}
|
||||
|
||||
private void init(Constructor<?> constructor)
|
||||
{
|
||||
this.memberObject = constructor;
|
||||
this.argTypes = constructor.getParameterTypes();
|
||||
this.vararg = VMBridge.instance.isVarArgs(constructor);
|
||||
}
|
||||
|
||||
Method method()
|
||||
{
|
||||
return (Method)memberObject;
|
||||
}
|
||||
|
||||
Constructor<?> ctor()
|
||||
{
|
||||
return (Constructor<?>)memberObject;
|
||||
}
|
||||
|
||||
Member member()
|
||||
{
|
||||
return memberObject;
|
||||
}
|
||||
|
||||
boolean isMethod()
|
||||
{
|
||||
return memberObject instanceof Method;
|
||||
}
|
||||
|
||||
boolean isCtor()
|
||||
{
|
||||
return memberObject instanceof Constructor;
|
||||
}
|
||||
|
||||
boolean isStatic()
|
||||
{
|
||||
return Modifier.isStatic(memberObject.getModifiers());
|
||||
}
|
||||
|
||||
String getName()
|
||||
{
|
||||
return memberObject.getName();
|
||||
}
|
||||
|
||||
Class<?> getDeclaringClass()
|
||||
{
|
||||
return memberObject.getDeclaringClass();
|
||||
}
|
||||
|
||||
String toJavaDeclaration()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer();
|
||||
if (isMethod()) {
|
||||
Method method = method();
|
||||
sb.append(method.getReturnType());
|
||||
sb.append(' ');
|
||||
sb.append(method.getName());
|
||||
} else {
|
||||
Constructor<?> ctor = ctor();
|
||||
String name = ctor.getDeclaringClass().getName();
|
||||
int lastDot = name.lastIndexOf('.');
|
||||
if (lastDot >= 0) {
|
||||
name = name.substring(lastDot + 1);
|
||||
}
|
||||
sb.append(name);
|
||||
}
|
||||
sb.append(JavaMembers.liveConnectSignature(argTypes));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return memberObject.toString();
|
||||
}
|
||||
|
||||
Object invoke(Object target, Object[] args)
|
||||
{
|
||||
Method method = method();
|
||||
try {
|
||||
try {
|
||||
return method.invoke(target, args);
|
||||
} catch (IllegalAccessException ex) {
|
||||
Method accessible = searchAccessibleMethod(method, argTypes);
|
||||
if (accessible != null) {
|
||||
memberObject = accessible;
|
||||
method = accessible;
|
||||
} else {
|
||||
if (!VMBridge.instance.tryToMakeAccessible(method)) {
|
||||
throw Context.throwAsScriptRuntimeEx(ex);
|
||||
}
|
||||
}
|
||||
// Retry after recovery
|
||||
return method.invoke(target, args);
|
||||
}
|
||||
} catch (InvocationTargetException ite) {
|
||||
// Must allow ContinuationPending exceptions to propagate unhindered
|
||||
Throwable e = ite;
|
||||
do {
|
||||
e = ((InvocationTargetException) e).getTargetException();
|
||||
} while ((e instanceof InvocationTargetException));
|
||||
if (e instanceof ContinuationPending)
|
||||
throw (ContinuationPending) e;
|
||||
throw Context.throwAsScriptRuntimeEx(e);
|
||||
} catch (Exception ex) {
|
||||
throw Context.throwAsScriptRuntimeEx(ex);
|
||||
}
|
||||
}
|
||||
|
||||
Object newInstance(Object[] args)
|
||||
{
|
||||
Constructor<?> ctor = ctor();
|
||||
try {
|
||||
try {
|
||||
return ctor.newInstance(args);
|
||||
} catch (IllegalAccessException ex) {
|
||||
if (!VMBridge.instance.tryToMakeAccessible(ctor)) {
|
||||
throw Context.throwAsScriptRuntimeEx(ex);
|
||||
}
|
||||
}
|
||||
return ctor.newInstance(args);
|
||||
} catch (Exception ex) {
|
||||
throw Context.throwAsScriptRuntimeEx(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static Method searchAccessibleMethod(Method method, Class<?>[] params)
|
||||
{
|
||||
int modifiers = method.getModifiers();
|
||||
if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) {
|
||||
Class<?> c = method.getDeclaringClass();
|
||||
if (!Modifier.isPublic(c.getModifiers())) {
|
||||
String name = method.getName();
|
||||
Class<?>[] intfs = c.getInterfaces();
|
||||
for (int i = 0, N = intfs.length; i != N; ++i) {
|
||||
Class<?> intf = intfs[i];
|
||||
if (Modifier.isPublic(intf.getModifiers())) {
|
||||
try {
|
||||
return intf.getMethod(name, params);
|
||||
} catch (NoSuchMethodException ex) {
|
||||
} catch (SecurityException ex) { }
|
||||
}
|
||||
}
|
||||
for (;;) {
|
||||
c = c.getSuperclass();
|
||||
if (c == null) { break; }
|
||||
if (Modifier.isPublic(c.getModifiers())) {
|
||||
try {
|
||||
Method m = c.getMethod(name, params);
|
||||
int mModifiers = m.getModifiers();
|
||||
if (Modifier.isPublic(mModifiers)
|
||||
&& !Modifier.isStatic(mModifiers))
|
||||
{
|
||||
return m;
|
||||
}
|
||||
} catch (NoSuchMethodException ex) {
|
||||
} catch (SecurityException ex) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
in.defaultReadObject();
|
||||
Member member = readMember(in);
|
||||
if (member instanceof Method) {
|
||||
init((Method)member);
|
||||
} else {
|
||||
init((Constructor<?>)member);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.defaultWriteObject();
|
||||
writeMember(out, memberObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a Constructor or Method object.
|
||||
*
|
||||
* Methods and Constructors are not serializable, so we must serialize
|
||||
* information about the class, the name, and the parameters and
|
||||
* recreate upon deserialization.
|
||||
*/
|
||||
private static void writeMember(ObjectOutputStream out, Member member)
|
||||
throws IOException
|
||||
{
|
||||
if (member == null) {
|
||||
out.writeBoolean(false);
|
||||
return;
|
||||
}
|
||||
out.writeBoolean(true);
|
||||
if (!(member instanceof Method || member instanceof Constructor))
|
||||
throw new IllegalArgumentException("not Method or Constructor");
|
||||
out.writeBoolean(member instanceof Method);
|
||||
out.writeObject(member.getName());
|
||||
out.writeObject(member.getDeclaringClass());
|
||||
if (member instanceof Method) {
|
||||
writeParameters(out, ((Method) member).getParameterTypes());
|
||||
} else {
|
||||
writeParameters(out, ((Constructor<?>) member).getParameterTypes());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a Method or a Constructor from the stream.
|
||||
*/
|
||||
private static Member readMember(ObjectInputStream in)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
if (!in.readBoolean())
|
||||
return null;
|
||||
boolean isMethod = in.readBoolean();
|
||||
String name = (String) in.readObject();
|
||||
Class<?> declaring = (Class<?>) in.readObject();
|
||||
Class<?>[] parms = readParameters(in);
|
||||
try {
|
||||
if (isMethod) {
|
||||
return declaring.getMethod(name, parms);
|
||||
} else {
|
||||
return declaring.getConstructor(parms);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new IOException("Cannot find member: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
private static final Class<?>[] primitives = {
|
||||
Boolean.TYPE,
|
||||
Byte.TYPE,
|
||||
Character.TYPE,
|
||||
Double.TYPE,
|
||||
Float.TYPE,
|
||||
Integer.TYPE,
|
||||
Long.TYPE,
|
||||
Short.TYPE,
|
||||
Void.TYPE
|
||||
};
|
||||
|
||||
/**
|
||||
* Writes an array of parameter types to the stream.
|
||||
*
|
||||
* Requires special handling because primitive types cannot be
|
||||
* found upon deserialization by the default Java implementation.
|
||||
*/
|
||||
private static void writeParameters(ObjectOutputStream out, Class<?>[] parms)
|
||||
throws IOException
|
||||
{
|
||||
out.writeShort(parms.length);
|
||||
outer:
|
||||
for (int i=0; i < parms.length; i++) {
|
||||
Class<?> parm = parms[i];
|
||||
boolean primitive = parm.isPrimitive();
|
||||
out.writeBoolean(primitive);
|
||||
if (!primitive) {
|
||||
out.writeObject(parm);
|
||||
continue;
|
||||
}
|
||||
for (int j=0; j < primitives.length; j++) {
|
||||
if (parm.equals(primitives[j])) {
|
||||
out.writeByte(j);
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Primitive " + parm +
|
||||
" not found");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an array of parameter types from the stream.
|
||||
*/
|
||||
private static Class<?>[] readParameters(ObjectInputStream in)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
Class<?>[] result = new Class[in.readShort()];
|
||||
for (int i=0; i < result.length; i++) {
|
||||
if (!in.readBoolean()) {
|
||||
result[i] = (Class<?>) in.readObject();
|
||||
continue;
|
||||
}
|
||||
result[i] = primitives[in.readByte()];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,175 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Igor Bukanov
|
||||
* Mike McCabe
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* This class implements the Boolean native object.
|
||||
* See ECMA 15.6.
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
final class NativeBoolean extends IdScriptableObject
|
||||
{
|
||||
static final long serialVersionUID = -3716996899943880933L;
|
||||
|
||||
private static final Object BOOLEAN_TAG = "Boolean";
|
||||
|
||||
static void init(Scriptable scope, boolean sealed)
|
||||
{
|
||||
NativeBoolean obj = new NativeBoolean(false);
|
||||
obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
|
||||
}
|
||||
|
||||
private NativeBoolean(boolean b)
|
||||
{
|
||||
booleanValue = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName()
|
||||
{
|
||||
return "Boolean";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDefaultValue(Class<?> typeHint) {
|
||||
// This is actually non-ECMA, but will be proposed
|
||||
// as a change in round 2.
|
||||
if (typeHint == ScriptRuntime.BooleanClass)
|
||||
return ScriptRuntime.wrapBoolean(booleanValue);
|
||||
return super.getDefaultValue(typeHint);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_constructor: arity=1; s="constructor"; break;
|
||||
case Id_toString: arity=0; s="toString"; break;
|
||||
case Id_toSource: arity=0; s="toSource"; break;
|
||||
case Id_valueOf: arity=0; s="valueOf"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(BOOLEAN_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (!f.hasTag(BOOLEAN_TAG)) {
|
||||
return super.execIdCall(f, cx, scope, thisObj, args);
|
||||
}
|
||||
int id = f.methodId();
|
||||
|
||||
if (id == Id_constructor) {
|
||||
boolean b;
|
||||
if (args.length == 0) {
|
||||
b = false;
|
||||
} else {
|
||||
b = args[0] instanceof ScriptableObject &&
|
||||
((ScriptableObject) args[0]).avoidObjectDetection()
|
||||
? true
|
||||
: ScriptRuntime.toBoolean(args[0]);
|
||||
}
|
||||
if (thisObj == null) {
|
||||
// new Boolean(val) creates a new boolean object.
|
||||
return new NativeBoolean(b);
|
||||
}
|
||||
// Boolean(val) converts val to a boolean.
|
||||
return ScriptRuntime.wrapBoolean(b);
|
||||
}
|
||||
|
||||
// The rest of Boolean.prototype methods require thisObj to be Boolean
|
||||
|
||||
if (!(thisObj instanceof NativeBoolean))
|
||||
throw incompatibleCallError(f);
|
||||
boolean value = ((NativeBoolean)thisObj).booleanValue;
|
||||
|
||||
switch (id) {
|
||||
|
||||
case Id_toString:
|
||||
return value ? "true" : "false";
|
||||
|
||||
case Id_toSource:
|
||||
return value ? "(new Boolean(true))" : "(new Boolean(false))";
|
||||
|
||||
case Id_valueOf:
|
||||
return ScriptRuntime.wrapBoolean(value);
|
||||
}
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
@Override
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2007-05-09 08:15:31 EDT
|
||||
L0: { id = 0; String X = null; int c;
|
||||
int s_length = s.length();
|
||||
if (s_length==7) { X="valueOf";id=Id_valueOf; }
|
||||
else if (s_length==8) {
|
||||
c=s.charAt(3);
|
||||
if (c=='o') { X="toSource";id=Id_toSource; }
|
||||
else if (c=='t') { X="toString";id=Id_toString; }
|
||||
}
|
||||
else if (s_length==11) { X="constructor";id=Id_constructor; }
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
break L0;
|
||||
}
|
||||
// #/generated#
|
||||
return id;
|
||||
}
|
||||
|
||||
private static final int
|
||||
Id_constructor = 1,
|
||||
Id_toString = 2,
|
||||
Id_toSource = 3,
|
||||
Id_valueOf = 4,
|
||||
MAX_PROTOTYPE_ID = 4;
|
||||
|
||||
// #/string_id_map#
|
||||
|
||||
private boolean booleanValue;
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Bob Jervis
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* This class implements the activation object.
|
||||
*
|
||||
* See ECMA 10.1.6
|
||||
*
|
||||
* @see org.mozilla.javascript.Arguments
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
public final class NativeCall extends IdScriptableObject
|
||||
{
|
||||
static final long serialVersionUID = -7471457301304454454L;
|
||||
|
||||
private static final Object CALL_TAG = "Call";
|
||||
|
||||
static void init(Scriptable scope, boolean sealed)
|
||||
{
|
||||
NativeCall obj = new NativeCall();
|
||||
obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
|
||||
}
|
||||
|
||||
NativeCall() { }
|
||||
|
||||
NativeCall(NativeFunction function, Scriptable scope, Object[] args)
|
||||
{
|
||||
this.function = function;
|
||||
|
||||
setParentScope(scope);
|
||||
// leave prototype null
|
||||
|
||||
this.originalArgs = (args == null) ? ScriptRuntime.emptyArgs : args;
|
||||
|
||||
// initialize values of arguments
|
||||
int paramAndVarCount = function.getParamAndVarCount();
|
||||
int paramCount = function.getParamCount();
|
||||
if (paramAndVarCount != 0) {
|
||||
for (int i = 0; i < paramCount; ++i) {
|
||||
String name = function.getParamOrVarName(i);
|
||||
Object val = i < args.length ? args[i]
|
||||
: Undefined.instance;
|
||||
defineProperty(name, val, PERMANENT);
|
||||
}
|
||||
}
|
||||
|
||||
// initialize "arguments" property but only if it was not overridden by
|
||||
// the parameter with the same name
|
||||
if (!super.has("arguments", this)) {
|
||||
defineProperty("arguments", new Arguments(this), PERMANENT);
|
||||
}
|
||||
|
||||
if (paramAndVarCount != 0) {
|
||||
for (int i = paramCount; i < paramAndVarCount; ++i) {
|
||||
String name = function.getParamOrVarName(i);
|
||||
if (!super.has(name, this)) {
|
||||
if (function.getParamOrVarConst(i))
|
||||
defineProperty(name, Undefined.instance, CONST);
|
||||
else
|
||||
defineProperty(name, Undefined.instance, PERMANENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName()
|
||||
{
|
||||
return "Call";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
return s.equals("constructor") ? Id_constructor : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
if (id == Id_constructor) {
|
||||
arity=1; s="constructor";
|
||||
} else {
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(CALL_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (!f.hasTag(CALL_TAG)) {
|
||||
return super.execIdCall(f, cx, scope, thisObj, args);
|
||||
}
|
||||
int id = f.methodId();
|
||||
if (id == Id_constructor) {
|
||||
if (thisObj != null) {
|
||||
throw Context.reportRuntimeError1("msg.only.from.new", "Call");
|
||||
}
|
||||
ScriptRuntime.checkDeprecated(cx, "Call");
|
||||
NativeCall result = new NativeCall();
|
||||
result.setPrototype(getObjectPrototype(scope));
|
||||
return result;
|
||||
}
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
private static final int
|
||||
Id_constructor = 1,
|
||||
MAX_PROTOTYPE_ID = 1;
|
||||
|
||||
NativeFunction function;
|
||||
Object[] originalArgs;
|
||||
|
||||
transient NativeCall parentActivationCall;
|
||||
}
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
public final class NativeContinuation extends IdScriptableObject
|
||||
implements Function
|
||||
{
|
||||
static final long serialVersionUID = 1794167133757605367L;
|
||||
|
||||
private static final Object FTAG = "Continuation";
|
||||
|
||||
private Object implementation;
|
||||
|
||||
public static void init(Context cx, Scriptable scope, boolean sealed)
|
||||
{
|
||||
NativeContinuation obj = new NativeContinuation();
|
||||
obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
|
||||
}
|
||||
|
||||
public Object getImplementation()
|
||||
{
|
||||
return implementation;
|
||||
}
|
||||
|
||||
public void initImplementation(Object implementation)
|
||||
{
|
||||
this.implementation = implementation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName()
|
||||
{
|
||||
return "Continuation";
|
||||
}
|
||||
|
||||
public Scriptable construct(Context cx, Scriptable scope, Object[] args)
|
||||
{
|
||||
throw Context.reportRuntimeError("Direct call is not supported");
|
||||
}
|
||||
|
||||
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
|
||||
Object[] args)
|
||||
{
|
||||
return Interpreter.restartContinuation(this, cx, scope, args);
|
||||
}
|
||||
|
||||
public static boolean isContinuationConstructor(IdFunctionObject f)
|
||||
{
|
||||
if (f.hasTag(FTAG) && f.methodId() == Id_constructor) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_constructor: arity=0; s="constructor"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(FTAG, id, s, arity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (!f.hasTag(FTAG)) {
|
||||
return super.execIdCall(f, cx, scope, thisObj, args);
|
||||
}
|
||||
int id = f.methodId();
|
||||
switch (id) {
|
||||
case Id_constructor:
|
||||
throw Context.reportRuntimeError("Direct call is not supported");
|
||||
}
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
@Override
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2007-05-09 08:16:40 EDT
|
||||
L0: { id = 0; String X = null;
|
||||
if (s.length()==11) { X="constructor";id=Id_constructor; }
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
break L0;
|
||||
}
|
||||
// #/generated#
|
||||
return id;
|
||||
}
|
||||
|
||||
private static final int
|
||||
Id_constructor = 1,
|
||||
MAX_PROTOTYPE_ID = 1;
|
||||
|
||||
// #/string_id_map#
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,232 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov
|
||||
* Roger Lawrence
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
*
|
||||
* The class of error objects
|
||||
*
|
||||
* ECMA 15.11
|
||||
*/
|
||||
final class NativeError extends IdScriptableObject
|
||||
{
|
||||
static final long serialVersionUID = -5338413581437645187L;
|
||||
|
||||
private static final Object ERROR_TAG = "Error";
|
||||
|
||||
static void init(Scriptable scope, boolean sealed)
|
||||
{
|
||||
NativeError obj = new NativeError();
|
||||
ScriptableObject.putProperty(obj, "name", "Error");
|
||||
ScriptableObject.putProperty(obj, "message", "");
|
||||
ScriptableObject.putProperty(obj, "fileName", "");
|
||||
ScriptableObject.putProperty(obj, "lineNumber", Integer.valueOf(0));
|
||||
obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
|
||||
}
|
||||
|
||||
static NativeError make(Context cx, Scriptable scope,
|
||||
IdFunctionObject ctorObj, Object[] args)
|
||||
{
|
||||
Scriptable proto = (Scriptable)(ctorObj.get("prototype", ctorObj));
|
||||
|
||||
NativeError obj = new NativeError();
|
||||
obj.setPrototype(proto);
|
||||
obj.setParentScope(scope);
|
||||
|
||||
int arglen = args.length;
|
||||
if (arglen >= 1) {
|
||||
ScriptableObject.putProperty(obj, "message",
|
||||
ScriptRuntime.toString(args[0]));
|
||||
if (arglen >= 2) {
|
||||
ScriptableObject.putProperty(obj, "fileName", args[1]);
|
||||
if (arglen >= 3) {
|
||||
int line = ScriptRuntime.toInt32(args[2]);
|
||||
ScriptableObject.putProperty(obj, "lineNumber",
|
||||
Integer.valueOf(line));
|
||||
}
|
||||
}
|
||||
}
|
||||
if(arglen < 3 && cx.hasFeature(Context.FEATURE_LOCATION_INFORMATION_IN_ERROR)) {
|
||||
// Fill in fileName and lineNumber automatically when not specified
|
||||
// explicitly, see Bugzilla issue #342807
|
||||
int[] linep = new int[1];
|
||||
String fileName = Context.getSourcePositionFromStack(linep);
|
||||
ScriptableObject.putProperty(obj, "lineNumber",
|
||||
Integer.valueOf(linep[0]));
|
||||
if(arglen < 2) {
|
||||
ScriptableObject.putProperty(obj, "fileName", fileName);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName()
|
||||
{
|
||||
return "Error";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return js_toString(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_constructor: arity=1; s="constructor"; break;
|
||||
case Id_toString: arity=0; s="toString"; break;
|
||||
case Id_toSource: arity=0; s="toSource"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(ERROR_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (!f.hasTag(ERROR_TAG)) {
|
||||
return super.execIdCall(f, cx, scope, thisObj, args);
|
||||
}
|
||||
int id = f.methodId();
|
||||
switch (id) {
|
||||
case Id_constructor:
|
||||
return make(cx, scope, f, args);
|
||||
|
||||
case Id_toString:
|
||||
return js_toString(thisObj);
|
||||
|
||||
case Id_toSource:
|
||||
return js_toSource(cx, scope, thisObj);
|
||||
}
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
private static String js_toString(Scriptable thisObj)
|
||||
{
|
||||
return getString(thisObj, "name")+": "+getString(thisObj, "message");
|
||||
}
|
||||
|
||||
private static String js_toSource(Context cx, Scriptable scope,
|
||||
Scriptable thisObj)
|
||||
{
|
||||
// Emulation of SpiderMonkey behavior
|
||||
Object name = ScriptableObject.getProperty(thisObj, "name");
|
||||
Object message = ScriptableObject.getProperty(thisObj, "message");
|
||||
Object fileName = ScriptableObject.getProperty(thisObj, "fileName");
|
||||
Object lineNumber = ScriptableObject.getProperty(thisObj, "lineNumber");
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("(new ");
|
||||
if (name == NOT_FOUND) {
|
||||
name = Undefined.instance;
|
||||
}
|
||||
sb.append(ScriptRuntime.toString(name));
|
||||
sb.append("(");
|
||||
if (message != NOT_FOUND
|
||||
|| fileName != NOT_FOUND
|
||||
|| lineNumber != NOT_FOUND)
|
||||
{
|
||||
if (message == NOT_FOUND) {
|
||||
message = "";
|
||||
}
|
||||
sb.append(ScriptRuntime.uneval(cx, scope, message));
|
||||
if (fileName != NOT_FOUND || lineNumber != NOT_FOUND) {
|
||||
sb.append(", ");
|
||||
if (fileName == NOT_FOUND) {
|
||||
fileName = "";
|
||||
}
|
||||
sb.append(ScriptRuntime.uneval(cx, scope, fileName));
|
||||
if (lineNumber != NOT_FOUND) {
|
||||
int line = ScriptRuntime.toInt32(lineNumber);
|
||||
if (line != 0) {
|
||||
sb.append(", ");
|
||||
sb.append(ScriptRuntime.toString(line));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.append("))");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String getString(Scriptable obj, String id)
|
||||
{
|
||||
Object value = ScriptableObject.getProperty(obj, id);
|
||||
if (value == NOT_FOUND) return "";
|
||||
return ScriptRuntime.toString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
// #string_id_map#
|
||||
// #generated# Last update: 2007-05-09 08:15:45 EDT
|
||||
L0: { id = 0; String X = null; int c;
|
||||
int s_length = s.length();
|
||||
if (s_length==8) {
|
||||
c=s.charAt(3);
|
||||
if (c=='o') { X="toSource";id=Id_toSource; }
|
||||
else if (c=='t') { X="toString";id=Id_toString; }
|
||||
}
|
||||
else if (s_length==11) { X="constructor";id=Id_constructor; }
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
break L0;
|
||||
}
|
||||
// #/generated#
|
||||
return id;
|
||||
}
|
||||
|
||||
private static final int
|
||||
Id_constructor = 1,
|
||||
Id_toString = 2,
|
||||
Id_toSource = 3,
|
||||
|
||||
MAX_PROTOTYPE_ID = 3;
|
||||
|
||||
// #/string_id_map#
|
||||
}
|
||||
@@ -1,172 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Igor Bukanov
|
||||
* Bob Jervis
|
||||
* Roger Lawrence
|
||||
* Mike McCabe
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import org.mozilla.javascript.debug.DebuggableScript;
|
||||
|
||||
/**
|
||||
* This class implements the Function native object.
|
||||
* See ECMA 15.3.
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
public abstract class NativeFunction extends BaseFunction
|
||||
{
|
||||
|
||||
public final void initScriptFunction(Context cx, Scriptable scope)
|
||||
{
|
||||
ScriptRuntime.setFunctionProtoAndParent(this, scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param indent How much to indent the decompiled result
|
||||
*
|
||||
* @param flags Flags specifying format of decompilation output
|
||||
*/
|
||||
@Override
|
||||
final String decompile(int indent, int flags)
|
||||
{
|
||||
String encodedSource = getEncodedSource();
|
||||
if (encodedSource == null) {
|
||||
return super.decompile(indent, flags);
|
||||
} else {
|
||||
UintMap properties = new UintMap(1);
|
||||
properties.put(Decompiler.INITIAL_INDENT_PROP, indent);
|
||||
return Decompiler.decompile(encodedSource, flags, properties);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength()
|
||||
{
|
||||
int paramCount = getParamCount();
|
||||
if (getLanguageVersion() != Context.VERSION_1_2) {
|
||||
return paramCount;
|
||||
}
|
||||
Context cx = Context.getContext();
|
||||
NativeCall activation = ScriptRuntime.findFunctionActivation(cx, this);
|
||||
if (activation == null) {
|
||||
return paramCount;
|
||||
}
|
||||
return activation.originalArgs.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArity()
|
||||
{
|
||||
return getParamCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link BaseFunction#getFunctionName()} instead.
|
||||
* For backwards compatibility keep an old method name used by
|
||||
* Batik and possibly others.
|
||||
*/
|
||||
public String jsGet_name()
|
||||
{
|
||||
return getFunctionName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get encoded source string.
|
||||
*/
|
||||
public String getEncodedSource()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public DebuggableScript getDebuggableView()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resume execution of a suspended generator.
|
||||
* @param cx The current context
|
||||
* @param scope Scope for the parent generator function
|
||||
* @param operation The resumption operation (next, send, etc.. )
|
||||
* @param state The generator state (has locals, stack, etc.)
|
||||
* @param value The return value of yield (if required).
|
||||
* @return The next yielded value (if any)
|
||||
*/
|
||||
public Object resumeGenerator(Context cx, Scriptable scope,
|
||||
int operation, Object state, Object value)
|
||||
{
|
||||
throw new EvaluatorException("resumeGenerator() not implemented");
|
||||
}
|
||||
|
||||
|
||||
protected abstract int getLanguageVersion();
|
||||
|
||||
/**
|
||||
* Get number of declared parameters. It should be 0 for scripts.
|
||||
*/
|
||||
protected abstract int getParamCount();
|
||||
|
||||
/**
|
||||
* Get number of declared parameters and variables defined through var
|
||||
* statements.
|
||||
*/
|
||||
protected abstract int getParamAndVarCount();
|
||||
|
||||
/**
|
||||
* Get parameter or variable name.
|
||||
* If <tt>index < {@link #getParamCount()}</tt>, then return the name of the
|
||||
* corresponding parameter. Otherwise return the name of variable.
|
||||
*/
|
||||
protected abstract String getParamOrVarName(int index);
|
||||
|
||||
/**
|
||||
* Get parameter or variable const-ness.
|
||||
* If <tt>index < {@link #getParamCount()}</tt>, then return the const-ness
|
||||
* of the corresponding parameter. Otherwise return whether the variable is
|
||||
* const.
|
||||
*/
|
||||
protected boolean getParamOrVarConst(int index)
|
||||
{
|
||||
// By default return false to preserve compatibility with existing
|
||||
// classes subclassing this class, which are mostly generated by jsc
|
||||
// from earlier Rhino versions. See Bugzilla #396117.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,288 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* This class implements generator objects. See
|
||||
* http://developer.mozilla.org/en/docs/New_in_JavaScript_1.7#Generators
|
||||
*
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
public final class NativeGenerator extends IdScriptableObject {
|
||||
private static final long serialVersionUID = 1645892441041347273L;
|
||||
|
||||
private static final Object GENERATOR_TAG = "Generator";
|
||||
|
||||
static NativeGenerator init(ScriptableObject scope, boolean sealed) {
|
||||
// Generator
|
||||
// Can't use "NativeGenerator().exportAsJSClass" since we don't want
|
||||
// to define "Generator" as a constructor in the top-level scope.
|
||||
|
||||
NativeGenerator prototype = new NativeGenerator();
|
||||
if (scope != null) {
|
||||
prototype.setParentScope(scope);
|
||||
prototype.setPrototype(getObjectPrototype(scope));
|
||||
}
|
||||
prototype.activatePrototypeMap(MAX_PROTOTYPE_ID);
|
||||
if (sealed) {
|
||||
prototype.sealObject();
|
||||
}
|
||||
|
||||
// Need to access Generator prototype when constructing
|
||||
// Generator instances, but don't have a generator constructor
|
||||
// to use to find the prototype. Use the "associateValue"
|
||||
// approach instead.
|
||||
if (scope != null) {
|
||||
scope.associateValue(GENERATOR_TAG, prototype);
|
||||
}
|
||||
|
||||
return prototype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only for constructing the prototype object.
|
||||
*/
|
||||
private NativeGenerator() { }
|
||||
|
||||
public NativeGenerator(Scriptable scope, NativeFunction function,
|
||||
Object savedState)
|
||||
{
|
||||
this.function = function;
|
||||
this.savedState = savedState;
|
||||
// Set parent and prototype properties. Since we don't have a
|
||||
// "Generator" constructor in the top scope, we stash the
|
||||
// prototype in the top scope's associated value.
|
||||
Scriptable top = ScriptableObject.getTopLevelScope(scope);
|
||||
this.setParentScope(top);
|
||||
NativeGenerator prototype = (NativeGenerator)
|
||||
ScriptableObject.getTopScopeValue(top, GENERATOR_TAG);
|
||||
this.setPrototype(prototype);
|
||||
}
|
||||
|
||||
public static final int GENERATOR_SEND = 0,
|
||||
GENERATOR_THROW = 1,
|
||||
GENERATOR_CLOSE = 2;
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return "Generator";
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the generator if it is still open.
|
||||
*/
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
if (savedState != null) {
|
||||
// This is a little tricky since we are most likely running in
|
||||
// a different thread. We need to get a Context to run this, and
|
||||
// we must call "doTopCall" since this will likely be the outermost
|
||||
// JavaScript frame on this thread.
|
||||
Context cx = Context.getCurrentContext();
|
||||
ContextFactory factory = cx != null ? cx.getFactory()
|
||||
: ContextFactory.getGlobal();
|
||||
factory.call(new CloseGeneratorAction(this));
|
||||
}
|
||||
}
|
||||
|
||||
private static class CloseGeneratorAction implements ContextAction {
|
||||
private NativeGenerator generator;
|
||||
|
||||
CloseGeneratorAction(NativeGenerator generator) {
|
||||
this.generator = generator;
|
||||
}
|
||||
|
||||
public Object run(Context cx) {
|
||||
Scriptable scope = ScriptableObject.getTopLevelScope(generator);
|
||||
Callable closeGenerator = new Callable() {
|
||||
public Object call(Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args) {
|
||||
return ((NativeGenerator)thisObj).resume(cx, scope,
|
||||
GENERATOR_CLOSE, new GeneratorClosedException());
|
||||
}
|
||||
};
|
||||
return ScriptRuntime.doTopCall(closeGenerator, cx, scope,
|
||||
generator, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initPrototypeId(int id) {
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_close: arity=1; s="close"; break;
|
||||
case Id_next: arity=1; s="next"; break;
|
||||
case Id_send: arity=0; s="send"; break;
|
||||
case Id_throw: arity=0; s="throw"; break;
|
||||
case Id___iterator__: arity=1; s="__iterator__"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(GENERATOR_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (!f.hasTag(GENERATOR_TAG)) {
|
||||
return super.execIdCall(f, cx, scope, thisObj, args);
|
||||
}
|
||||
int id = f.methodId();
|
||||
|
||||
if (!(thisObj instanceof NativeGenerator))
|
||||
throw incompatibleCallError(f);
|
||||
|
||||
NativeGenerator generator = (NativeGenerator) thisObj;
|
||||
|
||||
switch (id) {
|
||||
|
||||
case Id_close:
|
||||
// need to run any pending finally clauses
|
||||
return generator.resume(cx, scope, GENERATOR_CLOSE,
|
||||
new GeneratorClosedException());
|
||||
|
||||
case Id_next:
|
||||
// arguments to next() are ignored
|
||||
generator.firstTime = false;
|
||||
return generator.resume(cx, scope, GENERATOR_SEND,
|
||||
Undefined.instance);
|
||||
|
||||
case Id_send: {
|
||||
Object arg = args.length > 0 ? args[0] : Undefined.instance;
|
||||
if (generator.firstTime && !arg.equals(Undefined.instance)) {
|
||||
throw ScriptRuntime.typeError0("msg.send.newborn");
|
||||
}
|
||||
return generator.resume(cx, scope, GENERATOR_SEND, arg);
|
||||
}
|
||||
|
||||
case Id_throw:
|
||||
return generator.resume(cx, scope, GENERATOR_THROW,
|
||||
args.length > 0 ? args[0] : Undefined.instance);
|
||||
|
||||
case Id___iterator__:
|
||||
return thisObj;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
}
|
||||
|
||||
private Object resume(Context cx, Scriptable scope, int operation,
|
||||
Object value)
|
||||
{
|
||||
if (savedState == null) {
|
||||
if (operation == GENERATOR_CLOSE)
|
||||
return Undefined.instance;
|
||||
Object thrown;
|
||||
if (operation == GENERATOR_THROW) {
|
||||
thrown = value;
|
||||
} else {
|
||||
thrown = NativeIterator.getStopIterationObject(scope);
|
||||
}
|
||||
throw new JavaScriptException(thrown, lineSource, lineNumber);
|
||||
}
|
||||
try {
|
||||
synchronized (this) {
|
||||
// generator execution is necessarily single-threaded and
|
||||
// non-reentrant.
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=349263
|
||||
if (locked)
|
||||
throw ScriptRuntime.typeError0("msg.already.exec.gen");
|
||||
locked = true;
|
||||
}
|
||||
return function.resumeGenerator(cx, scope, operation, savedState,
|
||||
value);
|
||||
} catch (GeneratorClosedException e) {
|
||||
// On closing a generator in the compile path, the generator
|
||||
// throws a special exception. This ensures execution of all pending
|
||||
// finalizers and will not get caught by user code.
|
||||
return Undefined.instance;
|
||||
} catch (RhinoException e) {
|
||||
lineNumber = e.lineNumber();
|
||||
lineSource = e.lineSource();
|
||||
savedState = null;
|
||||
throw e;
|
||||
} finally {
|
||||
synchronized (this) {
|
||||
locked = false;
|
||||
}
|
||||
if (operation == GENERATOR_CLOSE)
|
||||
savedState = null;
|
||||
}
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
@Override
|
||||
protected int findPrototypeId(String s) {
|
||||
int id;
|
||||
// #generated# Last update: 2007-06-14 13:13:03 EDT
|
||||
L0: { id = 0; String X = null; int c;
|
||||
int s_length = s.length();
|
||||
if (s_length==4) {
|
||||
c=s.charAt(0);
|
||||
if (c=='n') { X="next";id=Id_next; }
|
||||
else if (c=='s') { X="send";id=Id_send; }
|
||||
}
|
||||
else if (s_length==5) {
|
||||
c=s.charAt(0);
|
||||
if (c=='c') { X="close";id=Id_close; }
|
||||
else if (c=='t') { X="throw";id=Id_throw; }
|
||||
}
|
||||
else if (s_length==12) { X="__iterator__";id=Id___iterator__; }
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
break L0;
|
||||
}
|
||||
// #/generated#
|
||||
return id;
|
||||
}
|
||||
|
||||
private static final int
|
||||
Id_close = 1,
|
||||
Id_next = 2,
|
||||
Id_send = 3,
|
||||
Id_throw = 4,
|
||||
Id___iterator__ = 5,
|
||||
MAX_PROTOTYPE_ID = 5;
|
||||
|
||||
// #/string_id_map#
|
||||
private NativeFunction function;
|
||||
private Object savedState;
|
||||
private String lineSource;
|
||||
private int lineNumber;
|
||||
private boolean firstTime = true;
|
||||
private boolean locked;
|
||||
|
||||
public static class GeneratorClosedException extends RuntimeException {
|
||||
private static final long serialVersionUID = 2561315658662379681L;
|
||||
}
|
||||
}
|
||||
@@ -1,795 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Igor Bukanov
|
||||
* Mike McCabe
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.mozilla.javascript.xml.XMLLib;
|
||||
|
||||
/**
|
||||
* This class implements the global native object (function and value
|
||||
* properties only).
|
||||
*
|
||||
* See ECMA 15.1.[12].
|
||||
*
|
||||
* @author Mike Shaver
|
||||
*/
|
||||
|
||||
public class NativeGlobal implements Serializable, IdFunctionCall
|
||||
{
|
||||
static final long serialVersionUID = 6080442165748707530L;
|
||||
|
||||
public static void init(Context cx, Scriptable scope, boolean sealed) {
|
||||
NativeGlobal obj = new NativeGlobal();
|
||||
|
||||
for (int id = 1; id <= LAST_SCOPE_FUNCTION_ID; ++id) {
|
||||
String name;
|
||||
int arity = 1;
|
||||
switch (id) {
|
||||
case Id_decodeURI:
|
||||
name = "decodeURI";
|
||||
break;
|
||||
case Id_decodeURIComponent:
|
||||
name = "decodeURIComponent";
|
||||
break;
|
||||
case Id_encodeURI:
|
||||
name = "encodeURI";
|
||||
break;
|
||||
case Id_encodeURIComponent:
|
||||
name = "encodeURIComponent";
|
||||
break;
|
||||
case Id_escape:
|
||||
name = "escape";
|
||||
break;
|
||||
case Id_eval:
|
||||
name = "eval";
|
||||
break;
|
||||
case Id_isFinite:
|
||||
name = "isFinite";
|
||||
break;
|
||||
case Id_isNaN:
|
||||
name = "isNaN";
|
||||
break;
|
||||
case Id_isXMLName:
|
||||
name = "isXMLName";
|
||||
break;
|
||||
case Id_parseFloat:
|
||||
name = "parseFloat";
|
||||
break;
|
||||
case Id_parseInt:
|
||||
name = "parseInt";
|
||||
arity = 2;
|
||||
break;
|
||||
case Id_unescape:
|
||||
name = "unescape";
|
||||
break;
|
||||
case Id_uneval:
|
||||
name = "uneval";
|
||||
break;
|
||||
default:
|
||||
throw Kit.codeBug();
|
||||
}
|
||||
IdFunctionObject f = new IdFunctionObject(obj, FTAG, id, name,
|
||||
arity, scope);
|
||||
if (sealed) {
|
||||
f.sealObject();
|
||||
}
|
||||
f.exportAsScopeProperty();
|
||||
}
|
||||
|
||||
ScriptableObject.defineProperty(
|
||||
scope, "NaN", ScriptRuntime.NaNobj,
|
||||
ScriptableObject.DONTENUM);
|
||||
ScriptableObject.defineProperty(
|
||||
scope, "Infinity",
|
||||
ScriptRuntime.wrapNumber(Double.POSITIVE_INFINITY),
|
||||
ScriptableObject.DONTENUM);
|
||||
ScriptableObject.defineProperty(
|
||||
scope, "undefined", Undefined.instance,
|
||||
ScriptableObject.DONTENUM);
|
||||
|
||||
String[] errorMethods = {
|
||||
"ConversionError",
|
||||
"EvalError",
|
||||
"RangeError",
|
||||
"ReferenceError",
|
||||
"SyntaxError",
|
||||
"TypeError",
|
||||
"URIError",
|
||||
"InternalError",
|
||||
"JavaException"
|
||||
};
|
||||
|
||||
/*
|
||||
Each error constructor gets its own Error object as a prototype,
|
||||
with the 'name' property set to the name of the error.
|
||||
*/
|
||||
for (int i = 0; i < errorMethods.length; i++) {
|
||||
String name = errorMethods[i];
|
||||
Scriptable errorProto = ScriptRuntime.
|
||||
newObject(cx, scope, "Error",
|
||||
ScriptRuntime.emptyArgs);
|
||||
errorProto.put("name", errorProto, name);
|
||||
if (sealed) {
|
||||
if (errorProto instanceof ScriptableObject) {
|
||||
((ScriptableObject)errorProto).sealObject();
|
||||
}
|
||||
}
|
||||
IdFunctionObject ctor = new IdFunctionObject(obj, FTAG,
|
||||
Id_new_CommonError,
|
||||
name, 1, scope);
|
||||
ctor.markAsConstructor(errorProto);
|
||||
if (sealed) {
|
||||
ctor.sealObject();
|
||||
}
|
||||
ctor.exportAsScopeProperty();
|
||||
}
|
||||
}
|
||||
|
||||
public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (f.hasTag(FTAG)) {
|
||||
int methodId = f.methodId();
|
||||
switch (methodId) {
|
||||
case Id_decodeURI:
|
||||
case Id_decodeURIComponent: {
|
||||
String str = ScriptRuntime.toString(args, 0);
|
||||
return decode(str, methodId == Id_decodeURI);
|
||||
}
|
||||
|
||||
case Id_encodeURI:
|
||||
case Id_encodeURIComponent: {
|
||||
String str = ScriptRuntime.toString(args, 0);
|
||||
return encode(str, methodId == Id_encodeURI);
|
||||
}
|
||||
|
||||
case Id_escape:
|
||||
return js_escape(args);
|
||||
|
||||
case Id_eval:
|
||||
return js_eval(cx, scope, thisObj, args);
|
||||
|
||||
case Id_isFinite: {
|
||||
boolean result;
|
||||
if (args.length < 1) {
|
||||
result = false;
|
||||
} else {
|
||||
double d = ScriptRuntime.toNumber(args[0]);
|
||||
result = (d == d
|
||||
&& d != Double.POSITIVE_INFINITY
|
||||
&& d != Double.NEGATIVE_INFINITY);
|
||||
}
|
||||
return ScriptRuntime.wrapBoolean(result);
|
||||
}
|
||||
|
||||
case Id_isNaN: {
|
||||
// The global method isNaN, as per ECMA-262 15.1.2.6.
|
||||
boolean result;
|
||||
if (args.length < 1) {
|
||||
result = true;
|
||||
} else {
|
||||
double d = ScriptRuntime.toNumber(args[0]);
|
||||
result = (d != d);
|
||||
}
|
||||
return ScriptRuntime.wrapBoolean(result);
|
||||
}
|
||||
|
||||
case Id_isXMLName: {
|
||||
Object name = (args.length == 0)
|
||||
? Undefined.instance : args[0];
|
||||
XMLLib xmlLib = XMLLib.extractFromScope(scope);
|
||||
return ScriptRuntime.wrapBoolean(
|
||||
xmlLib.isXMLName(cx, name));
|
||||
}
|
||||
|
||||
case Id_parseFloat:
|
||||
return js_parseFloat(args);
|
||||
|
||||
case Id_parseInt:
|
||||
return js_parseInt(args);
|
||||
|
||||
case Id_unescape:
|
||||
return js_unescape(args);
|
||||
|
||||
case Id_uneval: {
|
||||
Object value = (args.length != 0)
|
||||
? args[0] : Undefined.instance;
|
||||
return ScriptRuntime.uneval(cx, scope, value);
|
||||
}
|
||||
|
||||
case Id_new_CommonError:
|
||||
// The implementation of all the ECMA error constructors
|
||||
// (SyntaxError, TypeError, etc.)
|
||||
return NativeError.make(cx, scope, f, args);
|
||||
}
|
||||
}
|
||||
throw f.unknown();
|
||||
}
|
||||
|
||||
/**
|
||||
* The global method parseInt, as per ECMA-262 15.1.2.2.
|
||||
*/
|
||||
private Object js_parseInt(Object[] args) {
|
||||
String s = ScriptRuntime.toString(args, 0);
|
||||
int radix = ScriptRuntime.toInt32(args, 1);
|
||||
|
||||
int len = s.length();
|
||||
if (len == 0)
|
||||
return ScriptRuntime.NaNobj;
|
||||
|
||||
boolean negative = false;
|
||||
int start = 0;
|
||||
char c;
|
||||
do {
|
||||
c = s.charAt(start);
|
||||
if (!Character.isWhitespace(c))
|
||||
break;
|
||||
start++;
|
||||
} while (start < len);
|
||||
|
||||
if (c == '+' || (negative = (c == '-')))
|
||||
start++;
|
||||
|
||||
final int NO_RADIX = -1;
|
||||
if (radix == 0) {
|
||||
radix = NO_RADIX;
|
||||
} else if (radix < 2 || radix > 36) {
|
||||
return ScriptRuntime.NaNobj;
|
||||
} else if (radix == 16 && len - start > 1 && s.charAt(start) == '0') {
|
||||
c = s.charAt(start+1);
|
||||
if (c == 'x' || c == 'X')
|
||||
start += 2;
|
||||
}
|
||||
|
||||
if (radix == NO_RADIX) {
|
||||
radix = 10;
|
||||
if (len - start > 1 && s.charAt(start) == '0') {
|
||||
c = s.charAt(start+1);
|
||||
if (c == 'x' || c == 'X') {
|
||||
radix = 16;
|
||||
start += 2;
|
||||
} else if ('0' <= c && c <= '9') {
|
||||
radix = 8;
|
||||
start++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double d = ScriptRuntime.stringToNumber(s, start, radix);
|
||||
return ScriptRuntime.wrapNumber(negative ? -d : d);
|
||||
}
|
||||
|
||||
/**
|
||||
* The global method parseFloat, as per ECMA-262 15.1.2.3.
|
||||
*
|
||||
* @param args the arguments to parseFloat, ignoring args[>=1]
|
||||
*/
|
||||
private Object js_parseFloat(Object[] args)
|
||||
{
|
||||
if (args.length < 1)
|
||||
return ScriptRuntime.NaNobj;
|
||||
|
||||
String s = ScriptRuntime.toString(args[0]);
|
||||
int len = s.length();
|
||||
int start = 0;
|
||||
// Scan forward to skip whitespace
|
||||
char c;
|
||||
for (;;) {
|
||||
if (start == len) {
|
||||
return ScriptRuntime.NaNobj;
|
||||
}
|
||||
c = s.charAt(start);
|
||||
if (!TokenStream.isJSSpace(c)) {
|
||||
break;
|
||||
}
|
||||
++start;
|
||||
}
|
||||
|
||||
int i = start;
|
||||
if (c == '+' || c == '-') {
|
||||
++i;
|
||||
if (i == len) {
|
||||
return ScriptRuntime.NaNobj;
|
||||
}
|
||||
c = s.charAt(i);
|
||||
}
|
||||
|
||||
if (c == 'I') {
|
||||
// check for "Infinity"
|
||||
if (i+8 <= len && s.regionMatches(i, "Infinity", 0, 8)) {
|
||||
double d;
|
||||
if (s.charAt(start) == '-') {
|
||||
d = Double.NEGATIVE_INFINITY;
|
||||
} else {
|
||||
d = Double.POSITIVE_INFINITY;
|
||||
}
|
||||
return ScriptRuntime.wrapNumber(d);
|
||||
}
|
||||
return ScriptRuntime.NaNobj;
|
||||
}
|
||||
|
||||
// Find the end of the legal bit
|
||||
int decimal = -1;
|
||||
int exponent = -1;
|
||||
for (; i < len; i++) {
|
||||
switch (s.charAt(i)) {
|
||||
case '.':
|
||||
if (decimal != -1) // Only allow a single decimal point.
|
||||
break;
|
||||
decimal = i;
|
||||
continue;
|
||||
|
||||
case 'e':
|
||||
case 'E':
|
||||
if (exponent != -1)
|
||||
break;
|
||||
exponent = i;
|
||||
continue;
|
||||
|
||||
case '+':
|
||||
case '-':
|
||||
// Only allow '+' or '-' after 'e' or 'E'
|
||||
if (exponent != i-1)
|
||||
break;
|
||||
continue;
|
||||
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
continue;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
s = s.substring(start, i);
|
||||
try {
|
||||
return Double.valueOf(s);
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
return ScriptRuntime.NaNobj;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The global method escape, as per ECMA-262 15.1.2.4.
|
||||
|
||||
* Includes code for the 'mask' argument supported by the C escape
|
||||
* method, which used to be part of the browser imbedding. Blame
|
||||
* for the strange constant names should be directed there.
|
||||
*/
|
||||
|
||||
private Object js_escape(Object[] args) {
|
||||
final int
|
||||
URL_XALPHAS = 1,
|
||||
URL_XPALPHAS = 2,
|
||||
URL_PATH = 4;
|
||||
|
||||
String s = ScriptRuntime.toString(args, 0);
|
||||
|
||||
int mask = URL_XALPHAS | URL_XPALPHAS | URL_PATH;
|
||||
if (args.length > 1) { // the 'mask' argument. Non-ECMA.
|
||||
double d = ScriptRuntime.toNumber(args[1]);
|
||||
if (d != d || ((mask = (int) d) != d) ||
|
||||
0 != (mask & ~(URL_XALPHAS | URL_XPALPHAS | URL_PATH)))
|
||||
{
|
||||
throw Context.reportRuntimeError0("msg.bad.esc.mask");
|
||||
}
|
||||
}
|
||||
|
||||
StringBuffer sb = null;
|
||||
for (int k = 0, L = s.length(); k != L; ++k) {
|
||||
int c = s.charAt(k);
|
||||
if (mask != 0
|
||||
&& ((c >= '0' && c <= '9')
|
||||
|| (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')
|
||||
|| c == '@' || c == '*' || c == '_' || c == '-' || c == '.'
|
||||
|| (0 != (mask & URL_PATH) && (c == '/' || c == '+'))))
|
||||
{
|
||||
if (sb != null) {
|
||||
sb.append((char)c);
|
||||
}
|
||||
} else {
|
||||
if (sb == null) {
|
||||
sb = new StringBuffer(L + 3);
|
||||
sb.append(s);
|
||||
sb.setLength(k);
|
||||
}
|
||||
|
||||
int hexSize;
|
||||
if (c < 256) {
|
||||
if (c == ' ' && mask == URL_XPALPHAS) {
|
||||
sb.append('+');
|
||||
continue;
|
||||
}
|
||||
sb.append('%');
|
||||
hexSize = 2;
|
||||
} else {
|
||||
sb.append('%');
|
||||
sb.append('u');
|
||||
hexSize = 4;
|
||||
}
|
||||
|
||||
// append hexadecimal form of c left-padded with 0
|
||||
for (int shift = (hexSize - 1) * 4; shift >= 0; shift -= 4) {
|
||||
int digit = 0xf & (c >> shift);
|
||||
int hc = (digit < 10) ? '0' + digit : 'A' - 10 + digit;
|
||||
sb.append((char)hc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (sb == null) ? s : sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* The global unescape method, as per ECMA-262 15.1.2.5.
|
||||
*/
|
||||
|
||||
private Object js_unescape(Object[] args)
|
||||
{
|
||||
String s = ScriptRuntime.toString(args, 0);
|
||||
int firstEscapePos = s.indexOf('%');
|
||||
if (firstEscapePos >= 0) {
|
||||
int L = s.length();
|
||||
char[] buf = s.toCharArray();
|
||||
int destination = firstEscapePos;
|
||||
for (int k = firstEscapePos; k != L;) {
|
||||
char c = buf[k];
|
||||
++k;
|
||||
if (c == '%' && k != L) {
|
||||
int end, start;
|
||||
if (buf[k] == 'u') {
|
||||
start = k + 1;
|
||||
end = k + 5;
|
||||
} else {
|
||||
start = k;
|
||||
end = k + 2;
|
||||
}
|
||||
if (end <= L) {
|
||||
int x = 0;
|
||||
for (int i = start; i != end; ++i) {
|
||||
x = Kit.xDigitToInt(buf[i], x);
|
||||
}
|
||||
if (x >= 0) {
|
||||
c = (char)x;
|
||||
k = end;
|
||||
}
|
||||
}
|
||||
}
|
||||
buf[destination] = c;
|
||||
++destination;
|
||||
}
|
||||
s = new String(buf, 0, destination);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
private Object js_eval(Context cx, Scriptable scope, Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (thisObj.getParentScope() == null) {
|
||||
// We allow indirect calls to eval as long as the script will execute in
|
||||
// the global scope.
|
||||
return ScriptRuntime.evalSpecial(cx, scope, thisObj, args, "eval code", 1);
|
||||
}
|
||||
String m = ScriptRuntime.getMessage1("msg.cant.call.indirect", "eval");
|
||||
throw NativeGlobal.constructError(cx, "EvalError", m, scope);
|
||||
}
|
||||
|
||||
static boolean isEvalFunction(Object functionObj)
|
||||
{
|
||||
if (functionObj instanceof IdFunctionObject) {
|
||||
IdFunctionObject function = (IdFunctionObject)functionObj;
|
||||
if (function.hasTag(FTAG) && function.methodId() == Id_eval) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link ScriptRuntime#constructError(String,String)}
|
||||
* instead.
|
||||
*/
|
||||
public static EcmaError constructError(Context cx,
|
||||
String error,
|
||||
String message,
|
||||
Scriptable scope)
|
||||
{
|
||||
return ScriptRuntime.constructError(error, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use
|
||||
* {@link ScriptRuntime#constructError(String,String,String,int,String,int)}
|
||||
* instead.
|
||||
*/
|
||||
public static EcmaError constructError(Context cx,
|
||||
String error,
|
||||
String message,
|
||||
Scriptable scope,
|
||||
String sourceName,
|
||||
int lineNumber,
|
||||
int columnNumber,
|
||||
String lineSource)
|
||||
{
|
||||
return ScriptRuntime.constructError(error, message,
|
||||
sourceName, lineNumber,
|
||||
lineSource, columnNumber);
|
||||
}
|
||||
|
||||
/*
|
||||
* ECMA 3, 15.1.3 URI Handling Function Properties
|
||||
*
|
||||
* The following are implementations of the algorithms
|
||||
* given in the ECMA specification for the hidden functions
|
||||
* 'Encode' and 'Decode'.
|
||||
*/
|
||||
private static String encode(String str, boolean fullUri) {
|
||||
byte[] utf8buf = null;
|
||||
StringBuffer sb = null;
|
||||
|
||||
for (int k = 0, length = str.length(); k != length; ++k) {
|
||||
char C = str.charAt(k);
|
||||
if (encodeUnescaped(C, fullUri)) {
|
||||
if (sb != null) {
|
||||
sb.append(C);
|
||||
}
|
||||
} else {
|
||||
if (sb == null) {
|
||||
sb = new StringBuffer(length + 3);
|
||||
sb.append(str);
|
||||
sb.setLength(k);
|
||||
utf8buf = new byte[6];
|
||||
}
|
||||
if (0xDC00 <= C && C <= 0xDFFF) {
|
||||
throw Context.reportRuntimeError0("msg.bad.uri");
|
||||
}
|
||||
int V;
|
||||
if (C < 0xD800 || 0xDBFF < C) {
|
||||
V = C;
|
||||
} else {
|
||||
k++;
|
||||
if (k == length) {
|
||||
throw Context.reportRuntimeError0("msg.bad.uri");
|
||||
}
|
||||
char C2 = str.charAt(k);
|
||||
if (!(0xDC00 <= C2 && C2 <= 0xDFFF)) {
|
||||
throw Context.reportRuntimeError0("msg.bad.uri");
|
||||
}
|
||||
V = ((C - 0xD800) << 10) + (C2 - 0xDC00) + 0x10000;
|
||||
}
|
||||
int L = oneUcs4ToUtf8Char(utf8buf, V);
|
||||
for (int j = 0; j < L; j++) {
|
||||
int d = 0xff & utf8buf[j];
|
||||
sb.append('%');
|
||||
sb.append(toHexChar(d >>> 4));
|
||||
sb.append(toHexChar(d & 0xf));
|
||||
}
|
||||
}
|
||||
}
|
||||
return (sb == null) ? str : sb.toString();
|
||||
}
|
||||
|
||||
private static char toHexChar(int i) {
|
||||
if (i >> 4 != 0) Kit.codeBug();
|
||||
return (char)((i < 10) ? i + '0' : i - 10 + 'A');
|
||||
}
|
||||
|
||||
private static int unHex(char c) {
|
||||
if ('A' <= c && c <= 'F') {
|
||||
return c - 'A' + 10;
|
||||
} else if ('a' <= c && c <= 'f') {
|
||||
return c - 'a' + 10;
|
||||
} else if ('0' <= c && c <= '9') {
|
||||
return c - '0';
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private static int unHex(char c1, char c2) {
|
||||
int i1 = unHex(c1);
|
||||
int i2 = unHex(c2);
|
||||
if (i1 >= 0 && i2 >= 0) {
|
||||
return (i1 << 4) | i2;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static String decode(String str, boolean fullUri) {
|
||||
char[] buf = null;
|
||||
int bufTop = 0;
|
||||
|
||||
for (int k = 0, length = str.length(); k != length;) {
|
||||
char C = str.charAt(k);
|
||||
if (C != '%') {
|
||||
if (buf != null) {
|
||||
buf[bufTop++] = C;
|
||||
}
|
||||
++k;
|
||||
} else {
|
||||
if (buf == null) {
|
||||
// decode always compress so result can not be bigger then
|
||||
// str.length()
|
||||
buf = new char[length];
|
||||
str.getChars(0, k, buf, 0);
|
||||
bufTop = k;
|
||||
}
|
||||
int start = k;
|
||||
if (k + 3 > length)
|
||||
throw Context.reportRuntimeError0("msg.bad.uri");
|
||||
int B = unHex(str.charAt(k + 1), str.charAt(k + 2));
|
||||
if (B < 0) throw Context.reportRuntimeError0("msg.bad.uri");
|
||||
k += 3;
|
||||
if ((B & 0x80) == 0) {
|
||||
C = (char)B;
|
||||
} else {
|
||||
// Decode UTF-8 sequence into ucs4Char and encode it into
|
||||
// UTF-16
|
||||
int utf8Tail, ucs4Char, minUcs4Char;
|
||||
if ((B & 0xC0) == 0x80) {
|
||||
// First UTF-8 should be ouside 0x80..0xBF
|
||||
throw Context.reportRuntimeError0("msg.bad.uri");
|
||||
} else if ((B & 0x20) == 0) {
|
||||
utf8Tail = 1; ucs4Char = B & 0x1F;
|
||||
minUcs4Char = 0x80;
|
||||
} else if ((B & 0x10) == 0) {
|
||||
utf8Tail = 2; ucs4Char = B & 0x0F;
|
||||
minUcs4Char = 0x800;
|
||||
} else if ((B & 0x08) == 0) {
|
||||
utf8Tail = 3; ucs4Char = B & 0x07;
|
||||
minUcs4Char = 0x10000;
|
||||
} else if ((B & 0x04) == 0) {
|
||||
utf8Tail = 4; ucs4Char = B & 0x03;
|
||||
minUcs4Char = 0x200000;
|
||||
} else if ((B & 0x02) == 0) {
|
||||
utf8Tail = 5; ucs4Char = B & 0x01;
|
||||
minUcs4Char = 0x4000000;
|
||||
} else {
|
||||
// First UTF-8 can not be 0xFF or 0xFE
|
||||
throw Context.reportRuntimeError0("msg.bad.uri");
|
||||
}
|
||||
if (k + 3 * utf8Tail > length)
|
||||
throw Context.reportRuntimeError0("msg.bad.uri");
|
||||
for (int j = 0; j != utf8Tail; j++) {
|
||||
if (str.charAt(k) != '%')
|
||||
throw Context.reportRuntimeError0("msg.bad.uri");
|
||||
B = unHex(str.charAt(k + 1), str.charAt(k + 2));
|
||||
if (B < 0 || (B & 0xC0) != 0x80)
|
||||
throw Context.reportRuntimeError0("msg.bad.uri");
|
||||
ucs4Char = (ucs4Char << 6) | (B & 0x3F);
|
||||
k += 3;
|
||||
}
|
||||
// Check for overlongs and other should-not-present codes
|
||||
if (ucs4Char < minUcs4Char
|
||||
|| ucs4Char == 0xFFFE || ucs4Char == 0xFFFF)
|
||||
{
|
||||
ucs4Char = 0xFFFD;
|
||||
}
|
||||
if (ucs4Char >= 0x10000) {
|
||||
ucs4Char -= 0x10000;
|
||||
if (ucs4Char > 0xFFFFF)
|
||||
throw Context.reportRuntimeError0("msg.bad.uri");
|
||||
char H = (char)((ucs4Char >>> 10) + 0xD800);
|
||||
C = (char)((ucs4Char & 0x3FF) + 0xDC00);
|
||||
buf[bufTop++] = H;
|
||||
} else {
|
||||
C = (char)ucs4Char;
|
||||
}
|
||||
}
|
||||
if (fullUri && URI_DECODE_RESERVED.indexOf(C) >= 0) {
|
||||
for (int x = start; x != k; x++) {
|
||||
buf[bufTop++] = str.charAt(x);
|
||||
}
|
||||
} else {
|
||||
buf[bufTop++] = C;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (buf == null) ? str : new String(buf, 0, bufTop);
|
||||
}
|
||||
|
||||
private static boolean encodeUnescaped(char c, boolean fullUri) {
|
||||
if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')
|
||||
|| ('0' <= c && c <= '9'))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ("-_.!~*'()".indexOf(c) >= 0)
|
||||
return true;
|
||||
if (fullUri) {
|
||||
return URI_DECODE_RESERVED.indexOf(c) >= 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static final String URI_DECODE_RESERVED = ";/?:@&=+$,#";
|
||||
|
||||
/* Convert one UCS-4 char and write it into a UTF-8 buffer, which must be
|
||||
* at least 6 bytes long. Return the number of UTF-8 bytes of data written.
|
||||
*/
|
||||
private static int oneUcs4ToUtf8Char(byte[] utf8Buffer, int ucs4Char) {
|
||||
int utf8Length = 1;
|
||||
|
||||
//JS_ASSERT(ucs4Char <= 0x7FFFFFFF);
|
||||
if ((ucs4Char & ~0x7F) == 0)
|
||||
utf8Buffer[0] = (byte)ucs4Char;
|
||||
else {
|
||||
int i;
|
||||
int a = ucs4Char >>> 11;
|
||||
utf8Length = 2;
|
||||
while (a != 0) {
|
||||
a >>>= 5;
|
||||
utf8Length++;
|
||||
}
|
||||
i = utf8Length;
|
||||
while (--i > 0) {
|
||||
utf8Buffer[i] = (byte)((ucs4Char & 0x3F) | 0x80);
|
||||
ucs4Char >>>= 6;
|
||||
}
|
||||
utf8Buffer[0] = (byte)(0x100 - (1 << (8-utf8Length)) + ucs4Char);
|
||||
}
|
||||
return utf8Length;
|
||||
}
|
||||
|
||||
private static final Object FTAG = "Global";
|
||||
|
||||
private static final int
|
||||
Id_decodeURI = 1,
|
||||
Id_decodeURIComponent = 2,
|
||||
Id_encodeURI = 3,
|
||||
Id_encodeURIComponent = 4,
|
||||
Id_escape = 5,
|
||||
Id_eval = 6,
|
||||
Id_isFinite = 7,
|
||||
Id_isNaN = 8,
|
||||
Id_isXMLName = 9,
|
||||
Id_parseFloat = 10,
|
||||
Id_parseInt = 11,
|
||||
Id_unescape = 12,
|
||||
Id_uneval = 13,
|
||||
|
||||
LAST_SCOPE_FUNCTION_ID = 13,
|
||||
|
||||
Id_new_CommonError = 14;
|
||||
}
|
||||
@@ -1,269 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* This class implements iterator objects. See
|
||||
* http://developer.mozilla.org/en/docs/New_in_JavaScript_1.7#Iterators
|
||||
*
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
public final class NativeIterator extends IdScriptableObject {
|
||||
private static final long serialVersionUID = -4136968203581667681L;
|
||||
private static final Object ITERATOR_TAG = "Iterator";
|
||||
|
||||
static void init(ScriptableObject scope, boolean sealed) {
|
||||
// Iterator
|
||||
NativeIterator iterator = new NativeIterator();
|
||||
iterator.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
|
||||
|
||||
// Generator
|
||||
NativeGenerator.init(scope, sealed);
|
||||
|
||||
// StopIteration
|
||||
NativeObject obj = new StopIteration();
|
||||
obj.setPrototype(getObjectPrototype(scope));
|
||||
obj.setParentScope(scope);
|
||||
if (sealed) { obj.sealObject(); }
|
||||
ScriptableObject.defineProperty(scope, STOP_ITERATION, obj,
|
||||
ScriptableObject.DONTENUM);
|
||||
// Use "associateValue" so that generators can continue to
|
||||
// throw StopIteration even if the property of the global
|
||||
// scope is replaced or deleted.
|
||||
scope.associateValue(ITERATOR_TAG, obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only for constructing the prototype object.
|
||||
*/
|
||||
private NativeIterator() {
|
||||
}
|
||||
|
||||
private NativeIterator(Object objectIterator) {
|
||||
this.objectIterator = objectIterator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the "StopIteration" object. Note that this value
|
||||
* is stored in the top-level scope using "associateValue" so the
|
||||
* value can still be found even if a script overwrites or deletes
|
||||
* the global "StopIteration" property.
|
||||
* @param scope a scope whose parent chain reaches a top-level scope
|
||||
* @return the StopIteration object
|
||||
*/
|
||||
public static Object getStopIterationObject(Scriptable scope) {
|
||||
Scriptable top = ScriptableObject.getTopLevelScope(scope);
|
||||
return ScriptableObject.getTopScopeValue(top, ITERATOR_TAG);
|
||||
}
|
||||
|
||||
private static final String STOP_ITERATION = "StopIteration";
|
||||
public static final String ITERATOR_PROPERTY_NAME = "__iterator__";
|
||||
|
||||
static class StopIteration extends NativeObject {
|
||||
private static final long serialVersionUID = 2485151085722377663L;
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return STOP_ITERATION;
|
||||
}
|
||||
|
||||
/* StopIteration has custom instanceof behavior since it
|
||||
* doesn't have a constructor.
|
||||
*/
|
||||
@Override
|
||||
public boolean hasInstance(Scriptable instance) {
|
||||
return instance instanceof StopIteration;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return "Iterator";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initPrototypeId(int id) {
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_constructor: arity=2; s="constructor"; break;
|
||||
case Id_next: arity=0; s="next"; break;
|
||||
case Id___iterator__: arity=1; s=ITERATOR_PROPERTY_NAME; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(ITERATOR_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (!f.hasTag(ITERATOR_TAG)) {
|
||||
return super.execIdCall(f, cx, scope, thisObj, args);
|
||||
}
|
||||
int id = f.methodId();
|
||||
|
||||
if (id == Id_constructor) {
|
||||
return jsConstructor(cx, scope, thisObj, args);
|
||||
}
|
||||
|
||||
if (!(thisObj instanceof NativeIterator))
|
||||
throw incompatibleCallError(f);
|
||||
|
||||
NativeIterator iterator = (NativeIterator) thisObj;
|
||||
|
||||
switch (id) {
|
||||
|
||||
case Id_next:
|
||||
return iterator.next(cx, scope);
|
||||
|
||||
case Id___iterator__:
|
||||
/// XXX: what about argument? SpiderMonkey apparently ignores it
|
||||
return thisObj;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
}
|
||||
|
||||
/* The JavaScript constructor */
|
||||
private static Object jsConstructor(Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (args.length == 0 || args[0] == null ||
|
||||
args[0] == Undefined.instance)
|
||||
{
|
||||
throw ScriptRuntime.typeError1("msg.no.properties",
|
||||
ScriptRuntime.toString(args[0]));
|
||||
}
|
||||
Scriptable obj = ScriptRuntime.toObject(scope, args[0]);
|
||||
boolean keyOnly = args.length > 1 && ScriptRuntime.toBoolean(args[1]);
|
||||
if (thisObj != null) {
|
||||
// Called as a function. Convert to iterator if possible.
|
||||
|
||||
// For objects that implement java.lang.Iterable or
|
||||
// java.util.Iterator, have JavaScript Iterator call the underlying
|
||||
// iteration methods
|
||||
Iterator<?> iterator =
|
||||
VMBridge.instance.getJavaIterator(cx, scope, obj);
|
||||
if (iterator != null) {
|
||||
scope = ScriptableObject.getTopLevelScope(scope);
|
||||
return cx.getWrapFactory().wrap(cx, scope,
|
||||
new WrappedJavaIterator(iterator, scope),
|
||||
WrappedJavaIterator.class);
|
||||
}
|
||||
|
||||
// Otherwise, just call the runtime routine
|
||||
Scriptable jsIterator = ScriptRuntime.toIterator(cx, scope, obj,
|
||||
keyOnly);
|
||||
if (jsIterator != null) {
|
||||
return jsIterator;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, just set up to iterate over the properties of the object.
|
||||
// Do not call __iterator__ method.
|
||||
Object objectIterator = ScriptRuntime.enumInit(obj, cx,
|
||||
keyOnly ? ScriptRuntime.ENUMERATE_KEYS_NO_ITERATOR
|
||||
: ScriptRuntime.ENUMERATE_ARRAY_NO_ITERATOR);
|
||||
ScriptRuntime.setEnumNumbers(objectIterator, true);
|
||||
NativeIterator result = new NativeIterator(objectIterator);
|
||||
result.setPrototype(ScriptableObject.getClassPrototype(scope,
|
||||
result.getClassName()));
|
||||
result.setParentScope(scope);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Object next(Context cx, Scriptable scope) {
|
||||
Boolean b = ScriptRuntime.enumNext(this.objectIterator);
|
||||
if (!b.booleanValue()) {
|
||||
// Out of values. Throw StopIteration.
|
||||
throw new JavaScriptException(
|
||||
NativeIterator.getStopIterationObject(scope), null, 0);
|
||||
}
|
||||
return ScriptRuntime.enumId(this.objectIterator, cx);
|
||||
}
|
||||
|
||||
static public class WrappedJavaIterator
|
||||
{
|
||||
WrappedJavaIterator(Iterator<?> iterator, Scriptable scope) {
|
||||
this.iterator = iterator;
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public Object next() {
|
||||
if (!iterator.hasNext()) {
|
||||
// Out of values. Throw StopIteration.
|
||||
throw new JavaScriptException(
|
||||
NativeIterator.getStopIterationObject(scope), null, 0);
|
||||
}
|
||||
return iterator.next();
|
||||
}
|
||||
|
||||
public Object __iterator__(boolean b) {
|
||||
return this;
|
||||
}
|
||||
|
||||
private Iterator<?> iterator;
|
||||
private Scriptable scope;
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
@Override
|
||||
protected int findPrototypeId(String s) {
|
||||
int id;
|
||||
// #generated# Last update: 2007-06-11 09:43:19 EDT
|
||||
L0: { id = 0; String X = null;
|
||||
int s_length = s.length();
|
||||
if (s_length==4) { X="next";id=Id_next; }
|
||||
else if (s_length==11) { X="constructor";id=Id_constructor; }
|
||||
else if (s_length==12) { X="__iterator__";id=Id___iterator__; }
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
break L0;
|
||||
}
|
||||
// #/generated#
|
||||
return id;
|
||||
}
|
||||
|
||||
private static final int
|
||||
Id_constructor = 1,
|
||||
Id_next = 2,
|
||||
Id___iterator__ = 3,
|
||||
MAX_PROTOTYPE_ID = 3;
|
||||
|
||||
// #/string_id_map#
|
||||
|
||||
private Object objectIterator;
|
||||
}
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Igor Bukanov
|
||||
* Frank Mitchell
|
||||
* Mike Shaver
|
||||
* Kemal Bayram
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
/**
|
||||
* This class reflects Java arrays into the JavaScript environment.
|
||||
*
|
||||
* @author Mike Shaver
|
||||
* @see NativeJavaClass
|
||||
* @see NativeJavaObject
|
||||
* @see NativeJavaPackage
|
||||
*/
|
||||
|
||||
public class NativeJavaArray extends NativeJavaObject
|
||||
{
|
||||
static final long serialVersionUID = -924022554283675333L;
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return "JavaArray";
|
||||
}
|
||||
|
||||
public static NativeJavaArray wrap(Scriptable scope, Object array) {
|
||||
return new NativeJavaArray(scope, array);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object unwrap() {
|
||||
return array;
|
||||
}
|
||||
|
||||
public NativeJavaArray(Scriptable scope, Object array) {
|
||||
super(scope, null, ScriptRuntime.ObjectClass);
|
||||
Class<?> cl = array.getClass();
|
||||
if (!cl.isArray()) {
|
||||
throw new RuntimeException("Array expected");
|
||||
}
|
||||
this.array = array;
|
||||
this.length = Array.getLength(array);
|
||||
this.cls = cl.getComponentType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(String id, Scriptable start) {
|
||||
return id.equals("length") || super.has(id, start);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(int index, Scriptable start) {
|
||||
return 0 <= index && index < length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String id, Scriptable start) {
|
||||
if (id.equals("length"))
|
||||
return Integer.valueOf(length);
|
||||
Object result = super.get(id, start);
|
||||
if (result == NOT_FOUND &&
|
||||
!ScriptableObject.hasProperty(getPrototype(), id))
|
||||
{
|
||||
throw Context.reportRuntimeError2(
|
||||
"msg.java.member.not.found", array.getClass().getName(), id);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(int index, Scriptable start) {
|
||||
if (0 <= index && index < length) {
|
||||
Context cx = Context.getContext();
|
||||
Object obj = Array.get(array, index);
|
||||
return cx.getWrapFactory().wrap(cx, this, obj, cls);
|
||||
}
|
||||
return Undefined.instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(String id, Scriptable start, Object value) {
|
||||
// Ignore assignments to "length"--it's readonly.
|
||||
if (!id.equals("length"))
|
||||
throw Context.reportRuntimeError1(
|
||||
"msg.java.array.member.not.found", id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(int index, Scriptable start, Object value) {
|
||||
if (0 <= index && index < length) {
|
||||
Array.set(array, index, Context.jsToJava(value, cls));
|
||||
}
|
||||
else {
|
||||
throw Context.reportRuntimeError2(
|
||||
"msg.java.array.index.out.of.bounds", String.valueOf(index),
|
||||
String.valueOf(length - 1));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDefaultValue(Class<?> hint) {
|
||||
if (hint == null || hint == ScriptRuntime.StringClass)
|
||||
return array.toString();
|
||||
if (hint == ScriptRuntime.BooleanClass)
|
||||
return Boolean.TRUE;
|
||||
if (hint == ScriptRuntime.NumberClass)
|
||||
return ScriptRuntime.NaNobj;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getIds() {
|
||||
Object[] result = new Object[length];
|
||||
int i = length;
|
||||
while (--i >= 0)
|
||||
result[i] = Integer.valueOf(i);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasInstance(Scriptable value) {
|
||||
if (!(value instanceof Wrapper))
|
||||
return false;
|
||||
Object instance = ((Wrapper)value).unwrap();
|
||||
return cls.isInstance(instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scriptable getPrototype() {
|
||||
if (prototype == null) {
|
||||
prototype =
|
||||
ScriptableObject.getClassPrototype(this.getParentScope(),
|
||||
"Array");
|
||||
}
|
||||
return prototype;
|
||||
}
|
||||
|
||||
Object array;
|
||||
int length;
|
||||
Class<?> cls;
|
||||
}
|
||||
@@ -1,330 +0,0 @@
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1997-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Frank Mitchell
|
||||
* Mike Shaver
|
||||
* Kurt Westerfeld
|
||||
* Kemal Bayram
|
||||
* Ulrike Mueller <umueller@demandware.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This class reflects Java classes into the JavaScript environment, mainly
|
||||
* for constructors and static members. We lazily reflect properties,
|
||||
* and currently do not guarantee that a single j.l.Class is only
|
||||
* reflected once into the JS environment, although we should.
|
||||
* The only known case where multiple reflections
|
||||
* are possible occurs when a j.l.Class is wrapped as part of a
|
||||
* method return or property access, rather than by walking the
|
||||
* Packages/java tree.
|
||||
*
|
||||
* @author Mike Shaver
|
||||
* @see NativeJavaArray
|
||||
* @see NativeJavaObject
|
||||
* @see NativeJavaPackage
|
||||
*/
|
||||
|
||||
public class NativeJavaClass extends NativeJavaObject implements Function
|
||||
{
|
||||
static final long serialVersionUID = -6460763940409461664L;
|
||||
|
||||
// Special property for getting the underlying Java class object.
|
||||
static final String javaClassPropertyName = "__javaObject__";
|
||||
|
||||
public NativeJavaClass() {
|
||||
}
|
||||
|
||||
public NativeJavaClass(Scriptable scope, Class<?> cl) {
|
||||
this.parent = scope;
|
||||
this.javaObject = cl;
|
||||
initMembers();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initMembers() {
|
||||
Class<?> cl = (Class<?>)javaObject;
|
||||
members = JavaMembers.lookupClass(parent, cl, cl, false);
|
||||
staticFieldAndMethods
|
||||
= members.getFieldAndMethodsObjects(this, cl, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return "JavaClass";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(String name, Scriptable start) {
|
||||
return members.has(name, true) || javaClassPropertyName.equals(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String name, Scriptable start) {
|
||||
// When used as a constructor, ScriptRuntime.newObject() asks
|
||||
// for our prototype to create an object of the correct type.
|
||||
// We don't really care what the object is, since we're returning
|
||||
// one constructed out of whole cloth, so we return null.
|
||||
if (name.equals("prototype"))
|
||||
return null;
|
||||
|
||||
if (staticFieldAndMethods != null) {
|
||||
Object result = staticFieldAndMethods.get(name);
|
||||
if (result != null)
|
||||
return result;
|
||||
}
|
||||
|
||||
if (members.has(name, true)) {
|
||||
return members.get(this, name, javaObject, true);
|
||||
}
|
||||
|
||||
if (javaClassPropertyName.equals(name)) {
|
||||
Context cx = Context.getContext();
|
||||
Scriptable scope = ScriptableObject.getTopLevelScope(start);
|
||||
return cx.getWrapFactory().wrap(cx, scope, javaObject,
|
||||
ScriptRuntime.ClassClass);
|
||||
}
|
||||
|
||||
// experimental: look for nested classes by appending $name to
|
||||
// current class' name.
|
||||
Class<?> nestedClass = findNestedClass(getClassObject(), name);
|
||||
if (nestedClass != null) {
|
||||
NativeJavaClass nestedValue = new NativeJavaClass
|
||||
(ScriptableObject.getTopLevelScope(this), nestedClass);
|
||||
nestedValue.setParentScope(this);
|
||||
return nestedValue;
|
||||
}
|
||||
|
||||
throw members.reportMemberNotFound(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(String name, Scriptable start, Object value) {
|
||||
members.put(this, name, javaObject, value, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getIds() {
|
||||
return members.getIds(true);
|
||||
}
|
||||
|
||||
public Class<?> getClassObject() {
|
||||
return (Class<?>) super.unwrap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDefaultValue(Class<?> hint) {
|
||||
if (hint == null || hint == ScriptRuntime.StringClass)
|
||||
return this.toString();
|
||||
if (hint == ScriptRuntime.BooleanClass)
|
||||
return Boolean.TRUE;
|
||||
if (hint == ScriptRuntime.NumberClass)
|
||||
return ScriptRuntime.NaNobj;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
|
||||
Object[] args)
|
||||
{
|
||||
// If it looks like a "cast" of an object to this class type,
|
||||
// walk the prototype chain to see if there's a wrapper of a
|
||||
// object that's an instanceof this class.
|
||||
if (args.length == 1 && args[0] instanceof Scriptable) {
|
||||
Class<?> c = getClassObject();
|
||||
Scriptable p = (Scriptable) args[0];
|
||||
do {
|
||||
if (p instanceof Wrapper) {
|
||||
Object o = ((Wrapper) p).unwrap();
|
||||
if (c.isInstance(o))
|
||||
return p;
|
||||
}
|
||||
p = p.getPrototype();
|
||||
} while (p != null);
|
||||
}
|
||||
return construct(cx, scope, args);
|
||||
}
|
||||
|
||||
public Scriptable construct(Context cx, Scriptable scope, Object[] args)
|
||||
{
|
||||
Class<?> classObject = getClassObject();
|
||||
int modifiers = classObject.getModifiers();
|
||||
if (! (Modifier.isInterface(modifiers) ||
|
||||
Modifier.isAbstract(modifiers)))
|
||||
{
|
||||
MemberBox[] ctors = members.ctors;
|
||||
int index = NativeJavaMethod.findFunction(cx, ctors, args);
|
||||
if (index < 0) {
|
||||
String sig = NativeJavaMethod.scriptSignature(args);
|
||||
throw Context.reportRuntimeError2(
|
||||
"msg.no.java.ctor", classObject.getName(), sig);
|
||||
}
|
||||
|
||||
// Found the constructor, so try invoking it.
|
||||
return constructSpecific(cx, scope, args, ctors[index]);
|
||||
} else {
|
||||
Scriptable topLevel = ScriptableObject.getTopLevelScope(this);
|
||||
String msg = "";
|
||||
try {
|
||||
// trying to construct an interface; use JavaAdapter to
|
||||
// construct a new class on the fly that implements this
|
||||
// interface.
|
||||
Object v = topLevel.get("JavaAdapter", topLevel);
|
||||
if (v != NOT_FOUND) {
|
||||
Function f = (Function) v;
|
||||
// Args are (interface, js object)
|
||||
Object[] adapterArgs = { this, args[0] };
|
||||
return f.construct(cx, topLevel, adapterArgs);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// fall through to error
|
||||
String m = ex.getMessage();
|
||||
if (m != null)
|
||||
msg = m;
|
||||
}
|
||||
throw Context.reportRuntimeError2(
|
||||
"msg.cant.instantiate", msg, classObject.getName());
|
||||
}
|
||||
}
|
||||
|
||||
static Scriptable constructSpecific(Context cx, Scriptable scope,
|
||||
Object[] args, MemberBox ctor)
|
||||
{
|
||||
Scriptable topLevel = ScriptableObject.getTopLevelScope(scope);
|
||||
Class<?>[] argTypes = ctor.argTypes;
|
||||
|
||||
if (ctor.vararg) {
|
||||
// marshall the explicit parameter
|
||||
Object[] newArgs = new Object[argTypes.length];
|
||||
for (int i = 0; i < argTypes.length-1; i++) {
|
||||
newArgs[i] = Context.jsToJava(args[i], argTypes[i]);
|
||||
}
|
||||
|
||||
Object varArgs;
|
||||
|
||||
// Handle special situation where a single variable parameter
|
||||
// is given and it is a Java or ECMA array.
|
||||
if (args.length == argTypes.length &&
|
||||
(args[args.length-1] == null ||
|
||||
args[args.length-1] instanceof NativeArray ||
|
||||
args[args.length-1] instanceof NativeJavaArray))
|
||||
{
|
||||
// convert the ECMA array into a native array
|
||||
varArgs = Context.jsToJava(args[args.length-1],
|
||||
argTypes[argTypes.length - 1]);
|
||||
} else {
|
||||
// marshall the variable parameter
|
||||
Class<?> componentType = argTypes[argTypes.length - 1].
|
||||
getComponentType();
|
||||
varArgs = Array.newInstance(componentType,
|
||||
args.length - argTypes.length + 1);
|
||||
for (int i=0; i < Array.getLength(varArgs); i++) {
|
||||
Object value = Context.jsToJava(args[argTypes.length-1 + i],
|
||||
componentType);
|
||||
Array.set(varArgs, i, value);
|
||||
}
|
||||
}
|
||||
|
||||
// add varargs
|
||||
newArgs[argTypes.length-1] = varArgs;
|
||||
// replace the original args with the new one
|
||||
args = newArgs;
|
||||
} else {
|
||||
Object[] origArgs = args;
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
Object arg = args[i];
|
||||
Object x = Context.jsToJava(arg, argTypes[i]);
|
||||
if (x != arg) {
|
||||
if (args == origArgs) {
|
||||
args = origArgs.clone();
|
||||
}
|
||||
args[i] = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object instance = ctor.newInstance(args);
|
||||
// we need to force this to be wrapped, because construct _has_
|
||||
// to return a scriptable
|
||||
return cx.getWrapFactory().wrapNewObject(cx, topLevel, instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[JavaClass " + getClassObject().getName() + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if prototype is a wrapped Java object and performs
|
||||
* a Java "instanceof".
|
||||
* Exception: if value is an instance of NativeJavaClass, it isn't
|
||||
* considered an instance of the Java class; this forestalls any
|
||||
* name conflicts between java.lang.Class's methods and the
|
||||
* static methods exposed by a JavaNativeClass.
|
||||
*/
|
||||
@Override
|
||||
public boolean hasInstance(Scriptable value) {
|
||||
|
||||
if (value instanceof Wrapper &&
|
||||
!(value instanceof NativeJavaClass)) {
|
||||
Object instance = ((Wrapper)value).unwrap();
|
||||
|
||||
return getClassObject().isInstance(instance);
|
||||
}
|
||||
|
||||
// value wasn't something we understand
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Class<?> findNestedClass(Class<?> parentClass, String name) {
|
||||
String nestedClassName = parentClass.getName() + '$' + name;
|
||||
ClassLoader loader = parentClass.getClassLoader();
|
||||
if (loader == null) {
|
||||
// ALERT: if loader is null, nested class should be loaded
|
||||
// via system class loader which can be different from the
|
||||
// loader that brought Rhino classes that Class.forName() would
|
||||
// use, but ClassLoader.getSystemClassLoader() is Java 2 only
|
||||
return Kit.classOrNull(nestedClassName);
|
||||
} else {
|
||||
return Kit.classOrNull(loader, nestedClassName);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String,FieldAndMethods> staticFieldAndMethods;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user