KickJava   Java API By Example, From Geeks To Geeks.

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


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 org.eclipse.jdt.core.compiler.CharOperation;
19 import org.eclipse.jdt.core.compiler.IProblem;
20 import org.eclipse.jdt.internal.compiler.ASTVisitor;
21 import org.eclipse.jdt.internal.compiler.CompilationResult;
22 import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
23 import org.eclipse.jdt.internal.compiler.ast.Expression;
24 import org.eclipse.jdt.internal.compiler.ast.MessageSend;
25 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
26 import org.eclipse.jdt.internal.compiler.lookup.Scope;
27 import org.eclipse.jdt.internal.compiler.problem.DefaultProblem;
28 import org.eclipse.jdt.internal.compiler.problem.ProblemHandler;
29 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
30 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
31
32 import java.util.Map JavaDoc;
33
34 /**
35  * Walks a
36  * {@link org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration} to
37  * find <code>GWT.create()</code> class so that we can eagerly complain about
38  * deferred binding problems.
39  */

40 public class FindDeferredBindingSitesVisitor extends ASTVisitor {
41
42   /**
43    * Information about the site at which a rebind request was found, used to
44    * report problems.
45    */

46   public static class DeferredBindingSite {
47     public final MessageSend messageSend;
48
49     public final Scope scope;
50
51     public DeferredBindingSite(MessageSend messageSend, Scope scope) {
52       this.messageSend = messageSend;
53       this.scope = scope;
54     }
55   }
56
57   public static final String JavaDoc REBIND_MAGIC_CLASS = "com.google.gwt.core.client.GWT";
58   public static final String JavaDoc REBIND_MAGIC_METHOD = "create";
59
60   public static void reportRebindProblem(DeferredBindingSite site,
61       String JavaDoc message) {
62     MessageSend messageSend = site.messageSend;
63     Scope scope = site.scope;
64     CompilationResult compResult = scope.compilationUnitScope().referenceContext().compilationResult();
65     int startLine = ProblemHandler.searchLineNumber(
66         compResult.lineSeparatorPositions, messageSend.sourceStart());
67     DefaultProblem problem = new DefaultProblem(compResult.fileName, message,
68         IProblem.Unclassified, null, ProblemSeverities.Error,
69         messageSend.sourceStart, messageSend.sourceEnd, startLine);
70     compResult.record(problem, scope.referenceContext());
71   }
72
73   private final Map JavaDoc results;
74
75   public FindDeferredBindingSitesVisitor(Map JavaDoc requestedTypes) {
76     this.results = requestedTypes;
77   }
78
79   public void endVisit(MessageSend messageSend, BlockScope scope) {
80     final ProblemReporter problemReporter = scope.problemReporter();
81
82     if (messageSend.binding == null) {
83       // Some sort of problem.
84
//
85
return;
86     }
87
88     String JavaDoc methodName = String.valueOf(messageSend.selector);
89     if (!methodName.equals(REBIND_MAGIC_METHOD)) {
90       // Not the create() method.
91
//
92
return;
93     }
94
95     char[][] targetClass = messageSend.binding.declaringClass.compoundName;
96     String JavaDoc targetClassName = CharOperation.toString(targetClass);
97     if (!targetClassName.equals(REBIND_MAGIC_CLASS)) {
98       // Not being called on the Rebind class.
99
return;
100     }
101
102     DeferredBindingSite site = new DeferredBindingSite(messageSend, scope);
103     
104     Expression[] args = messageSend.arguments;
105     if (args.length != 1) {
106       reportRebindProblem(site, "GWT.create() should take exactly one argument");
107       return;
108     }
109
110     Expression arg = args[0];
111     if (!(arg instanceof ClassLiteralAccess)) {
112       reportRebindProblem(site, "Only class literals may be used as arguments to GWT.create()");
113       return;
114     }
115
116     ClassLiteralAccess cla = (ClassLiteralAccess) arg;
117     String JavaDoc typeName = String.valueOf(cla.targetType.readableName());
118     if (!results.containsKey(typeName)) {
119       results.put(typeName, site);
120     }
121   }
122 }
123
Popular Tags