List of usage examples for org.eclipse.jdt.internal.compiler.lookup Substitution environment
LookupEnvironment environment();
From source file:org.eclipse.jdt.internal.compiler.lookup.Scope.java
License:Open Source License
/** * Returns a type, where original type was substituted using the receiver * parameterized type.//from w w w .j a va2s . c o m * In raw mode, all parameterized type denoting same original type are converted * to raw types. e.g. * class X <T> { * X<T> foo; * X<String> bar; * } when used in raw fashion, then type of both foo and bar is raw type X. * */ public static TypeBinding substitute(Substitution substitution, TypeBinding originalType) { if (originalType == null) return null; switch (originalType.kind()) { case Binding.TYPE_PARAMETER: return substitution.substitute((TypeVariableBinding) originalType); case Binding.PARAMETERIZED_TYPE: ParameterizedTypeBinding originalParameterizedType = (ParameterizedTypeBinding) originalType; ReferenceBinding originalEnclosing = originalType.enclosingType(); ReferenceBinding substitutedEnclosing = originalEnclosing; if (originalEnclosing != null) { substitutedEnclosing = (ReferenceBinding) substitute(substitution, originalEnclosing); } TypeBinding[] originalArguments = originalParameterizedType.arguments; TypeBinding[] substitutedArguments = originalArguments; if (originalArguments != null) { if (substitution.isRawSubstitution()) { return originalParameterizedType.environment .createRawType(originalParameterizedType.genericType(), substitutedEnclosing); } substitutedArguments = substitute(substitution, originalArguments); } if (substitutedArguments != originalArguments || substitutedEnclosing != originalEnclosing) { return originalParameterizedType.environment.createParameterizedType( originalParameterizedType.genericType(), substitutedArguments, substitutedEnclosing); } break; case Binding.ARRAY_TYPE: ArrayBinding originalArrayType = (ArrayBinding) originalType; TypeBinding originalLeafComponentType = originalArrayType.leafComponentType; TypeBinding substitute = substitute(substitution, originalLeafComponentType); // substitute could itself be array type if (substitute != originalLeafComponentType) { return originalArrayType.environment.createArrayType(substitute.leafComponentType(), substitute.dimensions() + originalType.dimensions()); } break; case Binding.WILDCARD_TYPE: case Binding.INTERSECTION_TYPE: WildcardBinding wildcard = (WildcardBinding) originalType; if (wildcard.boundKind != Wildcard.UNBOUND) { TypeBinding originalBound = wildcard.bound; TypeBinding substitutedBound = substitute(substitution, originalBound); TypeBinding[] originalOtherBounds = wildcard.otherBounds; TypeBinding[] substitutedOtherBounds = substitute(substitution, originalOtherBounds); if (substitutedBound != originalBound || originalOtherBounds != substitutedOtherBounds) { if (originalOtherBounds != null) { /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=347145: the constituent intersecting types have changed in the last round of substitution. Reevaluate the composite intersection type, as there is a possibility of the intersection collapsing into one of the constituents, the other being fully subsumed. */ TypeBinding[] bounds = new TypeBinding[1 + substitutedOtherBounds.length]; bounds[0] = substitutedBound; System.arraycopy(substitutedOtherBounds, 0, bounds, 1, substitutedOtherBounds.length); TypeBinding[] glb = Scope.greaterLowerBound(bounds); // re-evaluate if (glb != null && glb != bounds) { substitutedBound = glb[0]; if (glb.length == 1) { substitutedOtherBounds = null; } else { System.arraycopy(glb, 1, substitutedOtherBounds = new TypeBinding[glb.length - 1], 0, glb.length - 1); } } } return wildcard.environment.createWildcard(wildcard.genericType, wildcard.rank, substitutedBound, substitutedOtherBounds, wildcard.boundKind); } } break; case Binding.TYPE: if (!originalType.isMemberType()) break; ReferenceBinding originalReferenceType = (ReferenceBinding) originalType; originalEnclosing = originalType.enclosingType(); substitutedEnclosing = originalEnclosing; if (originalEnclosing != null) { substitutedEnclosing = (ReferenceBinding) substitute(substitution, originalEnclosing); } // treat as if parameterized with its type variables (non generic type gets 'null' arguments) if (substitutedEnclosing != originalEnclosing) { return substitution.isRawSubstitution() ? substitution.environment().createRawType(originalReferenceType, substitutedEnclosing) : substitution.environment().createParameterizedType(originalReferenceType, null, substitutedEnclosing); } break; case Binding.GENERIC_TYPE: originalReferenceType = (ReferenceBinding) originalType; originalEnclosing = originalType.enclosingType(); substitutedEnclosing = originalEnclosing; if (originalEnclosing != null) { substitutedEnclosing = (ReferenceBinding) substitute(substitution, originalEnclosing); } if (substitution.isRawSubstitution()) { return substitution.environment().createRawType(originalReferenceType, substitutedEnclosing); } // treat as if parameterized with its type variables (non generic type gets 'null' arguments) originalArguments = originalReferenceType.typeVariables(); substitutedArguments = substitute(substitution, originalArguments); return substitution.environment().createParameterizedType(originalReferenceType, substitutedArguments, substitutedEnclosing); } return originalType; }