-
-
Notifications
You must be signed in to change notification settings - Fork 358
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add support for paths for all elements from model root (CtEleme…
…nt#getPath) (#1874)
- Loading branch information
Showing
11 changed files
with
330 additions
and
95 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
97 changes: 97 additions & 0 deletions
97
src/main/java/spoon/reflect/path/CtElementPathBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package spoon.reflect.path; | ||
|
||
import spoon.reflect.declaration.CtElement; | ||
import spoon.reflect.declaration.CtNamedElement; | ||
import spoon.reflect.meta.RoleHandler; | ||
import spoon.reflect.meta.impl.RoleHandlerHelper; | ||
import spoon.reflect.path.impl.CtPathElement; | ||
import spoon.reflect.path.impl.CtPathImpl; | ||
import spoon.reflect.path.impl.CtRolePathElement; | ||
import spoon.reflect.reference.CtReference; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
/** | ||
* This builder allow to create some CtPath from CtElements | ||
* | ||
* Created by nharrand on 21/02/2018. | ||
*/ | ||
public class CtElementPathBuilder { | ||
/** | ||
* Build path to a CtElement el, from one of its parent. | ||
* | ||
* @throws CtPathException is thrown when root is not a parent of el. | ||
* | ||
* @param el : the element to which the CtPath leads to | ||
* @param root : Starting point of the CtPath | ||
* @return CtPath from root to el | ||
*/ | ||
public CtPath fromElement(CtElement el, CtElement root) throws CtPathException { | ||
CtPathImpl path = new CtPathImpl(); | ||
CtElement cur = el; | ||
while (cur != root) { | ||
CtElement parent = cur.getParent(); | ||
CtRole role = cur.getRoleInParent(); | ||
if (role == null) { | ||
throw new CtPathException(); | ||
} | ||
RoleHandler roleHandler = RoleHandlerHelper.getOptionalRoleHandler(parent.getClass(), role); | ||
if (roleHandler == null) { | ||
throw new CtPathException(); | ||
} | ||
CtPathElement pathElement = new CtRolePathElement(role); | ||
switch (roleHandler.getContainerKind()) { | ||
case SINGLE: | ||
break; | ||
|
||
case LIST: | ||
//Element needs to be differentiated from its brothers | ||
List list = roleHandler.asList(parent); | ||
//Assumes that List's order is deterministic. | ||
//Can't be replaced by list.indexOf(cur) | ||
//Because objects must be the same (and not just equals) | ||
int index = 0; | ||
for (Object o : list) { | ||
if (o == cur) { | ||
break; | ||
} | ||
index++; | ||
} | ||
pathElement.addArgument("index", index + ""); | ||
break; | ||
|
||
case SET: | ||
String name; | ||
if (cur instanceof CtNamedElement) { | ||
name = ((CtNamedElement) cur).getSimpleName(); | ||
} else if (cur instanceof CtReference) { | ||
name = ((CtReference) cur).getSimpleName(); | ||
} else { | ||
throw new CtPathException(); | ||
} | ||
pathElement.addArgument("name", name); | ||
break; | ||
|
||
case MAP: | ||
Map map = roleHandler.asMap(parent); | ||
String key = null; | ||
for (Object o : map.keySet()) { | ||
if (map.get(o) == cur) { | ||
key = (String) o; | ||
break; | ||
} | ||
} | ||
if (key == null) { | ||
throw new CtPathException(); | ||
} else { | ||
pathElement.addArgument("key", key); | ||
} | ||
break; | ||
} | ||
cur = parent; | ||
path.addFirst(pathElement); | ||
} | ||
return path; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.