blob: 79c3d3b085fae6b22ce46df71d23df266fe25926 [file] [log] [blame]
/*
* 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.JClassType;
import com.google.gwt.core.ext.typeinfo.JRealClassType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.JTypeParameter;
import com.google.gwt.dev.asm.signature.SignatureVisitor;
import com.google.gwt.dev.javac.Resolver;
import com.google.gwt.dev.javac.TypeParameterLookup;
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 List<JType[]> interfaces = new ArrayList<JType[]>();
private final TreeLogger logger;
private final TypeParameterLookup lookup;
private final Resolver resolver;
private 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);
}
}