| /********************************************************************** |
| * This file is part of "Object Teams Development Tooling"-Software |
| * |
| * Copyright 2003, 2010 Fraunhofer Gesellschaft, Munich, Germany, |
| * for its Fraunhofer Institute for Computer Architecture and Software |
| * Technology (FIRST), Berlin, Germany and Technical University Berlin, |
| * Germany. |
| * |
| * 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 |
| * $Id: AstConverter.java 23416 2010-02-03 19:59:31Z stephan $ |
| * |
| * Please visit http://www.eclipse.org/objectteams for updates and contact. |
| * |
| * Contributors: |
| * Fraunhofer FIRST - Initial API and implementation |
| * Technical University Berlin - Initial API and implementation |
| **********************************************************************/ |
| /** |
| * ObjectTeams Eclipse source extensions |
| * |
| * @author Markus Witte |
| * |
| * @date 17.09.2003 |
| */ |
| package org.eclipse.objectteams.otdt.internal.core.compiler.util; |
| |
| import java.util.Arrays; |
| |
| import org.eclipse.jdt.core.compiler.CharOperation; |
| import org.eclipse.jdt.internal.compiler.CompilationResult; |
| import org.eclipse.jdt.internal.compiler.ast.ASTNode; |
| import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; |
| import org.eclipse.jdt.internal.compiler.ast.Annotation; |
| import org.eclipse.jdt.internal.compiler.ast.Argument; |
| import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer; |
| import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; |
| import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration; |
| import org.eclipse.jdt.internal.compiler.ast.Expression; |
| import org.eclipse.jdt.internal.compiler.ast.Expression.DecapsulationState; |
| import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; |
| import org.eclipse.jdt.internal.compiler.ast.ImportReference; |
| import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; |
| import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression; |
| import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; |
| 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.impl.IntConstant; |
| import org.eclipse.jdt.internal.compiler.impl.StringConstant; |
| import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding; |
| import org.eclipse.jdt.internal.compiler.lookup.Binding; |
| import org.eclipse.jdt.internal.compiler.lookup.ElementValuePair; |
| import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; |
| import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; |
| import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; |
| import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; |
| import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; |
| import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; |
| import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding; |
| import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; |
| import org.eclipse.objectteams.otdt.core.compiler.IOTConstants; |
| import org.eclipse.objectteams.otdt.core.exceptions.InternalCompilerError; |
| import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.ConstantPoolObjectMapper; |
| import org.eclipse.objectteams.otdt.internal.core.compiler.control.ITranslationStates; |
| |
| /** |
| * Create AST-nodes from some other representation. |
| * |
| * @version $Id: AstConverter.java 23416 2010-02-03 19:59:31Z stephan $ |
| */ |
| public class AstConverter implements ClassFileConstants, ExtraCompilerModifiers, IOTConstants { |
| |
| static final char[] VALUE_ARG = "value".toCharArray(); //$NON-NLS-1$ |
| public static final char[] ROLE_ARG_NAME = "_OT$rolearg".toCharArray(); //$NON-NLS-1$ |
| |
| // ==== Mostly For RoleSplitting ==== |
| |
| /** |
| * Create the interface part of a role. Transfer superInterfaces from class part to interface. |
| * |
| * Only create AST, no bindings. |
| * |
| * @param teamDeclaration |
| * @param roleClassDeclaration |
| * @return the interface AST |
| */ |
| public static TypeDeclaration genRoleInterface(TypeDeclaration teamDeclaration, TypeDeclaration roleClassDeclaration) |
| { |
| TypeDeclaration typeDeclaration = |
| new TypeDeclaration(roleClassDeclaration.compilationResult); // same result as class part (might be role file) |
| // make it an interface, but clear Team and final flag if set. |
| // (there is no use in marking an interface as team: it has no member types!) |
| typeDeclaration.modifiers = (roleClassDeclaration.modifiers |
| | AccSynthIfc | AccRole) |
| & ~(AccTeam|AccFinal); |
| typeDeclaration.isGenerated = true; |
| typeDeclaration.name = roleClassDeclaration.name; |
| typeDeclaration.sourceStart = roleClassDeclaration.sourceStart; |
| typeDeclaration.sourceEnd = roleClassDeclaration.sourceEnd; |
| if (roleClassDeclaration.isRoleFile()) |
| AstEdit.addTypeDeclaration(roleClassDeclaration.compilationUnit, typeDeclaration); |
| |
| typeDeclaration.typeParameters= AstClone.copyTypeParameters(roleClassDeclaration.typeParameters); |
| |
| // transfer superInterfaces from class to interface: |
| if (roleClassDeclaration.superInterfaces != null) { |
| typeDeclaration.superInterfaces = roleClassDeclaration.superInterfaces; |
| roleClassDeclaration.superInterfaces = null; |
| } |
| TypeReference superClass= roleClassDeclaration.superclass; |
| if ( superClass != null |
| && superClass instanceof SingleTypeReference |
| && CharOperation.equals(((SingleTypeReference)superClass).token, IOTConstants.CONFINED)) |
| { |
| // if class extends Confined mark the role interface to extend __OT__Confined instead of Object. |
| AstGenerator gen= new AstGenerator(roleClassDeclaration.sourceStart, roleClassDeclaration.sourceEnd); |
| typeDeclaration.superclass= gen.singleTypeReference(IOTConstants.OTCONFINED); |
| } |
| return typeDeclaration; |
| } |
| |
| /** |
| * Compute the modifiers for an abstract method to be included in a role interface. |
| * |
| * @param modifiers modifiers of the method as it appears in the role class. |
| * @return modifiers |
| */ |
| static int computeIfcpartModifiers(int modifiers) { |
| return (modifiers |
| | AstGenerator.AccIfcMethod) |
| & ~(AccFinal|AccSynchronized|AccStrictfp|AccNative|AccDeprecated); |
| } |
| |
| // ==== For CopyInheritance: ==== |
| |
| public static AbstractMethodDeclaration createMethod( |
| MethodBinding methodBinding, |
| ReferenceBinding site, |
| CompilationResult compilationResult, |
| DecapsulationState decapsulation, |
| AstGenerator gen) |
| { |
| |
| if (methodBinding == null) |
| return null; |
| |
| AbstractMethodDeclaration abstractMethodDeclaration; |
| |
| if (CharOperation.equals(methodBinding.selector, TypeConstants.INIT)) { |
| ConstructorDeclaration constructorDeclaration = new ConstructorDeclaration(compilationResult); |
| constructorDeclaration.selector = site != null ? site.sourceName : methodBinding.declaringClass.sourceName; |
| abstractMethodDeclaration = constructorDeclaration; |
| } else { |
| MethodDeclaration methodDeclaration = new MethodDeclaration(compilationResult); |
| |
| // on these special methods see class header comment in CopyInheritance: |
| if ( CharOperation.prefixEquals(IOTConstants.CAST_PREFIX, methodBinding.selector) |
| || CharOperation.prefixEquals(IOTConstants._OT_LIFT_TO, methodBinding.selector)) |
| methodDeclaration.returnType = new SingleTypeReference(methodBinding.returnType.internalName(),0); |
| else |
| methodDeclaration.returnType = gen.typeReference(methodBinding.returnType); |
| |
| methodDeclaration.returnType.setBaseclassDecapsulation(decapsulation); |
| methodDeclaration.selector = methodBinding.selector; |
| TypeVariableBinding[] typeVariables= methodBinding.typeVariables(); |
| if (typeVariables != Binding.NO_TYPE_VARIABLES) { |
| TypeParameter[] parameters= new TypeParameter[typeVariables.length]; |
| for (int i = 0; i < typeVariables.length; i++) |
| parameters[i]= gen.typeParameter(typeVariables[i]); |
| methodDeclaration.typeParameters= parameters; |
| } |
| abstractMethodDeclaration = methodDeclaration; |
| } |
| gen.setMethodPositions(abstractMethodDeclaration); |
| |
| abstractMethodDeclaration.modifiers = methodBinding.modifiers & ~ClassFileConstants.AccSynthetic; |
| if (methodBinding.isAbstract()) |
| // AccSemicolonBody - flag does not exist in binary methods: |
| abstractMethodDeclaration.modifiers |= AccSemicolonBody; |
| abstractMethodDeclaration.arguments = createArguments(methodBinding.parameters, site, decapsulation, gen); |
| abstractMethodDeclaration.isCopied = true; |
| abstractMethodDeclaration.sourceMethodBinding=methodBinding; |
| |
| abstractMethodDeclaration.thrownExceptions = AstClone.copyExceptions(methodBinding, gen); |
| |
| return abstractMethodDeclaration; |
| } |
| |
| |
| public static FieldDeclaration createField( |
| FieldBinding fieldBinding, |
| TypeDeclaration roleDeclaration, |
| AstGenerator gen) |
| { |
| |
| if(fieldBinding==null) |
| return null; |
| |
| FieldDeclaration fieldDeclaration = new FieldDeclaration(); |
| fieldDeclaration.type = gen.typeReference(fieldBinding.type); |
| |
| fieldDeclaration.modifiers = (fieldBinding.modifiers &~ExtraCompilerModifiers.AccBlankFinal); // this modifier is not used on fieldDecl (AST), overlaps with AccReadOnly |
| fieldDeclaration.name = fieldBinding.name; |
| if (fieldBinding.copyInheritanceSrc != null) |
| fieldDeclaration.copyInheritanceSrc = fieldBinding.copyInheritanceSrc; |
| else |
| fieldDeclaration.copyInheritanceSrc = fieldBinding; |
| |
| AnnotationBinding[] annotBindings = fieldBinding.getAnnotations(); |
| if (annotBindings != Binding.NO_ANNOTATIONS) { |
| ProblemReporter pr = fieldBinding.isStatic() ? |
| roleDeclaration.staticInitializerScope.problemReporter() : |
| roleDeclaration.initializerScope.problemReporter(); |
| Annotation[] annotDecls = new Annotation[annotBindings.length]; |
| boolean hasAnnotationError = false; |
| for (int i = 0; i < annotBindings.length; i++) { |
| AnnotationBinding binding = annotBindings[i]; |
| ElementValuePair[] elementValuePairs = binding.getElementValuePairs(); |
| char[][] annotTypeName = binding.getAnnotationType().compoundName; |
| if (elementValuePairs == Binding.NO_ELEMENT_VALUE_PAIRS) { |
| annotDecls[i] = gen.markerAnnotation(annotTypeName); |
| } else { |
| int numPairs = elementValuePairs.length; |
| char[][] names = new char[numPairs][]; |
| Expression[] values = new Expression[numPairs]; |
| for (int j = 0; j<names.length; j++) { |
| names[j] = elementValuePairs[j].getName(); |
| Object elementValue = elementValuePairs[j].getValue(); |
| values[j] = annotationValues(elementValue, gen, pr); |
| } |
| if (values.length == 0 || values[0] == null) { |
| pr.unexpectedAnnotationStructure(annotTypeName, fieldBinding.name, gen.sourceStart, gen.sourceEnd); |
| hasAnnotationError = true; |
| } else |
| if ( numPairs == 1 |
| && CharOperation.equals(names[0], TypeConstants.VALUE)) { |
| annotDecls[i] = gen.singleMemberAnnotation(annotTypeName, values[0]); |
| } else { |
| annotDecls[i] = gen.normalAnnotation(annotTypeName, names, values); |
| } |
| } |
| } |
| if (!hasAnnotationError) |
| fieldDeclaration.annotations = annotDecls; |
| } |
| |
| //field initializations are copied using a RoleInitializationMethod |
| return fieldDeclaration; |
| } |
| |
| private static Expression annotationValues(Object elementValue, AstGenerator gen, ProblemReporter pr) { |
| if (elementValue instanceof Object[]) { |
| Object[] valuesArray = (Object[])elementValue; |
| ArrayInitializer arrayInit = new ArrayInitializer(); |
| arrayInit.expressions = new Expression[valuesArray.length]; |
| for (int k = 0; k<valuesArray.length; k++) { |
| arrayInit.expressions[k] = annotationValue(valuesArray[k], gen, pr); |
| if (arrayInit.expressions[k] == null) |
| return null; // error detected. |
| } |
| return arrayInit; |
| } else { |
| return annotationValue(elementValue, gen, pr); |
| } |
| } |
| |
| private static Expression annotationValue(Object elementValue, AstGenerator gen, ProblemReporter pr) { |
| if (elementValue instanceof StringConstant) |
| return gen.stringLiteral(((StringConstant)elementValue).stringValue().toCharArray()); |
| if (elementValue instanceof IntConstant) |
| return gen.intLiteral(((IntConstant)elementValue).intValue()); |
| if (elementValue instanceof FieldBinding) { |
| FieldBinding field = (FieldBinding) elementValue; |
| if (field.isStatic()) { |
| char[][] tokens = CharOperation.splitOn('.', field.declaringClass.readableName()); |
| tokens = CharOperation.arrayConcat(tokens, field.name); |
| return gen.qualifiedNameReference(tokens); |
| } |
| } |
| return null; |
| } |
| |
| public static TypeDeclaration createNestedType ( |
| char[] name, |
| int modifiers, |
| boolean isNestedType, |
| boolean isPurelyCopied, |
| TypeDeclaration teamDecl, |
| ReferenceBinding tsuperRole) |
| { |
| TypeDeclaration enclosingTypeDecl = teamDecl; |
| if (tsuperRole != null && isNestedType) |
| { |
| ReferenceBinding srcEnclosing = tsuperRole.enclosingType(); |
| // TODO (SH): recurse even more |
| TypeDeclaration[] members = enclosingTypeDecl.memberTypes; |
| if (members != null) |
| for (int i=0; i<members.length; i++) { |
| if (CharOperation.equals(members[i].name, srcEnclosing.internalName())) { |
| enclosingTypeDecl = members[i]; |
| break; |
| } |
| } |
| } |
| |
| TypeDeclaration nestedType = |
| new TypeDeclaration(enclosingTypeDecl.compilationResult); |
| nestedType.name = name; |
| nestedType.modifiers = modifiers; |
| nestedType.isGenerated = true; |
| nestedType.isPurelyCopied = isPurelyCopied; |
| int sStart = enclosingTypeDecl.sourceStart; |
| int sEnd = enclosingTypeDecl.sourceEnd; |
| if (enclosingTypeDecl.superclass != null) { |
| sStart = enclosingTypeDecl.superclass.sourceStart; |
| sEnd = enclosingTypeDecl.superclass.sourceEnd; |
| } |
| nestedType.declarationSourceStart = sStart; |
| nestedType.declarationSourceEnd = sEnd; |
| nestedType.sourceStart = sStart; |
| nestedType.sourceEnd = sEnd; |
| nestedType.bodyStart = sStart; |
| nestedType.bodyEnd = sEnd; |
| AstGenerator gen = new AstGenerator(sStart, sEnd); |
| if (tsuperRole != null && tsuperRole.isInterface()) { |
| ReferenceBinding superclass= tsuperRole.superclass(); |
| if (superclass != null && CharOperation.equals(superclass.internalName(), IOTConstants.OTCONFINED)) { |
| nestedType.superclass= gen.qualifiedTypeReference(IOTConstants.ORG_OBJECTTEAMS_TEAM_OTCONFINED); |
| nestedType.superclass.resolvedType= superclass; |
| } |
| } |
| |
| if (tsuperRole != null && tsuperRole.isLocalType()) { |
| nestedType.bits |= ASTNode.IsLocalType; |
| if (tsuperRole.isAnonymousType()) { |
| // have no name, need at least a super type |
| // (otherwise ClassScope.checkAndSetModifiers() will fail) |
| ReferenceBinding superType; |
| ReferenceBinding[] superIfcs = tsuperRole.superInterfaces(); |
| if (superIfcs != Binding.NO_SUPERINTERFACES) |
| superType = superIfcs[0]; |
| else |
| superType = tsuperRole.superclass(); |
| nestedType.allocation = new QualifiedAllocationExpression(); |
| nestedType.allocation.type = gen.typeReference(superType); |
| nestedType.allocation.anonymousType = nestedType; |
| } |
| AstEdit.addLocalTypeDeclaration(enclosingTypeDecl, nestedType); |
| } else { |
| AstEdit.addMemberTypeDeclaration(enclosingTypeDecl, nestedType); |
| } |
| |
| if (tsuperRole != null && tsuperRole.roleModel != null && tsuperRole.roleModel.isRoleFile()) { |
| // for role copied from a role file create an enclosing CUD to allow for |
| // late role catch-up of this phantom role. |
| ProblemReporter reporter = enclosingTypeDecl.scope.problemReporter(); |
| CompilationResult compilationResult= new CompilationResult("nofile".toCharArray(), 0, 0, 0); //$NON-NLS-1$ |
| CompilationUnitDeclaration cud = new CompilationUnitDeclaration(reporter, compilationResult, 0); |
| nestedType.compilationResult= compilationResult; |
| nestedType.compilationUnit = cud; |
| cud.types= new TypeDeclaration[] { nestedType }; |
| char[][] enclosingName = enclosingTypeDecl.binding.compoundName; |
| char[][] tokens= CharOperation.arrayConcat(enclosingName, nestedType.name); |
| long[] positions= new long[tokens.length]; |
| Arrays.fill(positions, 0L); |
| cud.currentPackage= new ImportReference(enclosingName, positions, false, ClassFileConstants.AccTeam); |
| } |
| |
| // Create TypeBindings for this type |
| enclosingTypeDecl.scope.addGeneratedType(nestedType); |
| |
| int state= enclosingTypeDecl.getModel().getState(); |
| if (enclosingTypeDecl.isTeam()) |
| state= enclosingTypeDecl.getTeamModel().getState(); |
| |
| // Create Type-Hierarchy? |
| nestedType.scope.connectTypeHierarchyForGenerated(state>=ITranslationStates.STATE_LENV_CONNECT_TYPE_HIERARCHY); |
| |
| |
| // don't set past the state of the enclosing team: |
| state = Math.min(state, ITranslationStates.STATE_LENV_CONNECT_TYPE_HIERARCHY); |
| |
| if (nestedType.getRoleModel() != null) |
| nestedType.getRoleModel().setState(state); |
| if (nestedType.isTeam() && nestedType.getTeamModel() != null) |
| nestedType.getTeamModel().setState(state); |
| |
| return nestedType; |
| } |
| |
| /** |
| * Create method arguments which match the given parameters. |
| * If a site is given, try to map all types to this new context. |
| * @param parameters |
| * @param site class for whose context types shall be adjusted, or null. |
| * @return an array of arguments names "arg<n>" with types according to parameters. |
| */ |
| private static Argument[] createArguments( |
| TypeBinding[] parameters, |
| ReferenceBinding site, |
| DecapsulationState decapsulation, |
| AstGenerator gen) |
| { |
| if(parameters==null || parameters.length == 0) |
| return null; |
| |
| int length=parameters.length; |
| Argument[] arguments = new Argument[length]; |
| |
| for(int i=0;i<length;i++){ |
| TypeBinding tb = parameters[i]; |
| if (site != null && (tb instanceof ReferenceBinding)) |
| tb = ConstantPoolObjectMapper.searchRoleClass((ReferenceBinding)tb, site); |
| TypeReference tr = gen.typeReference(tb); |
| tr.setBaseclassDecapsulation(decapsulation); |
| char[] bez = ("arg"+i).toCharArray(); // dummy argument names, don't have original names. //$NON-NLS-1$ |
| arguments[i] = new Argument(bez,0,tr,0); |
| |
| } |
| return arguments; |
| } |
| |
| /** If a generated method was copied from tsuper, adjust its flags and argument names, |
| * but leave its signature for true overriding. |
| * Thus copying generated methods does the job of signature weakening. |
| */ |
| public static MethodDeclaration findAndAdjustCopiedMethod( |
| TypeDeclaration teamDecl, |
| char[] methodName, |
| Argument[] arguments) |
| { |
| int argumentsCount = arguments == null ? 0 : arguments.length; |
| AbstractMethodDeclaration foundMethod = |
| TypeAnalyzer.findMethodDecl(teamDecl, methodName, argumentsCount); |
| if (foundMethod != null) |
| { |
| if (!foundMethod.isCopied) { |
| // could mean different things |
| if (!foundMethod.isGenerated) { |
| // it is a user defined method! |
| foundMethod.scope.problemReporter().overridingPredefined(foundMethod); |
| return null; |
| } |
| throw new InternalCompilerError("Generated methods conflicting with each other: "+new String(foundMethod.selector)); //$NON-NLS-1$ |
| } |
| foundMethod.isCopied = false; |
| foundMethod.isGenerated = true; |
| foundMethod.modifiers &= ~(AccAbstract|AccSemicolonBody); |
| for (int i = 0; i < argumentsCount; i++) { |
| foundMethod.arguments[i].updateName(arguments[i].name); |
| } |
| if (foundMethod.binding != null) { |
| foundMethod.binding.modifiers &= ~(AccAbstract); |
| if (foundMethod.binding.copyInheritanceSrc != null) { |
| // not directly copied any more but overriding a tsuper version: |
| foundMethod.binding.addOverriddenTSuper(foundMethod.binding.copyInheritanceSrc); |
| foundMethod.binding.setCopyInheritanceSrc(null); |
| } |
| } |
| return (MethodDeclaration)foundMethod; |
| } |
| return null; |
| } |
| |
| /** |
| * Create the declaration of a role method to be inserted into the role interface. |
| * @param typeDecl (only need the CompilationResult) |
| * @param classpartMethod |
| * @return the method AST |
| */ |
| public static MethodDeclaration genRoleIfcMethod(TypeDeclaration typeDecl, MethodDeclaration classpartMethod) { |
| MethodDeclaration newmethod = AstClone.copyMethod(typeDecl, classpartMethod, null/*AstGenerator*/); |
| // TODO (SH): AccNative is even illegal! |
| newmethod.modifiers = computeIfcpartModifiers(classpartMethod.modifiers); |
| classpartMethod.interfacePartMethod = newmethod; |
| return newmethod; |
| } |
| |
| /** |
| * Create the declaration of a role method to be inserted into the role interface. |
| * @param teamDecl |
| * @param classpartMethod |
| * @return the method AST |
| */ |
| public static MethodDeclaration genIfcMethodFromBinding(TypeDeclaration teamDecl, |
| MethodBinding classpartMethod, |
| AstGenerator gen) |
| { |
| MethodDeclaration newmethod = |
| new MethodDeclaration(teamDecl.compilationResult); |
| |
| newmethod.selector = classpartMethod.selector; |
| newmethod.modifiers = computeIfcpartModifiers(classpartMethod.modifiers); |
| // special case of copying cast method for non-public role: |
| if ( CharOperation.prefixEquals(IOTConstants.CAST_PREFIX, classpartMethod.selector) |
| && !((ReferenceBinding)classpartMethod.returnType).isPublic()) |
| { |
| newmethod.modifiers = AccProtected|AstGenerator.AccIfcMethod; // see StandardElementGenerator.getCastMethod(); |
| } |
| |
| newmethod.isGenerated = true; // don't try to parse it etc.. |
| // no position, created from binding, so use pre-set default location |
| gen.setMethodPositions(newmethod); |
| |
| newmethod.arguments = AstConverter.createArgumentsFromParameters(classpartMethod.parameters, gen); |
| |
| newmethod.returnType = gen.typeReference(classpartMethod.returnType); |
| |
| if (classpartMethod.typeVariables() != Binding.NO_TYPE_VARIABLES) { |
| TypeVariableBinding[] typeVarBindings = classpartMethod.typeVariables; |
| newmethod.typeParameters = new TypeParameter[typeVarBindings.length]; |
| for (int i = 0; i < typeVarBindings.length; i++) { |
| newmethod.typeParameters[i] = gen.typeParameter(typeVarBindings[i]); |
| } |
| } |
| |
| newmethod.thrownExceptions = AstClone.copyExceptions(classpartMethod, gen); |
| return newmethod; |
| } |
| |
| /** |
| * Create arguments from type bindings by assigning dummy names. |
| * @param parameters template for the new arguments. |
| * @return an array of new Arguments (named "arg<n>") |
| */ |
| public static Argument[] createArgumentsFromParameters(TypeBinding[] parameters, AstGenerator gen) { |
| if (parameters.length == 0) |
| return null; |
| Argument[] newArguments = new Argument[parameters.length]; |
| for (int a=0; a<parameters.length; a++) { |
| TypeBinding param = parameters[a]; |
| newArguments[a] = new Argument( |
| ("arg"+a).toCharArray(), //$NON-NLS-1$ |
| gen.pos, |
| gen.typeReference(param), |
| /*modifiers*/0); |
| } |
| return newArguments; |
| } |
| } |
| |
| //Markus Witte} |