KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > google > gwt > dev > jdt > FindJsniRefVisitor


1 /*
2  * Copyright 2006 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */

16 package com.google.gwt.dev.jdt;
17
18 import com.google.gwt.dev.jjs.InternalCompilerException;
19 import com.google.gwt.dev.js.JsParser;
20 import com.google.gwt.dev.js.JsParserException;
21 import com.google.gwt.dev.js.ast.JsContext;
22 import com.google.gwt.dev.js.ast.JsNameRef;
23 import com.google.gwt.dev.js.ast.JsProgram;
24 import com.google.gwt.dev.js.ast.JsStatements;
25 import com.google.gwt.dev.js.ast.JsVisitor;
26
27 import org.eclipse.jdt.internal.compiler.ASTVisitor;
28 import org.eclipse.jdt.internal.compiler.ast.Argument;
29 import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
30 import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
31
32 import java.io.IOException JavaDoc;
33 import java.io.StringReader JavaDoc;
34 import java.util.Set JavaDoc;
35
36 /**
37  * Walks the AST to find references to Java identifiers from within JSNI blocks.
38  */

39 public class FindJsniRefVisitor extends ASTVisitor {
40
41   private final Set JavaDoc/* <String> */jsniClasses;
42   private final JsParser jsParser = new JsParser();
43   private final JsProgram jsProgram = new JsProgram();
44
45   public FindJsniRefVisitor(Set JavaDoc/* <String> */jsniClasses) {
46     this.jsniClasses = jsniClasses;
47   }
48
49   public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
50     if (!methodDeclaration.isNative()) {
51       return false;
52     }
53
54     // Handle JSNI block
55
char[] source = methodDeclaration.compilationResult().getCompilationUnit().getContents();
56     String JavaDoc jsniCode = String.valueOf(source, methodDeclaration.bodyStart,
57         methodDeclaration.bodyEnd - methodDeclaration.bodyStart + 1);
58     int startPos = jsniCode.indexOf("/*-{");
59     int endPos = jsniCode.lastIndexOf("}-*/");
60     if (startPos < 0 || endPos < 0) {
61       return false; // ignore the error
62
}
63
64     startPos += 3; // move up to open brace
65
endPos += 1; // move past close brace
66

67     jsniCode = jsniCode.substring(startPos, endPos);
68
69     String JavaDoc syntheticFnHeader = "function(";
70     boolean first = true;
71     if (methodDeclaration.arguments != null) {
72       for (int i = 0, c = methodDeclaration.arguments.length; i < c; ++i) {
73         Argument arg = methodDeclaration.arguments[i];
74         if (first) {
75           first = false;
76         } else {
77           syntheticFnHeader += ',';
78         }
79         syntheticFnHeader += String.valueOf(arg.name);
80       }
81     }
82     syntheticFnHeader += ')';
83     StringReader JavaDoc sr = new StringReader JavaDoc(syntheticFnHeader + '\n' + jsniCode);
84     try {
85       // start at -1 to avoid counting our synthetic header
86
JsStatements result = jsParser.parse(jsProgram.getScope(), sr, -1);
87       new JsVisitor() {
88         public void endVisit(JsNameRef x, JsContext ctx) {
89           String JavaDoc ident = x.getIdent();
90           if (ident.charAt(0) == '@') {
91             String JavaDoc className = ident.substring(1, ident.indexOf(':'));
92             jsniClasses.add(className);
93           }
94         }
95       }.accept(result);
96     } catch (IOException JavaDoc e) {
97       throw new InternalCompilerException(
98           "Internal error searching for JSNI references", e);
99     } catch (JsParserException e) {
100       // ignore, we only care about finding valid references
101
}
102
103     return false;
104   }
105
106 }
107
Popular Tags