private static IRegion getPathRegion( PathNameCS pathNameCS, IRegion selection, int[] selectedPos) { int[] positions = getPathPos(pathNameCS); if (positions == null) { return HyperlinkUtil.createRegion(pathNameCS); } int nameOffset = pathNameCS.getStartOffset(); int i = 0; for (SimpleNameCS name : pathNameCS.getSimpleNames()) { int offset = selection.getOffset(); if (nameOffset <= offset && offset <= nameOffset + name.getValue().length()) { selectedPos[0] = i; return new Region(nameOffset, name.getValue().length()); } if (i == positions.length) { break; } nameOffset = positions[i++]; } return HyperlinkUtil.createRegion(pathNameCS); }
private static int[] getPathPos(PathNameCS pathNameCS) { EList<SimpleNameCS> sequenceOfNames = pathNameCS.getSimpleNames(); if (sequenceOfNames.size() == 1) { return null; } int size = sequenceOfNames.size() - 1; int[] positions = new int[size]; Arrays.fill(positions, -1); IToken startToken = pathNameCS.getStartToken(); IToken endToken = pathNameCS.getEndToken(); IPrsStream prsStream = startToken.getIPrsStream(); IToken nextToken = startToken; int tokenIndex = 1; int i = 0; while (nextToken != endToken) { nextToken = prsStream.getIToken(startToken.getTokenIndex() + tokenIndex++); if (nextToken.getKind() == QVTOParsersym.TK_IDENTIFIER) { positions[i++] = nextToken.getStartOffset(); if (i == positions.length) { // safety exit in case we have inconsistent start end token break; } } } return positions; }
private static EModelElementRef findReferencedMetamodelElement( CSTNode syntaxElement, IRegion region) { Object astObj = syntaxElement.getAst(); if (astObj instanceof EClassifier) { if (syntaxElement instanceof SimpleNameCS) { if (astObj instanceof EModelElement) { return new EModelElementRef( (EModelElement) astObj, HyperlinkUtil.createRegion(syntaxElement)); } } else if (syntaxElement instanceof PathNameCS && !isConstructorCS(syntaxElement)) { if (astObj instanceof ENamedElement) { PathNameCS pathNameCS = (PathNameCS) syntaxElement; int[] selectedNamePos = new int[1]; // IRegion resultRegion = refineRegion(pathNameCS, region, selectedNamePos); IRegion resultRegion = getPathRegion(pathNameCS, region, selectedNamePos); if (resultRegion != null) { ENamedElement ast = (ENamedElement) pathNameCS.getAst(); int pos = selectedNamePos[0]; final EList<SimpleNameCS> csNames = pathNameCS.getSimpleNames(); if (pos >= 0 && pos < csNames.size() - 1) { QvtOperationalEnv env = getEnv(pathNameCS); List<SimpleNameCS> selectedNames = csNames.subList(0, pos + 1); List<String> stringNames = new ArrayList<String>(selectedNames.size()); for (SimpleNameCS nameCS : selectedNames) { stringNames.add(nameCS.getValue()); } ast = env.lookupClassifier(stringNames); if (ast == null) { ast = env.lookupPackage(stringNames); } } if (ast != null) { return new EModelElementRef(ast, resultRegion); } } } } } else if (astObj instanceof EEnumLiteral) { return new EModelElementRef((EEnumLiteral) astObj, HyperlinkUtil.createRegion(syntaxElement)); } return null; }