Fix #1368081: Variable not initialized does not work for array access
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / ast / QualifiedThisReference.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.ast;
12
13 import net.sourceforge.phpdt.internal.compiler.ASTVisitor;
14 import net.sourceforge.phpdt.internal.compiler.flow.FlowContext;
15 import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo;
16 import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
17 import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding;
18 import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding;
19
20 public class QualifiedThisReference extends ThisReference {
21         
22         public TypeReference qualification;
23         ReferenceBinding currentCompatibleType;
24         
25         public QualifiedThisReference(TypeReference name, int sourceStart, int sourceEnd) {
26                 super(sourceStart, sourceEnd);
27                 qualification = name;
28                 this.sourceStart = name.sourceStart;
29         }
30
31         public FlowInfo analyseCode(
32                 BlockScope currentScope,
33                 FlowContext flowContext,
34                 FlowInfo flowInfo) {
35
36                 return flowInfo;
37         }
38
39         public FlowInfo analyseCode(
40                 BlockScope currentScope,
41                 FlowContext flowContext,
42                 FlowInfo flowInfo,
43                 boolean valueRequired) {
44
45                 return flowInfo;
46         }
47
48         /**
49          * Code generation for QualifiedThisReference
50          *
51          * @param currentScope net.sourceforge.phpdt.internal.compiler.lookup.BlockScope
52          * @param codeStream net.sourceforge.phpdt.internal.compiler.codegen.CodeStream
53          * @param valueRequired boolean
54          */
55 //      public void generateCode(
56 //              BlockScope currentScope,
57 //              CodeStream codeStream,
58 //              boolean valueRequired) {
59 //
60 //              int pc = codeStream.position;
61 //              if (valueRequired) {
62 //                      if ((bits & DepthMASK) != 0) {
63 //                              Object[] emulationPath =
64 //                                      currentScope.getEmulationPath(this.currentCompatibleType, true /*only exact match*/, false/*consider enclosing arg*/);
65 //                              codeStream.generateOuterAccess(emulationPath, this, this.currentCompatibleType, currentScope);
66 //                      } else {
67 //                              // nothing particular after all
68 //                              codeStream.aload_0();
69 //                      }
70 //              }
71 //              codeStream.recordPositionsFrom(pc, this.sourceStart);
72 //      }
73
74         public TypeBinding resolveType(BlockScope scope) {
75
76                 constant = NotAConstant;
77                 this.resolvedType = qualification.resolveType(scope);
78                 if (this.resolvedType == null) return null;
79
80                 // the qualification MUST exactly match some enclosing type name
81                 // Its possible to qualify 'this' by the name of the current class
82                 int depth = 0;
83                 this.currentCompatibleType = scope.referenceType().binding;
84                 while (this.currentCompatibleType != null
85                         && this.currentCompatibleType != this.resolvedType) {
86                         depth++;
87                         this.currentCompatibleType = this.currentCompatibleType.isStatic() ? null : this.currentCompatibleType.enclosingType();
88                 }
89                 bits &= ~DepthMASK; // flush previous depth if any                      
90                 bits |= (depth & 0xFF) << DepthSHIFT; // encoded depth into 8 bits
91
92                 if (this.currentCompatibleType == null) {
93                         scope.problemReporter().noSuchEnclosingInstance(this.resolvedType, this, false);
94                         return this.resolvedType;
95                 }
96
97                 // Ensure one cannot write code like: B() { super(B.this); }
98                 if (depth == 0) {
99                         checkAccess(scope.methodScope());
100                 } // if depth>0, path emulation will diagnose bad scenarii
101                 return this.resolvedType;
102         }
103
104         public String toStringExpression() {
105
106                 return qualification.toString(0) + ".this"; //$NON-NLS-1$
107         }
108
109         public void traverse(
110             ASTVisitor visitor,
111                 BlockScope blockScope) {
112
113                 if (visitor.visit(this, blockScope)) {
114                         qualification.traverse(visitor, blockScope);
115                 }
116                 visitor.endVisit(this, blockScope);
117         }
118 }