Bug 86906 - [1.5][dom] SourceType#createField fails for enums
Summary: [1.5][dom] SourceType#createField fails for enums
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.1 M6   Edit
Assignee: David Audel CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-03-01 10:07 EST by Alexander Pavlov CLA
Modified: 2005-03-31 10:41 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alexander Pavlov CLA 2005-03-01 10:07:08 EST
(M5)
calling IType.createField(body, element, true, null);
results in this (in the Error Log):
java.lang.IllegalArgumentException: EnumDeclaration has no property 
bodyDeclarations
	at 
org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.validateHasChildProp
erty(RewriteEventStore.java:615)
	at org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.getEvent
(RewriteEventStore.java:296)
	at 
org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.getListEvent
(RewriteEventStore.java:325)
	at org.eclipse.jdt.core.dom.rewrite.ListRewrite.getEvent
(ListRewrite.java:56)
	at org.eclipse.jdt.core.dom.rewrite.ListRewrite.insertAfter
(ListRewrite.java:171)
	at 
org.eclipse.jdt.internal.core.CreateElementInCUOperation.insertASTNode
(CreateElementInCUOperation.java:257)
	at 
org.eclipse.jdt.internal.core.CreateElementInCUOperation.generateNewCompilationU
nitAST(CreateElementInCUOperation.java:184)
	at 
org.eclipse.jdt.internal.core.CreateElementInCUOperation.executeOperation
(CreateElementInCUOperation.java:137)
	at org.eclipse.jdt.internal.core.JavaModelOperation.run
(JavaModelOperation.java:710)
	at org.eclipse.core.internal.resources.Workspace.run
(Workspace.java:1702)
	at org.eclipse.jdt.internal.core.JavaModelOperation.runOperation
(JavaModelOperation.java:766)
	at org.eclipse.jdt.internal.core.SourceType.createField
(SourceType.java:117)

The cause seems to be located in 
org.eclipse.jdt.internal.core.CreateTypeMemberOperation:
protected StructuralPropertyDescriptor getChildPropertyDescriptor(ASTNode 
parent) {
	switch (parent.getNodeType()) {
		case ASTNode.COMPILATION_UNIT:
			return CompilationUnit.TYPES_PROPERTY;
		default:
			return TypeDeclaration.BODY_DECLARATIONS_PROPERTY;
	}
}
which obviously results in failures for EnumDeclarations and 
AnnotationTypeDeclarations. It might be a common issue to regard only 
TypeDeclaration and to not regard other AbstractTypeDeclaration subclasses.
Comment 1 Alexander Pavlov CLA 2005-03-01 10:55:34 EST
Additionally, when trying to create a method in an enum, the following occurs:

java.lang.IllegalArgumentException: EnumDeclaration has no property 
bodyDeclarations
	at 
org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.validateHasChildProp
erty(RewriteEventStore.java:615)
	at org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.getEvent
(RewriteEventStore.java:296)
	at 
org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.getListEvent
(RewriteEventStore.java:325)
	at org.eclipse.jdt.core.dom.rewrite.ListRewrite.getEvent
(ListRewrite.java:56)
	at org.eclipse.jdt.core.dom.rewrite.ListRewrite.internalInsertAt
(ListRewrite.java:283)
	at org.eclipse.jdt.core.dom.rewrite.ListRewrite.insertLast
(ListRewrite.java:248)
	at 
org.eclipse.jdt.internal.core.CreateElementInCUOperation.insertASTNode
(CreateElementInCUOperation.java:263)
	at 
org.eclipse.jdt.internal.core.CreateElementInCUOperation.generateNewCompilationU
nitAST(CreateElementInCUOperation.java:184)
	at 
org.eclipse.jdt.internal.core.CreateElementInCUOperation.executeOperation
(CreateElementInCUOperation.java:137)
	at org.eclipse.jdt.internal.core.JavaModelOperation.run
(JavaModelOperation.java:710)
	at org.eclipse.core.internal.resources.Workspace.run
(Workspace.java:1702)
	at org.eclipse.jdt.internal.core.JavaModelOperation.runOperation
(JavaModelOperation.java:766)
	at org.eclipse.jdt.internal.core.SourceType.createMethod
(SourceType.java:139)
Comment 2 David Audel CLA 2005-03-02 05:54:15 EST
Your diagnosis is exact, the problem is inside
CreateTypeMemberOperation#getChildPropertyDescriptor().

This method must be 

protected StructuralPropertyDescriptor getChildPropertyDescriptor(ASTNode parent) {
  switch (parent.getNodeType()) {
    case ASTNode.COMPILATION_UNIT:
      return CompilationUnit.TYPES_PROPERTY;
    case ASTNode.ENUM_DECLARATION:
      return EnumDeclaration.BODY_DECLARATIONS_PROPERTY;
    case ASTNode.ANNOTATION_TYPE_DECLARATION:
      return AnnotationTypeDeclaration.BODY_DECLARATIONS_PROPERTY;
    default:
      return TypeDeclaration.BODY_DECLARATIONS_PROPERTY;
  }
}


Fixed and test added
  CreateMembersTests#test002()
  CreateMembersTests#test003()
Comment 3 Alexander Pavlov CLA 2005-03-14 07:51:33 EST
Another issue has risen in the I200502171619. Consider this enum:

public enum MyEnum {
    VALUE1
}

We call createField("int someField=0;\n", null, true, null).
It fails because of the following intermediate search call to make the VALUE1 
enum constant declaration a sibling:
	SourceField.findNode(CompilationUnit) line: 40
	CreateFieldOperation(CreateElementInCUOperation).insertASTNode
(ASTRewrite, ASTNode, ASTNode) line: 255
	CreateFieldOperation
(CreateElementInCUOperation).generateNewCompilationUnitAST(ICompilationUnit) 
line: 184
	CreateFieldOperation(CreateElementInCUOperation).executeOperation() 
line: 137
	CreateFieldOperation(JavaModelOperation).run(IProgressMonitor) line: 710
	Workspace.run(IWorkspaceRunnable, ISchedulingRule, int, 
IProgressMonitor) line: 1702
	CreateFieldOperation(JavaModelOperation).runOperation(IProgressMonitor) 
line: 771
	SourceType.createField(String, IJavaElement, boolean, IProgressMonitor) 
line: 117

The reason is this: the SourceType method
public ASTNode findNode(org.eclipse.jdt.core.dom.CompilationUnit ast) {
	// For field declarations, a variable declaration fragment is returned
	// Return the FieldDeclaration instead
	ASTNode node = super.findNode(ast);
	if (node == null) return null;
	return node.getParent();
}

does find the EnumConstantDeclaration but does not return one, taking its 
parent (i.e. EnumDeclaration) as the final result. A check should be made to 
handle the enum constant case properly and return the constant declaration 
itself, not its parent node (something like

if (node instanceof VariableDeclarationFragment) {
    return node.getParent();
}
else {
    return node;
}

).
Comment 4 David Audel CLA 2005-03-17 06:41:23 EST
This bug is not the same. I create another bug report (bug 88312) and close the
current bug.
Comment 5 David Audel CLA 2005-03-31 10:41:40 EST
Verified in I20050330-0500