org.eclipse.objectteams.otdt.internal.core.compiler.lookup.WeakenedTypeBinding.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.objectteams.otdt.internal.core.compiler.lookup.WeakenedTypeBinding.java

Source

/**********************************************************************
 * 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.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * $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.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;
    }

}