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.BlockScope; 18 import org.eclipse.jdt.internal.compiler.lookup.ClassScope; 19 import org.eclipse.jdt.internal.compiler.lookup.Scope; 20 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; 21 22 public class ArrayTypeReference extends SingleTypeReference { 23 public int dimensions; 24 private Annotation[][] annotationsOnDimensions; // jsr308 style type annotations on dimensions. 25 public int originalSourceEnd; 26 public int extendedDimensions; 27 28 /** 29 * ArrayTypeReference constructor comment. 30 * @param source char[] 31 * @param dimensions int 32 * @param pos int 33 */ ArrayTypeReference(char[] source, int dimensions, long pos)34 public ArrayTypeReference(char[] source, int dimensions, long pos) { 35 36 super(source, pos); 37 this.originalSourceEnd = this.sourceEnd; 38 this.dimensions = dimensions ; 39 this.annotationsOnDimensions = null; 40 } 41 ArrayTypeReference(char[] source, int dimensions, Annotation[][] annotationsOnDimensions, long pos)42 public ArrayTypeReference(char[] source, int dimensions, Annotation[][] annotationsOnDimensions, long pos) { 43 this(source, dimensions, pos); 44 if (annotationsOnDimensions != null) { 45 this.bits |= ASTNode.HasTypeAnnotations; 46 } 47 this.annotationsOnDimensions = annotationsOnDimensions; 48 } 49 dimensions()50 public int dimensions() { 51 52 return this.dimensions; 53 } 54 extraDimensions()55 public int extraDimensions() { 56 return this.extendedDimensions; 57 } 58 59 /** 60 @see org.eclipse.jdt.internal.compiler.ast.TypeReference#getAnnotationsOnDimensions(boolean) 61 */ getAnnotationsOnDimensions(boolean useSourceOrder)62 public Annotation[][] getAnnotationsOnDimensions(boolean useSourceOrder) { 63 if (useSourceOrder || this.annotationsOnDimensions == null || this.annotationsOnDimensions.length == 0 || this.extendedDimensions == 0 || this.extendedDimensions == this.dimensions) 64 return this.annotationsOnDimensions; 65 Annotation [][] externalAnnotations = new Annotation[this.dimensions][]; 66 final int baseDimensions = this.dimensions - this.extendedDimensions; 67 System.arraycopy(this.annotationsOnDimensions, baseDimensions, externalAnnotations, 0, this.extendedDimensions); 68 System.arraycopy(this.annotationsOnDimensions, 0, externalAnnotations, this.extendedDimensions, baseDimensions); 69 return externalAnnotations; 70 } 71 setAnnotationsOnDimensions(Annotation [][] annotationsOnDimensions)72 public void setAnnotationsOnDimensions(Annotation [][] annotationsOnDimensions) { 73 this.annotationsOnDimensions = annotationsOnDimensions; 74 } 75 /** 76 * @return char[][] 77 */ getParameterizedTypeName()78 public char [][] getParameterizedTypeName(){ 79 int dim = this.dimensions; 80 char[] dimChars = new char[dim*2]; 81 for (int i = 0; i < dim; i++) { 82 int index = i*2; 83 dimChars[index] = '['; 84 dimChars[index+1] = ']'; 85 } 86 return new char[][]{ CharOperation.concat(this.token, dimChars) }; 87 } getTypeBinding(Scope scope)88 protected TypeBinding getTypeBinding(Scope scope) { 89 90 if (this.resolvedType != null) { 91 return this.resolvedType; 92 } 93 if (this.dimensions > 255) { 94 scope.problemReporter().tooManyDimensions(this); 95 } 96 TypeBinding leafComponentType = scope.getType(this.token); 97 return scope.createArrayType(leafComponentType, this.dimensions); 98 99 } 100 printExpression(int indent, StringBuffer output)101 public StringBuffer printExpression(int indent, StringBuffer output){ 102 103 super.printExpression(indent, output); 104 if ((this.bits & IsVarArgs) != 0) { 105 for (int i= 0 ; i < this.dimensions - 1; i++) { 106 if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[i] != null) { 107 output.append(' '); 108 printAnnotations(this.annotationsOnDimensions[i], output); 109 output.append(' '); 110 } 111 output.append("[]"); //$NON-NLS-1$ 112 } 113 if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[this.dimensions - 1] != null) { 114 output.append(' '); 115 printAnnotations(this.annotationsOnDimensions[this.dimensions - 1], output); 116 output.append(' '); 117 } 118 output.append("..."); //$NON-NLS-1$ 119 } else { 120 for (int i= 0 ; i < this.dimensions; i++) { 121 if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[i] != null) { 122 output.append(" "); //$NON-NLS-1$ 123 printAnnotations(this.annotationsOnDimensions[i], output); 124 output.append(" "); //$NON-NLS-1$ 125 } 126 output.append("[]"); //$NON-NLS-1$ 127 } 128 } 129 return output; 130 } 131 traverse(ASTVisitor visitor, BlockScope scope)132 public void traverse(ASTVisitor visitor, BlockScope scope) { 133 if (visitor.visit(this, scope)) { 134 if (this.annotations != null) { 135 Annotation [] typeAnnotations = this.annotations[0]; 136 for (int i = 0, length = typeAnnotations == null ? 0 : typeAnnotations.length; i < length; i++) { 137 typeAnnotations[i].traverse(visitor, scope); 138 } 139 } 140 if (this.annotationsOnDimensions != null) { 141 for (int i = 0, max = this.annotationsOnDimensions.length; i < max; i++) { 142 Annotation[] annotations2 = this.annotationsOnDimensions[i]; 143 if (annotations2 != null) { 144 for (int j = 0, max2 = annotations2.length; j < max2; j++) { 145 Annotation annotation = annotations2[j]; 146 annotation.traverse(visitor, scope); 147 } 148 } 149 } 150 } 151 } 152 visitor.endVisit(this, scope); 153 } 154 traverse(ASTVisitor visitor, ClassScope scope)155 public void traverse(ASTVisitor visitor, ClassScope scope) { 156 if (visitor.visit(this, scope)) { 157 if (this.annotations != null) { 158 Annotation [] typeAnnotations = this.annotations[0]; 159 for (int i = 0, length = typeAnnotations == null ? 0 : typeAnnotations.length; i < length; i++) { 160 typeAnnotations[i].traverse(visitor, scope); 161 } 162 } 163 if (this.annotationsOnDimensions != null) { 164 for (int i = 0, max = this.annotationsOnDimensions.length; i < max; i++) { 165 Annotation[] annotations2 = this.annotationsOnDimensions[i]; 166 if (annotations2 != null) { 167 for (int j = 0, max2 = annotations2.length; j < max2; j++) { 168 Annotation annotation = annotations2[j]; 169 annotation.traverse(visitor, scope); 170 } 171 } 172 } 173 } 174 } 175 visitor.endVisit(this, scope); 176 } 177 internalResolveType(Scope scope, int location)178 protected TypeBinding internalResolveType(Scope scope, int location) { 179 TypeBinding internalResolveType = super.internalResolveType(scope, location); 180 return internalResolveType; 181 } 182 } 183