blob: d6a66d7484d509e442bcc6347bfd2dc0e351e0f1 [file] [log] [blame]
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.dev.jjs;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.CompilerContext;
import com.google.gwt.dev.cfg.ConfigurationProperties;
import com.google.gwt.dev.javac.CompilationState;
import com.google.gwt.dev.javac.testing.impl.JavaResourceBase;
import com.google.gwt.dev.javac.testing.impl.MockJavaResource;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.thirdparty.guava.common.base.Joiner;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Constructs a Java AST for testing.
*/
public class JavaAstConstructor {
public static final MockJavaResource ASYNCFRAGMENTLOADER = new MockJavaResource(
"com.google.gwt.core.client.impl.AsyncFragmentLoader") {
@Override
public CharSequence getContent() {
return Joiner.on("\n").join(
"package com.google.gwt.core.client.impl;",
"import com.google.gwt.core.client.RunAsyncCallback;",
"public class AsyncFragmentLoader {",
" public static void onLoad(int fragment) { }",
" public static void runAsync(int fragment, RunAsyncCallback callback) { }",
" public static AsyncFragmentLoader BROWSER_LOADER = makeBrowserLoader(1, new int[]{});",
" private static AsyncFragmentLoader makeBrowserLoader(int numSp, int[] initial) {",
" return null;",
" }",
"}");
}
};
public static final MockJavaResource ARRAY = new MockJavaResource("com.google.gwt.lang.Array") {
@Override
public CharSequence getContent() {
return Joiner.on("\n").join(
"package com.google.gwt.lang;",
"import com.google.gwt.core.client.JavaScriptObject;",
"public final class Array {",
" static <T> T newArray(int size) { return null; }",
" static void setCheck(Object array, int index, Object value) { }",
" static void initUnidimensionalArray(",
" Class arrayClass, JavaScriptObject castableTypeMap,",
" int elementTypeId, int elementTypeCategory, int length) { }",
" static void initMultidimensionalArray(",
" Class arrayClasses[], JavaScriptObject[] castableTypeMapExprs,",
" int[] elementTypeIds, int leafElementTypeCategory, int[] dimExprs, int count) { }",
" static void stampJavaTypeInfo(Class arrayClass, JavaScriptObject castableTypeMap,",
" int elementTypeId, int elementTypeCategory, Object array) { }",
" static <T> Class<T> getClassLiteralForArray() { return null; }",
" public static boolean isJavaArray(Object o) { return false; }",
" static Object ensureNotNull(Object o) { return null; }",
"}"
);
}
};
public static final MockJavaResource CAST = new MockJavaResource("com.google.gwt.lang.Cast") {
@Override
public CharSequence getContent() {
return Joiner.on("\n").join(
"package com.google.gwt.lang;",
"import com.google.gwt.core.client.JavaScriptObject;",
"public final class Cast {",
" private static JavaScriptObject stringCastMap;",
" private static JavaScriptObject doubleCastMap;",
" private static JavaScriptObject booleanCastMap;",
" public static native String charToString(char x) /*-{ }-*/;",
" public static Object castTo(Object src, int dstId) { return src;}",
" public static Object castToAllowJso(Object src, int dstId) { return src;}",
" public static Object castToArray(Object src) { return src;}",
" public static Object castToJsoArray(Object src) { return src;}",
" public static Object castToJsArray(Object src) { return src;}",
" public static Object castToJso(Object src) { return src;}",
" public static Object castToString(Object src) { return src;}",
" public static Object castToDouble(Object src) { return src;}",
" public static Object castToBoolean(Object src) { return src;}",
" public static Object castToNative(Object src, JavaScriptObject type) { return src;}",
" public static Object castToUnknownNative(Object src) { return src;}",
" public static Object castToFunction(Object src) { return src; }",
" public static Object castToJsObject(Object src) { return src; }",
" public static Class<?> getClass(Object src) { return null; }",
" public static boolean hasJavaObjectVirtualDispatch(Object o) { return true; }",
" public static boolean instanceOf(Object src, int dstId) { return false;}",
" public static boolean instanceOfString(Object o) { return true; }",
" public static boolean instanceOfDouble(Object o) { return true; }",
" public static boolean instanceOfBoolean(Object o) { return true; }",
" public static boolean instanceOfArray(Object src) { return false;}",
" public static boolean instanceOfJsoArray(Object src) { return false;}",
" public static boolean instanceOfJsArray(Object src) { return false;}",
" public static boolean instanceOfAllowJso(Object src, int dst) { return false;}",
" public static boolean instanceOfJso(Object src) { return false;}",
" public static boolean instanceOfUnknownNative(Object src) { return false;}",
" public static boolean instanceOfNative(Object src, JavaScriptObject type) {",
" return false;",
" }",
" public static boolean instanceOfFunction(Object src) { return false; }",
" public static boolean instanceOfJsObject(Object src) { return false; }",
" public static boolean isArray(Object o) { return false; }",
" public static boolean isJavaScriptObject(Object o) { return true; }",
" public static native boolean isNull(Object a) /*-{ }-*/;",
" public static native boolean isNotNull(Object a) /*-{ }-*/;",
" public static native boolean jsEquals(Object a, Object b) /*-{ }-*/;",
" public static native boolean jsNotEquals(Object a, Object b) /*-{ }-*/;",
" public static native Object maskUndefined(Object src) /*-{ }-*/;",
" public static int narrow_int(double x) { return 0; }",
" public static byte narrow_long(double x) { return 0; }",
"}"
);
}
};
public static final MockJavaResource CLASS = new MockJavaResource("java.lang.Class") {
@Override
public CharSequence getContent() {
return Joiner.on("\n").join(
"package java.lang;",
"import com.google.gwt.core.client.JavaScriptObject;",
"public final class Class<T> {",
" static <T> Class<T> createForArray(String packageName, String className,",
" String typeId, Class<?> componentType) { return new Class<T>(); }",
" static <T> Class<T> createForClass(String packageName, String className,",
" String typeId, Class<? super T> superclass) { return new Class<T>(); }",
" static <T> Class<T> createForEnum(String packageName, String className,",
" String typeId, Class<? super T> superclass, JavaScriptObject enumConstantsFunc,",
" JavaScriptObject enumValueOfFunc) { return new Class<T>(); }",
" static <T> Class<T> createForInterface(String packageName, String className) {",
" return new Class<T>(); }",
" static <T> Class<T> createForPrimitive(String className,",
" String jni) { return new Class<T>(); }",
" static boolean isClassMetadataEnabled() { return true; }",
" public boolean desiredAssertionStatus() { return true; }",
" public String getName() { return null; }",
"}"
);
}
};
public static final MockJavaResource CLASS_LITERAL_HOLDER = new MockJavaResource(
"com.google.gwt.lang.ClassLiteralHolder") {
@Override
public CharSequence getContent() {
return Joiner.on("\n").join(
"package com.google.gwt.lang;",
"final class ClassLiteralHolder {",
"}"
);
}
};
public static final MockJavaResource COLLAPSED_PROPERTY_HOLDER =
new MockJavaResource("com.google.gwt.lang.CollapsedPropertyHolder") {
@Override
public CharSequence getContent() {
return Joiner.on("\n").join(
"package com.google.gwt.lang; public class CollapsedPropertyHolder {",
" private static final int PERMUTATION_NOT_SET = 0xFFFFFFFF;",
" public static int permutationId = PERMUTATION_NOT_SET;",
"}"
);
}
};
public static final MockJavaResource ENUM = new MockJavaResource("java.lang.Enum") {
@Override
public CharSequence getContent() {
return Joiner.on("\n").join(
"package java.lang;",
"import java.io.Serializable;",
"import com.google.gwt.core.client.JavaScriptObject;",
"import jsinterop.annotations.JsIgnore;",
"import jsinterop.annotations.JsType;",
"@JsType public abstract class Enum<E extends Enum<E>> implements Serializable {",
" @JsIgnore public static native <T extends Enum<T>> T valueOf(Class<T> enumType,",
" String name) /*-{ return enumType + name; }-*/;",
" public static native <T extends Enum<T>> T valueOf(JavaScriptObject enumType,",
" String name) /*-{ return enumType + name; }-*/;",
" protected static native <T extends Enum<T>> JavaScriptObject createValueOfMap(",
" T[] enumConstants) /*-{ }-*/;",
" protected Enum(String name, int ordinal) { ",
" this.name = name;",
" this.ordinal = ordinal;}",
" private final String name;",
" private final int ordinal;",
" public final String name() { return name; }",
" public final int ordinal() { return ordinal; }",
"}"
);
}
};
public static final MockJavaResource EXCEPTIONS = new MockJavaResource(
"com.google.gwt.lang.Exceptions") {
@Override
public CharSequence getContent() {
return Joiner.on("\n").join(
"package com.google.gwt.lang;",
"public class Exceptions { ",
" static Object toJava(Object e) { return e; }",
" static Object toJs(Object e) { return e; }",
" static RuntimeException makeAssertionError() { return new RuntimeException(); }",
" static Throwable safeClose(AutoCloseable resource, Throwable mainException) {",
" return mainException;", " }",
" static <T> T checkNotNull(T value) { return value; }",
"}"
);
}
};
public static final MockJavaResource GWT = new MockJavaResource(
"com.google.gwt.core.client.GWT") {
@Override
public CharSequence getContent() {
return Joiner.on("\n").join(
"package com.google.gwt.core.client;",
"public final class GWT {",
" public static <T> T create(Class<?> classLiteral) { return null; }",
" public static boolean isClient() { return true; };",
" public static boolean isProdMode() { return true; };",
" public static boolean isScript() { return true; };",
" public static void runAsync(RunAsyncCallback callback) { }",
" public static void runAsync(Class<?> name, RunAsyncCallback callback) { }",
"}"
);
}
};
public static final MockJavaResource GWT_SHARED = new MockJavaResource(
"com.google.gwt.core.shared.GWT") {
@Override
public CharSequence getContent() {
return Joiner.on("\n").join(
"package com.google.gwt.core.shared;",
"public final class GWT {",
" public static <T> T create(Class<?> classLiteral) { return null; }",
" public static boolean isClient() { return true; };",
" public static boolean isProdMode() { return true; };",
" public static boolean isScript() { return true; };",
" public static void debugger() { }",
"}"
);
}
};
public static final MockJavaResource IMPL =
new MockJavaResource("com.google.gwt.core.client.impl.Impl") {
@Override
public CharSequence getContent() {
return Joiner.on("\n").join(
"package com.google.gwt.core.client.impl;",
"public class Impl {",
" public static Object registerEntry(){ return null;}",
" public static String getNameOf(String jsniIdent) { return null; }",
"}"
);
}
};
public static final MockJavaResource RUNTIME =
new MockJavaResource("com.google.gwt.lang.Runtime") {
@Override
public CharSequence getContent() {
return Joiner.on("\n")
.join(
"package com.google.gwt.lang;",
"public class Runtime {",
" public static Object defineClass(int typeId, int superTypeId, Object map) {",
" return null;",
" }",
" public static void provide() {}",
" public static void bootstrap() {}",
" public static void emptyMethod() {}",
" public static void getClassPrototype() {}",
" public static String toString(Object object) { return null; }",
" static native void typeMarkerFn() /*-{}-*/;",
"}");
}
};
public static final MockJavaResource LONGLIB = new MockJavaResource(
"com.google.gwt.lang.LongLib") {
@Override
public CharSequence getContent() {
return Joiner.on("\n").join(
"package com.google.gwt.lang;",
"public final class LongLib {",
" public static String toString(long a) { return \"\";}",
"}"
);
}
};
public static final MockJavaResource MODULE_UTILS =
new MockJavaResource("com.google.gwt.lang.ModuleUtils") {
@Override
public CharSequence getContent() {
return Joiner.on("\n").join(
"package com.google.gwt.lang;",
"import com.google.gwt.core.client.impl.Impl;",
"public class ModuleUtils {",
" public static void gwtOnLoad() {}",
" public static void addInitFunctions() {}",
" public static void setGwtProperty() {}",
" public static Object registerEntry() { return Impl.registerEntry(); }",
"}"
);
}
};
public static final MockJavaResource RUNASYNCCALLBACK = new MockJavaResource(
"com.google.gwt.core.client.RunAsyncCallback") {
@Override
public CharSequence getContent() {
return Joiner.on("\n").join(
"package com.google.gwt.core.client;",
"public interface RunAsyncCallback {",
" void onSuccess();",
" void onFailure(Throwable reason);",
"}"
);
}
};
public static final MockJavaResource RUNASYNCCODE = new MockJavaResource(
"com.google.gwt.core.client.prefetch.RunAsyncCode") {
@Override
public CharSequence getContent() {
return Joiner.on("\n").join(
"package com.google.gwt.core.client.prefetch;",
"public class RunAsyncCode {",
" public static RunAsyncCode runAsyncCode(Class<?> splitPoint) {",
" return null;",
" }",
"}"
);
}
};
public static final MockJavaResource STATS = new MockJavaResource("com.google.gwt.lang.Stats") {
@Override
public CharSequence getContent() {
return Joiner.on("\n").join(
"package com.google.gwt.lang;",
"public class Stats {",
" static boolean isStatsAvailable() { return false; };",
" static boolean onModuleStart(String mainClassName) { return false; }",
"}"
);
}
};
public static final MockJavaResource UTIL = new MockJavaResource("com.google.gwt.lang.Util") {
@Override
public CharSequence getContent() {
return Joiner.on("\n").join(
"package com.google.gwt.lang;",
"public class Util {",
"}"
);
}
};
public static JProgram construct(TreeLogger logger, CompilationState state,
CompilerContext compilerContext, ConfigurationProperties config,
String... entryPoints) throws UnableToCompleteException {
compilerContext.getOptions().setEnableAssertions(true);
JProgram jprogram = AstConstructor.construct(logger, state, compilerContext, config);
// Add entry methods for entry points.
for (String entryPoint : entryPoints) {
JDeclaredType entryType = jprogram.getFromTypeMap(entryPoint);
for (JMethod method : entryType.getMethods()) {
if (method.isStatic() && JProgram.isClinit(method)) {
jprogram.addEntryMethod(method);
}
}
}
// Tree is now ready to optimize.
return jprogram;
}
public static MockJavaResource[] getCompilerTypes() {
List<MockJavaResource> result = new ArrayList<MockJavaResource>();
Collections.addAll(result, JavaResourceBase.getStandardResources());
// Replace the basic Class and Enum with a compiler-specific one.
result.remove(JavaResourceBase.CLASS);
result.remove(JavaResourceBase.ENUM);
Collections.addAll(result, ASYNCFRAGMENTLOADER, ARRAY, CAST, CLASS, CLASS_LITERAL_HOLDER,
COLLAPSED_PROPERTY_HOLDER, ENUM, EXCEPTIONS, GWT, GWT_SHARED, IMPL,
RUNTIME, LONGLIB, MODULE_UTILS, RUNASYNCCALLBACK, RUNASYNCCODE,
UTIL);
return result.toArray(new MockJavaResource[result.size()]);
}
}