001 /* Copyright (c) 2015, Jesper Öqvist <jesper.oqvist@cs.lth.se> 002 * All rights reserved. 003 * 004 * Redistribution and use in source and binary forms, with or without 005 * modification, are permitted provided that the following conditions are met: 006 * 007 * 1. Redistributions of source code must retain the above copyright notice, 008 * this list of conditions and the following disclaimer. 009 * 010 * 2. Redistributions in binary form must reproduce the above copyright notice, 011 * this list of conditions and the following disclaimer in the documentation 012 * and/or other materials provided with the distribution. 013 * 014 * 3. Neither the name of the copyright holder nor the names of its 015 * contributors may be used to endorse or promote products derived from this 016 * software without specific prior written permission. 017 * 018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 021 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 022 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 028 * POSSIBILITY OF SUCH DAMAGE. 029 */ 030 031 /** 032 * Attributes for checking if a type argument is within the bounds of a given 033 * type variable. 034 */ 035 aspect GenericBoundCheck { 036 /** 037 * @param bound the bounded type variable 038 * @param par a parameterization of the type for which the type variable 039 * occurs in the type parameter list 040 * @return {@code true} if this type is within the bounds of the parameter type 041 */ 042 syn boolean TypeDecl.withinBounds(TypeDecl bound, Parameterization par) = 043 bound.boundOf(this, par); 044 045 eq UnknownType.withinBounds(TypeDecl bound, Parameterization par) = false; 046 047 eq WildcardType.withinBounds(TypeDecl bound, Parameterization par) = true; 048 eq WildcardExtendsType.withinBounds(TypeDecl bound, Parameterization par) = 049 bound.boundOf(extendsType(), par) || extendsType().boundOf(bound, par); 050 eq WildcardSuperType.withinBounds(TypeDecl bound, Parameterization par) = 051 bound.boundOf(superType(), par); 052 053 /** 054 * Check if a type is in the bound of this type, given a specific 055 * parameterization of this type. 056 * 057 * See JLS SE7 $4.5 058 * 059 * @param argument argument type 060 * @param par a parameterization 061 * @return {@code true} if the argument type is in the bound of this type 062 */ 063 syn boolean TypeDecl.boundOf(TypeDecl argument, Parameterization par) = false; 064 065 eq TypeVariable.boundOf(TypeDecl argument, Parameterization par) { 066 for (int i = 0; i < getNumTypeBound(); ++i) { 067 TypeDecl bound = getTypeBound(i).type(); 068 if (bound.usesTypeVariable()) { 069 Access substituted = bound.substitute(par); 070 substituted.setParent(this); 071 bound = substituted.type(); 072 } 073 if (!argument.subtype(bound)) { 074 return false; 075 } 076 } 077 return true; 078 } 079 080 syn boolean TypeDecl.boundOfWildcard(WildcardType type) = false; 081 eq TypeVariable.boundOfWildcard(WildcardType type) = true; 082 083 syn boolean TypeDecl.boundOfWildcardExtends(WildcardExtendsType type) = false; 084 eq TypeVariable.boundOfWildcardExtends(WildcardExtendsType type) = 085 type.extendsType().subtype(this); 086 087 syn boolean TypeDecl.boundOfWildcardSuper(WildcardSuperType type) = false; 088 eq TypeVariable.boundOfWildcardSuper(WildcardSuperType type) = 089 type.superType().subtype(this); 090 } 091