| /********************************************************************** |
| * This file is part of "Object Teams Development Tooling"-Software |
| * |
| * Copyright 2006, 2009 Fraunhofer Gesellschaft, Munich, Germany, |
| * for its Fraunhofer Institute for Computer Architecture and Software |
| * Technology (FIRST), Berlin, Germany and Technical University Berlin, |
| * Germany. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * $Id: WeakenedTypeBinding.java 23417 2010-02-03 20:13:55Z stephan $ |
| * |
| * Please visit http://www.eclipse.org/objectteams for updates and contact. |
| * |
| * Contributors: |
| * Fraunhofer FIRST - Initial API and implementation |
| * Technical University Berlin - Initial API and implementation |
| **********************************************************************/ |
| package org.eclipse.objectteams.otdt.internal.core.compiler.lookup; |
| |
| import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment; |
| import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; |
| import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; |
| |
| |
| /** |
| * NEW for OTDT. |
| * |
| * This class models a type binding for which declaration and byte-code view differ. |
| * Weakening is used to make the JVM happy when overriding methods with role-signatures. |
| * Type-checking should mostly use the declared type. |
| * Byte code will be generated using the weakened type. |
| * |
| * @author stephan |
| * @version $Id: WeakenedTypeBinding.java 23417 2010-02-03 20:13:55Z stephan $ |
| * @since OTDT 0.9.2 |
| */ |
| public class WeakenedTypeBinding extends DependentTypeBinding { |
| |
| /** The version that goes into the byte-code. */ |
| public final ReferenceBinding weakenedType; |
| |
| public WeakenedTypeBinding(DependentTypeBinding declaredType, ReferenceBinding weakenedType, LookupEnvironment environment) |
| { |
| super(declaredType, declaredType.arguments, declaredType._teamAnchor, declaredType.enclosingType(), environment); |
| this.weakenedType = weakenedType; |
| this.roleModel = declaredType.roleModel; |
| if (this.type instanceof WeakenedTypeBinding) |
| this.type = ((WeakenedTypeBinding)this.type).type; |
| initializeDependentType(declaredType._teamAnchor, declaredType._valueParamPosition); |
| } |
| |
| /** Factory method. */ |
| public static TypeBinding makeWeakenedTypeBinding(DependentTypeBinding declaredType, ReferenceBinding weakenedType, int dimensions) |
| { |
| if (declaredType instanceof WeakenedTypeBinding) { |
| if (((WeakenedTypeBinding)declaredType).contains(weakenedType)) |
| return declaredType; |
| declaredType = ((WeakenedTypeBinding)declaredType).getStrongType(); |
| } |
| if (weakenedType instanceof WeakenedTypeBinding) { |
| WeakenedTypeBinding weakenedTypeBinding = (WeakenedTypeBinding)weakenedType; |
| weakenedType = weakenedTypeBinding.weakenedType; |
| } |
| WeakenedTypeBinding leafType = new WeakenedTypeBinding(declaredType, weakenedType, declaredType.environment); |
| if (dimensions == 0) |
| return leafType; |
| return declaredType.environment.createArrayType(leafType, dimensions); |
| } |
| |
| boolean contains(TypeBinding other) { |
| if (!(other instanceof ReferenceBinding)) |
| return false; |
| TypeBinding otherStrong = other; |
| TypeBinding otherWeak = other; |
| if (other instanceof WeakenedTypeBinding) { |
| otherWeak = ((WeakenedTypeBinding) other).weakenedType; |
| otherStrong = ((WeakenedTypeBinding) other).getStrongType(); |
| } |
| return this.type.isCompatibleWith(otherStrong) |
| && otherWeak.isCompatibleWith(this.weakenedType); |
| } |
| |
| // ----- BYTE CODE VIEW ----- |
| @Override |
| public char[] constantPoolName() { |
| return this.weakenedType.constantPoolName(); |
| } |
| |
| @Override |
| public TypeBinding erasure() { |
| return this.weakenedType.erasure(); |
| } |
| |
| // ----- SOURCE CODE / TYPE CHECKING VIEW. |
| @Override |
| protected void registerAnchor() { |
| // don't registered lightweight weakened types. |
| } |
| |
| @Override |
| public TypeBinding maybeInstantiate(ITeamAnchor anchor, int dimensions) { |
| return ((DependentTypeBinding)this.type).maybeInstantiate(anchor, dimensions); |
| } |
| |
| @Override |
| public boolean isCompatibleWith(TypeBinding otherType) { |
| return this.type.isCompatibleWith(otherType); |
| } |
| |
| /** Forward to either part: */ |
| @Override |
| public boolean isProvablyDistinct(TypeBinding otherType) { |
| if (super.isProvablyDistinct(otherType)) |
| return true; |
| return this.weakenedType.isProvablyDistinct(otherType); |
| } |
| |
| public DependentTypeBinding getStrongType () { |
| return (DependentTypeBinding) this.type; // cast is safe by construction in constructor |
| } |
| |
| @Override |
| public DependentTypeBinding asPlainDependentType() { |
| return this.type.asPlainDependentType(); |
| } |
| |
| public static ReferenceBinding getBytecodeType(TypeBinding returnType) { |
| if (returnType instanceof WeakenedTypeBinding) |
| // recursivly unpack all contained WTB, too: |
| return getBytecodeType(((WeakenedTypeBinding)returnType).weakenedType); |
| return (ReferenceBinding)returnType; |
| } |
| |
| public boolean isSignificantlyWeakened() { |
| return TypeBinding.notEquals(this.weakenedType, this.type.getRealType()); |
| } |
| |
| @Override |
| public boolean isRoleType() { |
| return this.type.isRoleType(); |
| } |
| |
| @Override |
| public boolean isPlainDependentType() { |
| return this.type.isPlainDependentType(); |
| } |
| |
| /** |
| * Weakening implies that the interfaces are used to ensure compatibility, |
| * so never use the signature of a class part. |
| */ |
| @Override |
| public char[] signature() { |
| if (this.signature != null) |
| return this.signature; |
| |
| return this.signature = this.weakenedType.signature(); |
| } |
| |
| public static boolean requireWeakening(DependentTypeBinding strongType, ReferenceBinding weakType) { |
| if (TypeBinding.equalsEquals(strongType, weakType)) |
| return false; |
| if (strongType instanceof WeakenedTypeBinding) |
| return TypeBinding.equalsEquals(((WeakenedTypeBinding)strongType).weakenedType, weakType); |
| return false; |
| } |
| |
| } |