KickJava   Java API By Example, From Geeks To Geeks.

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


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.core.ext.TreeLogger;
19 import com.google.gwt.core.ext.UnableToCompleteException;
20 import com.google.gwt.dev.jdt.FindDeferredBindingSitesVisitor.DeferredBindingSite;
21 import com.google.gwt.dev.util.Empty;
22 import com.google.gwt.dev.util.Util;
23
24 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
25 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
26 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
27 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
28 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
29
30 import java.util.HashMap JavaDoc;
31 import java.util.HashSet JavaDoc;
32 import java.util.Iterator JavaDoc;
33 import java.util.Map JavaDoc;
34 import java.util.Set JavaDoc;
35
36 /**
37  * Provides a reusable front-end based on the JDT compiler that incorporates
38  * GWT-specific concepts such as JSNI and deferred binding.
39  */

40 public class WebModeCompilerFrontEnd extends AstCompiler {
41
42   private final RebindPermutationOracle rebindPermOracle;
43
44   public WebModeCompilerFrontEnd(SourceOracle sourceOracle,
45       RebindPermutationOracle rebindPermOracle) {
46     super(sourceOracle);
47     this.rebindPermOracle = rebindPermOracle;
48   }
49
50   public CompilationUnitDeclaration[] getCompilationUnitDeclarations(
51       TreeLogger logger, String JavaDoc[] seedTypeNames)
52       throws UnableToCompleteException {
53
54     // Build the initial set of compilation units.
55
//
56
ICompilationUnit[] units = new ICompilationUnit[seedTypeNames.length];
57     for (int i = 0; i < seedTypeNames.length; i++) {
58       String JavaDoc seedTypeName = seedTypeNames[i];
59       units[i] = getCompilationUnitForType(logger, seedTypeName);
60     }
61
62     // Compile, which will pull in everything else via
63
// doFindAdditionalTypesUsingMagic()
64
//
65
CompilationUnitDeclaration[] cuds = compile(logger, units);
66     return cuds;
67   }
68
69   public RebindPermutationOracle getRebindPermutationOracle() {
70     return rebindPermOracle;
71   }
72
73   /**
74    * Pull in types referenced only via JSNI.
75    */

76   protected String JavaDoc[] doFindAdditionalTypesUsingJsni(TreeLogger logger,
77       CompilationUnitDeclaration cud) {
78     Set JavaDoc dependentTypeNames = new HashSet JavaDoc();
79     FindJsniRefVisitor v = new FindJsniRefVisitor(dependentTypeNames);
80     cud.traverse(v, cud.scope);
81     return (String JavaDoc[]) dependentTypeNames.toArray(Empty.STRINGS);
82   }
83
84   /**
85    * Pull in types implicitly referenced through rebind answers.
86    */

87   protected String JavaDoc[] doFindAdditionalTypesUsingRebinds(TreeLogger logger,
88       CompilationUnitDeclaration cud) {
89     Set JavaDoc dependentTypeNames = new HashSet JavaDoc();
90
91     // Find all the deferred binding request types.
92
//
93
Map JavaDoc requestedTypes = new HashMap JavaDoc();
94     FindDeferredBindingSitesVisitor v = new FindDeferredBindingSitesVisitor(
95         requestedTypes);
96     cud.traverse(v, cud.scope);
97
98     // For each, ask the host for every possible deferred binding answer.
99
//
100
for (Iterator JavaDoc iter = requestedTypes.keySet().iterator(); iter.hasNext();) {
101       String JavaDoc reqType = (String JavaDoc) iter.next();
102       DeferredBindingSite site = (DeferredBindingSite) requestedTypes.get(reqType);
103
104       try {
105         String JavaDoc[] resultTypes = rebindPermOracle.getAllPossibleRebindAnswers(
106             getLogger(), reqType);
107         // Check that each result is instantiable.
108
for (int i = 0; i < resultTypes.length; ++i) {
109           String JavaDoc typeName = resultTypes[i];
110
111           // This causes the compiler to find the additional type, possibly
112
// winding its back to ask for the compilation unit from the source
113
// oracle.
114
//
115
ReferenceBinding type = resolvePossiblyNestedType(typeName);
116
117           // Sanity check rebind results.
118
if (type == null) {
119             FindDeferredBindingSitesVisitor.reportRebindProblem(site,
120                 "Rebind result '" + typeName + "' could not be found");
121             continue;
122           }
123           if (!type.isClass()) {
124             FindDeferredBindingSitesVisitor.reportRebindProblem(site,
125                 "Rebind result '" + typeName + "' must be a class");
126             continue;
127           }
128           if (type.isAbstract()) {
129             FindDeferredBindingSitesVisitor.reportRebindProblem(site,
130                 "Rebind result '" + typeName + "' cannot be abstract");
131             continue;
132           }
133           if (type.isNestedType() && !type.isStatic()) {
134             FindDeferredBindingSitesVisitor.reportRebindProblem(site,
135                 "Rebind result '" + typeName
136                     + "' cannot be a non-static nested class");
137             continue;
138           }
139           if (type.isLocalType()) {
140             FindDeferredBindingSitesVisitor.reportRebindProblem(site,
141                 "Rebind result '" + typeName + "' cannot be a local class");
142             continue;
143           }
144           // Look for a noArg ctor.
145
MethodBinding noArgCtor = type.getExactMethod("<init>".toCharArray(),
146               TypeBinding.NoParameters, cud.scope);
147
148           if (noArgCtor == null) {
149             FindDeferredBindingSitesVisitor.reportRebindProblem(site,
150                 "Rebind result '" + typeName
151                     + "' has no default (zero argument) constructors");
152             continue;
153           }
154           dependentTypeNames.add(typeName);
155         }
156         Util.addAll(dependentTypeNames, resultTypes);
157       } catch (UnableToCompleteException e) {
158         FindDeferredBindingSitesVisitor.reportRebindProblem(site,
159             "Failed to resolve '" + reqType + "' via deferred binding");
160       }
161     }
162     return (String JavaDoc[]) dependentTypeNames.toArray(Empty.STRINGS);
163   }
164 }
165
Popular Tags