List of usage examples for org.eclipse.jdt.internal.compiler.ast TypeDeclaration createDefaultConstructor
public ConstructorDeclaration createDefaultConstructor(boolean needExplicitConstructorCall, boolean needToInsert)
From source file:com.codenvy.ide.ext.java.server.internal.compiler.parser.SourceTypeConverter.java
License:Open Source License
private TypeDeclaration convert(SourceType typeHandle, CompilationResult compilationResult) throws JavaModelException { SourceTypeElementInfo typeInfo = (SourceTypeElementInfo) typeHandle.getElementInfo(); if (typeInfo.isAnonymousMember()) throw new AnonymousMemberFound(); /* create type declaration - can be member type */ TypeDeclaration type = new TypeDeclaration(compilationResult); if (typeInfo.getEnclosingType() == null) { if (typeHandle.isAnonymous()) { type.name = CharOperation.NO_CHAR; type.bits |= (ASTNode.IsAnonymousType | ASTNode.IsLocalType); } else {//from w ww . j a v a 2s.c o m if (typeHandle.isLocal()) { type.bits |= ASTNode.IsLocalType; } } } else { type.bits |= ASTNode.IsMemberType; } if ((type.bits & ASTNode.IsAnonymousType) == 0) { type.name = typeInfo.getName(); } type.name = typeInfo.getName(); int start, end; // only positions available type.sourceStart = start = typeInfo.getNameSourceStart(); type.sourceEnd = end = typeInfo.getNameSourceEnd(); type.modifiers = typeInfo.getModifiers(); type.declarationSourceStart = typeInfo.getDeclarationSourceStart(); type.declarationSourceEnd = typeInfo.getDeclarationSourceEnd(); type.bodyEnd = type.declarationSourceEnd; // convert 1.5 specific constructs only if compliance is 1.5 or above if (this.has1_5Compliance) { /* convert annotations */ type.annotations = convertAnnotations(typeHandle); } /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, even in a 1.4 project, we must internalize type variables and observe any parameterization of super class and/or super interfaces in order to be able to detect overriding in the presence of generics. */ char[][] typeParameterNames = typeInfo.getTypeParameterNames(); if (typeParameterNames.length > 0) { int parameterCount = typeParameterNames.length; char[][][] typeParameterBounds = typeInfo.getTypeParameterBounds(); type.typeParameters = new TypeParameter[parameterCount]; for (int i = 0; i < parameterCount; i++) { type.typeParameters[i] = createTypeParameter(typeParameterNames[i], typeParameterBounds[i], start, end); } } /* set superclass and superinterfaces */ if (typeInfo.getSuperclassName() != null) { type.superclass = createTypeReference(typeInfo.getSuperclassName(), start, end, true /* include generics */); type.superclass.bits |= ASTNode.IsSuperType; } char[][] interfaceNames = typeInfo.getInterfaceNames(); int interfaceCount = interfaceNames == null ? 0 : interfaceNames.length; if (interfaceCount > 0) { type.superInterfaces = new TypeReference[interfaceCount]; for (int i = 0; i < interfaceCount; i++) { type.superInterfaces[i] = createTypeReference(interfaceNames[i], start, end, true /* include generics */); type.superInterfaces[i].bits |= ASTNode.IsSuperType; } } /* convert member types */ if ((this.flags & MEMBER_TYPE) != 0) { SourceType[] sourceMemberTypes = typeInfo.getMemberTypeHandles(); int sourceMemberTypeCount = sourceMemberTypes.length; type.memberTypes = new TypeDeclaration[sourceMemberTypeCount]; for (int i = 0; i < sourceMemberTypeCount; i++) { type.memberTypes[i] = convert(sourceMemberTypes[i], compilationResult); type.memberTypes[i].enclosingType = type; } } /* convert intializers and fields*/ InitializerElementInfo[] initializers = null; int initializerCount = 0; if ((this.flags & LOCAL_TYPE) != 0) { initializers = typeInfo.getInitializers(); initializerCount = initializers.length; } SourceField[] sourceFields = null; int sourceFieldCount = 0; if ((this.flags & FIELD) != 0) { sourceFields = typeInfo.getFieldHandles(); sourceFieldCount = sourceFields.length; } int length = initializerCount + sourceFieldCount; if (length > 0) { type.fields = new FieldDeclaration[length]; for (int i = 0; i < initializerCount; i++) { type.fields[i] = convert(initializers[i], compilationResult); } int index = 0; for (int i = initializerCount; i < length; i++) { type.fields[i] = convert(sourceFields[index++], type, compilationResult); } } /* convert methods - need to add default constructor if necessary */ boolean needConstructor = (this.flags & CONSTRUCTOR) != 0; boolean needMethod = (this.flags & METHOD) != 0; if (needConstructor || needMethod) { SourceMethod[] sourceMethods = typeInfo.getMethodHandles(); int sourceMethodCount = sourceMethods.length; /* source type has a constructor ? */ /* by default, we assume that one is needed. */ int extraConstructor = 0; int methodCount = 0; int kind = TypeDeclaration.kind(type.modifiers); boolean isAbstract = kind == TypeDeclaration.INTERFACE_DECL || kind == TypeDeclaration.ANNOTATION_TYPE_DECL; if (!isAbstract) { extraConstructor = needConstructor ? 1 : 0; for (int i = 0; i < sourceMethodCount; i++) { if (sourceMethods[i].isConstructor()) { if (needConstructor) { extraConstructor = 0; // Does not need the extra constructor since one constructor already exists. methodCount++; } } else if (needMethod) { methodCount++; } } } else { methodCount = needMethod ? sourceMethodCount : 0; } type.methods = new AbstractMethodDeclaration[methodCount + extraConstructor]; if (extraConstructor != 0) { // add default constructor in first position type.methods[0] = type.createDefaultConstructor(false, false); } int index = 0; boolean hasAbstractMethods = false; for (int i = 0; i < sourceMethodCount; i++) { SourceMethod sourceMethod = sourceMethods[i]; SourceMethodElementInfo methodInfo = (SourceMethodElementInfo) sourceMethod.getElementInfo(); boolean isConstructor = methodInfo.isConstructor(); if ((methodInfo.getModifiers() & ClassFileConstants.AccAbstract) != 0) { hasAbstractMethods = true; } if ((isConstructor && needConstructor) || (!isConstructor && needMethod)) { AbstractMethodDeclaration method = convert(sourceMethod, methodInfo, compilationResult); if (isAbstract || method.isAbstract()) { // fix-up flag method.modifiers |= ExtraCompilerModifiers.AccSemicolonBody; } type.methods[extraConstructor + index++] = method; } } if (hasAbstractMethods) type.bits |= ASTNode.HasAbstractMethods; } return type; }
From source file:com.codenvy.ide.ext.java.server.internal.core.BinaryTypeConverter.java
License:Open Source License
private TypeDeclaration convert(IType type, IType alreadyComputedMember, TypeDeclaration alreadyComputedMemberDeclaration) throws JavaModelException { /* create type declaration - can be member type */ TypeDeclaration typeDeclaration = new TypeDeclaration(this.compilationResult); if (type.getDeclaringType() != null) { typeDeclaration.bits |= ASTNode.IsMemberType; }//w ww.ja v a2 s.c o m typeDeclaration.name = type.getElementName().toCharArray(); typeDeclaration.modifiers = type.getFlags(); /* set superclass and superinterfaces */ if (type.getSuperclassName() != null) { TypeReference typeReference = createTypeReference(type.getSuperclassTypeSignature()); if (typeReference != null) { typeDeclaration.superclass = typeReference; typeDeclaration.superclass.bits |= ASTNode.IsSuperType; } } String[] interfaceTypes = type.getSuperInterfaceTypeSignatures(); int interfaceCount = interfaceTypes == null ? 0 : interfaceTypes.length; typeDeclaration.superInterfaces = new TypeReference[interfaceCount]; int count = 0; for (int i = 0; i < interfaceCount; i++) { TypeReference typeReference = createTypeReference(interfaceTypes[i]); if (typeReference != null) { typeDeclaration.superInterfaces[count] = typeReference; typeDeclaration.superInterfaces[count++].bits |= ASTNode.IsSuperType; } } if (count != interfaceCount) { System.arraycopy(typeDeclaration.fields, 0, typeDeclaration.superInterfaces = new TypeReference[interfaceCount], 0, interfaceCount); } // convert 1.5 specific constructs only if compliance is 1.5 or above if (this.has1_5Compliance) { /* convert type parameters */ ITypeParameter[] typeParameters = type.getTypeParameters(); if (typeParameters != null && typeParameters.length > 0) { int parameterCount = typeParameters.length; org.eclipse.jdt.internal.compiler.ast.TypeParameter[] typeParams = new org.eclipse.jdt.internal.compiler.ast.TypeParameter[parameterCount]; for (int i = 0; i < parameterCount; i++) { ITypeParameter typeParameter = typeParameters[i]; typeParams[i] = createTypeParameter(typeParameter.getElementName().toCharArray(), stringArrayToCharArray(typeParameter.getBounds()), 0, 0); } typeDeclaration.typeParameters = typeParams; } } /* convert member types */ IType[] memberTypes = type.getTypes(); int memberTypeCount = memberTypes == null ? 0 : memberTypes.length; typeDeclaration.memberTypes = new TypeDeclaration[memberTypeCount]; for (int i = 0; i < memberTypeCount; i++) { if (alreadyComputedMember != null && alreadyComputedMember.getFullyQualifiedName() .equals(memberTypes[i].getFullyQualifiedName())) { typeDeclaration.memberTypes[i] = alreadyComputedMemberDeclaration; } else { typeDeclaration.memberTypes[i] = convert(memberTypes[i], null, null); } typeDeclaration.memberTypes[i].enclosingType = typeDeclaration; } /* convert fields */ IField[] fields = type.getFields(); int fieldCount = fields == null ? 0 : fields.length; typeDeclaration.fields = new FieldDeclaration[fieldCount]; count = 0; for (int i = 0; i < fieldCount; i++) { FieldDeclaration fieldDeclaration = convert(fields[i], type); if (fieldDeclaration != null) { typeDeclaration.fields[count++] = fieldDeclaration; } } if (count != fieldCount) { System.arraycopy(typeDeclaration.fields, 0, typeDeclaration.fields = new FieldDeclaration[count], 0, count); } /* convert methods - need to add default constructor if necessary */ IMethod[] methods = type.getMethods(); int methodCount = methods == null ? 0 : methods.length; /* source type has a constructor ? */ /* by default, we assume that one is needed. */ int neededCount = 1; for (int i = 0; i < methodCount; i++) { if (methods[i].isConstructor()) { neededCount = 0; // Does not need the extra constructor since one constructor already exists. break; } } boolean isInterface = type.isInterface(); neededCount = isInterface ? 0 : neededCount; typeDeclaration.methods = new AbstractMethodDeclaration[methodCount + neededCount]; if (neededCount != 0) { // add default constructor in first position typeDeclaration.methods[0] = typeDeclaration.createDefaultConstructor(false, false); } boolean hasAbstractMethods = false; count = 0; for (int i = 0; i < methodCount; i++) { AbstractMethodDeclaration method = convert(methods[i], type); if (method != null) { boolean isAbstract; if ((isAbstract = method.isAbstract()) || isInterface) { // fix-up flag method.modifiers |= ExtraCompilerModifiers.AccSemicolonBody; } if (isAbstract) { hasAbstractMethods = true; } typeDeclaration.methods[neededCount + (count++)] = method; } } if (count != methodCount) { System.arraycopy(typeDeclaration.methods, 0, typeDeclaration.methods = new AbstractMethodDeclaration[count + neededCount], 0, count + neededCount); } if (hasAbstractMethods) { typeDeclaration.bits |= ASTNode.HasAbstractMethods; } return typeDeclaration; }
From source file:com.google.gwt.dev.javac.GwtIncompatiblePreprocessor.java
License:Apache License
/** * Removes all members of a class to leave it as an empty stub. *///from ww w .j a v a 2 s . co m private static void stripAllMembers(TypeDeclaration tyDecl) { tyDecl.superclass = null; tyDecl.superInterfaces = new TypeReference[0]; tyDecl.annotations = new Annotation[0]; tyDecl.methods = new AbstractMethodDeclaration[0]; tyDecl.memberTypes = new TypeDeclaration[0]; tyDecl.fields = new FieldDeclaration[0]; if (TypeDeclaration.kind(tyDecl.modifiers) != TypeDeclaration.INTERFACE_DECL && TypeDeclaration.kind(tyDecl.modifiers) != TypeDeclaration.ENUM_DECL) { // Create a default constructor so that the class is proper. ConstructorDeclaration constructor = tyDecl.createDefaultConstructor(true, true); // Mark only constructor as private so that it can not be instantiated. constructor.modifiers = ClassFileConstants.AccPrivate; // Clear a bit that is used for marking the constructor as default as it makes JDT // assume that the constructor is public. constructor.bits &= ~ASTNode.IsDefaultConstructor; // Mark the class as final so that it can not be extended. tyDecl.modifiers |= ClassFileConstants.AccFinal; tyDecl.modifiers &= ~ClassFileConstants.AccAbstract; } }
From source file:lombok.eclipse.handlers.HandleSuperBuilder.java
License:Open Source License
private EclipseNode generateBuilderAbstractClass(EclipseNode tdParent, String builderClass, TypeReference superclassBuilderClass, TypeParameter[] typeParams, ASTNode source, String classGenericName, String builderGenericName) { TypeDeclaration parent = (TypeDeclaration) tdParent.get(); TypeDeclaration builder = new TypeDeclaration(parent.compilationResult); builder.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG; builder.modifiers |= ClassFileConstants.AccPublic | ClassFileConstants.AccStatic | ClassFileConstants.AccAbstract; builder.name = builderClass.toCharArray(); // Keep any type params of the annotated class. builder.typeParameters = Arrays.copyOf(copyTypeParams(typeParams, source), typeParams.length + 2); // Add builder-specific type params required for inheritable builders. // 1. The return type for the build() method, named "C", which extends the annotated class. TypeParameter o = new TypeParameter(); o.name = classGenericName.toCharArray(); o.type = cloneSelfType(tdParent, source); builder.typeParameters[builder.typeParameters.length - 2] = o; // 2. The return type for all setter methods, named "B", which extends this builder class. o = new TypeParameter(); o.name = builderGenericName.toCharArray(); TypeReference[] typerefs = appendBuilderTypeReferences(typeParams, classGenericName, builderGenericName); o.type = new ParameterizedSingleTypeReference(builderClass.toCharArray(), typerefs, 0, 0); builder.typeParameters[builder.typeParameters.length - 1] = o; builder.superclass = copyType(superclassBuilderClass, source); builder.createDefaultConstructor(false, true); builder.traverse(new SetGeneratedByVisitor(source), (ClassScope) null); return injectType(tdParent, builder); }
From source file:lombok.eclipse.handlers.HandleSuperBuilder.java
License:Open Source License
private EclipseNode generateBuilderImplClass(EclipseNode tdParent, String builderImplClass, String builderAbstractClass, TypeParameter[] typeParams, ASTNode source) { TypeDeclaration parent = (TypeDeclaration) tdParent.get(); TypeDeclaration builder = new TypeDeclaration(parent.compilationResult); builder.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG; builder.modifiers |= ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic | ClassFileConstants.AccFinal; builder.name = builderImplClass.toCharArray(); // Add type params if there are any. if (typeParams != null && typeParams.length > 0) builder.typeParameters = copyTypeParams(typeParams, source); if (builderAbstractClass != null) { // Extend the abstract builder. // 1. Add any type params of the annotated class. TypeReference[] typeArgs = new TypeReference[typeParams.length + 2]; for (int i = 0; i < typeParams.length; i++) { typeArgs[i] = new SingleTypeReference(typeParams[i].name, 0); }//from w w w . j av a 2 s. co m // 2. The return type for the build() method (named "C" in the abstract builder), which is the annotated class. // 3. The return type for all setter methods (named "B" in the abstract builder), which is this builder class. typeArgs[typeArgs.length - 2] = cloneSelfType(tdParent, source); typeArgs[typeArgs.length - 1] = createTypeReferenceWithTypeParameters(builderImplClass, typeParams); builder.superclass = new ParameterizedSingleTypeReference(builderAbstractClass.toCharArray(), typeArgs, 0, 0); } builder.createDefaultConstructor(false, true); builder.traverse(new SetGeneratedByVisitor(source), (ClassScope) null); return injectType(tdParent, builder); }
From source file:org.eclipse.jdt.internal.compiler.parser.Parser.java
License:Open Source License
protected void consumeClassDeclaration() { // ClassDeclaration ::= ClassHeader ClassBody int length;/* w ww . j a v a 2s .com*/ if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) { //there are length declarations //dispatch according to the type of the declarations dispatchDeclarationInto(length); } TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr]; //convert constructor that do not have the type's name into methods boolean hasConstructor = typeDecl.checkConstructors(this); //add the default constructor when needed (interface don't have it) if (!hasConstructor) { switch (TypeDeclaration.kind(typeDecl.modifiers)) { case TypeDeclaration.CLASS_DECL: case TypeDeclaration.ENUM_DECL: boolean insideFieldInitializer = false; if (this.diet) { for (int i = this.nestedType; i > 0; i--) { if (this.variablesCounter[i] > 0) { insideFieldInitializer = true; break; } } } typeDecl.createDefaultConstructor(!this.diet || insideFieldInitializer, true); } } //always add <clinit> (will be remove at code gen time if empty) if (this.scanner.containsAssertKeyword) { typeDecl.bits |= ASTNode.ContainsAssertion; } typeDecl.addClinit(); typeDecl.bodyEnd = this.endStatementPosition; if (length == 0 && !containsComment(typeDecl.bodyStart, typeDecl.bodyEnd)) { typeDecl.bits |= ASTNode.UndocumentedEmptyBlock; } typeDecl.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition); }
From source file:org.eclipse.jdt.internal.compiler.parser.Parser.java
License:Open Source License
protected void consumeEnumDeclaration() { // EnumDeclaration ::= EnumHeader ClassHeaderImplementsopt EnumBody int length;/*w w w. j av a 2s .c o m*/ if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) { //there are length declarations //dispatch according to the type of the declarations dispatchDeclarationIntoEnumDeclaration(length); } TypeDeclaration enumDeclaration = (TypeDeclaration) this.astStack[this.astPtr]; //convert constructor that do not have the type's name into methods boolean hasConstructor = enumDeclaration.checkConstructors(this); //add the default constructor when needed if (!hasConstructor) { boolean insideFieldInitializer = false; if (this.diet) { for (int i = this.nestedType; i > 0; i--) { if (this.variablesCounter[i] > 0) { insideFieldInitializer = true; break; } } } enumDeclaration.createDefaultConstructor(!this.diet || insideFieldInitializer, true); } //always add <clinit> (will be remove at code gen time if empty) if (this.scanner.containsAssertKeyword) { enumDeclaration.bits |= ASTNode.ContainsAssertion; } enumDeclaration.addClinit(); enumDeclaration.bodyEnd = this.endStatementPosition; if (length == 0 && !containsComment(enumDeclaration.bodyStart, enumDeclaration.bodyEnd)) { enumDeclaration.bits |= ASTNode.UndocumentedEmptyBlock; } enumDeclaration.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition); }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.control.Dependencies.java
License:Open Source License
private static void createCtorsAndCreators(RoleModel clazz, TypeDeclaration teamType, TypeDeclaration subRoleDecl, SourceTypeBinding subTeam) { // ensure we have all constructors from tsuper (incl. default ctor) for (ReferenceBinding tsuperRole : clazz.getTSuperRoleBindings()) ensureBindingState(tsuperRole, ITranslationStates.STATE_METHODS_CREATED); CopyInheritance.copyGeneratedFeatures(clazz); boolean needMethodBodies = needMethodBodies(subRoleDecl); AbstractMethodDeclaration[] methodDeclarations = subRoleDecl.methods; // may need to create default constructor first: boolean hasConstructor = false; if (methodDeclarations != null) for (int i = 0; i < methodDeclarations.length; i++) if (methodDeclarations[i].isConstructor() && !TSuperHelper.isTSuper(methodDeclarations[i].binding)) { hasConstructor = true;//from w ww. j a v a2 s . c o m break; } if (!hasConstructor) { ConstructorDeclaration defCtor = subRoleDecl.createDefaultConstructor(needMethodBodies, false); AstEdit.addMethod(subRoleDecl, defCtor); CopyInheritance.connectDefaultCtor(clazz, defCtor.binding); methodDeclarations = subRoleDecl.methods; } // now the creation methods for all constructors: if (methodDeclarations != null) { for (int i = 0; i < methodDeclarations.length; i++) { if (methodDeclarations[i].isConstructor()) { ConstructorDeclaration constructor = (ConstructorDeclaration) methodDeclarations[i]; MethodDeclaration creator = CopyInheritance.createCreationMethod(teamType, clazz, constructor, constructor.binding, needMethodBodies); if (creator != null && !creator.ignoreFurtherInvestigation) { CopyInheritance.createCreatorIfcPart(subTeam, creator); subTeam.resolveGeneratedMethod(creator.binding); // this also wraps the signature using wrapTypesInMethodDeclSignature } } } } }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.copyinheritance.CopyInheritance.java
License:Open Source License
/** * Copy a given method to the tsub-role. * Adds the new method to AST and performs initial creation of bindings. * @param method method to copy/*from w w w. j a v a 2s .c o m*/ * @param targetRoleDecl target role class */ private static void copyMethod(MethodBinding method, TypeDeclaration targetRoleDecl) { boolean wasSynthetic = false; ReferenceBinding site = null; if ((method.modifiers & AccSynthetic) != 0) { wasSynthetic = true; // some, but not all, synthetics shall be generated with strong signatures as indicated by 'site': if (!SyntheticBaseCallSurrogate.isBaseCallSurrogateName(method.selector)) site = targetRoleDecl.binding; if (SyntheticRoleBridgeMethodBinding.isPrivateBridgeSelector(method.selector)) return; // will be generated anew } if (TypeContainerMethod.isTypeContainer(method)) return; // don't copy these dummy methods if (isCreator(method) || CharOperation.equals(IOTConstants._OT_GETBASE, method.selector) || CharOperation.prefixEquals(IOTConstants.CAST_PREFIX, method.selector) || CharOperation.prefixEquals(IOTConstants.GET_CLASS_PREFIX, method.selector)) return; // create/getBase/cast/getClass-methods are generated anew in each team. // (can only happen in a team that is a role of an outer team.) // Note: we don't use AccSynthetic on creators, because // Synthetic methods are not read from byte code. // FIXME(SH): this last note is not true any more. if (targetRoleDecl.isTeam() && (ReflectionGenerator.isReflectionMethod(method) || SerializationGenerator.isSerializationMethod(method))) return; if (MethodModel.isFakedMethod(method)) return; // will be generated anew (basecall-surrogate, rolefield-bridge) if (CharOperation.equals(IOTConstants.MIGRATE_TO_TEAM, method.selector)) return; // can only be used from the exact team // avoid copying twice (see copyGeneratedFeatures()): targetRoleDecl.getRoleModel().recordCopiedFeature(method); // some useful objects: ReferenceBinding srcRole = method.declaringClass; TypeDeclaration targetTeamDecl = targetRoleDecl.enclosingType; ReferenceBinding srcTeam = TeamModel.getEnclosingTeam(srcRole); ReferenceBinding tgtTeam = targetTeamDecl.binding; MethodBinding origin = (method.copyInheritanceSrc != null) ? method.copyInheritanceSrc : method; AbstractMethodDeclaration methodFound = findMethod(srcTeam, method, tgtTeam, targetRoleDecl); if (method.isConstructor()) { if (CharOperation.equals(srcRole.compoundName, IOTConstants.ORG_OBJECTTEAMS_TEAM_OTCONFINED)) { // must add default constructor explicitly, // since if we would copy the one from Team.__OT__Confined, // it would invoke the wrong super(). ConstructorDeclaration ctor = targetRoleDecl.createDefaultConstructor(true, true); targetRoleDecl.binding.resolveGeneratedMethod(ctor, false, origin); return; } else if (targetRoleDecl.getRoleModel()._refinesExtends) { // even if we can't copy the ctor, we need to mark // the current ctor as overriding the tsuper version. if (methodFound != null) methodFound.binding.addOverriddenTSuper(method); return; // extends is covariantly redefined, don't copy ctor! // attempts to invoke this tsuper ctor are caught in ExplicitConstructorCall.resolve(). } } // If method already exists in subteam, // + adjust method in subteam to the more general signature (here) // + extend copy with marker arg (below). // else give an exact copy. boolean reuseFoundMethod = false; if (methodFound != null) { // do not touch broken methods: // (methodFound might have no binding, // e.g., due to a missing import of return-type) if (methodFound.binding == null) return; if (methodFound.binding.copyInheritanceSrc == origin) return; // diamond inheritance: copying the same method from two different sources // tsuper method trumps previously inferred callout: if (methodFound.isMappingWrapper == WrapperKind.CALLOUT) { MethodModel model = methodFound.model; if (model != null && model._inferredCallout != null) { // reset callout related stuff: methodFound.isMappingWrapper = WrapperKind.NONE; model._inferredCallout = null; methodFound.statements = null; // setup as a copied method: methodFound.isCopied = true; methodFound.binding.copyInheritanceSrc = method; methodFound.sourceMethodBinding = method; reuseFoundMethod = true; } } // do this in any case so that ConstantPoolObjectMapper won't fail: methodFound.binding.addOverriddenTSuper(method); // abstract methods have no byte code to copy; // new method silently replaces abstract version: if (method.isAbstract()) { weakenSignature(methodFound, method); return; } if (method.isFinal()) { methodFound.scope.problemReporter().finalMethodCannotBeOverridden(methodFound.binding, method); return; } weakenSignature(methodFound, method); MethodBinding foundSrc = methodFound.binding.copyInheritanceSrc; if (foundSrc != null && foundSrc != origin) { // found a copied method which has a different origin, choose the more specific: // if incommensurable prefer the new copy (assuming it comes from *implicit* super team) if (!TeamModel.isMoreSpecificThan(foundSrc.declaringClass, origin.declaringClass)) { // more specific method overwrites previous linkage: methodFound.binding.setCopyInheritanceSrc(origin); methodFound.sourceMethodBinding = origin; methodFound.isTSuper = TSuperHelper.isTSuper(method); // TODO(SH): also update CopyInheritanceSrc-Attribute! if (!method.isAbstract()) { // not abstract any more, joining abstract and implemented methods: methodFound.modifiers &= ~(AccAbstract | AccSemicolonBody); methodFound.binding.modifiers &= ~(AccAbstract | AccSemicolonBody); // TODO(SH): might need multiple copyInheritanceSrc! // TODO(SH) need to adjust copiedInContext? } } return; } } AstGenerator gen = new AstGenerator(targetRoleDecl.sourceStart, targetRoleDecl.sourceEnd); gen.replaceableEnclosingClass = tgtTeam; final AbstractMethodDeclaration newMethodDecl; if (methodFound != null && reuseFoundMethod) { newMethodDecl = methodFound; } else { newMethodDecl = AstConverter.createMethod(method, site, targetRoleDecl.compilationResult, DecapsulationState.REPORTED, gen); if (methodFound != null) TSuperHelper.addMarkerArg(newMethodDecl, srcTeam); if (newMethodDecl.isConstructor()) { // comments (SH): // other phases may depend on this field (constructorCall) being set, // although it carries no real information. ConstructorDeclaration cd = (ConstructorDeclaration) newMethodDecl; cd.constructorCall = SuperReference.implicitSuperConstructorCall(); if (Lifting.isLiftingCtor(method) && method.parameters[0].isRole()) { // if baseclass is implicitely redefined use the strong type: ReferenceBinding newBase = targetRoleDecl.binding.baseclass(); if (TypeBinding.notEquals(newBase, method.parameters[0])) newMethodDecl.arguments[0].type = gen.baseclassReference(newBase); } } AstEdit.addMethod(targetRoleDecl, newMethodDecl, wasSynthetic, false/*addToFront*/, origin); } if (method.isPrivate()) { newMethodDecl.binding.modifiers |= ExtraCompilerModifiers.AccLocallyUsed; // don't warn unused copied method } newMethodDecl.binding.copiedInContext = tgtTeam.enclosingType(); MethodModel newModel = MethodModel.getModel(newMethodDecl); newModel.addAttribute(CopyInheritanceSourceAttribute.copyInherSrcAttribute(origin, newModel)); if (wasSynthetic) targetRoleDecl.getRoleModel().addSyntheticMethodMapping(method, newMethodDecl.binding); if (method.isAnyCallin() && !method.isCallin()) // callin wrapper newMethodDecl.isMappingWrapper = WrapperKind.CALLIN; if (methodFound == null) { // copy down some more properties: if (TSuperHelper.isTSuper(method)) newMethodDecl.isTSuper = true; if (method.model != null && method.model.callinFlags != 0) MethodModel.addCallinFlag(newMethodDecl, method.model.callinFlags); if (method.isAnyCallin()) { TypeBinding inheritedSrcReturn = MethodModel.getReturnType(method); if (inheritedSrcReturn.isRole()) inheritedSrcReturn = RoleTypeCreator.maybeWrapUnqualifiedRoleType(inheritedSrcReturn, targetRoleDecl.binding); MethodModel.saveReturnType(newMethodDecl.binding, inheritedSrcReturn); } else { if (!method.isPublic() // non-public source-level class method? && !method.isConstructor() && !targetRoleDecl.isInterface() && !CharOperation.prefixEquals(IOTConstants.OT_DOLLAR_NAME, method.selector)) { MethodModel.getModel(newMethodDecl).storeModifiers(newMethodDecl.modifiers); } } // more checking: abstract method in non-abstract class? if (newMethodDecl.isAbstract() && (targetRoleDecl.modifiers & ClassFileConstants.AccAbstract) == 0) { targetRoleDecl.scope.problemReporter().setRechecker(new IProblemRechecker() { public boolean shouldBeReported(IrritantSet[] foundIrritants) { if (newMethodDecl.isAbstract()) // implemented by callout? return true; return false; // false alarm } }).abstractMethodMustBeImplemented(targetRoleDecl.binding, newMethodDecl.binding); } } }