/******************************************************************************* | |
* Copyright (c) 2000, 2004 IBM Corporation and others. | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Common Public License v1.0 | |
* which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/cpl-v10.html | |
* | |
* Contributors: | |
* IBM Corporation - initial API and implementation | |
*******************************************************************************/ | |
package org.eclipse.wst.jsdt.internal.compiler.ast; | |
import org.eclipse.wst.jsdt.internal.compiler.ASTVisitor; | |
import org.eclipse.wst.jsdt.internal.compiler.codegen.*; | |
import org.eclipse.wst.jsdt.internal.compiler.flow.*; | |
import org.eclipse.wst.jsdt.internal.compiler.lookup.*; | |
public class QualifiedThisReference extends ThisReference { | |
public TypeReference qualification; | |
ReferenceBinding currentCompatibleType; | |
public QualifiedThisReference(TypeReference name, int sourceStart, int sourceEnd) { | |
super(sourceStart, sourceEnd); | |
qualification = name; | |
this.sourceStart = name.sourceStart; | |
} | |
public FlowInfo analyseCode( | |
BlockScope currentScope, | |
FlowContext flowContext, | |
FlowInfo flowInfo) { | |
return flowInfo; | |
} | |
public FlowInfo analyseCode( | |
BlockScope currentScope, | |
FlowContext flowContext, | |
FlowInfo flowInfo, | |
boolean valueRequired) { | |
return flowInfo; | |
} | |
/** | |
* Code generation for QualifiedThisReference | |
* | |
* @param currentScope org.eclipse.wst.jsdt.internal.compiler.lookup.BlockScope | |
* @param codeStream org.eclipse.wst.jsdt.internal.compiler.codegen.CodeStream | |
* @param valueRequired boolean | |
*/ | |
public void generateCode( | |
BlockScope currentScope, | |
CodeStream codeStream, | |
boolean valueRequired) { | |
int pc = codeStream.position; | |
if (valueRequired) { | |
if ((bits & DepthMASK) != 0) { | |
Object[] emulationPath = | |
currentScope.getEmulationPath(this.currentCompatibleType, true /*only exact match*/, false/*consider enclosing arg*/); | |
codeStream.generateOuterAccess(emulationPath, this, this.currentCompatibleType, currentScope); | |
} else { | |
// nothing particular after all | |
codeStream.aload_0(); | |
} | |
} | |
codeStream.recordPositionsFrom(pc, this.sourceStart); | |
} | |
public TypeBinding resolveType(BlockScope scope) { | |
constant = NotAConstant; | |
TypeBinding type = this.resolvedType = this.qualification.resolveType(scope); | |
if (type == null) return null; | |
// X.this is not a raw type as denoting enclosing instance | |
if (type.isRawType()) { | |
RawTypeBinding rawType = (RawTypeBinding) type; | |
type = this.resolvedType = rawType.type; // unwrap | |
} | |
// the qualification MUST exactly match some enclosing type name | |
// Its possible to qualify 'this' by the name of the current class | |
int depth = 0; | |
this.currentCompatibleType = scope.referenceType().binding; | |
while (this.currentCompatibleType != null | |
&& this.currentCompatibleType != type) { | |
depth++; | |
this.currentCompatibleType = this.currentCompatibleType.isStatic() ? null : this.currentCompatibleType.enclosingType(); | |
} | |
bits &= ~DepthMASK; // flush previous depth if any | |
bits |= (depth & 0xFF) << DepthSHIFT; // encoded depth into 8 bits | |
if (this.currentCompatibleType == null) { | |
scope.problemReporter().noSuchEnclosingInstance(type, this, false); | |
return type; | |
} | |
// Ensure one cannot write code like: B() { super(B.this); } | |
if (depth == 0) { | |
checkAccess(scope.methodScope()); | |
} // if depth>0, path emulation will diagnose bad scenarii | |
return type; | |
} | |
public StringBuffer printExpression(int indent, StringBuffer output) { | |
return qualification.print(0, output).append(".this"); //$NON-NLS-1$ | |
} | |
public void traverse( | |
ASTVisitor visitor, | |
BlockScope blockScope) { | |
if (visitor.visit(this, blockScope)) { | |
qualification.traverse(visitor, blockScope); | |
} | |
visitor.endVisit(this, blockScope); | |
} | |
} |