blob: 4dfe9905b7c0788dedee8076947ab4881ce53ac9 [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.ast;
import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.util.StringInterner;
import java.util.List;
/**
* Base class for any types entity.
*/
public abstract class JType extends JNode implements HasName, CanBeFinal {
static boolean replaces(List<? extends JType> newTypes, List<? extends JType> oldTypes) {
if (newTypes.size() != oldTypes.size()) {
return false;
}
for (int i = 0, c = newTypes.size(); i < c; ++i) {
if (!newTypes.get(i).replaces(oldTypes.get(i))) {
return false;
}
}
return true;
}
protected final String name;
private String shortName = null;
private String packageName = null;
/**
* Base type for AST type definitions.
*
* @param info tracks the source file origin of this type through compilation.
* @param name binary name of the type.
*/
public JType(SourceInfo info, String name) {
super(info);
this.name = StringInterner.get().intern(name);
}
/**
* Returns <code>true</code> if it's possible for this type to be
* <code>null</code>.
*
* @see JAnalysisDecoratedType
*/
public abstract boolean canBeNull();
public abstract boolean isArrayType();
public abstract boolean isPrimitiveType();
/**
* Returns {@code true} if this is {@link JReferenceType.JNullType.INSTANCE}.
*/
public boolean isNullType() {
return false;
}
public abstract boolean isJsType();
public abstract boolean isJsFunction();
public abstract boolean isJsNative();
public abstract boolean canBeImplementedExternally();
public abstract boolean canBeReferencedExternally();
public abstract boolean isJavaLangObject();
/**
* Returns {@code true} if this is a JavaScriptObject type.
*/
public abstract boolean isJsoType();
/**
* Returns <code>true</code> if it's possible for this type to be
* a subclass of the type denoted with this type.
*
* @see JAnalysisDecoratedType
*/
public abstract boolean canBeSubclass();
/**
* Returns a non nullable version of this type if possible.
*
* @see JAnalysisDecoratedType
*/
public abstract JType strengthenToNonNull();
public abstract JLiteral getDefaultValue();
public abstract String getJavahSignatureName();
public abstract String getJsniSignatureName();
public String getShortName() {
if (shortName == null) {
shortName = StringInterner.get().intern(name.substring(name.lastIndexOf('.') + 1));
}
return shortName;
}
/**
* Returns the compound name.
* <p>
* The compound name of a class is an array that contains the simple names of all enclosing
* types followed by the simple name of this type (in outer to inner order).
* <p>
* A simple name is the name as it appears in the class declaration (e.g. Name in
* "class Name { .. }"), i.e. it is a name that does not include enclosing type names nor package.
*/
public String[] getCompoundName() {
return new String[] { getShortName() };
}
/**
* Returns a customized description to be used by {@link
* com.google.gwt.dev.jjs.impl.ToStringGenerationVisitor}.
*/
public String getDescription() {
return getName();
}
/**
* If this type is a non-null type, returns the underlying (original) type.
*/
public JType getUnderlyingType() {
return this;
}
public String getPackageName() {
if (packageName == null) {
int dotpos = name.lastIndexOf('.');
packageName = StringInterner.get().intern(name.substring(0, dotpos < 0 ? 0 : dotpos));
}
return packageName;
}
/**
* Returns the (closest) enum supertype if the type is a subclass of an enum; it returns
* {@code this} if {@code this} is a {@link JEnumType} and {@code null} otherwise.
*/
public abstract JEnumType isEnumOrSubclass();
/**
* Binary name of the type.
*
* For example "com.example.Foo$Bar"
*/
@Override
public String getName() {
return name;
}
/**
* True if this class is provided externally to the program by the program's
* host execution environment. For example, while compiling for the JVM, JRE
* types are external types. External types definitions are provided by class
* files which are considered opaque by the GWT compiler.
*
* TODO(scottb): Means something totally different after AST stiching is done.
*/
public boolean isExternal() {
return false;
}
/**
* Checks type replacement from an external type to a resolved canonical type.
*/
public boolean replaces(JType originalType) {
if (this == originalType) {
return true;
}
return originalType.isExternal() && originalType.getName().equals(this.getName());
}
}