| /******************************************************************************* |
| * Copyright (c) 2008, 2015 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/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * |
| * Fraunhofer FIRST - extended API and implementation |
| * Technical University Berlin - extended API and implementation * |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.compiler; |
| |
| import java.util.ArrayList; |
| import java.util.Map; |
| |
| import org.eclipse.jdt.core.Signature; |
| import org.eclipse.jdt.core.compiler.CharOperation; |
| import org.eclipse.jdt.internal.compiler.ISourceElementRequestor.ParameterInfo; |
| import org.eclipse.jdt.internal.compiler.ISourceElementRequestor.TypeParameterInfo; |
| import org.eclipse.jdt.internal.compiler.ast.ASTNode; |
| import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; |
| import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; |
| import org.eclipse.jdt.internal.compiler.ast.AllocationExpression; |
| import org.eclipse.jdt.internal.compiler.ast.Annotation; |
| import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration; |
| import org.eclipse.jdt.internal.compiler.ast.Argument; |
| import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression; |
| import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer; |
| import org.eclipse.jdt.internal.compiler.ast.ArrayReference; |
| import org.eclipse.jdt.internal.compiler.ast.Assignment; |
| import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess; |
| import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; |
| import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration; |
| import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall; |
| import org.eclipse.jdt.internal.compiler.ast.Expression; |
| import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; |
| import org.eclipse.jdt.internal.compiler.ast.ImportReference; |
| import org.eclipse.jdt.internal.compiler.ast.Initializer; |
| import org.eclipse.jdt.internal.compiler.ast.MessageSend; |
| import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; |
| import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference; |
| import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression; |
| import org.eclipse.jdt.internal.compiler.ast.ThisReference; |
| import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; |
| import org.eclipse.jdt.internal.compiler.ast.TypeParameter; |
| import org.eclipse.jdt.internal.compiler.ast.TypeReference; |
| import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; |
| import org.eclipse.jdt.internal.compiler.lookup.BlockScope; |
| import org.eclipse.jdt.internal.compiler.lookup.ClassScope; |
| import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; |
| import org.eclipse.jdt.internal.compiler.lookup.MethodScope; |
| import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; |
| import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt; |
| import org.eclipse.objectteams.otdt.core.compiler.IOTConstants; |
| import org.eclipse.objectteams.otdt.internal.core.compiler.ast.AbstractMethodMappingDeclaration; |
| import org.eclipse.objectteams.otdt.internal.core.compiler.ast.CallinMappingDeclaration; |
| import org.eclipse.objectteams.otdt.internal.core.compiler.ast.CalloutMappingDeclaration; |
| import org.eclipse.objectteams.otdt.internal.core.compiler.ast.FieldAccessSpec; |
| import org.eclipse.objectteams.otdt.internal.core.compiler.ast.GuardPredicateDeclaration; |
| import org.eclipse.objectteams.otdt.internal.core.compiler.ast.LiftingTypeReference; |
| import org.eclipse.objectteams.otdt.internal.core.compiler.ast.MethodSpec; |
| import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.MethodSignatureEnhancer; |
| |
| @SuppressWarnings({"rawtypes", "unchecked"}) |
| public class SourceElementNotifier { |
| /** |
| * An ast visitor that visits local type declarations. |
| */ |
| public class LocalDeclarationVisitor extends ASTVisitor { |
| public ImportReference currentPackage; |
| ArrayList declaringTypes; |
| public void pushDeclaringType(TypeDeclaration declaringType) { |
| if (this.declaringTypes == null) { |
| this.declaringTypes = new ArrayList(); |
| } |
| this.declaringTypes.add(declaringType); |
| } |
| public void popDeclaringType() { |
| this.declaringTypes.remove(this.declaringTypes.size()-1); |
| } |
| public TypeDeclaration peekDeclaringType() { |
| if (this.declaringTypes == null) return null; |
| int size = this.declaringTypes.size(); |
| if (size == 0) return null; |
| return (TypeDeclaration) this.declaringTypes.get(size-1); |
| } |
| public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) { |
| notifySourceElementRequestor(typeDeclaration, true, peekDeclaringType(), this.currentPackage); |
| return false; // don't visit members as this was done during notifySourceElementRequestor(...) |
| } |
| public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) { |
| notifySourceElementRequestor(typeDeclaration, true, peekDeclaringType(), this.currentPackage); |
| return false; // don't visit members as this was done during notifySourceElementRequestor(...) |
| } |
| } |
| |
| ISourceElementRequestor requestor; |
| boolean reportReferenceInfo; |
| char[][] typeNames; |
| char[][] superTypeNames; |
| int nestedTypeIndex; |
| LocalDeclarationVisitor localDeclarationVisitor = null; |
| |
| HashtableOfObjectToInt sourceEnds; |
| Map nodesToCategories; |
| |
| int initialPosition; |
| int eofPosition; |
| |
| public SourceElementNotifier(ISourceElementRequestor requestor, boolean reportLocalDeclarations) { |
| this.requestor = requestor; |
| if (reportLocalDeclarations) { |
| this.localDeclarationVisitor = new LocalDeclarationVisitor(); |
| } |
| this.typeNames = new char[4][]; |
| this.superTypeNames = new char[4][]; |
| this.nestedTypeIndex = 0; |
| } |
| protected Object[][] getArgumentInfos(Argument[] arguments) { |
| int argumentLength = arguments.length; |
| char[][] argumentTypes = new char[argumentLength][]; |
| char[][] argumentNames = new char[argumentLength][]; |
| ParameterInfo[] parameterInfos = new ParameterInfo[argumentLength]; |
| for (int i = 0; i < argumentLength; i++) { |
| Argument argument = arguments[i]; |
| argumentTypes[i] = CharOperation.concatWith(argument.type.getParameterizedTypeName(), '.'); |
| char[] name = argument.name; |
| argumentNames[i] = name; |
| ParameterInfo parameterInfo = new ParameterInfo(); |
| parameterInfo.declarationStart = argument.declarationSourceStart; |
| parameterInfo.declarationEnd = argument.declarationSourceEnd; |
| parameterInfo.nameSourceStart = argument.sourceStart; |
| parameterInfo.nameSourceEnd = argument.sourceEnd; |
| parameterInfo.modifiers = argument.modifiers; |
| parameterInfo.name = name; |
| parameterInfos[i] = parameterInfo; |
| } |
| |
| return new Object[][] { parameterInfos, new char[][][] { argumentTypes, argumentNames } }; |
| } |
| protected char[][] getInterfaceNames(TypeDeclaration typeDeclaration) { |
| char[][] interfaceNames = null; |
| int superInterfacesLength = 0; |
| TypeReference[] superInterfaces = typeDeclaration.superInterfaces; |
| if (superInterfaces != null) { |
| superInterfacesLength = superInterfaces.length; |
| interfaceNames = new char[superInterfacesLength][]; |
| } else { |
| if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) { |
| // see PR 3442 |
| QualifiedAllocationExpression alloc = typeDeclaration.allocation; |
| if (alloc != null && alloc.type != null) { |
| superInterfaces = new TypeReference[] { alloc.type}; |
| superInterfacesLength = 1; |
| interfaceNames = new char[1][]; |
| } |
| } |
| } |
| if (superInterfaces != null) { |
| for (int i = 0; i < superInterfacesLength; i++) { |
| interfaceNames[i] = |
| CharOperation.concatWith(superInterfaces[i].getParameterizedTypeName(), '.'); |
| } |
| } |
| return interfaceNames; |
| } |
| protected char[] getSuperclassName(TypeDeclaration typeDeclaration) { |
| TypeReference superclass = typeDeclaration.superclass; |
| return superclass != null ? CharOperation.concatWith(superclass.getParameterizedTypeName(), '.') : null; |
| } |
| protected char[][] getThrownExceptions(AbstractMethodDeclaration methodDeclaration) { |
| char[][] thrownExceptionTypes = null; |
| TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions; |
| if (thrownExceptions != null) { |
| int thrownExceptionLength = thrownExceptions.length; |
| thrownExceptionTypes = new char[thrownExceptionLength][]; |
| for (int i = 0; i < thrownExceptionLength; i++) { |
| thrownExceptionTypes[i] = |
| CharOperation.concatWith(thrownExceptions[i].getParameterizedTypeName(), '.'); |
| } |
| } |
| return thrownExceptionTypes; |
| } |
| protected char[][] getTypeParameterBounds(TypeParameter typeParameter) { |
| TypeReference firstBound = typeParameter.type; |
| TypeReference[] otherBounds = typeParameter.bounds; |
| char[][] typeParameterBounds = null; |
| if (firstBound != null) { |
| if (otherBounds != null) { |
| int otherBoundsLength = otherBounds.length; |
| char[][] boundNames = new char[otherBoundsLength+1][]; |
| boundNames[0] = CharOperation.concatWith(firstBound.getParameterizedTypeName(), '.'); |
| for (int j = 0; j < otherBoundsLength; j++) { |
| boundNames[j+1] = |
| CharOperation.concatWith(otherBounds[j].getParameterizedTypeName(), '.'); |
| } |
| typeParameterBounds = boundNames; |
| } else { |
| typeParameterBounds = new char[][] { CharOperation.concatWith(firstBound.getParameterizedTypeName(), '.')}; |
| } |
| } else { |
| typeParameterBounds = CharOperation.NO_CHAR_CHAR; |
| } |
| |
| return typeParameterBounds; |
| } |
| private TypeParameterInfo[] getTypeParameterInfos(TypeParameter[] typeParameters) { |
| if (typeParameters == null) return null; |
| int typeParametersLength = typeParameters.length; |
| TypeParameterInfo[] result = new TypeParameterInfo[typeParametersLength]; |
| for (int i = 0; i < typeParametersLength; i++) { |
| TypeParameter typeParameter = typeParameters[i]; |
| char[][] typeParameterBounds = getTypeParameterBounds(typeParameter); |
| ISourceElementRequestor.TypeParameterInfo typeParameterInfo = new ISourceElementRequestor.TypeParameterInfo(); |
| typeParameterInfo.declarationStart = typeParameter.declarationSourceStart; |
| typeParameterInfo.declarationEnd = typeParameter.declarationSourceEnd; |
| typeParameterInfo.name = typeParameter.name; |
| typeParameterInfo.nameSourceStart = typeParameter.sourceStart; |
| typeParameterInfo.nameSourceEnd = typeParameter.sourceEnd; |
| typeParameterInfo.bounds = typeParameterBounds; |
| //{ObjectTeams: value parameter / <B base R> ? |
| if (typeParameter.getKind() == AbstractVariableDeclaration.TYPE_VALUE_PARAMETER) |
| typeParameterInfo.isValueParameter= true; |
| if (typeParameter.hasBaseBound()) |
| typeParameterInfo.hasBaseBound= true; |
| // SH} |
| result[i] = typeParameterInfo; |
| } |
| return result; |
| } |
| /* |
| * Checks whether one of the annotations is the @Deprecated annotation |
| * (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=89807) |
| */ |
| private boolean hasDeprecatedAnnotation(Annotation[] annotations) { |
| if (annotations != null) { |
| for (int i = 0, length = annotations.length; i < length; i++) { |
| Annotation annotation = annotations[i]; |
| if (CharOperation.equals(annotation.type.getLastToken(), TypeConstants.JAVA_LANG_DEPRECATED[2])) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| /* |
| * Update the bodyStart of the corresponding parse node |
| */ |
| protected void notifySourceElementRequestor(AbstractMethodDeclaration methodDeclaration, TypeDeclaration declaringType, ImportReference currentPackage) { |
| |
| // range check |
| boolean isInRange = |
| this.initialPosition <= methodDeclaration.declarationSourceStart |
| && this.eofPosition >= methodDeclaration.declarationSourceEnd; |
| |
| if (methodDeclaration.isClinit()) { |
| this.visitIfNeeded(methodDeclaration); |
| return; |
| } |
| |
| if (methodDeclaration.isDefaultConstructor()) { |
| if (this.reportReferenceInfo) { |
| ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) methodDeclaration; |
| ExplicitConstructorCall constructorCall = constructorDeclaration.constructorCall; |
| if (constructorCall != null) { |
| switch(constructorCall.accessMode) { |
| case ExplicitConstructorCall.This : |
| this.requestor.acceptConstructorReference( |
| this.typeNames[this.nestedTypeIndex-1], |
| constructorCall.arguments == null ? 0 : constructorCall.arguments.length, |
| constructorCall.sourceStart); |
| break; |
| case ExplicitConstructorCall.Super : |
| case ExplicitConstructorCall.ImplicitSuper : |
| this.requestor.acceptConstructorReference( |
| this.superTypeNames[this.nestedTypeIndex-1], |
| constructorCall.arguments == null ? 0 : constructorCall.arguments.length, |
| constructorCall.sourceStart); |
| break; |
| } |
| } |
| } |
| return; |
| } |
| char[][] argumentTypes = null; |
| char[][] argumentNames = null; |
| boolean isVarArgs = false; |
| //{ObjectTeams: retrench signature of callin method: |
| /* orig: |
| Argument[] arguments = methodDeclaration.arguments; |
| :giro */ |
| Argument[] arguments = MethodSignatureEnhancer.getSourceArguments(methodDeclaration); |
| boolean [] baseclassFlags = null; |
| // SH} |
| ParameterInfo[] parameterInfos = null; |
| ISourceElementRequestor.MethodInfo methodInfo = new ISourceElementRequestor.MethodInfo(); |
| methodInfo.typeAnnotated = ((methodDeclaration.bits & ASTNode.HasTypeAnnotations) != 0); |
| |
| if (arguments != null) { |
| Object[][] argumentInfos = getArgumentInfos(arguments); |
| parameterInfos = (ParameterInfo[]) argumentInfos[0]; |
| argumentTypes = (char[][]) argumentInfos[1][0]; |
| argumentNames = (char[][]) argumentInfos[1][1]; |
| |
| isVarArgs = arguments[arguments.length-1].isVarArgs(); |
| |
| //{ObjectTeams: compute flag array |
| baseclassFlags = new boolean[arguments.length]; |
| for (int i = 0; i < arguments.length; i++) |
| // LTRs resolve in base-import scope, if present. |
| baseclassFlags[i] = (arguments[i].type instanceof LiftingTypeReference); |
| // SH} |
| } |
| char[][] thrownExceptionTypes = getThrownExceptions(methodDeclaration); |
| // by default no selector end position |
| int selectorSourceEnd = -1; |
| if (methodDeclaration.isConstructor()) { |
| selectorSourceEnd = this.sourceEnds.get(methodDeclaration); |
| if (isInRange){ |
| int currentModifiers = methodDeclaration.modifiers; |
| currentModifiers &= ExtraCompilerModifiers.AccJustFlag | ClassFileConstants.AccDeprecated; |
| if (isVarArgs) |
| currentModifiers |= ClassFileConstants.AccVarargs; |
| if (hasDeprecatedAnnotation(methodDeclaration.annotations)) |
| currentModifiers |= ClassFileConstants.AccDeprecated; |
| |
| methodInfo.isConstructor = true; |
| methodInfo.declarationStart = methodDeclaration.declarationSourceStart; |
| methodInfo.modifiers = currentModifiers; |
| // Note(SH): OT: no callin flag in constructor ;-) |
| methodInfo.name = methodDeclaration.selector; |
| methodInfo.nameSourceStart = methodDeclaration.sourceStart; |
| methodInfo.nameSourceEnd = selectorSourceEnd; |
| methodInfo.parameterTypes = argumentTypes; |
| methodInfo.parameterNames = argumentNames; |
| //{ObjectTeams: store additional array |
| methodInfo.parameterBaseclassFlags = baseclassFlags; |
| // SH} |
| methodInfo.exceptionTypes = thrownExceptionTypes; |
| methodInfo.typeParameters = getTypeParameterInfos(methodDeclaration.typeParameters()); |
| methodInfo.parameterInfos = parameterInfos; |
| methodInfo.categories = (char[][]) this.nodesToCategories.get(methodDeclaration); |
| methodInfo.annotations = methodDeclaration.annotations; |
| methodInfo.declaringPackageName = currentPackage == null ? CharOperation.NO_CHAR : CharOperation.concatWith(currentPackage.tokens, '.'); |
| methodInfo.declaringTypeModifiers = declaringType.modifiers; |
| methodInfo.extraFlags = ExtraFlags.getExtraFlags(declaringType); |
| methodInfo.node = methodDeclaration; |
| this.requestor.enterConstructor(methodInfo); |
| } |
| if (this.reportReferenceInfo) { |
| ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) methodDeclaration; |
| ExplicitConstructorCall constructorCall = constructorDeclaration.constructorCall; |
| if (constructorCall != null) { |
| switch(constructorCall.accessMode) { |
| case ExplicitConstructorCall.This : |
| this.requestor.acceptConstructorReference( |
| this.typeNames[this.nestedTypeIndex-1], |
| constructorCall.arguments == null ? 0 : constructorCall.arguments.length, |
| constructorCall.sourceStart); |
| break; |
| case ExplicitConstructorCall.Super : |
| case ExplicitConstructorCall.ImplicitSuper : |
| this.requestor.acceptConstructorReference( |
| this.superTypeNames[this.nestedTypeIndex-1], |
| constructorCall.arguments == null ? 0 : constructorCall.arguments.length, |
| constructorCall.sourceStart); |
| break; |
| } |
| } |
| } |
| this.visitIfNeeded(methodDeclaration); |
| if (isInRange){ |
| this.requestor.exitConstructor(methodDeclaration.declarationSourceEnd); |
| } |
| return; |
| } |
| selectorSourceEnd = this.sourceEnds.get(methodDeclaration); |
| if (isInRange) { |
| int currentModifiers = methodDeclaration.modifiers; |
| //{ObjectTeams: additionally pass AccCallin: |
| /* orig: |
| currentModifiers &= ExtraCompilerModifiers.AccJustFlag | ClassFileConstants.AccDeprecated | ClassFileConstants.AccAnnotationDefault | ExtraCompilerModifiers.AccDefaultMethod; |
| :giro */ |
| currentModifiers &= ExtraCompilerModifiers.AccJustFlag | ExtraCompilerModifiers.AccCallin | ClassFileConstants.AccDeprecated | ClassFileConstants.AccAnnotationDefault | ExtraCompilerModifiers.AccDefaultMethod; |
| // SH} |
| if (isVarArgs) |
| currentModifiers |= ClassFileConstants.AccVarargs; |
| if (hasDeprecatedAnnotation(methodDeclaration.annotations)) |
| currentModifiers |= ClassFileConstants.AccDeprecated; |
| |
| TypeReference returnType = methodDeclaration instanceof MethodDeclaration |
| ? ((MethodDeclaration) methodDeclaration).returnType |
| : null; |
| methodInfo.isAnnotation = methodDeclaration instanceof AnnotationMethodDeclaration; |
| methodInfo.declarationStart = methodDeclaration.declarationSourceStart; |
| methodInfo.modifiers = currentModifiers; |
| methodInfo.returnType = returnType == null ? null : CharOperation.concatWith(returnType.getParameterizedTypeName(), '.'); |
| methodInfo.name = methodDeclaration.selector; |
| methodInfo.nameSourceStart = methodDeclaration.sourceStart; |
| methodInfo.nameSourceEnd = selectorSourceEnd; |
| methodInfo.parameterTypes = argumentTypes; |
| methodInfo.parameterNames = argumentNames; |
| //{ObjectTeams: store additional array |
| methodInfo.parameterBaseclassFlags = baseclassFlags; |
| // SH} |
| methodInfo.exceptionTypes = thrownExceptionTypes; |
| methodInfo.typeParameters = getTypeParameterInfos(methodDeclaration.typeParameters()); |
| methodInfo.parameterInfos = parameterInfos; |
| methodInfo.categories = (char[][]) this.nodesToCategories.get(methodDeclaration); |
| methodInfo.annotations = methodDeclaration.annotations; |
| methodInfo.node = methodDeclaration; |
| methodInfo.enclosingType = declaringType; |
| methodInfo.declaringPackageName = currentPackage == null ? CharOperation.NO_CHAR : CharOperation.concatWith(currentPackage.tokens, '.'); |
| this.requestor.enterMethod(methodInfo); |
| } |
| |
| this.visitIfNeeded(methodDeclaration); |
| |
| if (isInRange) { |
| if (methodDeclaration instanceof AnnotationMethodDeclaration) { |
| AnnotationMethodDeclaration annotationMethodDeclaration = (AnnotationMethodDeclaration) methodDeclaration; |
| Expression expression = annotationMethodDeclaration.defaultValue; |
| if (expression != null) { |
| this.requestor.exitMethod(methodDeclaration.declarationSourceEnd, expression); |
| return; |
| } |
| } |
| this.requestor.exitMethod(methodDeclaration.declarationSourceEnd, null); |
| } |
| } |
| //{OTDTUI: needed for method mappings |
| private char[] returnTypeName(MethodSpec spec) { |
| return (!spec.hasSignature || spec.returnType == null) ? |
| null : CharOperation.concatWith(spec.returnType.getParameterizedTypeName(), '.'); |
| } |
| |
| public void notifySourceElementRequestor(AbstractMethodMappingDeclaration mapping) |
| { |
| // range check |
| boolean isInRange = |
| this.initialPosition <= mapping.sourceStart |
| && this.eofPosition >= mapping.sourceEnd; |
| |
| if (isInRange) |
| { |
| if (mapping instanceof CalloutMappingDeclaration) |
| { |
| CalloutMappingDeclaration callout = (CalloutMappingDeclaration)mapping; |
| |
| // role method spec: |
| ISourceElementRequestor.MethodSpecInfo roleInfo= new ISourceElementRequestor.MethodSpecInfo(); |
| boolean isDeclaration = false; |
| if (callout.roleMethodSpec != null) { |
| roleInfo.node = callout.roleMethodSpec; |
| roleInfo.parameterTypes= argumentTypes(callout.roleMethodSpec); |
| roleInfo.parameterNames= argumentNames(callout.roleMethodSpec); |
| roleInfo.selector= callout.roleMethodSpec.selector; |
| roleInfo.returnType= returnTypeName(callout.roleMethodSpec); |
| isDeclaration= callout.roleMethodSpec.isDeclaration; |
| } |
| // prepare base side: |
| char[] baseReturnTypeName = null; |
| char[] baseSelector = null; |
| if (callout.baseMethodSpec != null) { |
| baseReturnTypeName= returnTypeName(callout.baseMethodSpec); |
| baseSelector= callout.baseMethodSpec.selector; |
| } |
| if (callout.isCalloutToField()) |
| { |
| ISourceElementRequestor.CalloutToFieldInfo info= new ISourceElementRequestor.CalloutToFieldInfo(); |
| info.isSetter= ((FieldAccessSpec)callout.baseMethodSpec).isSetter(); |
| info.declarationSourceStart= mapping.declarationSourceStart; |
| info.sourceStart= mapping.sourceStart; |
| info.hasSignature= callout.hasSignature; |
| info.isDeclaration= isDeclaration; |
| info.isOverride= mapping.isCalloutOverride(); |
| info.declaredModifiers= callout.declaredModifiers; |
| |
| info.left= roleInfo; |
| |
| // base field spec: |
| info.rightSelector= baseSelector; |
| info.rightReturnType= baseReturnTypeName; |
| |
| info.annotations = mapping.annotations; |
| |
| this.requestor.enterCalloutToFieldMapping(info); |
| visitIfNeeded(callout); |
| } else { |
| ISourceElementRequestor.CalloutInfo info= new ISourceElementRequestor.CalloutInfo(); |
| info.declarationSourceStart= mapping.declarationSourceStart; |
| info.sourceStart= mapping.sourceStart; |
| info.hasSignature= callout.hasSignature; |
| info.isDeclaration= isDeclaration; |
| info.isOverride= mapping.isCalloutOverride(); |
| info.declaredModifiers= callout.declaredModifiers; |
| |
| info.left= roleInfo; |
| |
| // base method spec: |
| ISourceElementRequestor.MethodSpecInfo baseInfo= new ISourceElementRequestor.MethodSpecInfo(); |
| baseInfo.node = callout.baseMethodSpec; |
| baseInfo.selector= baseSelector; |
| baseInfo.returnType= baseReturnTypeName; |
| baseInfo.parameterTypes= argumentTypes(callout.baseMethodSpec); |
| baseInfo.parameterNames= argumentNames(callout.baseMethodSpec); |
| info.right= baseInfo; |
| |
| info.annotations = mapping.annotations; |
| |
| this.requestor.enterCalloutMapping(info); |
| visitIfNeeded(callout); |
| } |
| } else { |
| CallinMappingDeclaration callinDecl = (CallinMappingDeclaration)mapping; |
| ISourceElementRequestor.CallinInfo info= new ISourceElementRequestor.CallinInfo(); |
| info.declarationSourceStart= mapping.declarationSourceStart; |
| info.sourceStart= mapping.sourceStart; |
| info.callinName= callinDecl.name; |
| info.callinKind= callinDecl.callinModifier; |
| info.hasSignature= callinDecl.hasSignature; |
| |
| ISourceElementRequestor.MethodSpecInfo roleInfo= new ISourceElementRequestor.MethodSpecInfo(); |
| roleInfo.node = callinDecl.roleMethodSpec; |
| roleInfo.selector= callinDecl.roleMethodSpec.selector; |
| roleInfo.returnType= returnTypeName(callinDecl.roleMethodSpec); |
| roleInfo.parameterTypes= argumentTypes(callinDecl.roleMethodSpec); |
| roleInfo.parameterNames= argumentNames(callinDecl.roleMethodSpec); |
| roleInfo.typeParameters = getTypeParameterInfos(callinDecl.roleMethodSpec.typeParameters); |
| info.left= roleInfo; |
| |
| int baseSpecsLength = (callinDecl.baseMethodSpecs == null) ? 0 : callinDecl.baseMethodSpecs.length; |
| ISourceElementRequestor.MethodSpecInfo[] baseInfos= new ISourceElementRequestor.MethodSpecInfo[baseSpecsLength]; |
| for (int idx=0; idx < baseSpecsLength; idx++) |
| { |
| MethodSpec spec = callinDecl.baseMethodSpecs[idx]; |
| baseInfos[idx]= new ISourceElementRequestor.MethodSpecInfo(); |
| baseInfos[idx].node = spec; |
| baseInfos[idx].selector= spec.selector; |
| if (callinDecl.hasSignature) { |
| int argListLength = spec.arguments == null ? 0: spec.arguments.length; |
| char[][] baseArgTypes= new char[argListLength][]; |
| char[][] baseArgNames= new char[argListLength][]; |
| |
| for(int argIdx = 0; argIdx < argListLength; argIdx++) |
| { |
| char[] argType = Signature.toQualifiedName(spec.arguments[argIdx].type.getParameterizedTypeName()); |
| baseArgTypes[argIdx] = argType; |
| baseArgNames[argIdx] = spec.arguments[argIdx].name; |
| |
| } |
| baseInfos[idx].parameterNames= baseArgNames; |
| baseInfos[idx].parameterTypes= baseArgTypes; |
| if (spec.returnType != null) |
| baseInfos[idx].returnType = Signature.toQualifiedName(spec.returnType.getParameterizedTypeName()); |
| } |
| } |
| info.right= baseInfos; |
| info.covariantReturn= callinDecl.hasCovariantReturn(); |
| |
| info.annotations = mapping.annotations; |
| |
| this.requestor.enterCallinMapping(info); |
| visitIfNeeded(callinDecl); |
| } |
| } |
| |
| if (isInRange) |
| { |
| if (mapping instanceof CalloutMappingDeclaration) |
| { |
| CalloutMappingDeclaration callout = (CalloutMappingDeclaration)mapping; |
| if (callout.isCalloutToField()) |
| this.requestor.exitCalloutToFieldMapping(callout.sourceEnd, callout.declarationSourceEnd); |
| else |
| this.requestor.exitCalloutMapping(mapping.sourceEnd, mapping.declarationSourceEnd); |
| } |
| else |
| { |
| this.requestor.exitCallinMapping(mapping.sourceEnd, mapping.declarationSourceEnd); |
| } |
| } |
| } |
| |
| private void visitIfNeeded(CalloutMappingDeclaration callout) |
| { |
| if (this.localDeclarationVisitor != null && (callout.bits & ASTNode.HasLocalType) != 0) { |
| if (callout.mappings != null) |
| { |
| for (int i = 0; i < callout.mappings.length; i++) |
| { |
| callout.mappings[i].traverse(this.localDeclarationVisitor, callout.scope); |
| } |
| } |
| } |
| } |
| |
| private void visitIfNeeded(CallinMappingDeclaration callinDecl) |
| { |
| if (this.localDeclarationVisitor != null && (callinDecl.bits & ASTNode.HasLocalType) != 0) { |
| if (callinDecl.mappings != null) |
| { |
| for (int i = 0; i < callinDecl.mappings.length; i++) |
| { |
| callinDecl.mappings[i].traverse(this.localDeclarationVisitor, callinDecl.scope); |
| } |
| } |
| } |
| } |
| |
| private char[][] argumentNames(MethodSpec methodSpec) |
| { |
| if (methodSpec == null) |
| return null; |
| char[][] argumentNames = null; |
| Argument[] arguments = methodSpec.arguments; |
| |
| if (methodSpec.hasSignature && arguments != null) |
| { |
| int argumentLength = arguments.length; |
| argumentNames = new char[argumentLength][]; |
| for (int idx = 0; idx < argumentLength; idx++) |
| { |
| argumentNames[idx] = arguments[idx].name; |
| } |
| } |
| |
| return argumentNames; |
| } |
| |
| private char[][] argumentTypes(MethodSpec methodSpec) |
| { |
| if (methodSpec == null) |
| return null; |
| char[][] argumentTypes = null; |
| Argument[] arguments = methodSpec.arguments; |
| |
| if (methodSpec.hasSignature && arguments != null) |
| { |
| int argumentLength = arguments.length; |
| argumentTypes = new char[argumentLength][]; |
| for (int idx = 0; idx < argumentLength; idx++) |
| { |
| argumentTypes[idx] = CharOperation.concatWith(arguments[idx].type.getParameterizedTypeName(), '.'); |
| } |
| } |
| |
| return argumentTypes; |
| } |
| //ak} |
| /* |
| * Update the bodyStart of the corresponding parse node |
| */ |
| public void notifySourceElementRequestor( |
| CompilationUnitDeclaration parsedUnit, |
| int sourceStart, |
| int sourceEnd, |
| boolean reportReference, |
| HashtableOfObjectToInt sourceEndsMap, |
| Map nodesToCategoriesMap) { |
| |
| this.initialPosition = sourceStart; |
| this.eofPosition = sourceEnd; |
| |
| this.reportReferenceInfo = reportReference; |
| this.sourceEnds = sourceEndsMap; |
| this.nodesToCategories = nodesToCategoriesMap; |
| |
| try { |
| // range check |
| boolean isInRange = |
| this.initialPosition <= parsedUnit.sourceStart |
| && this.eofPosition >= parsedUnit.sourceEnd; |
| |
| // collect the top level ast nodes |
| int length = 0; |
| ASTNode[] nodes = null; |
| if (isInRange) { |
| this.requestor.enterCompilationUnit(); |
| } |
| ImportReference currentPackage = parsedUnit.currentPackage; |
| if (this.localDeclarationVisitor != null) { |
| this.localDeclarationVisitor.currentPackage = currentPackage; |
| } |
| ImportReference[] imports = parsedUnit.imports; |
| TypeDeclaration[] types = parsedUnit.types; |
| length = |
| (currentPackage == null ? 0 : 1) |
| + (imports == null ? 0 : imports.length) |
| + (types == null ? 0 : types.length); |
| nodes = new ASTNode[length]; |
| int index = 0; |
| if (currentPackage != null) { |
| nodes[index++] = currentPackage; |
| } |
| if (imports != null) { |
| for (int i = 0, max = imports.length; i < max; i++) { |
| nodes[index++] = imports[i]; |
| } |
| } |
| if (types != null) { |
| for (int i = 0, max = types.length; i < max; i++) { |
| nodes[index++] = types[i]; |
| } |
| } |
| |
| // notify the nodes in the syntactical order |
| if (length > 0) { |
| quickSort(nodes, 0, length-1); |
| for (int i=0;i<length;i++) { |
| ASTNode node = nodes[i]; |
| if (node instanceof ImportReference) { |
| ImportReference importRef = (ImportReference)node; |
| if (node == parsedUnit.currentPackage) { |
| notifySourceElementRequestor(importRef, true); |
| } else { |
| notifySourceElementRequestor(importRef, false); |
| } |
| } else { // instanceof TypeDeclaration |
| notifySourceElementRequestor((TypeDeclaration)node, true, null, currentPackage); |
| } |
| } |
| } |
| |
| if (isInRange) { |
| this.requestor.exitCompilationUnit(parsedUnit.sourceEnd); |
| } |
| } finally { |
| reset(); |
| } |
| } |
| |
| /* |
| * Update the bodyStart of the corresponding parse node |
| */ |
| protected void notifySourceElementRequestor(FieldDeclaration fieldDeclaration, TypeDeclaration declaringType) { |
| |
| // range check |
| boolean isInRange = |
| this.initialPosition <= fieldDeclaration.declarationSourceStart |
| && this.eofPosition >= fieldDeclaration.declarationSourceEnd; |
| |
| switch(fieldDeclaration.getKind()) { |
| case AbstractVariableDeclaration.ENUM_CONSTANT: |
| if (this.reportReferenceInfo) { |
| // accept constructor reference for enum constant |
| if (fieldDeclaration.initialization instanceof AllocationExpression) { |
| AllocationExpression alloc = (AllocationExpression) fieldDeclaration.initialization; |
| this.requestor.acceptConstructorReference( |
| declaringType.name, |
| alloc.arguments == null ? 0 : alloc.arguments.length, |
| alloc.sourceStart); |
| } |
| } |
| // $FALL-THROUGH$ |
| case AbstractVariableDeclaration.FIELD: |
| int fieldEndPosition = this.sourceEnds.get(fieldDeclaration); |
| if (fieldEndPosition == -1) { |
| // use the declaration source end by default |
| fieldEndPosition = fieldDeclaration.declarationSourceEnd; |
| } |
| if (isInRange) { |
| int currentModifiers = fieldDeclaration.modifiers; |
| |
| // remember deprecation so as to not lose it below |
| boolean deprecated = (currentModifiers & ClassFileConstants.AccDeprecated) != 0 || hasDeprecatedAnnotation(fieldDeclaration.annotations); |
| |
| char[] typeName = null; |
| if (fieldDeclaration.type == null) { |
| // enum constant |
| typeName = declaringType.name; |
| currentModifiers |= ClassFileConstants.AccEnum; |
| } else { |
| // regular field |
| typeName = CharOperation.concatWith(fieldDeclaration.type.getParameterizedTypeName(), '.'); |
| } |
| ISourceElementRequestor.FieldInfo fieldInfo = new ISourceElementRequestor.FieldInfo(); |
| fieldInfo.typeAnnotated = ((fieldDeclaration.bits & ASTNode.HasTypeAnnotations) != 0); |
| fieldInfo.declarationStart = fieldDeclaration.declarationSourceStart; |
| fieldInfo.name = fieldDeclaration.name; |
| fieldInfo.modifiers = deprecated ? (currentModifiers & ExtraCompilerModifiers.AccJustFlag) | ClassFileConstants.AccDeprecated : currentModifiers & ExtraCompilerModifiers.AccJustFlag; |
| fieldInfo.type = typeName; |
| fieldInfo.nameSourceStart = fieldDeclaration.sourceStart; |
| fieldInfo.nameSourceEnd = fieldDeclaration.sourceEnd; |
| fieldInfo.categories = (char[][]) this.nodesToCategories.get(fieldDeclaration); |
| fieldInfo.annotations = fieldDeclaration.annotations; |
| fieldInfo.node = fieldDeclaration; |
| this.requestor.enterField(fieldInfo); |
| } |
| this.visitIfNeeded(fieldDeclaration, declaringType); |
| if (isInRange){ |
| this.requestor.exitField( |
| // filter out initializations that are not a constant (simple check) |
| (fieldDeclaration.initialization == null |
| || fieldDeclaration.initialization instanceof ArrayInitializer |
| || fieldDeclaration.initialization instanceof AllocationExpression |
| || fieldDeclaration.initialization instanceof ArrayAllocationExpression |
| || fieldDeclaration.initialization instanceof Assignment |
| || fieldDeclaration.initialization instanceof ClassLiteralAccess |
| || fieldDeclaration.initialization instanceof MessageSend |
| || fieldDeclaration.initialization instanceof ArrayReference |
| || fieldDeclaration.initialization instanceof ThisReference) ? |
| -1 : |
| fieldDeclaration.initialization.sourceStart, |
| fieldEndPosition, |
| fieldDeclaration.declarationSourceEnd); |
| } |
| break; |
| case AbstractVariableDeclaration.INITIALIZER: |
| if (isInRange){ |
| this.requestor.enterInitializer( |
| fieldDeclaration.declarationSourceStart, |
| fieldDeclaration.modifiers); |
| } |
| this.visitIfNeeded((Initializer)fieldDeclaration); |
| if (isInRange){ |
| this.requestor.exitInitializer(fieldDeclaration.declarationSourceEnd); |
| } |
| break; |
| } |
| } |
| protected void notifySourceElementRequestor( |
| ImportReference importReference, |
| boolean isPackage) { |
| if (isPackage) { |
| this.requestor.acceptPackage(importReference); |
| } else { |
| final boolean onDemand = (importReference.bits & ASTNode.OnDemand) != 0; |
| this.requestor.acceptImport( |
| importReference.declarationSourceStart, |
| importReference.declarationSourceEnd, |
| importReference.sourceStart, |
| onDemand ? importReference.trailingStarPosition : importReference.sourceEnd, |
| importReference.tokens, |
| onDemand, |
| importReference.modifiers); |
| } |
| } |
| protected void notifySourceElementRequestor(TypeDeclaration typeDeclaration, boolean notifyTypePresence, TypeDeclaration declaringType, ImportReference currentPackage) { |
| |
| //{ObjectTeams: don't convert generated types (role ifc part): |
| if (typeDeclaration.isGenerated) return; |
| // SH} |
| |
| if (CharOperation.equals(TypeConstants.PACKAGE_INFO_NAME, typeDeclaration.name)) return; |
| |
| // range check |
| boolean isInRange = |
| this.initialPosition <= typeDeclaration.declarationSourceStart |
| && this.eofPosition >= typeDeclaration.declarationSourceEnd; |
| |
| FieldDeclaration[] fields = typeDeclaration.fields; |
| AbstractMethodDeclaration[] methods = typeDeclaration.methods; |
| TypeDeclaration[] memberTypes = typeDeclaration.memberTypes; |
| //{ObjectTeams: treatment for method mappings |
| AbstractMethodMappingDeclaration[] bindings = typeDeclaration.callinCallouts; |
| //ak} |
| int fieldCounter = fields == null ? 0 : fields.length; |
| int methodCounter = methods == null ? 0 : methods.length; |
| int memberTypeCounter = memberTypes == null ? 0 : memberTypes.length; |
| //{ObjectTeams: treatment for method mappings |
| int bindingCount = (bindings == null) ? 0 : bindings.length; |
| //ak} |
| int fieldIndex = 0; |
| int methodIndex = 0; |
| int memberTypeIndex = 0; |
| //ObjectTeams: treatment for method mappings |
| int bindingIndex = 0; |
| //ak} |
| |
| if (notifyTypePresence){ |
| char[][] interfaceNames = getInterfaceNames(typeDeclaration); |
| //{ObjectTeams: construction of baseclass's name |
| char[] baseclassName = null; |
| char[] baseclassAnchor= null; |
| if (typeDeclaration.baseclass != null) |
| { |
| baseclassName = CharOperation.concatWith( |
| typeDeclaration.baseclass.getTypeName(), |
| '.'); |
| char[][] anchorNames= ParameterizedSingleTypeReference.getTypeAnchor(typeDeclaration.baseclass); |
| if (anchorNames != null) |
| baseclassAnchor = CharOperation.concatWith(anchorNames, '.'); |
| } |
| //ak} |
| int kind = TypeDeclaration.kind(typeDeclaration.modifiers); |
| char[] implicitSuperclassName = TypeConstants.CharArray_JAVA_LANG_OBJECT; |
| ISourceElementRequestor.TypeInfo typeInfo = new ISourceElementRequestor.TypeInfo(); |
| typeInfo.typeAnnotated = ((typeDeclaration.bits & ASTNode.HasTypeAnnotations) != 0); |
| if (isInRange) { |
| int currentModifiers = typeDeclaration.modifiers; |
| |
| // remember deprecation so as to not lose it below |
| boolean deprecated = (currentModifiers & ClassFileConstants.AccDeprecated) != 0 || hasDeprecatedAnnotation(typeDeclaration.annotations); |
| |
| boolean isEnumInit = typeDeclaration.allocation != null && typeDeclaration.allocation.enumConstant != null; |
| char[] superclassName; |
| if (isEnumInit) { |
| currentModifiers |= ClassFileConstants.AccEnum; |
| superclassName = declaringType.name; |
| } else { |
| superclassName = getSuperclassName(typeDeclaration); |
| } |
| if (typeDeclaration.allocation == null) { |
| typeInfo.declarationStart = typeDeclaration.declarationSourceStart; |
| } else if (isEnumInit) { |
| typeInfo.declarationStart = typeDeclaration.allocation.enumConstant.sourceStart; |
| } else { |
| typeInfo.declarationStart = typeDeclaration.allocation.sourceStart; |
| } |
| //{ObjectTeams: let Role/Team flags pass through, strip __OT__ prefix |
| /* orig: |
| typeInfo.modifiers = deprecated ? (currentModifiers & ExtraCompilerModifiers.AccJustFlag) | ClassFileConstants.AccDeprecated : currentModifiers & ExtraCompilerModifiers.AccJustFlag; |
| typeInfo.name = typeDeclaration.name; |
| :giro */ |
| typeInfo.modifiers = deprecated ? (currentModifiers & ExtraCompilerModifiers.AccOTTypeJustFlag) | ClassFileConstants.AccDeprecated : currentModifiers & ExtraCompilerModifiers.AccOTTypeJustFlag; |
| typeInfo.name = typeDeclaration.name; |
| // existing __OT__ prefix and special treatment for o.o.Team.Confined: |
| if (CharOperation.prefixEquals(IOTConstants.OT_DELIM_NAME, typeInfo.name)) { |
| typeInfo.name = CharOperation.subarray(typeInfo.name, IOTConstants.OT_DELIM_LEN, -1); |
| if (CharOperation.equals(IOTConstants.CONFINED, typeInfo.name) && CharOperation.equals(new char[][]{IOTConstants.CONFINED}, interfaceNames)) { |
| // avoid Confined implements Confined (revert manual role splitting) |
| superclassName = null; |
| interfaceNames = null; |
| } |
| // filtering interface o.o.T.Confined is already done at the call site. |
| } |
| // SH} |
| typeInfo.nameSourceStart = isEnumInit ? typeDeclaration.allocation.enumConstant.sourceStart : typeDeclaration.sourceStart; |
| typeInfo.nameSourceEnd = sourceEnd(typeDeclaration); |
| typeInfo.superclass = superclassName; |
| typeInfo.superinterfaces = interfaceNames; |
| typeInfo.typeParameters = getTypeParameterInfos(typeDeclaration.typeParameters); |
| typeInfo.categories = (char[][]) this.nodesToCategories.get(typeDeclaration); |
| typeInfo.secondary = typeDeclaration.isSecondary(); |
| typeInfo.anonymousMember = typeDeclaration.allocation != null && typeDeclaration.allocation.enclosingInstance != null; |
| typeInfo.annotations = typeDeclaration.annotations; |
| typeInfo.extraFlags = ExtraFlags.getExtraFlags(typeDeclaration); |
| typeInfo.node = typeDeclaration; |
| //{ObjectTeams: added baseclass reference, isRoleFile: |
| typeInfo.baseclassName = baseclassName; // yes, interfaces will have a baseclass, too. (Current compiler limitation though). |
| typeInfo.baseclassAnchor = baseclassAnchor; |
| typeInfo.isRoleFile = typeDeclaration.isRoleFile(); |
| //haebor,km}); |
| this.requestor.enterType(typeInfo); |
| switch (kind) { |
| case TypeDeclaration.CLASS_DECL : |
| if (superclassName != null) |
| implicitSuperclassName = superclassName; |
| break; |
| case TypeDeclaration.INTERFACE_DECL : |
| implicitSuperclassName = TypeConstants.CharArray_JAVA_LANG_OBJECT; |
| break; |
| case TypeDeclaration.ENUM_DECL : |
| implicitSuperclassName = TypeConstants.CharArray_JAVA_LANG_ENUM; |
| break; |
| case TypeDeclaration.ANNOTATION_TYPE_DECL : |
| implicitSuperclassName = TypeConstants.CharArray_JAVA_LANG_ANNOTATION_ANNOTATION; |
| break; |
| } |
| } |
| if (this.nestedTypeIndex == this.typeNames.length) { |
| // need a resize |
| System.arraycopy(this.typeNames, 0, (this.typeNames = new char[this.nestedTypeIndex * 2][]), 0, this.nestedTypeIndex); |
| System.arraycopy(this.superTypeNames, 0, (this.superTypeNames = new char[this.nestedTypeIndex * 2][]), 0, this.nestedTypeIndex); |
| } |
| this.typeNames[this.nestedTypeIndex] = typeDeclaration.name; |
| this.superTypeNames[this.nestedTypeIndex++] = implicitSuperclassName; |
| } |
| while ((fieldIndex < fieldCounter) |
| || (memberTypeIndex < memberTypeCounter) |
| || (methodIndex < methodCounter) |
| // {ObjectTeams: treatment for method mappings |
| || (bindingIndex < bindingCount)) |
| // orig: |
| { |
| FieldDeclaration nextFieldDeclaration = null; |
| AbstractMethodDeclaration nextMethodDeclaration = null; |
| TypeDeclaration nextMemberDeclaration = null; |
| // :giro |
| AbstractMethodMappingDeclaration nextBindingDeclaration = null; |
| //ak} |
| |
| int position = Integer.MAX_VALUE; |
| int nextDeclarationType = -1; |
| if (fieldIndex < fieldCounter) { |
| nextFieldDeclaration = fields[fieldIndex]; |
| if (nextFieldDeclaration.declarationSourceStart < position) { |
| position = nextFieldDeclaration.declarationSourceStart; |
| nextDeclarationType = 0; // FIELD |
| } |
| } |
| if (methodIndex < methodCounter) { |
| nextMethodDeclaration = methods[methodIndex]; |
| if (nextMethodDeclaration.declarationSourceStart < position) { |
| position = nextMethodDeclaration.declarationSourceStart; |
| nextDeclarationType = 1; // METHOD |
| } |
| } |
| if (memberTypeIndex < memberTypeCounter) { |
| nextMemberDeclaration = memberTypes[memberTypeIndex]; |
| if (nextMemberDeclaration.declarationSourceStart < position) { |
| position = nextMemberDeclaration.declarationSourceStart; |
| nextDeclarationType = 2; // MEMBER |
| } |
| } |
| //{ObjectTeams: treatment for method mappings |
| if (bindingIndex < bindingCount) |
| { |
| nextBindingDeclaration = bindings[bindingIndex]; |
| if (nextBindingDeclaration.sourceStart < position) |
| { |
| position = nextBindingDeclaration.sourceStart; |
| nextDeclarationType = 3; // BINDING |
| } |
| } |
| //ak} |
| switch (nextDeclarationType) { |
| case 0 : |
| fieldIndex++; |
| //{ObjectTeams: don't convert _OT$.. fields: |
| if ( nextFieldDeclaration.name != null |
| && CharOperation.prefixEquals(IOTConstants.OT_DOLLAR_NAME, nextFieldDeclaration.name)) |
| break; |
| // SH} |
| notifySourceElementRequestor(nextFieldDeclaration, typeDeclaration); |
| break; |
| case 1 : |
| methodIndex++; |
| //{ObjectTeams: don't convert generated methods: |
| if (nextMethodDeclaration.isGenerated && !(nextMethodDeclaration instanceof GuardPredicateDeclaration)) |
| break; |
| // SH} |
| notifySourceElementRequestor(nextMethodDeclaration, typeDeclaration, currentPackage); |
| break; |
| case 2 : |
| memberTypeIndex++; |
| //{ObjectTeams: don't convert interface o.o.T.Confined: |
| if ( currentPackage != null && CharOperation.equals(IOTConstants.ORG_OBJECTTEAMS, currentPackage.tokens) |
| && CharOperation.equals(IOTConstants.TEAM, typeDeclaration.name) |
| && CharOperation.equals(IOTConstants.CONFINED, nextMemberDeclaration.name)) |
| break; |
| notifySourceElementRequestor(nextMemberDeclaration, true, null, currentPackage); |
| //{ObjectTeams: treatment for method mappings |
| break; |
| case 3: |
| bindingIndex++; |
| notifySourceElementRequestor(nextBindingDeclaration); |
| break; |
| //ak} |
| } |
| } |
| if (notifyTypePresence){ |
| if (isInRange){ |
| this.requestor.exitType(typeDeclaration.declarationSourceEnd); |
| } |
| this.nestedTypeIndex--; |
| } |
| } |
| /* |
| * Sort the given ast nodes by their positions. |
| */ |
| private static void quickSort(ASTNode[] sortedCollection, int left, int right) { |
| int original_left = left; |
| int original_right = right; |
| ASTNode mid = sortedCollection[left + (right - left) / 2]; |
| do { |
| while (sortedCollection[left].sourceStart < mid.sourceStart) { |
| left++; |
| } |
| while (mid.sourceStart < sortedCollection[right].sourceStart) { |
| right--; |
| } |
| if (left <= right) { |
| ASTNode tmp = sortedCollection[left]; |
| sortedCollection[left] = sortedCollection[right]; |
| sortedCollection[right] = tmp; |
| left++; |
| right--; |
| } |
| } while (left <= right); |
| if (original_left < right) { |
| quickSort(sortedCollection, original_left, right); |
| } |
| if (left < original_right) { |
| quickSort(sortedCollection, left, original_right); |
| } |
| } |
| private void reset() { |
| this.typeNames = new char[4][]; |
| this.superTypeNames = new char[4][]; |
| this.nestedTypeIndex = 0; |
| |
| this.sourceEnds = null; |
| } |
| private int sourceEnd(TypeDeclaration typeDeclaration) { |
| if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) { |
| QualifiedAllocationExpression allocation = typeDeclaration.allocation; |
| if (allocation.enumConstant != null) // case of enum constant body |
| return allocation.enumConstant.sourceEnd; |
| return allocation.type.sourceEnd; |
| } else { |
| return typeDeclaration.sourceEnd; |
| } |
| } |
| private void visitIfNeeded(AbstractMethodDeclaration method) { |
| if (this.localDeclarationVisitor != null |
| && (method.bits & ASTNode.HasLocalType) != 0) { |
| if (method instanceof ConstructorDeclaration) { |
| ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) method; |
| if (constructorDeclaration.constructorCall != null) { |
| constructorDeclaration.constructorCall.traverse(this.localDeclarationVisitor, method.scope); |
| } |
| } |
| if (method.statements != null) { |
| int statementsLength = method.statements.length; |
| for (int i = 0; i < statementsLength; i++) |
| method.statements[i].traverse(this.localDeclarationVisitor, method.scope); |
| } |
| } |
| } |
| |
| private void visitIfNeeded(FieldDeclaration field, TypeDeclaration declaringType) { |
| if (this.localDeclarationVisitor != null |
| && (field.bits & ASTNode.HasLocalType) != 0) { |
| if (field.initialization != null) { |
| try { |
| this.localDeclarationVisitor.pushDeclaringType(declaringType); |
| field.initialization.traverse(this.localDeclarationVisitor, (MethodScope) null); |
| } finally { |
| this.localDeclarationVisitor.popDeclaringType(); |
| } |
| } |
| } |
| } |
| |
| private void visitIfNeeded(Initializer initializer) { |
| if (this.localDeclarationVisitor != null |
| && (initializer.bits & ASTNode.HasLocalType) != 0) { |
| if (initializer.block != null) { |
| initializer.block.traverse(this.localDeclarationVisitor, null); |
| } |
| } |
| } |
| } |