1 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 ; 33 import java.io.StringReader ; 34 import java.util.Set ; 35 36 39 public class FindJsniRefVisitor extends ASTVisitor { 40 41 private final Set jsniClasses; 42 private final JsParser jsParser = new JsParser(); 43 private final JsProgram jsProgram = new JsProgram(); 44 45 public FindJsniRefVisitor(Set 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 char[] source = methodDeclaration.compilationResult().getCompilationUnit().getContents(); 56 String 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; } 63 64 startPos += 3; endPos += 1; 67 jsniCode = jsniCode.substring(startPos, endPos); 68 69 String 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 sr = new StringReader (syntheticFnHeader + '\n' + jsniCode); 84 try { 85 JsStatements result = jsParser.parse(jsProgram.getScope(), sr, -1); 87 new JsVisitor() { 88 public void endVisit(JsNameRef x, JsContext ctx) { 89 String ident = x.getIdent(); 90 if (ident.charAt(0) == '@') { 91 String className = ident.substring(1, ident.indexOf(':')); 92 jsniClasses.add(className); 93 } 94 } 95 }.accept(result); 96 } catch (IOException e) { 97 throw new InternalCompilerException( 98 "Internal error searching for JSNI references", e); 99 } catch (JsParserException e) { 100 } 102 103 return false; 104 } 105 106 } 107 | Popular Tags |