blob: c8b99cb3cf87c39adea91cd772f074d8aff36b0b [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.jjs;
import com.google.gwt.dev.jjs.Correlation.Axis;
import com.google.gwt.dev.jjs.Correlation.Literal;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JField;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JType;
import org.apache.commons.collections.map.ReferenceMap;
import java.io.Serializable;
import java.util.Collections;
import java.util.EnumMap;
import java.util.Map;
/**
* A {@link Correlation} factory.
*/
public abstract class CorrelationFactory implements Serializable {
/**
* A dummy factory that always returns <code>null</code>.
*/
public static final class DummyCorrelationFactory extends CorrelationFactory {
public static final CorrelationFactory INSTANCE = new DummyCorrelationFactory();
private DummyCorrelationFactory() {
}
@Override
public Correlation by(JDeclaredType type) {
return null;
}
@Override
public Correlation by(JField field) {
return null;
}
@Override
public Correlation by(JMethod method) {
return null;
}
@Override
public Correlation by(Literal type) {
return null;
}
@Override
public SourceInfo makeSourceInfo(SourceOrigin origin) {
return origin;
}
}
/**
* A real factory that returns new {@link Correlation Correlations}.
*/
public static final class RealCorrelationFactory extends CorrelationFactory {
/*
* NB: The Correlation type uses AST nodes in its factory methods to make it
* easier to extract whatever information we want to include in the Compile
* Reports without having to update call sites with additional parameters.
*
* In the general case, references to AST nodes should not be exposed to any
* public-API consumers of the Correlation.
*/
public static final CorrelationFactory INSTANCE = new RealCorrelationFactory();
/**
* Correlations based on Literals are all the same, so we'll just cook up a
* Map to make {@link #by(Literal)} fast.
*/
private static final Map<Literal, Correlation> LITERAL_CORRELATIONS =
new EnumMap<Literal, Correlation>(Literal.class);
static {
for (Literal l : Literal.values()) {
LITERAL_CORRELATIONS.put(l, new Correlation(Axis.LITERAL, l.getDescription(), l));
}
}
private static String getMethodIdent(JMethod method) {
StringBuilder sb = new StringBuilder();
sb.append(method.getEnclosingType().getName()).append("::");
sb.append(method.getName()).append("(");
for (JType type : method.getOriginalParamTypes()) {
sb.append(type.getJsniSignatureName());
}
sb.append(")");
sb.append(method.getOriginalReturnType().getJsniSignatureName());
return sb.toString();
}
/**
* This cuts down on the total number of Correlation objects allocated.
*/
@SuppressWarnings("unchecked")
private final Map<Object, Correlation> canonicalMap = Collections
.synchronizedMap(new ReferenceMap(ReferenceMap.WEAK, ReferenceMap.WEAK));
private RealCorrelationFactory() {
}
@Override
public Correlation by(JDeclaredType type) {
Correlation toReturn = canonicalMap.get(type);
if (toReturn == null) {
toReturn = new Correlation(Axis.CLASS, type.getName(), type);
canonicalMap.put(type, toReturn);
}
return toReturn;
}
@Override
public Correlation by(JField field) {
Correlation toReturn = canonicalMap.get(field);
if (toReturn == null) {
toReturn =
new Correlation(Axis.FIELD,
field.getEnclosingType().getName() + "::" + field.getName(), field);
canonicalMap.put(field, toReturn);
}
return toReturn;
}
@Override
public Correlation by(JMethod method) {
Correlation toReturn = canonicalMap.get(method);
if (toReturn == null) {
toReturn = new Correlation(Axis.METHOD, getMethodIdent(method), method);
canonicalMap.put(method, toReturn);
}
return toReturn;
}
@Override
public Correlation by(Literal type) {
assert LITERAL_CORRELATIONS.containsKey(type);
return LITERAL_CORRELATIONS.get(type);
}
@Override
public SourceInfo makeSourceInfo(SourceOrigin origin) {
return new SourceInfoCorrelation(origin);
}
}
public abstract Correlation by(JDeclaredType type);
public abstract Correlation by(JField field);
public abstract Correlation by(JMethod method);
public abstract Correlation by(Literal type);
public abstract SourceInfo makeSourceInfo(SourceOrigin origin);
}