Initial upgrade to Platform/JDT 3.4.1
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / ast / ClassLiteralAccess.java
index 4c5b042..5f7c5f6 100644 (file)
@@ -1,24 +1,21 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v0.5 
+ * Copyright (c) 2000, 2008 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/cpl-v05.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- ******************************************************************************/
+ *******************************************************************************/
 package net.sourceforge.phpdt.internal.compiler.ast;
 
-import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import net.sourceforge.phpdt.internal.compiler.codegen.CodeStream;
-import net.sourceforge.phpdt.internal.compiler.flow.FlowContext;
-import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo;
-import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding;
-import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
-import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding;
-import net.sourceforge.phpdt.internal.compiler.lookup.SourceTypeBinding;
-import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding;
+import net.sourceforge.phpdt.internal.compiler.ASTVisitor;
+import net.sourceforge.phpdt.internal.compiler.classfmt.ClassFileConstants;
+import net.sourceforge.phpdt.internal.compiler.codegen.*;
+import net.sourceforge.phpdt.internal.compiler.flow.*;
+import net.sourceforge.phpdt.internal.compiler.impl.Constant;
+import net.sourceforge.phpdt.internal.compiler.lookup.*;
 
 public class ClassLiteralAccess extends Expression {
        
@@ -26,9 +23,10 @@ public class ClassLiteralAccess extends Expression {
        public TypeBinding targetType;
        FieldBinding syntheticField;
 
-       public ClassLiteralAccess(int sourceEnd, TypeReference t) {
-               type = t;
-               this.sourceStart = t.sourceStart;
+       public ClassLiteralAccess(int sourceEnd, TypeReference type) {
+               this.type = type;
+               type.bits |= IgnoreRawTypeCheck; // no need to worry about raw type usage
+               this.sourceStart = type.sourceStart;
                this.sourceEnd = sourceEnd;
        }
 
@@ -38,12 +36,12 @@ public class ClassLiteralAccess extends Expression {
                FlowInfo flowInfo) {
 
                // if reachable, request the addition of a synthetic field for caching the class descriptor
-               SourceTypeBinding sourceType =
-                       currentScope.outerMostMethodScope().enclosingSourceType();
-               if (!(sourceType.isInterface()
-                       // no field generated in interface case (would'nt verify) see 1FHHEZL
-                       || sourceType.isBaseType())) {
-                       syntheticField = sourceType.addSyntheticField(targetType, currentScope);
+               SourceTypeBinding sourceType = currentScope.outerMostClassScope().enclosingSourceType();
+               // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=22334
+               if (!sourceType.isInterface()
+                               && !targetType.isBaseType()
+                               && currentScope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_5) {
+                       syntheticField = sourceType.addSyntheticFieldForClassLiteral(targetType, currentScope);
                }
                return flowInfo;
        }
@@ -62,35 +60,54 @@ public class ClassLiteralAccess extends Expression {
                int pc = codeStream.position;
 
                // in interface case, no caching occurs, since cannot make a cache field for interface
-               if (valueRequired)
-                       codeStream.generateClassLiteralAccessForType(type.binding, syntheticField);
+               if (valueRequired) {
+                       codeStream.generateClassLiteralAccessForType(type.resolvedType, syntheticField);
+                       codeStream.generateImplicitConversion(this.implicitConversion);
+               }
                codeStream.recordPositionsFrom(pc, this.sourceStart);
        }
 
+       public StringBuffer printExpression(int indent, StringBuffer output) {
+
+               return type.print(0, output).append(".class"); //$NON-NLS-1$
+       }
+
        public TypeBinding resolveType(BlockScope scope) {
 
-               constant = NotAConstant;
-               if ((targetType = type.resolveType(scope)) == null)
+               constant = Constant.NotAConstant;
+               if ((targetType = type.resolveType(scope, true /* check bounds*/)) == null)
                        return null;
 
-               if (targetType.isArrayType()
-                       && ((ArrayBinding) targetType).leafComponentType == VoidBinding) {
-                       scope.problemReporter().cannotAllocateVoidArray(this);
-                       return null;
+               if (targetType.isArrayType()) {
+                       ArrayBinding arrayBinding = (ArrayBinding) this.targetType;
+                       TypeBinding leafComponentType = arrayBinding.leafComponentType;
+                       if (leafComponentType == TypeBinding.VOID) {
+                               scope.problemReporter().cannotAllocateVoidArray(this);
+                               return null;
+                       } else if (leafComponentType.isTypeVariable()) {
+                               scope.problemReporter().illegalClassLiteralForTypeVariable((TypeVariableBinding)leafComponentType, this);
+                       }
+               } else if (this.targetType.isTypeVariable()) {
+                       scope.problemReporter().illegalClassLiteralForTypeVariable((TypeVariableBinding)targetType, this);
                }
-
-               return scope.getJavaLangClass();
-       }
-
-       public String toStringExpression() {
-
-               String s = ""; //$NON-NLS-1$
-               s = s + type.toString(0) + ".class"; //$NON-NLS-1$
-               return s;
+               ReferenceBinding classType = scope.getJavaLangClass();
+               if (classType.isGenericType()) {
+                       // Integer.class --> Class<Integer>, perform boxing of base types (int.class --> Class<Integer>)
+                       TypeBinding boxedType = null;
+                       if (targetType.id == T_void) {
+                               boxedType = scope.environment().getResolvedType(JAVA_LANG_VOID, scope);
+                       } else {
+                               boxedType = scope.boxing(targetType);
+                       }
+                       this.resolvedType = scope.environment().createParameterizedType(classType, new TypeBinding[]{ boxedType }, null/*not a member*/);
+               } else {
+                       this.resolvedType = classType;
+               }
+               return this.resolvedType;
        }
 
        public void traverse(
-               IAbstractSyntaxTreeVisitor visitor,
+               ASTVisitor visitor,
                BlockScope blockScope) {
 
                if (visitor.visit(this, blockScope)) {
@@ -98,4 +115,4 @@ public class ClassLiteralAccess extends Expression {
                }
                visitor.endVisit(this, blockScope);
        }
-}
\ No newline at end of file
+}