Skip to content

Commit 1fc0bf7

Browse files
committed
FIX: Fixed case where the super interface could not be resolved correctly.
1 parent 7978301 commit 1fc0bf7

2 files changed

Lines changed: 34 additions & 29 deletions

File tree

src/main/java/jce/codemanipulation/ecore/EcoreImportManipulator.java

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package jce.codemanipulation.ecore;
22

3+
import java.util.Arrays;
4+
35
import org.eclipse.core.resources.IProject;
46
import org.eclipse.emf.ecore.EClass;
57
import org.eclipse.jdt.core.ICompilationUnit;
@@ -76,7 +78,7 @@ private ICompilationUnit findEcoreImplementation(ICompilationUnit unit) throws J
7678
String implementationName = getImplementationName(getPackageMemberName(unit));
7779
IType iType = project.findType(implementationName);
7880
if (iType == null) {
79-
return unit; // return original, better than nothing TODO (HIGH) make this more elegant
81+
return unit; // return original, better than nothing TODO (HIGH) make this more elegant
8082
}
8183
return iType.getCompilationUnit();
8284
}
@@ -91,9 +93,9 @@ private ICompilationUnit findEcoreInterface(ICompilationUnit unit) throws JavaMo
9193
}
9294

9395
/**
94-
* Checks for cases where the Ecore interface uses instances of itself. In those cases the import manipulation
95-
* cannot change the type of the instances, because the origin code type import would clash with the Ecore interface
96-
* itself. Therefore the correlating parameters are retyped manually.
96+
* Checks for cases where the Ecore interface uses instances of itself. In those cases the import manipulation cannot
97+
* change the type of the instances, because the origin code type import would clash with the Ecore interface itself.
98+
* Therefore the correlating parameters are retyped manually.
9799
*/
98100
private void fixSelfImports(ICompilationUnit ecoreInterface, IImportDeclaration importDeclaration) throws JavaModelException {
99101
String interfaceName = getPackageMemberName(ecoreInterface);
@@ -112,8 +114,8 @@ private String getImplementationName(String typeName) {
112114
}
113115

114116
/**
115-
* Returns the name of the Ecore interface of an Ecore implementation class name. E.g. returns "model.Main" when
116-
* given "model.impl.MainImpl".
117+
* Returns the name of the Ecore interface of an Ecore implementation class name. E.g. returns "model.Main" when given
118+
* "model.impl.MainImpl".
117119
*/
118120
private String getInterfaceName(String typeName) {
119121
String interfaceName = nameUtil.append(nameUtil.cutLastSegments(typeName, 2), nameUtil.getLastSegment(typeName));
@@ -122,9 +124,9 @@ private String getInterfaceName(String typeName) {
122124

123125
/**
124126
* Checks whether an {@link ICompilationUnit} is an Ecore implementation class. Ecore implementation classes are the
125-
* classes that implement the Ecore interfaces. The Ecore implementation classes are the types whose imports should
126-
* be edited. This method first checks the compilation unit on correct naming and then on the existence of a
127-
* counterpart in the Ecore metamodel
127+
* classes that implement the Ecore interfaces. The Ecore implementation classes are the types whose imports should be
128+
* edited. This method first checks the compilation unit on correct naming and then on the existence of a counterpart in
129+
* the Ecore metamodel
128130
*/
129131
private boolean isEcoreImplementation(ICompilationUnit unit) throws JavaModelException {
130132
String typeName = nameUtil.cutFirstSegment(getPackageMemberName(unit));
@@ -136,8 +138,8 @@ private boolean isEcoreImplementation(ICompilationUnit unit) throws JavaModelExc
136138
}
137139

138140
/**
139-
* Checks whether a fully qualified type name identifies a type which could be part of an Ecore implementation
140-
* package. That means the last package of the type name is called impl and the type name end with the suffix Impl.
141+
* Checks whether a fully qualified type name identifies a type which could be part of an Ecore implementation package.
142+
* That means the last package of the type name is called impl and the type name end with the suffix Impl.
141143
*/
142144
private boolean isEcoreImplementationName(String typeName) {
143145
return nameUtil.getLastSegment(nameUtil.cutLastSegment(typeName)).equals("impl") && typeName.endsWith("Impl");
@@ -179,9 +181,9 @@ private boolean isProblematic(IImportDeclaration importDeclaration) {
179181
}
180182

181183
/**
182-
* Changes the imports of a compilation unit and its Ecore interface if it is an Ecore implementation class. The
183-
* super interface declarations of the classes are retained, while the import declarations of the Ecore type are
184-
* changed to the relating types of the origin code.
184+
* Changes the imports of a compilation unit and its Ecore interface if it is an Ecore implementation class. The super
185+
* interface declarations of the classes are retained, while the import declarations of the Ecore type are changed to
186+
* the relating types of the origin code.
185187
* @param unit is the {@link ICompilationUnit}.
186188
* @throws JavaModelException if there are problems with the Java model.
187189
*/
@@ -195,9 +197,9 @@ private void manipulateEcoreClass(ICompilationUnit unit) throws JavaModelExcepti
195197

196198
/**
197199
* Changes the imports in the same package of a compilation unit if it is an Ecore interface. The super interface
198-
* declarations of the classes are retained, while the import declarations of the Ecore type are changed to the
199-
* relating types of the origin code, which are not represented as imports, as the Ecore types of the interfaces
200-
* reside in the same package.
200+
* declarations of the classes are retained, while the import declarations of the Ecore type are changed to the relating
201+
* types of the origin code, which are not represented as imports, as the Ecore types of the interfaces reside in the
202+
* same package.
201203
* @param unit is the {@link ICompilationUnit}.
202204
* @throws JavaModelException if there are problems with the Java model.
203205
*/
@@ -228,14 +230,17 @@ private void manipulateEcoreInterface(ICompilationUnit unit) throws JavaModelExc
228230
* Retains the super interface declarations and type parameter bounds of the Ecore interface and its implementation.
229231
*/
230232
private void retainTypes(ICompilationUnit ecoreImplementation, ICompilationUnit ecoreInterface) throws JavaModelException {
231-
// always use the implementation imports to resolve classes in the same package with the interface:
232-
applyRetentionVisitor(ecoreImplementation, ecoreImplementation.getImports());
233-
applyRetentionVisitor(ecoreInterface, ecoreImplementation.getImports());
233+
IImportDeclaration[] implementationImports = ecoreImplementation.getImports();
234+
IImportDeclaration[] interfaceImports = ecoreInterface.getImports();
235+
IImportDeclaration[] combinedImports = Arrays.copyOf(implementationImports, implementationImports.length + interfaceImports.length);
236+
System.arraycopy(interfaceImports, 0, combinedImports, implementationImports.length, interfaceImports.length);
237+
applyRetentionVisitor(ecoreImplementation, implementationImports);
238+
applyRetentionVisitor(ecoreInterface, combinedImports); // use combined imports for ecore interface
234239
}
235240

236241
/**
237-
* Edits an {@link IImportDeclaration} with the help of an {@link ImportRewrite} instance to refer to the origin
238-
* code instead to the Ecore code.
242+
* Edits an {@link IImportDeclaration} with the help of an {@link ImportRewrite} instance to refer to the origin code
243+
* instead to the Ecore code.
239244
*/
240245
private void rewriteImport(IImportDeclaration importDeclaration, ImportRewrite implementationRewrite, ImportRewrite interfaceRewrite) {
241246
String oldName = importDeclaration.getElementName();
@@ -267,9 +272,8 @@ private void rewriteImports(ICompilationUnit ecoreImplementation, ICompilationUn
267272

268273
/**
269274
* Changes the imports of a compilation unit and its Ecore interface if it is an Ecore implementation class and the
270-
* imports of types in the same package if it is an Ecore interface. The super interface declarations of the classes
271-
* are retained, while the import declarations of the Ecore type are changed to the relating types of the origin
272-
* code.
275+
* imports of types in the same package if it is an Ecore interface. The super interface declarations of the classes are
276+
* retained, while the import declarations of the Ecore type are changed to the relating types of the origin code.
273277
* @param unit is the {@link ICompilationUnit}.
274278
* @throws JavaModelException if there are problems with the Java model.
275279
*/

src/main/java/jce/codemanipulation/ecore/TypeRetentionVisitor.xtend

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ class TypeRetentionVisitor extends ASTVisitor {
103103
*/
104104
@SuppressWarnings("unchecked") def private void retainSuperInterface(Type oldInterface, TypeDeclaration node, AST ast) {
105105
var SimpleType interfaceType = TypeUtil.getSimpleType(oldInterface)
106-
if(isNotEObject(interfaceType)) {
107-
var String newName = resolveInterfaceName(interfaceType)
106+
if (isNotEObject(interfaceType)) {
107+
var newName = resolveInterfaceName(interfaceType)
108108
var Type newSuperInterface = ast.newSimpleType(ast.newName(newName))
109109
newSuperInterface = copyParameters(oldInterface, newSuperInterface, ast)
110110
node.superInterfaceTypes.remove(oldInterface)
@@ -116,7 +116,7 @@ class TypeRetentionVisitor extends ASTVisitor {
116116
* Adds all type parameters the old super interface to the new super interface.
117117
*/
118118
@SuppressWarnings("unchecked") def private Type copyParameters(Type oldInterface, Type newInterface, AST ast) {
119-
if(oldInterface.isParameterizedType) { // if interface has parameters
119+
if (oldInterface.isParameterizedType) { // if interface has parameters
120120
var ParameterizedType parameterizedType = ast.newParameterizedType(newInterface) // parameterized new interface
121121
var ParameterizedType castedType = (oldInterface as ParameterizedType) // cast old interface
122122
for (Type type : RawTypeUtil.castList(Type, castedType.typeArguments)) {
@@ -136,6 +136,7 @@ class TypeRetentionVisitor extends ASTVisitor {
136136
if (type.name.qualifiedName) {
137137
return type.name.fullyQualifiedName
138138
}
139+
// try to resolve name from imports, use current package + name as "last resort" (types in same package have no imports).
139140
return nameFromImports(type) ?: pathHelper.append(currentPackage, type.name.fullyQualifiedName)
140141
}
141142

@@ -158,7 +159,7 @@ class TypeRetentionVisitor extends ASTVisitor {
158159
return declaration.elementName
159160
}
160161
}
161-
return null
162+
return null // did not find type in imports
162163
}
163164

164165
/**

0 commit comments

Comments
 (0)