Bug 68343 - IDOMType.setSuperInterfaces() with empty array has no impact on Interfaces
Summary: IDOMType.setSuperInterfaces() with empty array has no impact on Interfaces
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.0   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 3.0.1   Edit
Assignee: Jerome Lanneluc CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-06-23 13:43 EDT by Paul Elder CLA
Modified: 2004-09-06 10:41 EDT (History)
1 user (show)

See Also:


Attachments
JUnit plug-in test project illustrating defect (4.65 KB, application/x-zip-compressed)
2004-06-23 13:48 EDT, Paul Elder CLA
no flags Details
Proposed fixed version of DOMType.java (25.59 KB, application/octet-stream)
2004-06-23 13:51 EDT, Paul Elder CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Paul Elder CLA 2004-06-23 13:43:12 EDT
Attempting to remove all super interfaces from an interface via
IDOMType.setSuperInterfaces() has no effect.

The same code executed against a class represented by IDOMTYpe works.

A JUnit test case to illustrate and reproduce this defect is included below. It
was created with 3.0RC3.

The problem is in plugin org.eclipse.jdt.core, class
org.eclipse.jdt.internal.jdom.DOMType, method appendMemberDeclarationContents(),
line 347 (in 3.0RC3). The code is:

  if (isClass()) {
      // code handling classes elided...
  } else {
    if (getMask(MASK_TYPE_HAS_INTERFACES)) {
      // code handling interfaces that extend one or more others elided...
      // except for this snippet, which shows how classes that extend
      // no interfaces are handled... (lines 321 - 325)
        if (fImplementsRange[0] < 0) {
          buffer.append(' ');
        } else {
          buffer.append(fDocument, fInterfacesRange[1] + 1, fOpenBodyRange[0] -
fInterfacesRange[1] - 1);
        }

    } else {
**** THIS IS THE STATEMENT THAT INJECTS THE WRONG CODE, line 347 ****
      buffer.append(fDocument, fNameRange[1] + 1, fOpenBodyRange[0] -
fNameRange[1] - 1);
    }
  }

Comparing the code handling interfaces and classes suggests the block should be:

      if (fImplementsRange[0] < 0) {
        buffer.append(' ');
      } else {
        buffer.append(fDocument, fNameRange[1] + 1, fOpenBodyRange[0] -
fNameRange[1] - 1);
      }

Making this change results in correct behavior.

At this point, I do not have any workarounds. I am unable to switch to DOM/AST,
I am encountering the problem via EMF's JMerge facility. I have been unable to
develop work arounds at the JMerge level, either.

******************* Begin JUNIT TEST ********************

/*
 * Created on Jun 23, 2004
 */
package jdt.jdom.defects;

import junit.framework.TestCase;

import org.eclipse.jdt.core.jdom.DOMFactory;
import org.eclipse.jdt.core.jdom.IDOMCompilationUnit;
import org.eclipse.jdt.core.jdom.IDOMType;

/**
 * Demonstrate IDOMType.setSuperInterface defect when called with
 * an empty array as argument, and where the underlying object is
 * an Interface.
 */
public class DefectTests extends TestCase {

	public void testIDOMTYPE_SetSuperInterfaces_onInterface() {
		final String NL = System.getProperty("line.separator");
		final String ORIGINAL_JAVA =
			"package jdom.defects;" + NL
			+ "public interface IRemoveExtends extends java.util.List {" + NL
			+ "}" + NL;
		
		final String EXPECTED_JAVA = 
			"package jdom.defects;" + NL
			+ "public interface IRemoveExtends {" + NL
			+ "}" + NL;
		
		final String unitName = "IRemoveExtends";
		
		// In 3.0RC3 (and before), this fails...
		doSetSuperInterfacesTest(ORIGINAL_JAVA, EXPECTED_JAVA, unitName);
	}

	public void testIDOMTYPE_SetSuperInterfaces_onClass() {
		final String NL = System.getProperty("line.separator");
		final String ORIGINAL_JAVA =
			"package jdom.defects;" + NL
			+ "public class RemoveImplements implements java.util.List {" + NL
			+ "}" + NL;
		
		final String EXPECTED_JAVA = 
			"package jdom.defects;" + NL
			+ "public class RemoveImplements {" + NL
			+ "}" + NL;
		final String unitName = "RemoveImplements";
		
		// In 3.0RC3 (and before), this succeeds...
		doSetSuperInterfacesTest(ORIGINAL_JAVA, EXPECTED_JAVA, unitName);

		
	}

	/**
	 * @param originalJava
	 * @param expectedJava
	 * @param unitName
	 */
	private void doSetSuperInterfacesTest(final String originalJava, final String
expectedJava, final String unitName) {
		// setup: Build a JDOM Compilation unit and the remove the super interfaces
		IDOMCompilationUnit cu = new DOMFactory().createCompilationUnit(originalJava,
unitName + "java");
		
		IDOMType type = (IDOMType)cu.getChild(unitName);
		
		// Note: stepping through the code of this method reveals that it "works", it
dutifully
		// records the node is "fragmented" and it sets a MASK_TYPE_HAS_INTERFACES to
false
		type.setSuperInterfaces(new String[] {});
		
		// Test: The defect actually occurs during conversion from JDOM model to String
		final String result = cu.getContents();
		
		// Compare:
		assertEquals(expectedJava, result);
	}
	
}
Comment 1 Paul Elder CLA 2004-06-23 13:48:14 EDT
Created attachment 12732 [details]
JUnit plug-in test project illustrating defect
Comment 2 Paul Elder CLA 2004-06-23 13:51:20 EDT
Created attachment 12733 [details]
Proposed fixed version of DOMType.java
Comment 3 Steven Wasleski CLA 2004-08-26 10:21:45 EDT
Is this change being considered for 3.0.1?
Comment 4 Jerome Lanneluc CLA 2004-08-30 11:30:38 EDT
Reviewed change. It looks good. Waiting on PMC approval.
Comment 5 Jerome Lanneluc CLA 2004-08-31 05:28:56 EDT
Got approval. Released fix and test case to both R3_0_maintenace stream and 
HEAD.
Comment 6 David Audel CLA 2004-09-06 10:41:03 EDT
Verified for 3.0.1 RC1