blob: 268f2663a9ea62a7347a80b99192f2daec4709a3 [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.impl;
import com.google.gwt.dev.jjs.ast.Context;
import com.google.gwt.dev.jjs.ast.JCastOperation;
import com.google.gwt.dev.jjs.ast.JClassType;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JInterfaceType;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JReferenceType;
import com.google.gwt.dev.jjs.ast.JType;
import com.google.gwt.dev.jjs.ast.JVisitor;
import java.util.HashSet;
import java.util.Set;
/**
* Record all Cast operations on JSOs as instantiations. This must run before
* {@link com.google.gwt.dev.jjs.impl.ImplementCastsAndTypeChecks}.
*/
public class ComputeInstantiatedJsoInterfaces {
class InstantiatedJsoInterfacesCollector extends JVisitor {
@Override
public void endVisit(JCastOperation x, Context ctx) {
JType toType = x.getCastType();
if (toType instanceof JReferenceType && !toType.isNullType()) {
toType = toType.getUnderlyingType();
if (program.typeOracle.willCrossCastLikeJso(toType) ||
program.typeOracle.isOrExtendsJsType(toType, true) ||
program.typeOracle.isJsFunction(toType)) {
instantiateJsoInterface((JReferenceType) toType);
}
}
}
}
private void instantiateJsoInterface(JReferenceType toType) {
if (instantiatedJsoTypes.add(toType)) {
if (program.typeOracle.getSingleJsoImpl(toType) != null) {
// rescuing an Interface via Cast, we record the JSO implementing it
instantiateJsoInterface(program.typeOracle.getSingleJsoImpl(toType));
}
// if it's a class, and the superType is JSO, rescue it too
if (toType instanceof JClassType) {
JClassType superType = ((JClassType) toType).getSuperClass();
if (superType != null && superType.isJsoType()) {
instantiateJsoInterface(superType);
}
}
// if we extend another JsType, or Interface with JSO implementation, rescue it
for (JInterfaceType intf : ((JDeclaredType) toType).getImplements()) {
if (intf.isJsType() || program.typeOracle.getSingleJsoImpl(intf) != null) {
instantiateJsoInterface(intf);
}
}
}
}
private final JProgram program;
private final Set<JReferenceType> instantiatedJsoTypes = new HashSet<JReferenceType>();
public static void exec(JProgram program) {
new ComputeInstantiatedJsoInterfaces(program).execImpl();
}
private ComputeInstantiatedJsoInterfaces(JProgram program) {
this.program = program;
}
private void execImpl() {
InstantiatedJsoInterfacesCollector replacer = new InstantiatedJsoInterfacesCollector();
replacer.accept(program);
program.typeOracle.setInstantiatedJsoTypesViaCast(instantiatedJsoTypes);
}
}