/* * Copyright 2009 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.javac.asm; import com.google.gwt.core.ext.TreeLogger; import com.google.gwt.core.ext.typeinfo.JType; import com.google.gwt.dev.asm.signature.SignatureVisitor; import com.google.gwt.dev.javac.Resolver; import com.google.gwt.dev.javac.TypeParameterLookup; import com.google.gwt.dev.javac.typemodel.JClassType; import com.google.gwt.dev.javac.typemodel.JRealClassType; import com.google.gwt.dev.javac.typemodel.JTypeParameter; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Signature visitor that resolves all the type variables and their bounds for a * given class. */ public class ResolveClassSignature extends EmptySignatureVisitor { private final Map<String, JRealClassType> binaryMapper; private ArrayList<JType[]> bounds = null; private JTypeParameter currentParam = null; private final List<JType[]> interfaces = new ArrayList<JType[]>(); private final TreeLogger logger; private final TypeParameterLookup lookup; private final Resolver resolver; private final JType[] superClass = new JType[1]; private final JRealClassType type; public ResolveClassSignature(Resolver resolver, Map<String, JRealClassType> binaryMapper, TreeLogger logger, JRealClassType type, TypeParameterLookup lookup) { this.resolver = resolver; this.binaryMapper = binaryMapper; this.logger = logger; this.type = type; this.lookup = lookup; } public void finish() { if (currentParam != null) { int n = bounds.size(); JClassType[] boundTypes = new JClassType[n]; for (int i = 0; i < n; ++i) { boundTypes[i] = (JClassType) bounds.get(i)[0]; } currentParam.setBounds(boundTypes); currentParam = null; // TODO(jat): remove after debugging phase bounds = null; } if (superClass[0] != null) { if (type.isInterface() != null) { // The generic signature contains a superclass for interfaces, // but TypeOracle doesn't like that -- verify that we were // told Object is the superclass and ignore it. assert superClass[0].equals(resolver.getTypeOracle().getJavaLangObject()); } else { resolver.setSuperClass(type, (JClassType) superClass[0]); } superClass[0] = null; } for (JType[] intfRef : interfaces) { if (intfRef[0] != null) { resolver.addImplementedInterface(type, (JClassType) intfRef[0]); } } interfaces.clear(); } @Override public SignatureVisitor visitArrayType() { throw new IllegalStateException( "visitArrayType called on ResolveClassTypeVariables"); } @Override public SignatureVisitor visitClassBound() { JType[] bound = new JType[1]; bounds.add(bound); return new ResolveTypeSignature(resolver, binaryMapper, logger, bound, lookup, null); } @Override public void visitFormalTypeParameter(String name) { finish(); currentParam = lookup.lookup(name); bounds = new ArrayList<JType[]>(); } @Override public SignatureVisitor visitInterface() { finish(); JType[] intf = new JType[1]; interfaces.add(intf); return new ResolveTypeSignature(resolver, binaryMapper, logger, intf, lookup, null); } @Override public SignatureVisitor visitInterfaceBound() { JType[] bound = new JType[1]; bounds.add(bound); return new ResolveTypeSignature(resolver, binaryMapper, logger, bound, lookup, null); } @Override public SignatureVisitor visitSuperclass() { finish(); return new ResolveTypeSignature(resolver, binaryMapper, logger, superClass, lookup, null); } }