/* * Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Business Objects nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * PreludeTypeConstants.java * Created: Dec 6, 2005 * By: Bo Ilic */ package org.openquark.cal.compiler; import org.openquark.cal.module.Cal.Core.CAL_Prelude; /** * Sometimes client code needs to have access to various TypeExpr objects. In general, given a particular * workspace, one can construct a type via TypeChecker.getTypeFromString (or a helper than ends up calling this). * This is the general approach, and will always work. * <p> * However, there are many commonly used types defined in the Prelude module and this class holds useful TypeExpr * constants for the convenience of clients. * <p> * Note that these constants are not *static* constants- a workspace is required to create them. * The constants below are always available since: * <ol> * <li>the Prelude module must be imported into every CAL module * <li>the types below are all public in scope * <li>the Prelude module is stable so these constants will continue to be available * </ol> * Creating TypeExpr constants using this class is efficient, as values are re-used when possible. * * @author Bo Ilic */ public class PreludeTypeConstants { /** ModuleTypeInfo for the Prelude module. */ private final ModuleTypeInfo preludeModuleTypeInfo; /** constant for the Prelude.Char type */ private TypeExpr CHAR_TYPE; /** constant for the Prelude.Boolean type */ private TypeExpr BOOLEAN_TYPE; /** constant for the Prelude.Byte type */ private TypeExpr BYTE_TYPE; /** constant for the Prelude.Short type */ private TypeExpr SHORT_TYPE; /** constant for the Prelude.Int type */ private TypeExpr INT_TYPE; /** constant for the Prelude.Long type */ private TypeExpr LONG_TYPE; /** constant for the Prelude.Float type */ private TypeExpr FLOAT_TYPE; /** constant for the Prelude.Double type */ private TypeExpr DOUBLE_TYPE; /** constant for the Prelude.String type */ private TypeExpr STRING_TYPE; /** constant for the Prelude.Integer type */ private TypeExpr INTEGER_TYPE; /** constant for the Prelude.Decimal type */ private TypeExpr DECIMAL_TYPE; /** constant for the type [Prelude.Char] */ private TypeExpr CHARLIST_TYPE; /** constant for the type Prelude.Unit, also known as (). */ private TypeExpr UNIT_TYPE; /** for the Prelude.List type */ private TypeConstructor LIST_TYPE_CONS; /** * @param moduleTypeInfo for the current module. */ public PreludeTypeConstants(ModuleTypeInfo moduleTypeInfo) { if (moduleTypeInfo.getModuleName().equals(CAL_Prelude.MODULE_NAME)) { this.preludeModuleTypeInfo = moduleTypeInfo; } else { this.preludeModuleTypeInfo = moduleTypeInfo.getImportedModule(CAL_Prelude.MODULE_NAME); if (preludeModuleTypeInfo == null) { throw new IllegalStateException(moduleTypeInfo.getModuleName() + " does not import the Prelude module."); } } } /** * @return TypeExpr constant for the Prelude.Char type. */ public final TypeExpr getCharType() { if (CHAR_TYPE == null) { CHAR_TYPE = makeNonParametricPreludeType(CAL_Prelude.TypeConstructors.Char.getUnqualifiedName()); if (CHAR_TYPE == null) { throw new IllegalStateException(CAL_Prelude.TypeConstructors.Char.getQualifiedName() + " type not available."); } } return CHAR_TYPE; } /** * @return TypeExpr constant for the Prelude.Boolean type. */ public final TypeExpr getBooleanType() { if (BOOLEAN_TYPE == null) { BOOLEAN_TYPE = makeNonParametricPreludeType(CAL_Prelude.TypeConstructors.Boolean.getUnqualifiedName()); if (BOOLEAN_TYPE == null) { throw new IllegalStateException(CAL_Prelude.TypeConstructors.Boolean.getQualifiedName() + " type not available."); } } return BOOLEAN_TYPE; } /** * @return TypeExpr constant for the Prelude.Byte type. */ public final TypeExpr getByteType() { if (BYTE_TYPE == null) { BYTE_TYPE = makeNonParametricPreludeType(CAL_Prelude.TypeConstructors.Byte.getUnqualifiedName()); if (BYTE_TYPE == null) { throw new IllegalStateException(CAL_Prelude.TypeConstructors.Byte.getQualifiedName() + " type not available."); } } return BYTE_TYPE; } /** * @return TypeExpr constant for the Prelude.Short type. */ public final TypeExpr getShortType() { if (SHORT_TYPE == null) { SHORT_TYPE = makeNonParametricPreludeType(CAL_Prelude.TypeConstructors.Short.getUnqualifiedName()); if (SHORT_TYPE == null) { throw new IllegalStateException(CAL_Prelude.TypeConstructors.Short.getQualifiedName() + " type not available."); } } return SHORT_TYPE; } /** * @return TypeExpr constant for the Prelude.Int type. */ public final TypeExpr getIntType() { if (INT_TYPE == null) { INT_TYPE = makeNonParametricPreludeType(CAL_Prelude.TypeConstructors.Int.getUnqualifiedName()); if (INT_TYPE == null) { throw new IllegalStateException(CAL_Prelude.TypeConstructors.Int.getQualifiedName() + " type not available."); } } return INT_TYPE; } /** * @return TypeExpr constant for the Prelude.Long type. */ public final TypeExpr getLongType() { if (LONG_TYPE == null) { LONG_TYPE = makeNonParametricPreludeType(CAL_Prelude.TypeConstructors.Long.getUnqualifiedName()); if (LONG_TYPE == null) { throw new IllegalStateException(CAL_Prelude.TypeConstructors.Long.getQualifiedName() + " type not available."); } } return LONG_TYPE; } /** * @return TypeExpr constant for the Prelude.Float type. */ public final TypeExpr getFloatType() { if (FLOAT_TYPE == null) { FLOAT_TYPE = makeNonParametricPreludeType(CAL_Prelude.TypeConstructors.Float.getUnqualifiedName()); if (FLOAT_TYPE == null) { throw new IllegalStateException(CAL_Prelude.TypeConstructors.Float.getQualifiedName() + " type not available."); } } return FLOAT_TYPE; } /** * @return TypeExpr constant for the Prelude.Double type. */ public final TypeExpr getDoubleType() { if (DOUBLE_TYPE == null) { DOUBLE_TYPE = makeNonParametricPreludeType(CAL_Prelude.TypeConstructors.Double.getUnqualifiedName()); if (DOUBLE_TYPE == null) { throw new IllegalStateException(CAL_Prelude.TypeConstructors.Double.getQualifiedName() + " type not available."); } } return DOUBLE_TYPE; } /** * @return TypeExpr constant for the Prelude.String type. */ public final TypeExpr getStringType() { if (STRING_TYPE == null) { STRING_TYPE = makeNonParametricPreludeType(CAL_Prelude.TypeConstructors.String.getUnqualifiedName()); if (STRING_TYPE == null) { throw new IllegalStateException(CAL_Prelude.TypeConstructors.String.getQualifiedName() + " type not available."); } } return STRING_TYPE; } /** * @return TypeExpr constant for the Prelude.Integer type. */ public final TypeExpr getIntegerType() { if (INTEGER_TYPE == null) { INTEGER_TYPE = makeNonParametricPreludeType(CAL_Prelude.TypeConstructors.Integer.getUnqualifiedName()); if (INTEGER_TYPE == null) { throw new IllegalStateException(CAL_Prelude.TypeConstructors.Integer.getQualifiedName() + " type not available."); } } return INTEGER_TYPE; } /** * @return TypeExpr constant for the Prelude.Decimal type. */ public final TypeExpr getDecimalType() { if (DECIMAL_TYPE == null) { DECIMAL_TYPE = makeNonParametricPreludeType(CAL_Prelude.TypeConstructors.Decimal.getUnqualifiedName()); if (DECIMAL_TYPE == null) { throw new IllegalStateException(CAL_Prelude.TypeConstructors.Decimal.getQualifiedName() + " type not available."); } } return DECIMAL_TYPE; } /** * @return TypeExpr constant for the [Prelude.Char] type. */ public final TypeExpr getCharListType() { if (CHARLIST_TYPE == null) { CHARLIST_TYPE = makeListType(getCharType()); } return CHARLIST_TYPE; } /** * @return TypeExpr constant for the Prelude.Unit type, also known as (). */ public final TypeExpr getUnitType() { if (UNIT_TYPE == null) { UNIT_TYPE = makeNonParametricPreludeType(CAL_Prelude.TypeConstructors.Unit.getUnqualifiedName()); if (UNIT_TYPE == null) { throw new IllegalStateException(CAL_Prelude.TypeConstructors.Unit.getQualifiedName() + " type not available."); } } return UNIT_TYPE; } private final TypeConstructor getListTypeCons() { if (LIST_TYPE_CONS == null) { LIST_TYPE_CONS = preludeModuleTypeInfo.getVisibleTypeConstructor(CAL_Prelude.TypeConstructors.List); if (LIST_TYPE_CONS == null) { throw new IllegalStateException(CAL_Prelude.TypeConstructors.List.getQualifiedName() + " type not available."); } } return LIST_TYPE_CONS; } /** * Create a type expression for a list. * * @param elementTypeExpr the type of the element * @return TypeExpr the type expression for the list with given element type */ public final TypeExpr makeListType(TypeExpr elementTypeExpr) { return new TypeConsApp(getListTypeCons(), new TypeExpr [] {elementTypeExpr}); } /** * Creates a non-parametric TypeExpr from a given Prelude type constructor name. * When both are applicable, this function will be faster than calling getTypeFromString * since it doesn't need to parse a type string. * * @param preludeTypeConsName * @return TypeExpr for the non-parametric type with type constructor name as supplied. Will be null if the typeCons * name is not-valid or not visible. */ private final TypeExpr makeNonParametricPreludeType(String preludeTypeConsName) { TypeConstructor typeCons = preludeModuleTypeInfo.getTypeConstructor(preludeTypeConsName); if (typeCons == null) { return null; } return TypeExpr.makeNonParametricType(typeCons); } }