001 /* Copyright (c) 2011-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 aspect ReifiableTypes { 032 /** 033 * A type is reifiable if it either refers to a non-parameterized type, 034 * is a raw type, is a parameterized type with only unbound wildcard 035 * parameters or is an array type with a reifiable type parameter. 036 * 037 * @see "JLS SE7 §4.7" 038 */ 039 syn boolean TypeDecl.isReifiable() = true; 040 041 /** 042 * We only check for wildcards in type parameter list when checking 043 * reifiability. A wildcard type in general is not reifiable. 044 */ 045 eq AbstractWildcardType.isReifiable() = false; 046 047 /** 048 * A type variable is never reifiable. 049 * @return false 050 */ 051 eq TypeVariable.isReifiable() = false; 052 053 /** 054 * A class is reifiable if its enclosing type is reifiable. 055 */ 056 eq ClassDecl.isReifiable() = !isInnerClass() || enclosingType().isReifiable(); 057 058 eq GenericClassDecl.isReifiable() = false; 059 060 /** 061 * A parameterized type is reifiable only if it's 062 * type parameters are all unbound wildcard types. 063 */ 064 eq ParClassDecl.isReifiable() { 065 if (original().isInnerClass() && !original().enclosingType().isReifiable()) { 066 return false; 067 } 068 for (Access argument: getArgumentList()) { 069 if (!argument.isWildcard()) { 070 return false; 071 } 072 } 073 return true; 074 } 075 076 eq RawClassDecl.isReifiable() = true; 077 078 eq GenericInterfaceDecl.isReifiable() = false; 079 080 /** 081 * A parameterized type is reifiable only if it's 082 * type parameters are all unbound wildcard types. 083 */ 084 eq ParInterfaceDecl.isReifiable() { 085 for (Access argument: getArgumentList()) { 086 if (!argument.isWildcard()) { 087 return false; 088 } 089 } 090 return true; 091 } 092 093 eq RawInterfaceDecl.isReifiable() = true; 094 095 /** 096 * An array type is reifiable only if the elements of the 097 * array are reifiable. 098 */ 099 eq ArrayDecl.isReifiable() = componentType().isReifiable(); 100 101 /** 102 * WARNING: this attribute is not the same as TypeDecl.isWildcard, 103 * which returns true for any wildcard type (even bounded wildcard types). 104 * @return {@code true} if this is an unbounded wildcard access 105 */ 106 syn boolean Access.isWildcard() = false; 107 eq Wildcard.isWildcard() = true; 108 eq BoundTypeAccess.isWildcard() = getTypeDecl() instanceof WildcardType; 109 } 110