/*******************************************************************************
 * Copyright (c) 2000, 2019 IBM Corporation and others.
 *
 * 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
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Fraunhofer FIRST - extended API and implementation
 *     Technical University Berlin - extended API and implementation
 *     Stephan Herrmann - Contribution for
 *								bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
 *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
 *								bug 392384 - [1.8][compiler][null] Restore nullness info from type annotations in class files
 *								Bug 415043 - [1.8][null] Follow-up re null type annotations after bug 392099
 *								Bug 415850 - [1.8] Ensure RunJDTCoreTests can cope with null annotations enabled
 *								Bug 417295 - [1.8[[null] Massage type annotated null analysis to gel well with deep encoded type bindings.
 *								Bug 427163 - [1.8][null] bogus error "Contradictory null specification" on varags
 *								Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
 *								Bug 434570 - Generic type mismatch for parametrized class annotation attribute with inner class
 *								Bug 434600 - Incorrect null analysis error reporting on type parameters
 *								Bug 439516 - [1.8][null] NonNullByDefault wrongly applied to implicit type bound of binary type
 *								Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
 *								Bug 435570 - [1.8][null] @NonNullByDefault illegally tries to affect "throws E"
 *								Bug 435805 - [1.8][compiler][null] Java 8 compiler does not recognize declaration style null annotations
 *								Bug 437072 - [compiler][null] Null analysis emits possibly incorrect warning for new int[][] despite @NonNullByDefault
 *								Bug 466713 - Null Annotations: NullPointerException using <int @Nullable []> as Type Param 
 *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
 *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
 *                          Bug 409236 - [1.8][compiler] Type annotations on intersection cast types dropped by code generator
 *                          Bug 415399 - [1.8][compiler] Type annotations on constructor results dropped by the code generator
 *      Jesper S Møller <jesper@selskabet.org> -  Contributions for
 *                          bug 527554 - [18.3] Compiler support for JEP 286 Local-Variable Type
 *                          bug 529556 - [18.3] Add content assist support for 'var' as a type
 *                          
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.codeassist.select.SelectionNodeFound;
import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.ast.NullAnnotationMatching.CheckMode;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.codegen.AnnotationContext;
import org.eclipse.jdt.internal.compiler.codegen.AnnotationTargetTypeConstants;
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.MethodModel.FakeKind;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.TSuperHelper;

/**
 * OTDT changes:
 *
 * What: new query isDeclaredLifting
 *
 * What: Support multiple strategies for resolve
 * 		 + base import scope
 *       + anchored role type
 *
 * What: Support baseclass decapsulation
 *
 */
@SuppressWarnings({"rawtypes", "unchecked"})
public abstract class TypeReference extends Expression {
	public static final TypeReference[] NO_TYPE_ARGUMENTS = new TypeReference[0];

	/**
	 * Simplified specification of where in a (possibly complex) type reference
	 * we are looking for type annotations.
	 * @see TypeReference#hasNullTypeAnnotation(AnnotationPosition)
	 */
	public static enum AnnotationPosition {
		/**
		 * For arrays: the outermost dimension, for parameterized types the type, for nested types the innermost type.
		 * This is the level that a declaration annotation would apply to.
		 */
		MAIN_TYPE,
		/** For arrays: the leaf component type, else like MAIN_TYPE. */
		LEAF_TYPE,
		/** Any position admitting type annotations. */
		ANY
	}
	
static class AnnotationCollector extends ASTVisitor {
	List annotationContexts;
	Expression typeReference;
	int targetType;
	int info = 0;
	int info2 = 0;
	LocalVariableBinding localVariable;
	Annotation[][] annotationsOnDimensions;
	int dimensions;
	Wildcard currentWildcard;

	public AnnotationCollector(
			TypeParameter typeParameter,
			int targetType,
			int typeParameterIndex,
			List annotationContexts) {
		this.annotationContexts = annotationContexts;
		this.typeReference = typeParameter.type;
		this.targetType = targetType;
		this.info = typeParameterIndex;
	}

	public AnnotationCollector(
			LocalDeclaration localDeclaration,
			int targetType,
			LocalVariableBinding localVariable,
			List annotationContexts) {
		this.annotationContexts = annotationContexts;
		this.typeReference = localDeclaration.type;
		this.targetType = targetType;
		this.localVariable = localVariable;
	}

	public AnnotationCollector(
			LocalDeclaration localDeclaration,
			int targetType,
			int parameterIndex,
			List annotationContexts) {
		this.annotationContexts = annotationContexts;
		this.typeReference = localDeclaration.type;
		this.targetType = targetType;
		this.info = parameterIndex;
	}

	public AnnotationCollector(
			TypeReference typeReference,
			int targetType,
			List annotationContexts) {
		this.annotationContexts = annotationContexts;
		this.typeReference = typeReference;
		this.targetType = targetType;
	}
	public AnnotationCollector(
			Expression typeReference,
			int targetType,
			int info,
			List annotationContexts) {
		this.annotationContexts = annotationContexts;
		this.typeReference = typeReference;
		this.info = info;
		this.targetType = targetType;
	}
	public AnnotationCollector(
			TypeReference typeReference,
			int targetType,
			int info,
			int typeIndex,
			List annotationContexts) {
		this.annotationContexts = annotationContexts;
		this.typeReference = typeReference;
		this.info = info;
		this.targetType = targetType;
		this.info2 = typeIndex;
	}
	public AnnotationCollector(
			TypeReference typeReference,
			int targetType,
			int info,
			List annotationContexts,
			Annotation[][] annotationsOnDimensions,
			int dimensions) {
		this.annotationContexts = annotationContexts;
		this.typeReference = typeReference;
		this.info = info;
		this.targetType = targetType;
		this.annotationsOnDimensions = annotationsOnDimensions;
		// Array references like 'new String[]' manifest as an ArrayAllocationExpression
		// with a 'type' of String.  When the type is not carrying the dimensions count
		// it is passed in via the dimensions parameter.  It is not possible to use
		// annotationsOnDimensions as it will be null if there are no annotations on any
		// of the dimensions.
		this.dimensions = dimensions;
	}
	
	private boolean internalVisit(Annotation annotation) {
		AnnotationContext annotationContext = null;
		if (annotation.isRuntimeTypeInvisible()) {
			annotationContext = new AnnotationContext(annotation, this.typeReference, this.targetType, AnnotationContext.INVISIBLE);
		} else if (annotation.isRuntimeTypeVisible()) {
			annotationContext = new AnnotationContext(annotation, this.typeReference, this.targetType, AnnotationContext.VISIBLE);
		}
		if (annotationContext != null) {
			annotationContext.wildcard = this.currentWildcard;
			switch(this.targetType) {
				case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER :
				case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER :
				case AnnotationTargetTypeConstants.CLASS_EXTENDS:
				case AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER :
				case AnnotationTargetTypeConstants.THROWS :
				case AnnotationTargetTypeConstants.EXCEPTION_PARAMETER :
				case AnnotationTargetTypeConstants.INSTANCEOF:
				case AnnotationTargetTypeConstants.NEW :
				case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE :
				case AnnotationTargetTypeConstants.METHOD_REFERENCE :
					annotationContext.info = this.info;
					break;
				case AnnotationTargetTypeConstants.LOCAL_VARIABLE :
				case AnnotationTargetTypeConstants.RESOURCE_VARIABLE :
					annotationContext.variableBinding = this.localVariable;
					break;
				case AnnotationTargetTypeConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT :
				case AnnotationTargetTypeConstants.METHOD_INVOCATION_TYPE_ARGUMENT :
				case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT :
				case AnnotationTargetTypeConstants.METHOD_REFERENCE_TYPE_ARGUMENT :
				case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND :
				case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND :
				case AnnotationTargetTypeConstants.CAST:
					annotationContext.info2 = this.info2;
					annotationContext.info = this.info;
					break;
				case AnnotationTargetTypeConstants.FIELD :
				case AnnotationTargetTypeConstants.METHOD_RETURN :
				case AnnotationTargetTypeConstants.METHOD_RECEIVER :
					break;
					
			}
			this.annotationContexts.add(annotationContext);
		}
		return true;
	}
	@Override
	public boolean visit(MarkerAnnotation annotation, BlockScope scope) {
		return internalVisit(annotation);
	}
	@Override
	public boolean visit(NormalAnnotation annotation, BlockScope scope) {
		return internalVisit(annotation);
	}
	@Override
	public boolean visit(SingleMemberAnnotation annotation, BlockScope scope) {
		return internalVisit(annotation);
	}
	@Override
	public boolean visit(Wildcard wildcard, BlockScope scope) {
		this.currentWildcard = wildcard;
		return true;
	}
	@Override
	public boolean visit(Argument argument, BlockScope scope) {
		if ((argument.bits & ASTNode.IsUnionType) == 0) {
			return true;
		}
		for (int i = 0, max = this.localVariable.initializationCount; i < max; i++) {
			int startPC = this.localVariable.initializationPCs[i << 1];
			int endPC = this.localVariable.initializationPCs[(i << 1) + 1];
			if (startPC != endPC) { // only entries for non zero length
				return true;
			}
		}
		return false;
	}
	@Override
	public boolean visit(Argument argument, ClassScope scope) {
		if ((argument.bits & ASTNode.IsUnionType) == 0) {
			return true;
		}
		for (int i = 0, max = this.localVariable.initializationCount; i < max; i++) {
			int startPC = this.localVariable.initializationPCs[i << 1];
			int endPC = this.localVariable.initializationPCs[(i << 1) + 1];
			if (startPC != endPC) { // only entries for non zero length
				return true;
			}
		}
		return false;
	}
	@Override
	public boolean visit(LocalDeclaration localDeclaration, BlockScope scope) {
		for (int i = 0, max = this.localVariable.initializationCount; i < max; i++) {
			int startPC = this.localVariable.initializationPCs[i << 1];
			int endPC = this.localVariable.initializationPCs[(i << 1) + 1];
			if (startPC != endPC) { // only entries for non zero length
				return true;
			}
		}
		return false;
	}
	@Override
	public void endVisit(Wildcard wildcard, BlockScope scope) {
		this.currentWildcard = null;
	}
}

//{ObjectTeams: for baseclass decapsulation (implement interface from Expression):
private DecapsulationState baseclassDecapsulation = DecapsulationState.NONE;
public void setBaseclassDecapsulation(DecapsulationState state) {
	this.baseclassDecapsulation = state;
}
@Override
public DecapsulationState getBaseclassDecapsulation() {
	return this.baseclassDecapsulation;
}
@Override
public void tagReportedBaseclassDecapsulation() {
	setBaseclassDecapsulation(DecapsulationState.REPORTED);
}
public int deprecationProblemId = IProblem.UsingDeprecatedType;

public boolean isGenerated;
@Override
public boolean isGenerated() {
	return this.isGenerated;
}
//SH}

/*
 * Answer a base type reference (can be an array of base type).
 */
public static final TypeReference baseTypeReference(int baseType, int dim, Annotation [][] dimAnnotations) {

	if (dim == 0) {
		switch (baseType) {
			case (TypeIds.T_void) :
				return new SingleTypeReference(TypeBinding.VOID.simpleName, 0);
			case (TypeIds.T_boolean) :
				return new SingleTypeReference(TypeBinding.BOOLEAN.simpleName, 0);
			case (TypeIds.T_char) :
				return new SingleTypeReference(TypeBinding.CHAR.simpleName, 0);
			case (TypeIds.T_float) :
				return new SingleTypeReference(TypeBinding.FLOAT.simpleName, 0);
			case (TypeIds.T_double) :
				return new SingleTypeReference(TypeBinding.DOUBLE.simpleName, 0);
			case (TypeIds.T_byte) :
				return new SingleTypeReference(TypeBinding.BYTE.simpleName, 0);
			case (TypeIds.T_short) :
				return new SingleTypeReference(TypeBinding.SHORT.simpleName, 0);
			case (TypeIds.T_int) :
				return new SingleTypeReference(TypeBinding.INT.simpleName, 0);
			default : //T_long
				return new SingleTypeReference(TypeBinding.LONG.simpleName, 0);
		}
	}
	switch (baseType) {
		case (TypeIds.T_void) :
			return new ArrayTypeReference(TypeBinding.VOID.simpleName, dim, dimAnnotations, 0);
		case (TypeIds.T_boolean) :
			return new ArrayTypeReference(TypeBinding.BOOLEAN.simpleName, dim, dimAnnotations, 0);
		case (TypeIds.T_char) :
			return new ArrayTypeReference(TypeBinding.CHAR.simpleName, dim, dimAnnotations, 0);
		case (TypeIds.T_float) :
			return new ArrayTypeReference(TypeBinding.FLOAT.simpleName, dim, dimAnnotations, 0);
		case (TypeIds.T_double) :
			return new ArrayTypeReference(TypeBinding.DOUBLE.simpleName, dim, dimAnnotations, 0);
		case (TypeIds.T_byte) :
			return new ArrayTypeReference(TypeBinding.BYTE.simpleName, dim, dimAnnotations, 0);
		case (TypeIds.T_short) :
			return new ArrayTypeReference(TypeBinding.SHORT.simpleName, dim, dimAnnotations, 0);
		case (TypeIds.T_int) :
			return new ArrayTypeReference(TypeBinding.INT.simpleName, dim, dimAnnotations, 0);
		default : //T_long
			return new ArrayTypeReference(TypeBinding.LONG.simpleName, dim, dimAnnotations, 0);
	}
}

public static final TypeReference baseTypeReference(int baseType, int dim) {
	return baseTypeReference(baseType, dim, null);
}

// JSR308 type annotations...
public Annotation[][] annotations = null;

// allows us to trap completion & selection nodes
public void aboutToResolve(Scope scope) {
	// default implementation: do nothing
}
private void checkYieldUsage(Scope currentScope) {
	char [][] qName = getTypeName();
	String name = qName != null && qName[0] != null ? new String(qName[0]) : null;
	long sourceLevel = currentScope.compilerOptions().sourceLevel;
	if (sourceLevel < ClassFileConstants.JDK13 || name == null ||
			!("yield".equals(new String(name)))) //$NON-NLS-1$
		return;
	if (sourceLevel == ClassFileConstants.JDK13 && currentScope.compilerOptions().enablePreviewFeatures) {
		currentScope.problemReporter().switchExpressionsYieldTypeDeclarationError(this);
	} else {
		currentScope.problemReporter().switchExpressionsYieldTypeDeclarationWarning(this);
	}
}
@Override
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
	return flowInfo;
}
public void checkBounds(Scope scope) {
	// only parameterized type references have bounds
}
public abstract TypeReference augmentTypeWithAdditionalDimensions(int additionalDimensions, Annotation[][] additionalAnnotations, boolean isVarargs);

protected Annotation[][] getMergedAnnotationsOnDimensions(int additionalDimensions, Annotation[][] additionalAnnotations) {
	/* Note, we actually concatenate the additional annotations after base annotations, in bindings, they should appear before base annotations.
	   Given @English int @Nullable [] x @NonNull []; the type x is a @NonNull arrays of of @Nullable arrays of @English Strings, not the other
	   way about. Changing this in the compiler AST representation will cause too many ripples, so we leave it as is. On the bindings, the type
	   will reflect rotated (i.e will reflect correctly). See AnnotatableTypeSystem.flattenedAnnotations
	*/
	Annotation[][] annotationsOnDimensions = this.getAnnotationsOnDimensions(true);
	int dimensions = this.dimensions();
	
	if (annotationsOnDimensions == null && additionalAnnotations == null)
		return null;

	final int totalDimensions = dimensions + additionalDimensions;
	Annotation [][] mergedAnnotations = new Annotation[totalDimensions][];
	if (annotationsOnDimensions != null) {
		for (int i = 0; i < dimensions; i++) {
			mergedAnnotations[i] = annotationsOnDimensions[i];
		} 
	}
	if (additionalAnnotations != null) {
		for (int i = dimensions, j = 0; i < totalDimensions; i++, j++) {
			mergedAnnotations[i] = additionalAnnotations[j];
		}
	}
	return mergedAnnotations;
}

public int dimensions() {
	return 0;
}


/**
 * This method is used to return the array dimension declared after the
 * name of a local or a field declaration.
 * For example:
 *    int i, j[] = null, k[][] = {{}};
 *    It should return 0 for i, 1 for j and 2 for k.
 * @return int the extra dimension found
 */
public int extraDimensions() {
	return 0;
}

//{ObjectTeams: synthetic AST can use TypeReference as receiver for static method:
@Override
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
	// nop
}
// SH}

public AnnotationContext[] getAllAnnotationContexts(int targetType) {
	List allAnnotationContexts = new ArrayList();
	AnnotationCollector collector = new AnnotationCollector(this, targetType, allAnnotationContexts);
	this.traverse(collector, (BlockScope) null);
	return (AnnotationContext[]) allAnnotationContexts.toArray(new AnnotationContext[allAnnotationContexts.size()]);
}
/**
 * info can be either a type index (superclass/superinterfaces) or a pc into the bytecode
 * @param targetType
 * @param info
 * @param allAnnotationContexts
 */
public void getAllAnnotationContexts(int targetType, int info, List allAnnotationContexts) {
	AnnotationCollector collector = new AnnotationCollector(this, targetType, info, allAnnotationContexts);
	this.traverse(collector, (BlockScope) null);
}
public void getAllAnnotationContexts(int targetType, int info, List allAnnotationContexts, Annotation [] se7Annotations) {
	AnnotationCollector collector = new AnnotationCollector(this, targetType, info, allAnnotationContexts);
	for (int i = 0, length = se7Annotations == null ? 0 : se7Annotations.length; i < length; i++) {
		Annotation annotation = se7Annotations[i];
		annotation.traverse(collector, (BlockScope) null);
	}
	this.traverse(collector, (BlockScope) null);
}
/**
 * info can be either a type index (superclass/superinterfaces) or a pc into the bytecode
 */
public void getAllAnnotationContexts(int targetType, int info, List allAnnotationContexts, Annotation[][] annotationsOnDimensions, int dimensions) {
	AnnotationCollector collector = new AnnotationCollector(this, targetType, info, allAnnotationContexts, annotationsOnDimensions, dimensions);
	this.traverse(collector, (BlockScope) null);
	if (annotationsOnDimensions != null) {
		for (int i = 0, max = annotationsOnDimensions.length; i < max; i++) {
			Annotation[] annotationsOnDimension = annotationsOnDimensions[i];
			if (annotationsOnDimension != null) {
				for (int j = 0, max2 = annotationsOnDimension.length; j< max2; j++) {
					annotationsOnDimension[j].traverse(collector, (BlockScope) null);
				}
			}
		}
	}
}
public void getAllAnnotationContexts(int targetType, int info, int typeIndex, List allAnnotationContexts) {
	AnnotationCollector collector = new AnnotationCollector(this, targetType, info, typeIndex, allAnnotationContexts);
	this.traverse(collector, (BlockScope) null);
}
public void getAllAnnotationContexts(int targetType, List allAnnotationContexts) {
	AnnotationCollector collector = new AnnotationCollector(this, targetType, allAnnotationContexts);
	this.traverse(collector, (BlockScope) null);
}
public Annotation[][] getAnnotationsOnDimensions() {
	return getAnnotationsOnDimensions(false);
}

public TypeReference [][] getTypeArguments() {
	return null;
}
/**
 * @param useSourceOrder if true annotations on dimensions are returned in source order, otherwise they are returned per
 * how they ought to be interpreted by a type system, or external persistence view. For example, given the following:
 * int @Nullable [] f @NonNull [] ==> f is really a @NonNull array of @Nullable arrays of ints. This is the type system
 * view since extended dimensions bind more readily than type components that precede the identifier. This is how it ought
 * to be encoded in bindings and how it ought to be persisted in class files. However for DOM/AST construction, we need the
 * dimensions in source order, so we provide a way for the clients to ask what they want. 
 * 
 */
public Annotation[][] getAnnotationsOnDimensions(boolean useSourceOrder) {
	return null;
}

public void setAnnotationsOnDimensions(Annotation [][] annotationsOnDimensions) {
	// nothing to do. Subtypes should react suitably.
}

public abstract char[] getLastToken();

/**
 * @return char[][]
 * TODO (jerome) should merge back into #getTypeName()
 */
public char [][] getParameterizedTypeName(){
	return getTypeName();
}
protected abstract TypeBinding getTypeBinding(Scope scope);
/**
 * @return char[][]
 */
public abstract char [][] getTypeName() ;

protected TypeBinding internalResolveType(Scope scope, int location) {
	// handle the error here
	this.constant = Constant.NotAConstant;
	checkYieldUsage(scope);
	if (this.resolvedType != null) { // is a shared type reference which was already resolved
		if (this.resolvedType.isValidBinding()) {
			return this.resolvedType;
		} else {
			switch (this.resolvedType.problemId()) {
				case ProblemReasons.NotFound :
				case ProblemReasons.NotVisible :
				case ProblemReasons.InheritedNameHidesEnclosingName :
					TypeBinding type = this.resolvedType.closestMatch();
					if (type == null) return null;
					return scope.environment().convertToRawType(type, false /*do not force conversion of enclosing types*/);
				default :
					return null;
			}
		}
	}
	boolean hasError;
//{ObjectTeams: don't let SelectionNodeFound(null) prevent alternate searching strategies:
  SelectionNodeFound caughtException = null;
  TypeBinding type = null;
  try {
	// base import scope first:
	CompilationResult compilationResult = scope.referenceCompilationUnit().compilationResult();
	CompilationResult.CheckPoint cp = compilationResult.getCheckPoint(scope.referenceContext());
	try {
	  type = checkResolveUsingBaseImportScope(scope, location, false); // apply TOLERATE strategy only as a last resort below
	  // copied from below:
	  if (type != null && type.isValidBinding()) {
		type = scope.environment().convertToRawType(type, false /*do not force conversion of enclosing types*/);
		if (type.leafComponentType().isRawType()
				&& (this.bits & ASTNode.IgnoreRawTypeCheck) == 0
				&& scope.compilerOptions().getSeverity(CompilerOptions.RawTypeReference) != ProblemSeverities.Ignore) {
			scope.problemReporter().rawTypeReference(this, type);
		}
		return type;
	  }
	} catch (SelectionNodeFound snf) {
		if (snf.binding != null)
			throw snf; // found a valid node.
		caughtException = snf;
	} finally {
		if (   caughtException != null
			|| (type == null)
			|| !type.isValidBinding())
			compilationResult.rollBack(cp);
	}
// ~orig~:
	type = this.resolvedType = getTypeBinding(scope);
	if (type == null) {
		return null; // detected cycle while resolving hierarchy
	}
// :~giro~
  } catch (SelectionNodeFound snf) {
	if (snf.binding != null)
		throw snf; // found a valid node.
	caughtException = snf;
  }
// a third chance trying an anchored type:
  try {
    if (   (caughtException != null)
    	|| (this.resolvedType.problemId() == ProblemReasons.NotFound))
	{
    	// anchored type
	    TypeBinding result = resolveAnchoredType(scope);
	    if (result != null)             // did we do any better than before?
	    	type = this.resolvedType = result; // if non-null but ProblemBinding report below.
    }
  } catch (SelectionNodeFound snf2) {
	  caughtException = snf2; // throw the newer exception instead.
  }
//a forth chance trying a TOLERATED base imported type:
 try {
   if (   (caughtException != null)
	   || (this.resolvedType.problemId() == ProblemReasons.NotFound))
	{
   		if (this.baseclassDecapsulation == DecapsulationState.TOLERATED) {
   			TypeBinding result = checkResolveUsingBaseImportScope(scope, -1, true);
   			if (result != null)             // did we do any better than before?
   				type = this.resolvedType = result; // if non-null but ProblemBinding report below.
   		}
   }
 } catch (SelectionNodeFound snf2) {
	  caughtException = snf2; // throw the newer exception instead.
 } finally {
	  // the attempt to prevent an exception failed:
	  if (caughtException != null)
		  throw caughtException;
 }
// SH}
	if ((hasError = !type.isValidBinding()) == true) {
		if (this.isTypeNameVar(scope)) {
			reportVarIsNotAllowedHere(scope);
		} else {
			reportInvalidType(scope);
		}
		switch (type.problemId()) {
			case ProblemReasons.NotFound :
			case ProblemReasons.NotVisible :
			case ProblemReasons.InheritedNameHidesEnclosingName :
				type = type.closestMatch();
				if (type == null) return null;
				break;
			default :
				return null;
		}
	}
//{ObjectTeams: Split method to make tail accessible:
	return checkResolvedType(type, scope, location, hasError);
}
public TypeBinding checkResolvedType(TypeBinding type, Scope scope, int location, boolean hasError) {
// SH}
	if (type.isArrayType() && ((ArrayBinding) type).leafComponentType == TypeBinding.VOID) {
		scope.problemReporter().cannotAllocateVoidArray(this);
		return null;
	}
	if (!(this instanceof QualifiedTypeReference)   // QualifiedTypeReference#getTypeBinding called above will have already checked deprecation
			&& isTypeUseDeprecated(type, scope)) {
		reportDeprecatedType(type, scope);
	}
	type = scope.environment().convertToRawType(type, false /*do not force conversion of enclosing types*/);
	if (type.leafComponentType().isRawType()
			&& (this.bits & ASTNode.IgnoreRawTypeCheck) == 0
			&& scope.compilerOptions().getSeverity(CompilerOptions.RawTypeReference) != ProblemSeverities.Ignore) {
		scope.problemReporter().rawTypeReference(this, type);
	}
	if (hasError) {
		resolveAnnotations(scope, 0); // don't apply null defaults to buggy type
		return type;
	} else {
		// store the computed type only if no error, otherwise keep the problem type instead
		this.resolvedType = type;
		resolveAnnotations(scope, location);
		return this.resolvedType; // pick up value that may have been changed in resolveAnnotations(..)
	}
}

//{ObjectTeams: alternative strategies for resolving:
/** Try to resolve this reference from base imports. */
public TypeBinding checkResolveUsingBaseImportScope(Scope scope, int location, boolean tolerate) {
	return null; // override to do something useful (only in SingleTypeReference).
}
/**
 * Try to resolve this type reference as an anchored type "t.R".
 */
TypeBinding resolveAnchoredType(Scope scope) {
	return null; // override to do something useful
}
protected boolean shouldAnalyzeRoleReference() {
	if ((this.bits & ASTNode.InsideJavadoc) != 0)
		return false; // don't complain about role encapsulation in java doc
	return   this.resolvedType.isRole()  // no need to check non-role inner of role: either inherited (non-rolish) or local (cannot be referenced)
		  && !TSuperHelper.isMarkerInterface(this.resolvedType);
}
/* check for use of protected role (for parameterized/qualified type references). */
protected boolean isIllegalQualifiedUseOfProtectedRole(Scope scope)
{
	  // implies ReferenceBinding
	if (   ((ReferenceBinding)this.resolvedType).isProtected() // here we only check protected roles
		&& !this.getBaseclassDecapsulation().isAllowed())
	{
		scope.problemReporter().qualifiedProtectedRole(this, (ReferenceBinding)this.resolvedType);
		// keep a problem binding,  clients may be interested in this information, see CodeSelectionTests.testRoleCreation3
		this.resolvedType = new ProblemReferenceBinding(((ReferenceBinding)this.resolvedType).compoundName, (ReferenceBinding)this.resolvedType, ProblemReasons.NotVisible);
		return true;
	}
	return false;
}
// SH}
@Override
public boolean isTypeReference() {
	return true;
}
//{ObjectTeams
public boolean isDeclaredLifting() {
	  return false;
}
//Markus Witte}
public boolean isWildcard() {
	return false;
}
public boolean isUnionType() {
	return false;
}
public boolean isVarargs() {
	return (this.bits & ASTNode.IsVarArgs) != 0;
}
public boolean isParameterizedTypeReference() {
	return false;
}
protected void reportDeprecatedType(TypeBinding type, Scope scope, int index) {
	scope.problemReporter().deprecatedType(type, this, index);
}

protected void reportDeprecatedType(TypeBinding type, Scope scope) {
//{ObjectTeams:
  if (this.deprecationProblemId == 0)
	return;
  if (this.deprecationProblemId == IProblem.DeprecatedBaseclass)
	scope.problemReporter().deprecatedBaseclass(this, type);
  else
// SH}
	scope.problemReporter().deprecatedType(type, this, Integer.MAX_VALUE);
}

protected void reportInvalidType(Scope scope) {
//{ObjectTeams: suppress this in role feature bridge (the same will be reported against the original, too):
	if (scope.isFakeMethod(FakeKind.ROLE_FEATURE_BRIDGE)) {
		scope.referenceContext().tagAsHavingErrors();
		return;
	}
	// did we misread an OT keyword as a type reference (during syntax recovery)?
	if (!scope.environment().globalOptions.isPureJava) {
		char[] token = getLastToken();
        for (int j = 0; j < IOTConstants.OT_KEYWORDS.length; j++) {
			if (CharOperation.equals(token, IOTConstants.OT_KEYWORDS[j])) {
				if (scope.referenceContext().compilationResult().hasErrors())
					return; // assume this is a secondary error
			}
		}
	}
// SH}
	scope.problemReporter().invalidType(this, this.resolvedType);
}

protected void reportVarIsNotAllowedHere(Scope scope) {
	scope.problemReporter().varIsNotAllowedHere(this);
}

public TypeBinding resolveSuperType(ClassScope scope) {
	// assumes the implementation of resolveType(ClassScope) will call back to detect cycles
	TypeBinding superType = resolveType(scope);
	if (superType == null) return null;

	if (superType.isTypeVariable()) {
		if (this.resolvedType.isValidBinding()) {
			this.resolvedType = new ProblemReferenceBinding(getTypeName(), (ReferenceBinding)this.resolvedType, ProblemReasons.IllegalSuperTypeVariable);
			reportInvalidType(scope);
		}
		return null;
	}
	return superType;
}

@Override
public final TypeBinding resolveType(BlockScope blockScope) {
	return resolveType(blockScope, true /* checkbounds if any */);
}

public TypeBinding resolveType(BlockScope scope, boolean checkBounds) {
	return resolveType(scope, checkBounds, 0);
}

public TypeBinding resolveType(BlockScope scope, boolean checkBounds, int location) {
	return internalResolveType(scope, location);
}

@Override
public TypeBinding resolveType(ClassScope scope) {
	return resolveType(scope, 0);
}

public TypeBinding resolveType(ClassScope scope, int location) {
	return internalResolveType(scope, location);
}

public TypeBinding resolveTypeArgument(BlockScope blockScope, ReferenceBinding genericType, int rank) {
    return resolveType(blockScope, true /* check bounds*/, Binding.DefaultLocationTypeArgument);
}

public TypeBinding resolveTypeArgument(ClassScope classScope, ReferenceBinding genericType, int rank) {
	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=294057, circularity is allowed when we are
	// resolving type arguments i.e interface A<T extends C> {}	interface B extends A<D> {}
	// interface D extends C {}	interface C extends B {}
	ReferenceBinding ref = classScope.referenceContext.binding;
	boolean pauseHierarchyCheck = false;
	try {
		if (ref.isHierarchyBeingConnected()) {
			pauseHierarchyCheck = (ref.tagBits & TagBits.PauseHierarchyCheck) == 0;
			ref.tagBits |= TagBits.PauseHierarchyCheck;
		}
	    return resolveType(classScope, Binding.DefaultLocationTypeArgument);
	} finally {
		if (pauseHierarchyCheck) {
			ref.tagBits &= ~TagBits.PauseHierarchyCheck;
		}
	}
}

@Override
public abstract void traverse(ASTVisitor visitor, BlockScope scope);

@Override
public abstract void traverse(ASTVisitor visitor, ClassScope scope);

protected void resolveAnnotations(Scope scope, int location) {
	Annotation[][] annotationsOnDimensions = getAnnotationsOnDimensions();
	if (this.annotations != null || annotationsOnDimensions != null) {
		BlockScope resolutionScope = Scope.typeAnnotationsResolutionScope(scope);
		if (resolutionScope != null) {
			int dimensions = this.dimensions();
			if (this.annotations != null) {
				TypeBinding leafComponentType = this.resolvedType.leafComponentType();
				leafComponentType = resolveAnnotations(resolutionScope, this.annotations, leafComponentType);
				this.resolvedType = dimensions > 0 ? scope.environment().createArrayType(leafComponentType, dimensions) : leafComponentType;
				// contradictory null annotations on the type are already detected in Annotation.resolveType() (SE7 treatment)
			}
			if (annotationsOnDimensions != null) {
				this.resolvedType = resolveAnnotations(resolutionScope, annotationsOnDimensions, this.resolvedType);
				if (this.resolvedType instanceof ArrayBinding) {
					long[] nullTagBitsPerDimension = ((ArrayBinding)this.resolvedType).nullTagBitsPerDimension;
					if (nullTagBitsPerDimension != null) {
						for (int i = 0; i < dimensions; i++) { // skip last annotations at [dimensions] (concerns the leaf type)
							if ((nullTagBitsPerDimension[i] & TagBits.AnnotationNullMASK) == TagBits.AnnotationNullMASK) {
								scope.problemReporter().contradictoryNullAnnotations(annotationsOnDimensions[i]);
								nullTagBitsPerDimension[i] = 0;
							}
						}
					}
				}
			}
		}
	}
	if (scope.compilerOptions().isAnnotationBasedNullAnalysisEnabled
			&& this.resolvedType != null
			&& (this.resolvedType.tagBits & TagBits.AnnotationNullMASK) == 0
			&& !this.resolvedType.isTypeVariable()
			&& !this.resolvedType.isWildcard()
			&& location != 0
			&& scope.hasDefaultNullnessFor(location, this.sourceStart)) 
	{
		if (location == Binding.DefaultLocationTypeBound && this.resolvedType.id == TypeIds.T_JavaLangObject) {
			scope.problemReporter().implicitObjectBoundNoNullDefault(this);
		} else {
			LookupEnvironment environment = scope.environment();
			AnnotationBinding[] annots = new AnnotationBinding[]{environment.getNonNullAnnotation()};
			this.resolvedType = environment.createAnnotatedType(this.resolvedType, annots);
		}
	}
}
public int getAnnotatableLevels() {
	return 1;
}
/** Check all typeArguments for illegal null annotations on base types. */
protected void checkIllegalNullAnnotations(Scope scope, TypeReference[] typeArguments) {
	if (scope.environment().usesNullTypeAnnotations() && typeArguments != null) {
		for (int i = 0; i < typeArguments.length; i++) {
			TypeReference arg = typeArguments[i];
			if (arg.resolvedType != null)
				arg.checkIllegalNullAnnotation(scope);
		}
	}
}
/** Check whether this type reference conforms to the null constraints defined for the corresponding type variable. */
protected void checkNullConstraints(Scope scope, Substitution substitution, TypeBinding[] variables, int rank) {
	if (variables != null && variables.length > rank) {
		TypeBinding variable = variables[rank];
		if (variable.hasNullTypeAnnotations()) {
			if (NullAnnotationMatching.analyse(variable, this.resolvedType, null, substitution, -1, null, CheckMode.BOUND_CHECK).isAnyMismatch())
				scope.problemReporter().nullityMismatchTypeArgument(variable, this.resolvedType, this);
    	}
	}
	checkIllegalNullAnnotation(scope);
}
protected void checkIllegalNullAnnotation(Scope scope) {
	if (this.resolvedType.leafComponentType().isBaseType() && hasNullTypeAnnotation(AnnotationPosition.LEAF_TYPE))
		scope.problemReporter().illegalAnnotationForBaseType(this, this.annotations[0], this.resolvedType.tagBits & TagBits.AnnotationNullMASK);	
}
/** Retrieve the null annotation that has been translated to the given nullTagBits. */
public Annotation findAnnotation(long nullTagBits) {
	if (this.annotations != null) {
		Annotation[] innerAnnotations = this.annotations[this.annotations.length-1];
		if (innerAnnotations != null) {
			int annBit = nullTagBits == TagBits.AnnotationNonNull ? TypeIds.BitNonNullAnnotation : TypeIds.BitNullableAnnotation;
			for (int i = 0; i < innerAnnotations.length; i++) {
				if (innerAnnotations[i] != null && innerAnnotations[i].hasNullBit(annBit))
					return innerAnnotations[i];
			}
		}
	}
	return null;
}
public boolean hasNullTypeAnnotation(AnnotationPosition position) {
	if (this.annotations != null) {
		if (position == AnnotationPosition.MAIN_TYPE) {
			Annotation[] innerAnnotations = this.annotations[this.annotations.length-1];
			return containsNullAnnotation(innerAnnotations);
		} else {
			for (Annotation[] someAnnotations: this.annotations) {
				if (containsNullAnnotation(someAnnotations))
					return true;
			}
		}
	}
	return false;
}
public static boolean containsNullAnnotation(Annotation[] annotations) {
	if (annotations != null) {
		for (int i = 0; i < annotations.length; i++) {
			if (annotations[i] != null && (annotations[i].hasNullBit(TypeIds.BitNonNullAnnotation|TypeIds.BitNullableAnnotation)))
				return true;
		}
	}
	return false;	
}
public TypeReference[] getTypeReferences() {
	return new TypeReference [] { this };
}

public boolean isBaseTypeReference() {
	return false;
}
/**
 * Checks to see if the declaration uses 'var' as type name 
 * @param scope Relevant scope, for error reporting
 * @return true, if source level is Java 10 or above and the type name is just 'var', false otherwise 
 */
public boolean isTypeNameVar(Scope scope) {
	CompilerOptions compilerOptions = scope != null ? scope.compilerOptions() : null;
	if (compilerOptions != null && compilerOptions.sourceLevel < ClassFileConstants.JDK10) {
		return false;
	}
	char[][] typeName = this.getTypeName();
	return typeName.length == 1 && CharOperation.equals(typeName[0], TypeConstants.VAR);
}
}
