001    /* Copyright (c) 2014, Erik Hogeman <Erik.Hogemn@gmail.com>
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     *     * Redistributions of source code must retain the above copyright notice,
008     *       this list of conditions and the following disclaimer.
009     *     * Redistributions in binary form must reproduce the above copyright
010     *       notice, this list of conditions and the following disclaimer in the
011     *       documentation and/or other materials provided with the distribution.
012     *     * Neither the name of the Lund University nor the names of its
013     *       contributors may be used to endorse or promote products derived from
014     *       this software without specific prior written permission.
015     *
016     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
017     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
018     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
019     * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
020     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
021     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
022     * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
023     * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
024     * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
025     * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
026     * POSSIBILITY OF SUCH DAMAGE.
027     */
028    aspect StrictSubtype {
029    
030      /*
031      Most of this is a redeclaration of the already existing subtype attribute,
032      but this one also takes type variables into consideration. The existing attribute
033      does not compute the subtype correctly for type variables, but still uses the attribute
034      to check that types lies within the bounds of type variables and just changing the subtype
035      attribute would thus result in broken code
036      */
037    
038      eq GenericClassDecl.strictSubtype(TypeDecl type) = type.strictSupertypeGenericClassDecl(this);
039      syn boolean TypeDecl.strictSupertypeGenericClassDecl(GenericClassDecl type) =
040          strictSupertypeClassDecl(type);
041      eq RawClassDecl.strictSupertypeGenericClassDecl(GenericClassDecl type) =
042          type.strictSubtype(genericDecl().original());
043    
044      eq GenericInterfaceDecl.strictSubtype(TypeDecl type) =
045          type.strictSupertypeGenericInterfaceDecl(this);
046      syn boolean TypeDecl.strictSupertypeGenericInterfaceDecl(GenericInterfaceDecl type) =
047          this == type || strictSupertypeInterfaceDecl(type);
048      eq RawInterfaceDecl.strictSupertypeGenericInterfaceDecl(GenericInterfaceDecl type) =
049          type.strictSubtype(genericDecl().original());
050    
051      eq RawClassDecl.strictSubtype(TypeDecl type) = type.strictSupertypeRawClassDecl(this);
052      syn boolean TypeDecl.strictSupertypeRawClassDecl(RawClassDecl type) =
053          strictSupertypeParClassDecl(type);
054    
055      eq RawInterfaceDecl.strictSubtype(TypeDecl type) = type.strictSupertypeRawInterfaceDecl(this);
056      syn boolean TypeDecl.strictSupertypeRawInterfaceDecl(RawInterfaceDecl type) =
057          strictSupertypeParInterfaceDecl(type);
058    
059      // 5.1.9 Unchecked Conversion
060      eq ParClassDecl.strictSupertypeGenericClassDecl(GenericClassDecl type) =
061          type.strictSubtype(genericDecl().original());
062      eq ParInterfaceDecl.strictSupertypeGenericClassDecl(GenericClassDecl type) =
063          type.strictSubtype(genericDecl().original());
064      eq ParInterfaceDecl.strictSupertypeGenericInterfaceDecl(GenericInterfaceDecl type) =
065          type.strictSubtype(genericDecl().original());
066    
067      eq WildcardType.strictSubtype(TypeDecl type) = type.strictSupertypeWildcard(this);
068      syn boolean TypeDecl.strictSupertypeWildcard(WildcardType type) = false;
069      eq WildcardType.strictSupertypeWildcard(WildcardType type) = true;
070      eq TypeVariable.strictSupertypeWildcard(WildcardType type) = true;
071      eq WildcardExtendsType.strictSupertypeWildcard(WildcardType type) =
072          typeObject().strictSubtype(this);
073      eq WildcardSuperType.strictSupertypeWildcard(WildcardType type) =
074          superType().strictSubtype(typeObject());
075    
076      eq WildcardExtendsType.strictSubtype(TypeDecl type) = type.strictSupertypeWildcardExtends(this);
077      syn boolean TypeDecl.strictSupertypeWildcardExtends(WildcardExtendsType type) = false;
078      eq WildcardType.strictSupertypeWildcardExtends(WildcardExtendsType type) = true;
079      eq TypeVariable.strictSupertypeWildcardExtends(WildcardExtendsType type) =
080          type.extendsType().strictSubtype(this);
081      eq WildcardExtendsType.strictSupertypeWildcardExtends(WildcardExtendsType type) =
082          type.extendsType().strictSubtype(extendsType());
083    
084      eq WildcardSuperType.strictSubtype(TypeDecl type) = type.strictSupertypeWildcardSuper(this);
085      syn boolean TypeDecl.strictSupertypeWildcardSuper(WildcardSuperType type) = false;
086      eq WildcardType.strictSupertypeWildcardSuper(WildcardSuperType type) = true;
087      eq TypeVariable.strictSupertypeWildcardSuper(WildcardSuperType type) =
088          type.superType().strictSubtype(this);
089      eq WildcardSuperType.strictSupertypeWildcardSuper(WildcardSuperType type) =
090          type.superType().strictSubtype(superType());
091    
092      eq WildcardType.strictSupertypeClassDecl(ClassDecl type) = true;
093      eq WildcardType.strictSupertypeInterfaceDecl(InterfaceDecl type) = true;
094      eq WildcardType.strictSupertypeParClassDecl(ParClassDecl type) = true;
095      eq WildcardType.strictSupertypeParInterfaceDecl(ParInterfaceDecl type) = true;
096      eq WildcardType.strictSupertypeRawClassDecl(RawClassDecl type) = true;
097      eq WildcardType.strictSupertypeRawInterfaceDecl(RawInterfaceDecl type) = true;
098      eq WildcardType.strictSupertypeTypeVariable(TypeVariable type) = true;
099      eq WildcardType.strictSupertypeArrayDecl(ArrayDecl type) = true;
100    
101      eq WildcardExtendsType.strictSupertypeClassDecl(ClassDecl type) =
102          type.strictSubtype(extendsType());
103      eq WildcardExtendsType.strictSupertypeInterfaceDecl(InterfaceDecl type) =
104          type.strictSubtype(extendsType());
105      eq WildcardExtendsType.strictSupertypeParClassDecl(ParClassDecl type) =
106          type.strictSubtype(extendsType());
107      eq WildcardExtendsType.strictSupertypeParInterfaceDecl(ParInterfaceDecl type) =
108          type.strictSubtype(extendsType());
109      eq WildcardExtendsType.strictSupertypeRawClassDecl(RawClassDecl type) =
110          type.strictSubtype(extendsType());
111      eq WildcardExtendsType.strictSupertypeRawInterfaceDecl(RawInterfaceDecl type) =
112          type.strictSubtype(extendsType());
113      eq WildcardExtendsType.strictSupertypeTypeVariable(TypeVariable type) =
114          type.strictSubtype(extendsType());
115      eq WildcardExtendsType.strictSupertypeArrayDecl(ArrayDecl type) =
116          type.strictSubtype(extendsType());
117    
118      eq WildcardSuperType.strictSupertypeClassDecl(ClassDecl type) =
119          superType().strictSubtype(type);
120      eq WildcardSuperType.strictSupertypeInterfaceDecl(InterfaceDecl type) =
121          superType().strictSubtype(type);
122      eq WildcardSuperType.strictSupertypeParClassDecl(ParClassDecl type) =
123          superType().strictSubtype(type);
124      eq WildcardSuperType.strictSupertypeParInterfaceDecl(ParInterfaceDecl type) =
125          superType().strictSubtype(type);
126      eq WildcardSuperType.strictSupertypeRawClassDecl(RawClassDecl type) =
127          superType().strictSubtype(type);
128      eq WildcardSuperType.strictSupertypeRawInterfaceDecl(RawInterfaceDecl type) =
129          superType().strictSubtype(type);
130      eq WildcardSuperType.strictSupertypeTypeVariable(TypeVariable type) =
131          superType().strictSubtype(type);
132      eq WildcardSuperType.strictSupertypeArrayDecl(ArrayDecl type) =
133          superType().strictSubtype(type);
134    
135      eq ParClassDecl.strictSupertypeClassDecl(ClassDecl type) =
136          super.strictSupertypeClassDecl(type);
137      eq ParInterfaceDecl.strictSupertypeClassDecl(ClassDecl type) =
138          super.strictSupertypeClassDecl(type);
139    
140      eq RawClassDecl.strictSupertypeClassDecl(ClassDecl type) =
141          type.strictSubtype(genericDecl().original());
142      eq RawClassDecl.strictSupertypeInterfaceDecl(InterfaceDecl type) =
143          type.strictSubtype(genericDecl().original());
144      eq RawClassDecl.strictSupertypeParClassDecl(ParClassDecl type) =
145          type.genericDecl().original().strictSubtype(genericDecl().original());
146    
147      eq RawInterfaceDecl.strictSupertypeClassDecl(ClassDecl type) =
148          type.strictSubtype(genericDecl().original());
149      eq RawInterfaceDecl.strictSupertypeInterfaceDecl(InterfaceDecl type) =
150          type.strictSubtype(genericDecl().original());
151      eq RawInterfaceDecl.strictSupertypeParInterfaceDecl(ParInterfaceDecl type) =
152          type.genericDecl().original().strictSubtype(genericDecl().original());
153    
154      eq ParClassDecl.strictSubtype(TypeDecl type) = type.strictSupertypeParClassDecl(this);
155      syn boolean TypeDecl.strictSupertypeParClassDecl(ParClassDecl type) =
156          strictSupertypeClassDecl(type);
157    
158      eq ParInterfaceDecl.strictSubtype(TypeDecl type) = type.strictSupertypeParInterfaceDecl(this);
159      syn boolean TypeDecl.strictSupertypeParInterfaceDecl(ParInterfaceDecl type) =
160          strictSupertypeInterfaceDecl(type);
161    
162      eq ParClassDecl.strictSupertypeRawClassDecl(RawClassDecl type) =
163          type.genericDecl().original().strictSubtype(genericDecl().original());
164      eq ParClassDecl.strictSupertypeRawInterfaceDecl(RawInterfaceDecl type) =
165          type.genericDecl().original().strictSubtype(genericDecl().original());
166      eq ParInterfaceDecl.strictSupertypeRawClassDecl(RawClassDecl type) =
167          type.genericDecl().original().strictSubtype(genericDecl().original());
168      eq ParInterfaceDecl.strictSupertypeRawInterfaceDecl(RawInterfaceDecl type) =
169          type.genericDecl().original().strictSubtype(genericDecl().original());
170    
171      syn boolean TypeDecl.strictContainedIn(TypeDecl type) circular [true] {
172        if (type == this || type instanceof WildcardType) {
173          return true;
174        } else if (type instanceof WildcardExtendsType) {
175          return this.strictSubtype(((WildcardExtendsType) type).extendsType());
176        } else if (type instanceof WildcardSuperType) {
177          return ((WildcardSuperType) type).superType().strictSubtype(this);
178        } else if (type instanceof TypeVariable) {
179          return strictSubtype(type);
180        }
181        return sameStructure(type);
182      }
183    
184      eq WildcardExtendsType.strictContainedIn(TypeDecl type) {
185        if (type == this || type instanceof WildcardType) {
186          return true;
187        } else if (type instanceof WildcardExtendsType) {
188          return extendsType().strictSubtype(((WildcardExtendsType) type).extendsType());
189        } else {
190          return false;
191        }
192      }
193    
194      eq WildcardSuperType.strictContainedIn(TypeDecl type) {
195        if (type == this || type instanceof WildcardType) {
196          return true;
197        } else if (type instanceof WildcardSuperType) {
198          return ((WildcardSuperType)type).superType().strictSubtype(superType());
199        } else {
200          return false;
201        }
202      }
203    
204      eq WildcardType.strictContainedIn(TypeDecl type) {
205        if (type == this) {
206          return true;
207        } else if (type instanceof WildcardExtendsType) {
208          return typeObject().strictSubtype(((WildcardExtendsType) type).extendsType());
209        } else {
210          return false;
211        }
212      }
213    
214      eq ParClassDecl.strictSupertypeParClassDecl(ParClassDecl type) {
215        if (type.genericDecl().original() == genericDecl().original()
216            && type.getNumArgument() == getNumArgument()) {
217          for (int i = 0; i < getNumArgument(); i++) {
218            if (!type.getArgument(i).type().strictContainedIn(getArgument(i).type())) {
219              return false;
220            }
221          }
222          if (isNestedType() && type.isNestedType()) {
223            return type.enclosingType().strictSubtype(enclosingType());
224          }
225          return true;
226        }
227        return strictSupertypeClassDecl(type);
228      }
229    
230      eq ParClassDecl.strictSupertypeParInterfaceDecl(ParInterfaceDecl type) = false;
231    
232      eq ParInterfaceDecl.strictSupertypeParClassDecl(ParClassDecl type) {
233        if (type.genericDecl().original() == genericDecl().original()
234            && type.getNumArgument() == getNumArgument()) {
235          for (int i = 0; i < getNumArgument(); i++) {
236            if (!type.getArgument(i).type().strictContainedIn(getArgument(i).type())) {
237              return false;
238            }
239          }
240          if (isNestedType() && type.isNestedType()) {
241            return type.enclosingType().strictSubtype(enclosingType());
242          }
243          return true;
244        }
245        return strictSupertypeClassDecl(type);
246      }
247    
248      eq ParInterfaceDecl.strictSupertypeParInterfaceDecl(ParInterfaceDecl type) {
249        if (type.genericDecl().original() == genericDecl().original()
250            && type.getNumArgument() == getNumArgument()) {
251          for (int i = 0; i < getNumArgument(); i++) {
252            if (!type.getArgument(i).type().strictContainedIn(getArgument(i).type())) {
253              return false;
254            }
255          }
256          if (isNestedType() && type.isNestedType()) {
257            return type.enclosingType().strictSubtype(enclosingType());
258          }
259          return true;
260        }
261        return strictSupertypeInterfaceDecl(type);
262      }
263    
264      eq GenericClassDecl.strictSupertypeParClassDecl(ParClassDecl type) =
265          type.genericDecl().original().strictSubtype(this);
266      eq GenericClassDecl.strictSupertypeParInterfaceDecl(ParInterfaceDecl type) =
267          type.genericDecl().original().strictSubtype(this);
268      eq GenericInterfaceDecl.strictSupertypeParClassDecl(ParClassDecl type) =
269          type.genericDecl().original().strictSubtype(this);
270      eq GenericInterfaceDecl.strictSupertypeParInterfaceDecl(ParInterfaceDecl type) =
271          type.genericDecl().original().strictSubtype(this);
272    
273      eq TypeVariable.strictSupertypeArrayDecl(ArrayDecl type) = false;
274    
275      eq TypeVariable.strictSubtype(TypeDecl type) = type.strictSupertypeTypeVariable(this);
276      syn boolean TypeDecl.strictSupertypeTypeVariable(TypeVariable type) {
277        if (type == this) {
278          return true;
279        }
280        for (int i = 0; i < type.getNumTypeBound(); i++) {
281          if (type.getTypeBound(i).type().strictSubtype(this)) {
282            return true;
283          }
284        }
285        return false;
286      }
287    
288      eq TypeVariable.strictSupertypeTypeVariable(TypeVariable type) {
289        if (typeVarInMethod() && type.typeVarInMethod()
290            && genericMethodLevel() == type.genericMethodLevel()) {
291          if (typeVarPosition() == type.typeVarPosition() || this == type) {
292            return true;
293          }
294        } else {
295          if (this == type) {
296            return true;
297          }
298        }
299        for (int i = 0; i < type.getNumTypeBound(); i++) {
300          if (type.getTypeBound(i).type().strictSubtype(this)) {
301            return true;
302          }
303        }
304        return false;
305      }
306    
307      eq TypeVariable.strictSupertypeClassDecl(ClassDecl type) {
308        return false;
309      }
310    
311      eq TypeVariable.strictSupertypeInterfaceDecl(InterfaceDecl type) {
312        return false;
313      }
314    
315      eq LUBType.strictSubtype(TypeDecl type) = type.strictSupertypeLUBType(this);
316      syn boolean TypeDecl.strictSupertypeLUBType(LUBType type) {
317        for (int i = 0; i < type.getNumTypeBound(); i++) {
318          if (!type.getTypeBound(i).type().strictSubtype(this)) {
319            return false;
320          }
321        }
322        return true;
323      }
324      eq GLBType.strictSupertypeLUBType(LUBType type){
325        ArrayList bounds = new ArrayList(getNumTypeBound());
326        for (int i = 0; i < getNumTypeBound(); i++) {
327          bounds.add(getTypeBound(i));
328        }
329        return type == lookupLUBType(bounds);
330      }
331    
332      eq LUBType.strictSupertypeClassDecl(ClassDecl type) = type.strictSubtype(lub());
333      eq LUBType.strictSupertypeInterfaceDecl(InterfaceDecl type) = type.strictSubtype(lub());
334    
335      eq GLBType.strictSubtype(TypeDecl type) = type.strictSupertypeGLBType(this);
336      syn boolean TypeDecl.strictSupertypeGLBType(GLBType type) {
337        // T1 && .. && Tn <: this, if exists  0 < i <= n Ti <: this
338        for (int i = 0; i < type.getNumTypeBound(); i++) {
339          if (type.getTypeBound(i).type().strictSubtype(this)) {
340            return true;
341          }
342        }
343        return false;
344      }
345    
346      eq GLBType.strictSupertypeGLBType(GLBType type) = this == type;
347      eq LUBType.strictSupertypeGLBType(GLBType type) {
348        ArrayList bounds = new ArrayList(getNumTypeBound());
349        for (int i = 0; i < getNumTypeBound(); i++) {
350          bounds.add(getTypeBound(i));
351        }
352        return type == lookupGLBType(bounds);
353      }
354    
355      syn boolean TypeDecl.strictSubtype(TypeDecl type) circular [true] = type == this;
356      eq ClassDecl.strictSubtype(TypeDecl type) = type.strictSupertypeClassDecl(this);
357      eq InterfaceDecl.strictSubtype(TypeDecl type) = type.strictSupertypeInterfaceDecl(this);
358      eq ArrayDecl.strictSubtype(TypeDecl type) = type.strictSupertypeArrayDecl(this);
359      eq PrimitiveType.strictSubtype(TypeDecl type) = type.strictSupertypePrimitiveType(this);
360      eq NullType.strictSubtype(TypeDecl type) = type.strictSupertypeNullType(this);
361      eq VoidType.strictSubtype(TypeDecl type) = type.strictSupertypeVoidType(this);
362    
363      eq UnknownType.strictSubtype(TypeDecl type) = true;
364      eq UnknownType.strictSupertypeClassDecl(ClassDecl type) = true;
365      eq UnknownType.strictSupertypeInterfaceDecl(InterfaceDecl type) = true;
366      eq UnknownType.strictSupertypeArrayDecl(ArrayDecl type) = true;
367      eq UnknownType.strictSupertypePrimitiveType(PrimitiveType type) = true;
368      eq UnknownType.strictSupertypeNullType(NullType type) = true;
369    
370      syn boolean TypeDecl.strictSupertypeClassDecl(ClassDecl type) = type == this;
371    
372      eq ClassDecl.strictSupertypeClassDecl(ClassDecl type) =
373          super.strictSupertypeClassDecl(type) || type.hasSuperclass()
374          && type.superclass() != null && type.superclass().strictSubtype(this);
375    
376      eq InterfaceDecl.strictSupertypeClassDecl(ClassDecl type) {
377        if (super.strictSupertypeClassDecl(type)) {
378          return true;
379        }
380        for (Iterator<TypeDecl> iter = type.interfacesIterator(); iter.hasNext(); ) {
381          TypeDecl typeDecl = iter.next();
382          if (typeDecl.strictSubtype(this)) {
383            return true;
384          }
385        }
386        return type.hasSuperclass() && type.superclass() != null
387            && type.superclass().strictSubtype(this);
388      }
389    
390      syn boolean TypeDecl.strictSupertypeInterfaceDecl(InterfaceDecl type) = type == this;
391    
392      eq ClassDecl.strictSupertypeInterfaceDecl(InterfaceDecl type) = isObject();
393    
394      eq InterfaceDecl.strictSupertypeInterfaceDecl(InterfaceDecl type) {
395        if (super.strictSupertypeInterfaceDecl(type)) {
396          return true;
397        }
398        for (Iterator<TypeDecl> iter = type.interfacesIterator(); iter.hasNext(); ) {
399          TypeDecl superinterface = iter.next();
400          if (superinterface.strictSubtype(this)) {
401            return true;
402          }
403        }
404        return false;
405      }
406    
407      syn boolean TypeDecl.strictSupertypeArrayDecl(ArrayDecl type) = this == type;
408    
409      eq ClassDecl.strictSupertypeArrayDecl(ArrayDecl type) {
410        if (super.strictSupertypeArrayDecl(type)) {
411          return true;
412        }
413        return type.hasSuperclass() && type.superclass() != null
414            && type.superclass().strictSubtype(this);
415      }
416    
417      eq InterfaceDecl.strictSupertypeArrayDecl(ArrayDecl type) {
418        if (super.strictSupertypeArrayDecl(type)) {
419          return true;
420        }
421        for (Iterator<TypeDecl> iter = type.interfacesIterator(); iter.hasNext(); ) {
422          TypeDecl typeDecl = iter.next();
423          if (typeDecl.strictSubtype(this)) {
424            return true;
425          }
426        }
427        return false;
428      }
429    
430      eq ArrayDecl.strictSupertypeArrayDecl(ArrayDecl type) {
431        if (type.elementType().isPrimitive() && elementType().isPrimitive()) {
432          return type.dimension() == dimension() && type.elementType() == elementType();
433        }
434        return type.componentType().strictSubtype(componentType());
435      }
436    
437      syn boolean TypeDecl.strictSupertypePrimitiveType(PrimitiveType type) = type == this;
438      eq PrimitiveType.strictSupertypePrimitiveType(PrimitiveType type) {
439        if (super.strictSupertypePrimitiveType(type)) {
440          return true;
441        }
442        return type.hasSuperclass() && type.superclass().isPrimitive()
443            && type.superclass().strictSubtype(this);
444      }
445    
446      syn boolean TypeDecl.strictSupertypeNullType(NullType type) = false;
447      eq ReferenceType.strictSupertypeNullType(NullType type) = true;
448      eq NullType.strictSupertypeNullType(NullType type) = true;
449    
450      syn boolean TypeDecl.strictSupertypeVoidType(VoidType type) = false;
451      eq VoidType.strictSupertypeVoidType(VoidType type) = true;
452    
453      eq ClassDeclSubstituted.strictSubtype(TypeDecl type) =
454          type.strictSupertypeClassDeclSubstituted(this);
455      syn boolean TypeDecl.strictSupertypeClassDeclSubstituted(ClassDeclSubstituted type) =
456          type.original() == this || strictSupertypeClassDecl(type);
457      eq ClassDeclSubstituted.strictSupertypeClassDeclSubstituted(ClassDeclSubstituted type) =
458          original() == type.original() && type.enclosingType().strictSubtype(enclosingType())
459          || super.strictSupertypeClassDeclSubstituted(type);
460    
461      eq ClassDeclSubstituted.strictSupertypeClassDecl(ClassDecl type) =
462          super.strictSupertypeClassDecl(type) || original().strictSupertypeClassDecl(type);
463    
464      eq InterfaceDeclSubstituted.strictSubtype(TypeDecl type) =
465          type.strictSupertypeInterfaceDeclSubstituted(this);
466      syn boolean TypeDecl.strictSupertypeInterfaceDeclSubstituted(InterfaceDeclSubstituted type) =
467          type.original() == this || strictSupertypeInterfaceDecl(type);
468      eq InterfaceDeclSubstituted.strictSupertypeInterfaceDeclSubstituted(
469            InterfaceDeclSubstituted type) =
470          original() == type.original() && type.enclosingType().strictSubtype(enclosingType())
471          || super.strictSupertypeInterfaceDeclSubstituted(type);
472    
473      eq InterfaceDeclSubstituted.strictSupertypeInterfaceDecl(InterfaceDecl type) =
474          super.strictSupertypeInterfaceDecl(type) || original().strictSupertypeInterfaceDecl(type);
475    
476      eq GenericClassDeclSubstituted.strictSubtype(TypeDecl type) =
477          type.strictSupertypeGenericClassDeclSubstituted(this);
478      syn boolean TypeDecl.strictSupertypeGenericClassDeclSubstituted(
479            GenericClassDeclSubstituted type) =
480          type.original() == this || strictSupertypeGenericClassDecl(type);
481      eq GenericClassDeclSubstituted.strictSupertypeGenericClassDeclSubstituted(
482            GenericClassDeclSubstituted type) =
483          original() == type.original() && type.enclosingType().strictSubtype(enclosingType())
484          || super.strictSupertypeGenericClassDeclSubstituted(type);
485    
486      eq GenericClassDeclSubstituted.strictSupertypeGenericClassDecl(GenericClassDecl type) =
487          super.strictSupertypeGenericClassDecl(type)
488          || original().strictSupertypeGenericClassDecl(type);
489    
490      eq GenericInterfaceDeclSubstituted.strictSubtype(TypeDecl type) =
491          type.strictSupertypeGenericInterfaceDeclSubstituted(this);
492      syn boolean TypeDecl.strictSupertypeGenericInterfaceDeclSubstituted(
493            GenericInterfaceDeclSubstituted type) =
494          type.original() == this || strictSupertypeGenericInterfaceDecl(type);
495      eq GenericInterfaceDeclSubstituted.strictSupertypeGenericInterfaceDeclSubstituted(
496            GenericInterfaceDeclSubstituted type) =
497          original() == type.original() && type.enclosingType().strictSubtype(enclosingType())
498          || super.strictSupertypeGenericInterfaceDeclSubstituted(type);
499      eq GenericInterfaceDeclSubstituted.strictSupertypeGenericInterfaceDecl(GenericInterfaceDecl type) =
500          super.strictSupertypeGenericInterfaceDecl(type)
501          || original().strictSupertypeGenericInterfaceDecl(type);
502    
503    
504    }