KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openlaszlo > compiler > CompilerUtils


1 /* ****************************************************************************
2  * CompilerUtils.java
3 * ****************************************************************************/

4
5 /* J_LZ_COPYRIGHT_BEGIN *******************************************************
6 * Copyright 2001-2004 Laszlo Systems, Inc. All Rights Reserved. *
7 * Use is subject to license terms. *
8 * J_LZ_COPYRIGHT_END *********************************************************/

9
10 package org.openlaszlo.compiler;
11
12 import org.openlaszlo.css.CSSParser;
13 import org.openlaszlo.sc.Function;
14 import org.openlaszlo.sc.ScriptCompiler;
15 import org.openlaszlo.utils.ChainedException;
16
17 import java.io.*;
18 import java.util.*;
19 import org.jdom.Element;
20 import org.apache.log4j.*;
21 import java.text.DecimalFormat JavaDoc;
22 import java.text.FieldPosition JavaDoc;
23
24 public class CompilerUtils {
25     /** Return a string that can be included in a script to tell the
26      * script compiler that subsequent lines should be numbered
27      * relative to the beginning or end position of the source text
28      * for this element.
29      *
30      * @param start true if the location should be relative to the
31      * start of the element (otherwise it is relative to the end)
32      */

33     public static String JavaDoc sourceLocationDirective(Element elt, boolean start) {
34         // Parser adds these attributes.
35
String JavaDoc pathname = Parser.getSourceMessagePathname(elt);
36         Integer JavaDoc lineno = Parser.getSourceLocation(elt, Parser.LINENO, start);
37         Integer JavaDoc colno = Parser.getSourceLocation(elt, Parser.COLNO, start);
38         return sourceLocationDirective(pathname, lineno, colno);
39     }
40
41     /** Return a string that can be used as a unique name for the
42      * element for compiler generated function names.
43      *
44      * @param start true if the location should be relative to the
45      * start of the element (otherwise it is relative to the end)
46      */

47     public static String JavaDoc sourceUniqueName(Element elt, boolean start) {
48         // Parser adds these attributes.
49
String JavaDoc pathname = Parser.getSourceMessagePathname(elt);
50         Integer JavaDoc lineno = Parser.getSourceLocation(elt, Parser.LINENO, start);
51         Integer JavaDoc colno = Parser.getSourceLocation(elt, Parser.COLNO, start);
52         // When parsing with crimson, the column number isn't defined.
53
// TODO: [2004-11-10] This won't generate unique names, so it
54
// will fail with krank. Krank isn't used in this environment
55
// so that's okay for now.
56
if (colno.intValue() < 0)
57             colno = new Integer JavaDoc(0);
58         
59         if (pathname == null) {
60             pathname = "unknown_file";
61         } else {
62             pathname = encodeJavaScriptIdentifier(pathname);
63         }
64         return "$" + pathname + '_' + lineno + '_' + colno;
65     }
66     
67     /** Returns a string that is a valid JavaScript identifier.
68      * Characters in the input string that are not valid in a
69      * JavaScript identifier are replaced by "$xx", where xx is the
70      * hex code of the character. '$' is also replaced. This is
71      * similar to URL encoding, except '$' is used as the quote
72      * character. */

73     public static String JavaDoc encodeJavaScriptIdentifier(String JavaDoc s) {
74         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
75         for (int i = 0; i < s.length(); i++) {
76             char c = s.charAt(i);
77             // Java and JavaScript identifiers have the same lexical
78
// specification, so the Java methods work for this
79
if (!(Character.isJavaIdentifierPart(c) ||
80                   (i == 0 && Character.isJavaIdentifierStart(c))) ||
81                 c == '$') {
82                 String JavaDoc hex = Integer.toHexString((int) c);
83                 if (hex.length() < 2)
84                     hex = "0" + hex;
85                 buffer.append('$');
86                 buffer.append(hex.toUpperCase());
87             } else {
88                 buffer.append(c);
89             }
90         }
91         return buffer.toString();
92     }
93     
94     /* TODO: [2002-12-20 hqm] we need a better way to locate where
95      * an attribute occurs in a source file.
96      */

97     public static String JavaDoc attributeLocationDirective(Element elt,
98                                                     String JavaDoc attrname)
99     {
100         return sourceLocationDirective(elt, true);
101     }
102     
103     /** TODO: [2003-03-14 ptw] ditto */
104     public static String JavaDoc attributeUniqueName(Element elt, String JavaDoc attrname) {
105         return sourceUniqueName(elt, true);
106     }
107     
108     /** Return a string that can be included in a script to tell the
109      * script compiler that subsequent lines should be numbered
110      * relative to the beginning or end position of the source text
111      * for this element.
112      *
113      * @param start true if the location should be relative to the
114      * start of the element (otherwise it is relative to the end)
115      */

116     public static String JavaDoc sourceLocationDirective(String JavaDoc pathname,
117                                                  Integer JavaDoc lineno,
118                                                  Integer JavaDoc colno)
119     {
120         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
121         if (pathname != null) {
122             buffer.append("\n#file " + pathname + "\n");
123         }
124         if (lineno != null) {
125             // Set the line number of the following line. Prepend a
126
// line feed, in case this directive is being added after
127
// other text.
128
if (buffer.length() == 0) {
129                 buffer.append('\n');
130             }
131             buffer.append("#line " + lineno + "\n");
132             // Add enough spaces to line the column of the following
133
// text up to the same position it had within the source
134
// text, so that the column numbers in source reporting
135
// are correct.
136
if (colno != null) {
137                 for (int i = colno.intValue(); i > 0; --i) {
138                     buffer.append(' ');
139                 }
140             }
141         }
142         return buffer.toString();
143     }
144     
145     public static String JavaDoc sourceLocationPrettyString(Element elt) {
146         // Parser adds these attributes.
147
String JavaDoc pathname = Parser.getSourceMessagePathname(elt);
148         Integer JavaDoc lineno = Parser.getSourceLocation(elt, Parser.LINENO, true);
149         Integer JavaDoc colno = Parser.getSourceLocation(elt, Parser.COLNO, true);
150         return pathname+":"+lineno+":"+colno;
151     }
152     
153     /** Returns true if the argument is at the top level of an lzx
154      * program: it is immediately within a canvas element, or within a
155      * library element that is itself at the top level. */

156     static boolean isAtToplevel(Element element) {
157         // To simplify the implementation, root canvas and library
158
// elements are also considered to be at the top level, as is
159
// a canvas inside a top level element.
160
Element parent = element.getParent();
161         return parent == null
162             || (ToplevelCompiler.isElement(parent) &&
163                 isAtToplevel(parent));
164     }
165 }
166
Popular Tags