Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*******************************************************************************
* Copyright (c) 2000, 2013 IBM Corporation and others.
* 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
*
* Contributors:
* IBM Corporation - initial API and implementation
* Stephan Herrmann - Contributions for
* bug 365662 - [compiler][null] warn on contradictory and redundant null annotations
* bug 401030 - [1.8][null] Null analysis support for lambda methods.
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.CaseStatement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
public final class LocalTypeBinding extends NestedTypeBinding {
final static char[] LocalTypePrefix = { '$', 'L', 'o', 'c', 'a', 'l', '$' };
private InnerEmulationDependency[] dependents;
public CaseStatement enclosingCase; // from 1.4 on, local types should not be accessed across switch case blocks (52221)
public int sourceStart; // used by computeUniqueKey to uniquely identify this binding
public MethodBinding enclosingMethod;
public LocalTypeBinding(ClassScope scope, SourceTypeBinding enclosingType, CaseStatement switchCase) {
super(
new char[][] {CharOperation.concat(LocalTypeBinding.LocalTypePrefix, scope.referenceContext.name)},
scope,
enclosingType);
TypeDeclaration typeDeclaration = scope.referenceContext;
if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
this.tagBits |= TagBits.AnonymousTypeMask;
} else {
this.tagBits |= TagBits.LocalTypeMask;
}
this.enclosingCase = switchCase;
this.sourceStart = typeDeclaration.sourceStart;
MethodScope methodScope = scope.enclosingMethodScope();
MethodBinding methodBinding = methodScope.referenceMethodBinding();
if (methodBinding != null) {
this.enclosingMethod = methodBinding;
}
}
public LocalTypeBinding(LocalTypeBinding prototype) {
super(prototype);
this.dependents = prototype.dependents;
this.enclosingCase = prototype.enclosingCase;
this.sourceStart = prototype.sourceStart;
this.enclosingMethod = prototype.enclosingMethod;
}
/* Record a dependency onto a source target type which may be altered
* by the end of the innerclass emulation. Later on, we will revisit
* all its dependents so as to update them (see updateInnerEmulationDependents()).
*/
public void addInnerEmulationDependent(BlockScope dependentScope, boolean wasEnclosingInstanceSupplied) {
if (!isPrototype()) throw new IllegalStateException();
int index;
if (this.dependents == null) {
index = 0;
this.dependents = new InnerEmulationDependency[1];
} else {
index = this.dependents.length;
for (int i = 0; i < index; i++)
if (this.dependents[i].scope == dependentScope)
return; // already stored
System.arraycopy(this.dependents, 0, (this.dependents = new InnerEmulationDependency[index + 1]), 0, index);
}
this.dependents[index] = new InnerEmulationDependency(dependentScope, wasEnclosingInstanceSupplied);
// System.out.println("Adding dependency: "+ new String(scope.enclosingType().readableName()) + " --> " + new String(this.readableName()));
}
/*
* Returns the anonymous original super type (in some error cases, superclass may get substituted with Object)
*/
public ReferenceBinding anonymousOriginalSuperType() {
if (!isPrototype())
return ((LocalTypeBinding) this.prototype).anonymousOriginalSuperType();
if (this.superInterfaces != Binding.NO_SUPERINTERFACES) {
return this.superInterfaces[0];
}
if ((this.tagBits & TagBits.HierarchyHasProblems) == 0) {
return this.superclass;
}
if (this.scope != null) {
TypeReference typeReference = this.scope.referenceContext.allocation.type;
if (typeReference != null) {
return (ReferenceBinding) typeReference.resolvedType;
}
}
return this.superclass; // default answer
}
protected void checkRedundantNullnessDefaultRecurse(ASTNode location, Annotation[] annotations, long annotationTagBits) {
if (!isPrototype()) throw new IllegalStateException();
long outerDefault = this.enclosingMethod != null ? this.enclosingMethod.tagBits & ((TagBits.AnnotationNonNullByDefault|TagBits.AnnotationNullUnspecifiedByDefault)) : 0;
if (outerDefault != 0) {
if (outerDefault == annotationTagBits) {
this.scope.problemReporter().nullDefaultAnnotationIsRedundant(location, annotations, this.enclosingMethod);
}
return;
}
super.checkRedundantNullnessDefaultRecurse(location, annotations, annotationTagBits);
}
public char[] computeUniqueKey(boolean isLeaf) {
if (!isPrototype())
return this.prototype.computeUniqueKey(isLeaf);
char[] outerKey = outermostEnclosingType().computeUniqueKey(isLeaf);
int semicolon = CharOperation.lastIndexOf(';', outerKey);
StringBuffer sig = new StringBuffer();
sig.append(outerKey, 0, semicolon);
// insert $sourceStart
sig.append('$');
sig.append(String.valueOf(this.sourceStart));
// insert $LocalName if local
if (!isAnonymousType()) {
sig.append('$');
sig.append(this.sourceName);
}
// insert remaining from outer key
sig.append(outerKey, semicolon, outerKey.length-semicolon);
int sigLength = sig.length();
char[] uniqueKey = new char[sigLength];
sig.getChars(0, sigLength, uniqueKey, 0);
return uniqueKey;
}
public char[] constantPoolName() /* java/lang/Object */ {
if (this.constantPoolName != null)
return this.constantPoolName;
if (!isPrototype())
return this.constantPoolName = this.prototype.constantPoolName();
if (this.constantPoolName == null && this.scope != null) {
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=322154, we do have some
// cases where the left hand does not know what the right is doing.
this.constantPoolName = this.scope.compilationUnitScope().computeConstantPoolName(this);
}
return this.constantPoolName;
}
public TypeBinding clone(TypeBinding outerType) {
LocalTypeBinding copy = new LocalTypeBinding(this);
copy.enclosingType = (SourceTypeBinding) outerType;
return copy;
}
public int hashCode() {
return this.enclosingType.hashCode();
}
/*
* Overriden for code assist. In this case, the constantPoolName() has not been computed yet.
* Slam the source name so that the signature is syntactically correct.
* (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=99686)
*/
public char[] genericTypeSignature() {
if (!isPrototype())
return this.prototype.genericTypeSignature();
if (this.genericReferenceTypeSignature == null && this.constantPoolName == null) {
if (isAnonymousType())
setConstantPoolName(superclass().sourceName());
else
setConstantPoolName(sourceName());
}
return super.genericTypeSignature();
}
public char[] readableName() /*java.lang.Object, p.X */ {
char[] readableName;
if (isAnonymousType()) {
readableName = CharOperation.concat(TypeConstants.ANONYM_PREFIX, anonymousOriginalSuperType().readableName(), TypeConstants.ANONYM_SUFFIX);
} else if (isMemberType()) {
readableName = CharOperation.concat(enclosingType().readableName(), this.sourceName, '.');
} else {
readableName = this.sourceName;
}
TypeVariableBinding[] typeVars;
if ((typeVars = typeVariables()) != Binding.NO_TYPE_VARIABLES) {
StringBuffer nameBuffer = new StringBuffer(10);
nameBuffer.append(readableName).append('<');
for (int i = 0, length = typeVars.length; i < length; i++) {
if (i > 0) nameBuffer.append(',');
nameBuffer.append(typeVars[i].readableName());
}
nameBuffer.append('>');
int nameLength = nameBuffer.length();
readableName = new char[nameLength];
nameBuffer.getChars(0, nameLength, readableName, 0);
}
return readableName;
}
public char[] shortReadableName() /*Object*/ {
char[] shortReadableName;
if (isAnonymousType()) {
shortReadableName = CharOperation.concat(TypeConstants.ANONYM_PREFIX, anonymousOriginalSuperType().shortReadableName(), TypeConstants.ANONYM_SUFFIX);
} else if (isMemberType()) {
shortReadableName = CharOperation.concat(enclosingType().shortReadableName(), this.sourceName, '.');
} else {
shortReadableName = this.sourceName;
}
TypeVariableBinding[] typeVars;
if ((typeVars = typeVariables()) != Binding.NO_TYPE_VARIABLES) {
StringBuffer nameBuffer = new StringBuffer(10);
nameBuffer.append(shortReadableName).append('<');
for (int i = 0, length = typeVars.length; i < length; i++) {
if (i > 0) nameBuffer.append(',');
nameBuffer.append(typeVars[i].shortReadableName());
}
nameBuffer.append('>');
int nameLength = nameBuffer.length();
shortReadableName = new char[nameLength];
nameBuffer.getChars(0, nameLength, shortReadableName, 0);
}
return shortReadableName;
}
// Record that the type is a local member type
public void setAsMemberType() {
if (!isPrototype()) {
this.tagBits |= TagBits.MemberTypeMask;
((LocalTypeBinding) this.prototype).setAsMemberType();
return;
}
this.tagBits |= TagBits.MemberTypeMask;
}
public void setConstantPoolName(char[] computedConstantPoolName) /* java/lang/Object */ {
if (!isPrototype()) {
this.constantPoolName = computedConstantPoolName;
((LocalTypeBinding) this.prototype).setConstantPoolName(computedConstantPoolName);
return;
}
this.constantPoolName = computedConstantPoolName;
}
/*
* Overriden for code assist. In this case, the constantPoolName() has not been computed yet.
* Slam the source name so that the signature is syntactically correct.
* (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=102284)
*/
public char[] signature() {
if (!isPrototype())
return this.prototype.signature();
if (this.signature == null && this.constantPoolName == null) {
if (isAnonymousType())
setConstantPoolName(superclass().sourceName());
else
setConstantPoolName(sourceName());
}
return super.signature();
}
public char[] sourceName() {
if (isAnonymousType()) {
return CharOperation.concat(TypeConstants.ANONYM_PREFIX, anonymousOriginalSuperType().sourceName(), TypeConstants.ANONYM_SUFFIX);
} else
return this.sourceName;
}
public String toString() {
if (this.hasTypeAnnotations())
return annotatedDebugName() + " (local)"; //$NON-NLS-1$
if (isAnonymousType())
return "Anonymous type : " + super.toString(); //$NON-NLS-1$
if (isMemberType())
return "Local member type : " + new String(sourceName()) + " " + super.toString(); //$NON-NLS-2$ //$NON-NLS-1$
return "Local type : " + new String(sourceName()) + " " + super.toString(); //$NON-NLS-2$ //$NON-NLS-1$
}
/* Trigger the dependency mechanism forcing the innerclass emulation
* to be propagated to all dependent source types.
*/
public void updateInnerEmulationDependents() {
if (!isPrototype()) throw new IllegalStateException();
if (this.dependents != null) {
for (int i = 0; i < this.dependents.length; i++) {
InnerEmulationDependency dependency = this.dependents[i];
// System.out.println("Updating " + new String(this.readableName()) + " --> " + new String(dependency.scope.enclosingType().readableName()));
dependency.scope.propagateInnerEmulation(this, dependency.wasEnclosingInstanceSupplied);
}
}
}
}