1 /******************************************************************************* 2 * Copyright (c) 2000, 2014 IBM Corporation and others. 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * IBM Corporation - initial API and implementation 10 * Stephan Herrmann - Contribution for 11 * Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault 12 *******************************************************************************/ 13 package org.eclipse.jdt.internal.compiler.ast; 14 15 import org.eclipse.jdt.core.compiler.CharOperation; 16 import org.eclipse.jdt.internal.compiler.ASTVisitor; 17 import org.eclipse.jdt.internal.compiler.lookup.*; 18 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; 19 20 public class ArrayQualifiedTypeReference extends QualifiedTypeReference { 21 int dimensions; 22 private Annotation[][] annotationsOnDimensions; // jsr308 style type annotations on dimensions 23 public int extendedDimensions; 24 ArrayQualifiedTypeReference(char[][] sources , int dim, long[] poss)25 public ArrayQualifiedTypeReference(char[][] sources , int dim, long[] poss) { 26 27 super( sources , poss); 28 this.dimensions = dim ; 29 this.annotationsOnDimensions = null; 30 } 31 ArrayQualifiedTypeReference(char[][] sources, int dim, Annotation[][] annotationsOnDimensions, long[] poss)32 public ArrayQualifiedTypeReference(char[][] sources, int dim, Annotation[][] annotationsOnDimensions, long[] poss) { 33 this(sources, dim, poss); 34 this.annotationsOnDimensions = annotationsOnDimensions; 35 if (annotationsOnDimensions != null) 36 this.bits |= ASTNode.HasTypeAnnotations; 37 } 38 dimensions()39 public int dimensions() { 40 41 return this.dimensions; 42 } 43 extraDimensions()44 public int extraDimensions() { 45 return this.extendedDimensions; 46 } 47 48 /** 49 @see org.eclipse.jdt.internal.compiler.ast.TypeReference#getAnnotationsOnDimensions(boolean) 50 */ getAnnotationsOnDimensions(boolean useSourceOrder)51 public Annotation[][] getAnnotationsOnDimensions(boolean useSourceOrder) { 52 if (useSourceOrder || this.annotationsOnDimensions == null || this.annotationsOnDimensions.length == 0 || this.extendedDimensions == 0 || this.extendedDimensions == this.dimensions) 53 return this.annotationsOnDimensions; 54 Annotation [][] externalAnnotations = new Annotation[this.dimensions][]; 55 final int baseDimensions = this.dimensions - this.extendedDimensions; 56 System.arraycopy(this.annotationsOnDimensions, baseDimensions, externalAnnotations, 0, this.extendedDimensions); 57 System.arraycopy(this.annotationsOnDimensions, 0, externalAnnotations, this.extendedDimensions, baseDimensions); 58 return externalAnnotations; 59 } 60 setAnnotationsOnDimensions(Annotation [][] annotationsOnDimensions)61 public void setAnnotationsOnDimensions(Annotation [][] annotationsOnDimensions) { 62 this.annotationsOnDimensions = annotationsOnDimensions; 63 } 64 65 /** 66 * @return char[][] 67 */ getParameterizedTypeName()68 public char [][] getParameterizedTypeName(){ 69 int dim = this.dimensions; 70 char[] dimChars = new char[dim*2]; 71 for (int i = 0; i < dim; i++) { 72 int index = i*2; 73 dimChars[index] = '['; 74 dimChars[index+1] = ']'; 75 } 76 int length = this.tokens.length; 77 char[][] qParamName = new char[length][]; 78 System.arraycopy(this.tokens, 0, qParamName, 0, length-1); 79 qParamName[length-1] = CharOperation.concat(this.tokens[length-1], dimChars); 80 return qParamName; 81 } 82 getTypeBinding(Scope scope)83 protected TypeBinding getTypeBinding(Scope scope) { 84 85 if (this.resolvedType != null) 86 return this.resolvedType; 87 if (this.dimensions > 255) { 88 scope.problemReporter().tooManyDimensions(this); 89 } 90 LookupEnvironment env = scope.environment(); 91 try { 92 env.missingClassFileLocation = this; 93 TypeBinding leafComponentType = super.getTypeBinding(scope); 94 if (leafComponentType != null) { 95 return this.resolvedType = scope.createArrayType(leafComponentType, this.dimensions); 96 } 97 return null; 98 } catch (AbortCompilation e) { 99 e.updateContext(this, scope.referenceCompilationUnit().compilationResult); 100 throw e; 101 } finally { 102 env.missingClassFileLocation = null; 103 } 104 } 105 internalResolveType(Scope scope, int location)106 protected TypeBinding internalResolveType(Scope scope, int location) { 107 TypeBinding internalResolveType = super.internalResolveType(scope, location); 108 return internalResolveType; 109 } 110 printExpression(int indent, StringBuffer output)111 public StringBuffer printExpression(int indent, StringBuffer output){ 112 113 super.printExpression(indent, output); 114 if ((this.bits & IsVarArgs) != 0) { 115 for (int i= 0 ; i < this.dimensions - 1; i++) { 116 if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[i] != null) { 117 output.append(' '); 118 printAnnotations(this.annotationsOnDimensions[i], output); 119 output.append(' '); 120 } 121 output.append("[]"); //$NON-NLS-1$ 122 } 123 if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[this.dimensions - 1] != null) { 124 output.append(' '); 125 printAnnotations(this.annotationsOnDimensions[this.dimensions - 1], output); 126 output.append(' '); 127 } 128 output.append("..."); //$NON-NLS-1$ 129 } else { 130 for (int i= 0 ; i < this.dimensions; i++) { 131 if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[i] != null) { 132 output.append(" "); //$NON-NLS-1$ 133 printAnnotations(this.annotationsOnDimensions[i], output); 134 output.append(" "); //$NON-NLS-1$ 135 } 136 output.append("[]"); //$NON-NLS-1$ 137 } 138 } 139 return output; 140 } 141 traverse(ASTVisitor visitor, BlockScope scope)142 public void traverse(ASTVisitor visitor, BlockScope scope) { 143 if (visitor.visit(this, scope)) { 144 if (this.annotations != null) { 145 int annotationsLevels = this.annotations.length; 146 for (int i = 0; i < annotationsLevels; i++) { 147 int annotationsLength = this.annotations[i] == null ? 0 : this.annotations[i].length; 148 for (int j = 0; j < annotationsLength; j++) 149 this.annotations[i][j].traverse(visitor, scope); 150 } 151 } 152 if (this.annotationsOnDimensions != null) { 153 for (int i = 0, max = this.annotationsOnDimensions.length; i < max; i++) { 154 Annotation[] annotations2 = this.annotationsOnDimensions[i]; 155 for (int j = 0, max2 = annotations2 == null ? 0 : annotations2.length; j < max2; j++) { 156 Annotation annotation = annotations2[j]; 157 annotation.traverse(visitor, scope); 158 } 159 } 160 } 161 } 162 visitor.endVisit(this, scope); 163 } 164 traverse(ASTVisitor visitor, ClassScope scope)165 public void traverse(ASTVisitor visitor, ClassScope scope) { 166 if (visitor.visit(this, scope)) { 167 if (this.annotations != null) { 168 int annotationsLevels = this.annotations.length; 169 for (int i = 0; i < annotationsLevels; i++) { 170 int annotationsLength = this.annotations[i] == null ? 0 : this.annotations[i].length; 171 for (int j = 0; j < annotationsLength; j++) 172 this.annotations[i][j].traverse(visitor, scope); 173 } 174 } 175 if (this.annotationsOnDimensions != null) { 176 for (int i = 0, max = this.annotationsOnDimensions.length; i < max; i++) { 177 Annotation[] annotations2 = this.annotationsOnDimensions[i]; 178 for (int j = 0, max2 = annotations2 == null ? 0 : annotations2.length; j < max2; j++) { 179 Annotation annotation = annotations2[j]; 180 annotation.traverse(visitor, scope); 181 } 182 } 183 } 184 } 185 visitor.endVisit(this, scope); 186 } 187 } 188