001: /*
002: * Copyright 2007 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.core.ext.typeinfo;
017:
018: import com.google.gwt.core.ext.TreeLogger;
019: import com.google.gwt.core.ext.UnableToCompleteException;
020: import com.google.gwt.dev.jdt.StaticCompilationUnitProvider;
021: import com.google.gwt.dev.jdt.TypeOracleBuilder;
022: import com.google.gwt.dev.jdt.URLCompilationUnitProvider;
023: import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
024:
025: import junit.framework.TestCase;
026:
027: import java.io.File;
028: import java.net.MalformedURLException;
029: import java.net.URI;
030: import java.net.URISyntaxException;
031: import java.net.URL;
032:
033: /**
034: * Tests related to JClassType. See individual test methods to details.
035: */
036: public class JClassTypeTest extends TestCase {
037: private final boolean logToConsole = false;
038: private final ModuleContext moduleContext = new ModuleContext(
039: logToConsole ? new PrintWriterTreeLogger()
040: : TreeLogger.NULL,
041: "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
042:
043: public JClassTypeTest() throws UnableToCompleteException {
044: }
045:
046: public void testGetOverridableMethods() throws TypeOracleException {
047: TreeLogger logger = TreeLogger.NULL;
048: TypeOracle typeOracle = moduleContext.getOracle();
049: // TypeOracle typeOracle = buildOracleFromTestPackage(logger);
050:
051: String[] noParams = new String[0];
052: String[] intObjectParams = new String[] { "int",
053: "java.lang.Object" };
054:
055: // Verify IA.
056: {
057: JClassType type = typeOracle
058: .getType("com.google.gwt.core.ext.typeinfo.test.IA");
059: JMethod[] leafMethods = type.getOverridableMethods();
060: assertEquals(3, leafMethods.length);
061:
062: assertMethodOverridable(typeOracle,
063: "com.google.gwt.core.ext.typeinfo.test.IA",
064: "com.google.gwt.core.ext.typeinfo.test.IA", "ia",
065: noParams);
066:
067: assertMethodOverridable(typeOracle,
068: "com.google.gwt.core.ext.typeinfo.test.IA",
069: "com.google.gwt.core.ext.typeinfo.test.IA", "ia",
070: intObjectParams);
071:
072: assertMethodOverridable(typeOracle,
073: "com.google.gwt.core.ext.typeinfo.test.IA",
074: "com.google.gwt.core.ext.typeinfo.test.IA", "foo",
075: noParams);
076: }
077:
078: // Verify IB.
079: {
080: JClassType type = typeOracle
081: .getType("com.google.gwt.core.ext.typeinfo.test.IB");
082: JMethod[] leafMethods = type.getOverridableMethods();
083: assertEquals(5, leafMethods.length);
084:
085: assertMethodOverridable(typeOracle,
086: "com.google.gwt.core.ext.typeinfo.test.IA",
087: "com.google.gwt.core.ext.typeinfo.test.IB", "ia",
088: noParams);
089:
090: assertMethodOverridable(typeOracle,
091: "com.google.gwt.core.ext.typeinfo.test.IA",
092: "com.google.gwt.core.ext.typeinfo.test.IB", "ia",
093: intObjectParams);
094:
095: assertMethodOverridable(typeOracle,
096: "com.google.gwt.core.ext.typeinfo.test.IB",
097: "com.google.gwt.core.ext.typeinfo.test.IB", "ib",
098: noParams);
099:
100: assertMethodOverridable(typeOracle,
101: "com.google.gwt.core.ext.typeinfo.test.IB",
102: "com.google.gwt.core.ext.typeinfo.test.IB", "ib",
103: intObjectParams);
104:
105: assertMethodOverridable(typeOracle,
106: "com.google.gwt.core.ext.typeinfo.test.IB",
107: "com.google.gwt.core.ext.typeinfo.test.IB", "foo",
108: noParams);
109: }
110:
111: // Verify IC.
112: {
113: JClassType type = typeOracle
114: .getType("com.google.gwt.core.ext.typeinfo.test.IC");
115: JMethod[] leafMethods = type.getOverridableMethods();
116: assertEquals(7, leafMethods.length);
117:
118: assertMethodOverridable(typeOracle,
119: "com.google.gwt.core.ext.typeinfo.test.IA",
120: "com.google.gwt.core.ext.typeinfo.test.IC", "ia",
121: noParams);
122:
123: assertMethodOverridable(typeOracle,
124: "com.google.gwt.core.ext.typeinfo.test.IA",
125: "com.google.gwt.core.ext.typeinfo.test.IC", "ia",
126: intObjectParams);
127:
128: assertMethodOverridable(typeOracle,
129: "com.google.gwt.core.ext.typeinfo.test.IC",
130: "com.google.gwt.core.ext.typeinfo.test.IC", "ib",
131: noParams);
132:
133: assertMethodOverridable(typeOracle,
134: "com.google.gwt.core.ext.typeinfo.test.IC",
135: "com.google.gwt.core.ext.typeinfo.test.IC", "ib",
136: intObjectParams);
137:
138: assertMethodOverridable(typeOracle,
139: "com.google.gwt.core.ext.typeinfo.test.IC",
140: "com.google.gwt.core.ext.typeinfo.test.IC", "ic",
141: noParams);
142:
143: assertMethodOverridable(typeOracle,
144: "com.google.gwt.core.ext.typeinfo.test.IC",
145: "com.google.gwt.core.ext.typeinfo.test.IC", "ic",
146: intObjectParams);
147:
148: assertMethodOverridable(typeOracle,
149: "com.google.gwt.core.ext.typeinfo.test.IB",
150: "com.google.gwt.core.ext.typeinfo.test.IC", "foo",
151: noParams);
152: }
153:
154: // Both overloads of ia are only declared in IA, so all searches should find
155: // them there.
156: {
157: assertMethodOverridable(typeOracle,
158: "com.google.gwt.core.ext.typeinfo.test.IA",
159: "com.google.gwt.core.ext.typeinfo.test.CA", "ia",
160: noParams);
161:
162: assertMethodOverridable(typeOracle,
163: "com.google.gwt.core.ext.typeinfo.test.IA",
164: "com.google.gwt.core.ext.typeinfo.test.CB", "ia",
165: noParams);
166:
167: assertMethodOverridable(typeOracle,
168: "com.google.gwt.core.ext.typeinfo.test.IA",
169: "com.google.gwt.core.ext.typeinfo.test.CC", "ia",
170: noParams);
171:
172: assertMethodOverridable(typeOracle,
173: "com.google.gwt.core.ext.typeinfo.test.IA",
174: "com.google.gwt.core.ext.typeinfo.test.CA", "ia",
175: intObjectParams);
176:
177: assertMethodOverridable(typeOracle,
178: "com.google.gwt.core.ext.typeinfo.test.IA",
179: "com.google.gwt.core.ext.typeinfo.test.CB", "ia",
180: intObjectParams);
181:
182: assertMethodOverridable(typeOracle,
183: "com.google.gwt.core.ext.typeinfo.test.IA",
184: "com.google.gwt.core.ext.typeinfo.test.CC", "ia",
185: intObjectParams);
186: }
187:
188: // Both overloads of ib are declared in both IB and IC, so
189: // - searching for ib in CB will return IB
190: // - searching for ib in CC will return IC
191: {
192: assertMethodOverridable(typeOracle,
193: "com.google.gwt.core.ext.typeinfo.test.IB",
194: "com.google.gwt.core.ext.typeinfo.test.CB", "ib",
195: noParams);
196:
197: assertMethodOverridable(typeOracle,
198: "com.google.gwt.core.ext.typeinfo.test.IC",
199: "com.google.gwt.core.ext.typeinfo.test.CC", "ib",
200: noParams);
201:
202: assertMethodOverridable(typeOracle,
203: "com.google.gwt.core.ext.typeinfo.test.IB",
204: "com.google.gwt.core.ext.typeinfo.test.CB", "ib",
205: intObjectParams);
206:
207: assertMethodOverridable(typeOracle,
208: "com.google.gwt.core.ext.typeinfo.test.IC",
209: "com.google.gwt.core.ext.typeinfo.test.CC", "ib",
210: intObjectParams);
211: }
212:
213: // Both overloads of ic are declared only in IC, but ic() is also declared
214: // in CB, so
215: // - searching for ic() in CB will return CB
216: // - searching for ic() in CC will return CB
217: // - searching for ic(int, Object) in CC will return IC
218: {
219: assertMethodOverridable(typeOracle,
220: "com.google.gwt.core.ext.typeinfo.test.CB",
221: "com.google.gwt.core.ext.typeinfo.test.CB", "ic",
222: noParams);
223:
224: assertMethodOverridable(typeOracle,
225: "com.google.gwt.core.ext.typeinfo.test.CB",
226: "com.google.gwt.core.ext.typeinfo.test.CC", "ic",
227: noParams);
228:
229: assertMethodOverridable(typeOracle,
230: "com.google.gwt.core.ext.typeinfo.test.IC",
231: "com.google.gwt.core.ext.typeinfo.test.CC", "ic",
232: intObjectParams);
233: }
234:
235: // Both IA and IB define foo(), and searching for foo() on IC should return
236: // IB.foo(). This matters because IC also extends IA, so a naive algorithm
237: // for getLeafMethods() might prefer IA.foo() to IB.foo().
238: {
239: assertMethodOverridable(typeOracle,
240: "com.google.gwt.core.ext.typeinfo.test.IB",
241: "com.google.gwt.core.ext.typeinfo.test.IC", "foo",
242: noParams);
243: }
244:
245: // Check that we aren't including methods that aren't actually overridable
246: // because they are final and/or private.
247: {
248: assertMethodNotOverridable(typeOracle,
249: "com.google.gwt.core.ext.typeinfo.test.CA",
250: "com.google.gwt.core.ext.typeinfo.test.CA",
251: "caNotOverridableFinal", noParams);
252:
253: assertMethodNotOverridable(typeOracle,
254: "com.google.gwt.core.ext.typeinfo.test.CA",
255: "com.google.gwt.core.ext.typeinfo.test.CA",
256: "caNotOverridablePrivate", noParams);
257: }
258: }
259:
260: private void addCompilationUnitsInPath(TypeOracleBuilder builder,
261: File sourcePathEntry, String pkgName)
262: throws UnableToCompleteException, MalformedURLException {
263: File pkgPath = new File(sourcePathEntry, pkgName.replace('.',
264: '/'));
265: File[] files = pkgPath.listFiles();
266: if (files == null) {
267: // No files found.
268: return;
269: }
270:
271: for (int i = 0; i < files.length; i++) {
272: File file = files[i];
273: if (file.isFile()) {
274: // If it's a source file, slurp it in.
275: if (file.getName().endsWith(".java")) {
276: URL location = file.toURL();
277: CompilationUnitProvider cup = new URLCompilationUnitProvider(
278: location, pkgName);
279: builder.addCompilationUnit(cup);
280: }
281: } else {
282: // Recurse into subpackages.
283: addCompilationUnitsInPath(builder, sourcePathEntry,
284: pkgName + file.getName());
285: }
286: }
287: }
288:
289: private void assertMethodNotOverridable(TypeOracle typeOracle,
290: String expectedTypeName, String searchTypeName,
291: String methodName, String[] paramTypeNames)
292: throws TypeOracleException {
293: assertOverridableMethodInclusion(false, typeOracle,
294: expectedTypeName, searchTypeName, methodName,
295: paramTypeNames);
296: }
297:
298: private void assertMethodOverridable(TypeOracle typeOracle,
299: String expectedTypeName, String searchTypeName,
300: String methodName, String[] paramTypeNames)
301: throws TypeOracleException {
302: assertOverridableMethodInclusion(true, typeOracle,
303: expectedTypeName, searchTypeName, methodName,
304: paramTypeNames);
305: }
306:
307: private void assertOverridableMethodInclusion(
308: boolean shouldBeFound, TypeOracle oracle,
309: String expectedTypeName, String searchTypeName,
310: String methodName, String[] paramTypeNames)
311: throws TypeOracleException {
312:
313: boolean wasFound = false;
314:
315: JClassType expectedType = oracle.getType(expectedTypeName);
316: JClassType searchType = oracle.getType(searchTypeName);
317: JType[] paramTypes = new JType[paramTypeNames.length];
318: for (int i = 0; i < paramTypeNames.length; i++) {
319: String paramTypeName = paramTypeNames[i];
320: paramTypes[i] = oracle.parse(paramTypeName);
321: }
322:
323: JMethod[] leafMethods = searchType.getOverridableMethods();
324: for (int i = 0; i < leafMethods.length; i++) {
325: JMethod method = leafMethods[i];
326: if (method.getName().equals(methodName)) {
327: if (method.hasParamTypes(paramTypes)) {
328: String typeName = method.getEnclosingType()
329: .getQualifiedSourceName();
330: assertEquals(expectedTypeName, typeName);
331: wasFound = true;
332: break;
333: }
334: }
335: }
336:
337: if (shouldBeFound) {
338: if (wasFound) {
339: // Good. We wanted to find it and we did.
340: } else {
341: fail("Did not find expected method '" + methodName
342: + "' on type '" + expectedTypeName + "'");
343: }
344: } else {
345: // We want to *not* find it.
346: if (wasFound) {
347: fail("Did not expect to find method '" + methodName
348: + "' on type '" + expectedTypeName + "'");
349: } else {
350: // Good. We didn't want to find it and didn't.
351: }
352: }
353: }
354: }
|