/** * CollectAll resolutions under the cursor at offset. * */ List<IssueResolution> collectAllResolutions(XtextResource resource, RegionWithCursor offset, Multimap<Integer, Issue> offset2issue) { EObject script = resource.getContents().get(0); ICompositeNode scriptNode = NodeModelUtils.getNode(script); ILeafNode offsetNode = NodeModelUtils.findLeafNodeAtOffset(scriptNode, offset.getGlobalCursorOffset()); int offStartLine = offsetNode.getTotalStartLine(); List<Issue> allIssues = QuickFixTestHelper.extractAllIssuesInLine(offStartLine, offset2issue); List<IssueResolution> resolutions = Lists.newArrayList(); for (Issue issue : allIssues) { if (issue.getLineNumber() == offsetNode.getStartLine() && issue.getLineNumber() <= offsetNode.getEndLine()) { Display.getDefault().syncExec(() -> resolutions.addAll(quickfixProvider.getResolutions(issue))); } } return resolutions; }
private DeadCodeRegion getDeadCodeRegion(Set<ControlFlowElement> deadCodeGroup) { int startIdx = Integer.MAX_VALUE; int endIdx = 0; int firstElementOffset = Integer.MAX_VALUE; ControlFlowElement firstElement = null; for (ControlFlowElement deadCodeElement : deadCodeGroup) { ICompositeNode compNode = NodeModelUtils.findActualNodeFor(deadCodeElement); int elemStartIdx = compNode.getOffset(); int elemEndIdx = elemStartIdx + compNode.getLength(); startIdx = Math.min(startIdx, elemStartIdx); endIdx = Math.max(endIdx, elemEndIdx); if (elemStartIdx < firstElementOffset) { firstElementOffset = elemStartIdx; firstElement = deadCodeElement; } } ControlFlowElement containerCFE = flowAnalyzer.getContainer(firstElement); ControlFlowElement reachablePredecessor = findPrecedingStatement(firstElement); return new DeadCodeRegion(startIdx, endIdx - startIdx, containerCFE, reachablePredecessor); }
@Override protected Acceptor toAcceptor(IAcceptor<IReferenceDescription> acceptor) { return new ReferenceAcceptor(acceptor, getResourceServiceProviderRegistry()) { @Override public void accept(EObject source, URI sourceURI, EReference eReference, int index, EObject targetOrProxy, URI targetURI) { // Check if we should ignore named import specifier if (N4JSReferenceQueryExecutor.ignoreNamedImportSpecifier && source instanceof NamedImportSpecifier) return; EObject displayObject = calculateDisplayEObject(source); String logicallyQualifiedDisplayName = N4JSHierarchicalNameComputerHelper .calculateLogicallyQualifiedDisplayName(displayObject, labelProvider, false); ICompositeNode srcNode = NodeModelUtils.getNode(source); int line = srcNode.getStartLine(); LabelledReferenceDescription description = new LabelledReferenceDescription(source, displayObject, sourceURI, targetOrProxy, targetURI, eReference, index, logicallyQualifiedDisplayName, line); accept(description); } }; }
@SuppressWarnings({ "unused", "deprecation" }) private AliasLocation enhanceExistingImportDeclaration(ImportDeclaration importDeclaration, QualifiedName qualifiedName, String optionalAlias, MultiTextEdit result) { addImportSpecifier(importDeclaration, qualifiedName, optionalAlias); ICompositeNode replaceMe = NodeModelUtils.getNode(importDeclaration); int offset = replaceMe.getOffset(); AliasLocationAwareBuffer observableBuffer = new AliasLocationAwareBuffer( optionalAlias, offset, grammarAccess); try { serializer.serialize( importDeclaration, observableBuffer, SaveOptions.newBuilder().noValidation().getOptions()); } catch (IOException e) { throw new RuntimeException("Should never happen since we write into memory", e); } result.addChild(new ReplaceEdit(offset, replaceMe.getLength(), observableBuffer.toString())); return observableBuffer.getAliasLocation(); }
private int findInsertionOffset() { int result = 0; List<ScriptElement> scriptElements = script.getScriptElements(); for (int i = 0, size = scriptElements.size(); i < size; i++) { ScriptElement element = scriptElements.get(i); if (element instanceof ImportDeclaration) { // Instead of getting the total offset for the first non-import-declaration, we try to get the // total end offset for the most recent import declaration which is followed by any other script element // this is required for the linebreak handling for automatic semicolon insertion. final ICompositeNode importNode = NodeModelUtils.findActualNodeFor(element); if (null != importNode) { result = importNode.getTotalOffset() + getLengthWithoutAutomaticSemicolon(importNode); } } else { // Otherwise, we assume there is no import declarations yet, we can put it to the top of the document. return result; } } return result; }
/** * Take the content of resource * * @param resource * JS-code snippet which will be treated as text. * @param outCode * writer to output to. */ private void doWrapAndWrite(N4JSResource resource, Writer outCode) { // check if wrapping really applies. boolean moduleWrapping = projectUtils.isModuleWrappingEnabled(resource.getURI()); // get script EObject script = resource.getContents().get(0); // obtain text CharSequence scriptAsText = NodeModelUtils.getNode(script).getRootNode().getText(); // wrap and write String decorated = (moduleWrapping ? ModuleWrappingTransformation.wrapPlainJSCode(scriptAsText) : scriptAsText).toString(); try { outCode.write(decorated); } catch (IOException e) { e.printStackTrace(); } }
private String toPos(EObject eobj) { if (eobj == null) return ""; StringBuilder strb = new StringBuilder(); String res = null; if (eobj.eResource() != null) { res = eobj.eResource().getURI().toString(); if (res.startsWith("platform:/resource/")) { res = res.substring("platform:/resource/".length()); } } if (res != null) strb.append(res); EObject astNode = eobj instanceof SyntaxRelatedTElement ? ((SyntaxRelatedTElement) eobj).getAstElement() : eobj; ICompositeNode node = NodeModelUtils.findActualNodeFor(astNode); if (node != null) { strb.append(":").append(node.getStartLine()); } return strb.toString(); }
private void provideHighligtingFor(ElementReferenceExpression expression, org.eclipse.xtext.ui.editor.syntaxcoloring.IHighlightedPositionAcceptor acceptor) { EObject reference = expression.getReference(); if (reference instanceof Declaration) { Declaration decl = (Declaration) expression.getReference(); switch (decl.getName()) { case "msg": case "block": case "tx": case "now": case "this": case "super": ICompositeNode node = NodeModelUtils.findActualNodeFor(expression); acceptor.addPosition(node.getTotalOffset(), node.getLength() + 1, DefaultHighlightingConfiguration.KEYWORD_ID); } } }
@Check public void checkNoJavaStyleTypeCasting(XBlockExpression blockExpression) { if(isIgnored(JAVA_STYLE_TYPE_CAST)) { return; } if (blockExpression.getExpressions().size() <= 1) { return; } ICompositeNode node = NodeModelUtils.getNode(blockExpression); if (node == null) { return; } INode expressionNode = null; for (INode child : node.getChildren()) { if (isSemicolon(child)) { expressionNode = null; } else if (isXExpressionInsideBlock(child)) { if (expressionNode != null) { checkNoJavaStyleTypeCasting(expressionNode); } expressionNode = child; } } }
protected void checkNoJavaStyleTypeCasting(INode node) { BidiTreeIterator<INode> iterator = node.getAsTreeIterable().reverse().iterator(); ILeafNode child = getFirstLeafNode(iterator); if (child != null && child.getGrammarElement() == grammarAccess.getXParenthesizedExpressionAccess().getRightParenthesisKeyword_2()) { INode expressionNode = getNode(iterator, grammarAccess.getXParenthesizedExpressionAccess().getXExpressionParserRuleCall_1()); EObject semanticObject = NodeModelUtils.findActualSemanticObjectFor(expressionNode); if (semanticObject instanceof XFeatureCall || semanticObject instanceof XMemberFeatureCall) { XAbstractFeatureCall featureCall = (XAbstractFeatureCall) semanticObject; if (featureCall.isTypeLiteral()) { ICompositeNode parenthesizedNode = child.getParent(); ITextRegion parenthesizedRegion = parenthesizedNode.getTextRegion(); addIssue("Use 'as' keyword for type casting.", featureCall, parenthesizedRegion.getOffset(), parenthesizedRegion.getLength(), JAVA_STYLE_TYPE_CAST); } } } }
private LightweightTypeReference createUnknownTypeReference(JvmParameterizedTypeReference reference) { List<INode> nodes = NodeModelUtils.findNodesForFeature(reference, TypesPackage.Literals.JVM_PARAMETERIZED_TYPE_REFERENCE__TYPE); if (nodes.isEmpty()) { Set<EObject> sourceElements = owner.getServices().getJvmModelAssociations().getSourceElements(reference); EObject firstSource = Iterables.getFirst(sourceElements, null); if (firstSource instanceof JvmParameterizedTypeReference) { nodes = NodeModelUtils.findNodesForFeature(firstSource, TypesPackage.Literals.JVM_PARAMETERIZED_TYPE_REFERENCE__TYPE); } } if (nodes.size() == 1) { String name = nodes.get(0).getText().trim(); if (name != null && name.length() != 0) { int lastDot = name.lastIndexOf('.'); int lastDollar = name.lastIndexOf('$'); int lastDotOrDollar = Math.max(lastDot, lastDollar); if (lastDotOrDollar != -1 && lastDotOrDollar != name.length() - 1) { String shortName = name.substring(lastDotOrDollar + 1); if (shortName.length() != 0) { name = shortName; } } return owner.newUnknownTypeReference(name); } } return owner.newUnknownTypeReference(); }
@Override public ITextRegion getSignificantTextRegion(EObject element) { if (element instanceof XAbstractFeatureCall) { XAbstractFeatureCall typeLiteral = typeLiteralHelper.getRootTypeLiteral((XAbstractFeatureCall) element); if (typeLiteral != null) { if (typeLiteral instanceof XMemberFeatureCall) { XAbstractFeatureCall target = (XAbstractFeatureCall) ((XMemberFeatureCall) typeLiteral).getMemberCallTarget(); if (target.isTypeLiteral()) { return super.getSignificantTextRegion(typeLiteral); } } INode node = NodeModelUtils.findActualNodeFor(typeLiteral); if (node != null) { return toZeroBasedRegion(node.getTextRegionWithLineInformation()); } } } return super.getSignificantTextRegion(element); }
@Override protected EObject resolveCrossReferencedElement(INode node) { EObject referenceOwner = NodeModelUtils.findActualSemanticObjectFor(node); if (referenceOwner != null) { EReference crossReference = GrammarUtil.getReference((CrossReference) node.getGrammarElement(), referenceOwner.eClass()); if (!crossReference.isMany()) { EObject resultOrProxy = (EObject) referenceOwner.eGet(crossReference); if (resultOrProxy != null && resultOrProxy.eIsProxy() && crossReference == XbasePackage.Literals.XCONSTRUCTOR_CALL__CONSTRUCTOR) { if (referenceOwner instanceof XConstructorCall) { JvmIdentifiableElement linkedType = batchTypeResolver.resolveTypes(referenceOwner).getLinkedFeature((XConstructorCall)referenceOwner); if (linkedType != null) return linkedType; } } return resultOrProxy; } else { return super.resolveCrossReferencedElement(node); } } return null; }
@Test public void test1() { try { this.with(ReferenceGrammarTestLanguageStandaloneSetup.class); final String model = "kind (Hugo 13)"; final ParserRule kindRule = this.<ReferenceGrammarTestLanguageGrammarAccess>get(ReferenceGrammarTestLanguageGrammarAccess.class).getKindRule(); final XtextResource resource = this.createResource(); resource.setEntryPoint(kindRule); StringInputStream _stringInputStream = new StringInputStream(model); resource.load(_stringInputStream, CollectionLiterals.<Object, Object>emptyMap()); Assert.assertTrue(resource.getErrors().isEmpty()); Assert.assertEquals(kindRule, NodeModelUtils.getEntryParserRule(resource.getParseResult().getRootNode())); final String originalNodeModel = NodeModelUtils.compactDump(resource.getParseResult().getRootNode(), false); resource.update(0, model.length(), ((" " + model) + " ")); final String reparsedNodeModel = NodeModelUtils.compactDump(resource.getParseResult().getRootNode(), false); Assert.assertEquals(originalNodeModel, reparsedNodeModel); final ParserRule erwachsenerRule = this.<ReferenceGrammarTestLanguageGrammarAccess>get(ReferenceGrammarTestLanguageGrammarAccess.class).getErwachsenerRule(); resource.setEntryPoint(erwachsenerRule); resource.update(0, model.length(), "erwachsener (Peter 30)"); Assert.assertEquals(erwachsenerRule, NodeModelUtils.getEntryParserRule(resource.getParseResult().getRootNode())); } catch (Throwable _e) { throw Exceptions.sneakyThrow(_e); } }
@Test public void testTreeIteratorForSyntheticNodes_Backwards() throws Exception { EObject object = getModel("d - e / e * d"); ICompositeNode root = NodeModelUtils.getNode(object).getRootNode(); INode firstChild = root.getFirstChild(); INode firstGrandChild = ((ICompositeNode) firstChild).getFirstChild(); INode sibling = firstGrandChild.getNextSibling().getNextSibling().getNextSibling(); INode siblingChild = ((ICompositeNode) sibling).getFirstChild(); INode siblingGrandChild = ((ICompositeNode) siblingChild).getFirstChild(); INode synthetic = ((ICompositeNode) siblingGrandChild).getFirstChild(); assertTrue(synthetic instanceof SyntheticCompositeNode); INode expectedFirstChild = ((ICompositeNode)synthetic).getFirstChild(); while(expectedFirstChild instanceof ICompositeNode) expectedFirstChild = ((ICompositeNode)expectedFirstChild).getFirstChild(); INode actualFirstChild = null; for(INode child: synthetic.getAsTreeIterable().reverse()) actualFirstChild = child; assertEquals(expectedFirstChild, actualFirstChild); }
@Override public TreeAppendable append(JvmType type) { if(type.eIsProxy()) { String fragment = ((InternalEObject)type).eProxyURI().fragment(); Triple<EObject, EReference, INode> unresolvedLink = encoder.decode(getState().getResource(), fragment); if(unresolvedLink != null) { INode linkNode = unresolvedLink.getThird(); if(linkNode != null) { append(NodeModelUtils.getTokenText(linkNode)); return this; } } append("unresolved type"); return this; } return super.append(type); }
/** {@inheritDoc} */ @Override public void apply(final IModificationContext context) throws BadLocationException { final IXtextDocument xtextDocument = context.getXtextDocument(); xtextDocument.readOnly(new IUnitOfWork.Void<XtextResource>() { @Override public void process(final XtextResource state) throws Exception { // NOPMD final EObject target = EcoreUtil2.getContainerOfType(state.getEObject(issue.getUriToProblem().fragment()), type); if (type.isInstance(target)) { int offset = NodeModelUtils.findActualNodeFor(target).getOffset(); int lineOfOffset = xtextDocument.getLineOfOffset(offset); int lineOffset = xtextDocument.getLineOffset(lineOfOffset); StringBuffer buffer = new StringBuffer(); for (int i = 0; i < (offset - lineOffset); i++) { buffer.append(' '); } xtextDocument.replace(offset, 0, NLS.bind(autodocumentation, buffer.toString())); } } }); }
@Test public void testErrorMarkers() throws Exception { with(ReferenceGrammarTestLanguageStandaloneSetup.class); // model contains an error due to missing ) at idx 23 String model = "spielplatz 1 {kind (k 1}"; XtextResource resource = getResourceFromStringAndExpect(model, 1); assertEquals(1, resource.getErrors().size()); assertEquals(1, Iterables.size(resource.getParseResult().getSyntaxErrors())); ICompositeNode rootNode = resource.getParseResult().getRootNode(); ILeafNode leaf = NodeModelUtils.findLeafNodeAtOffset(rootNode, model.length() - 1); assertTrue(leaf.getSyntaxErrorMessage() != null); // resource.update(23, 0, ")"); // assertTrue(resource.getParseResult().getParseErrors().isEmpty()); IParseResult reparse = reparse(resource.getParseResult(), 23, 0, ")"); rootNode = reparse.getRootNode(); String expectedFixedModel = "spielplatz 1 {kind (k 1)}"; String fixedModel = rootNode.getText(); assertEquals("serialized model as expected", expectedFixedModel, fixedModel); resource = getResourceFromString(fixedModel); assertEquals("full reparse is fine", 0, resource.getErrors().size()); assertFalse("partial reparse is fine", reparse.hasSyntaxErrors()); }
@Override public boolean filterKeyword(final Keyword keyword, final ContentAssistContext context) { final String value = keyword.getValue(); if (((value.length() > 1) && Character.isLetter(value.charAt(0)))) { if ((Objects.equal(value, "as") || Objects.equal(value, "instanceof"))) { final EObject previousModel = context.getPreviousModel(); if ((previousModel instanceof XExpression)) { if (((context.getPrefix().length() == 0) && (NodeModelUtils.getNode(previousModel).getEndOffset() > context.getOffset()))) { return false; } final LightweightTypeReference type = this.typeResolver.resolveTypes(previousModel).getActualType(((XExpression)previousModel)); if (((type == null) || type.isPrimitiveVoid())) { return false; } } } return true; } return false; }
protected void completeXFeatureCall(final EObject model, final ContentAssistContext context, final IIdeContentProposalAcceptor acceptor) { if ((model != null)) { boolean _hasExpressionScope = this.typeResolver.resolveTypes(model).hasExpressionScope(model, IExpressionScope.Anchor.WITHIN); if (_hasExpressionScope) { return; } } if ((model instanceof XMemberFeatureCall)) { final ICompositeNode node = NodeModelUtils.getNode(model); boolean _isInMemberFeatureCall = this.isInMemberFeatureCall(model, node.getEndOffset(), context); if (_isInMemberFeatureCall) { return; } } this.createLocalVariableAndImplicitProposals(model, IExpressionScope.Anchor.AFTER, context, acceptor); }
/** * Gets the URI of the semantic element currently selected. * * @return URI or null */ public URI getSelectedElementUri() { if (selection instanceof IStructuredSelection) { if (((IStructuredSelection) selection).getFirstElement() instanceof InternalEObject) { // structured selection, e.g. GMFEditor return EcoreUtil.getURI((EObject) ((IStructuredSelection) selection).getFirstElement()); } else if (((IStructuredSelection) selection).getFirstElement() instanceof EObjectNode) { // selection in outline return ((EObjectNode) ((IStructuredSelection) selection).getFirstElement()).getEObjectURI(); } } else { ILeafNode node = nodeAtTextSelection(); EObject semanticObject = NodeModelUtils.findActualSemanticObjectFor(node); if (semanticObject != null) { return EcoreUtil.getURI(semanticObject); } } return null; }
/** * Gets the EClass of the semantic element currently selected. * * @return EClass or null */ public EClass getSelectedElementType() { if (selection instanceof IStructuredSelection) { if (((IStructuredSelection) selection).getFirstElement() instanceof EObject) { // structured selection, e.g. GMFEditor EObject eObject = (EObject) ((IStructuredSelection) selection).getFirstElement(); if (eObject.eResource() != null) { return eObject.eClass(); } } else if (((IStructuredSelection) selection).getFirstElement() instanceof EObjectNode) { // selection in outline return ((EObjectNode) ((IStructuredSelection) selection).getFirstElement()).getEClass(); } } else { ILeafNode node = nodeAtTextSelection(); EObject semanticObject = NodeModelUtils.findActualSemanticObjectFor(node); if (semanticObject != null) { return semanticObject.eClass(); } } return null; }
public ICompositeNode findEntryPoint(IParseResult parseResult, int offset) { ICompositeNode rootNode = parseResult.getRootNode(); if (rootNode.getTotalLength() == offset) { return null; } ILeafNode leafNode = NodeModelUtils.findLeafNodeAtOffset(rootNode, offset); ICompositeNode parent = leafNode.getParent(); ICompositeNode result = findEntryPoint(parent, offset); if (result != null) { EObject grammarElement = result.getGrammarElement(); if (grammarElement instanceof AbstractElement) { return result; } } return null; }
/** * Gets the offset for given text by analyzing the parse tree and looking for leaf nodes having * a text attribute matching given value. Returns the first instance found and an error value if * no match found. * * @param model * the model * @param text * the text * @return the offset for text */ protected int getOffsetForText(final EObject model, final String text) { Iterable<ILeafNode> parseTreeNodes = NodeModelUtils.getNode(model).getLeafNodes(); try { ILeafNode result = Iterables.find(parseTreeNodes, new Predicate<ILeafNode>() { @Override public boolean apply(final ILeafNode input) { return text.equals(input.getText()); } }); return result.getOffset(); } catch (NoSuchElementException e) { return LEAF_NOT_FOUND_VALUE; } }
/** * Model: '<code>myID</code>' * The following parse tree is expected: * <pre> * CompositeNode (GrammarElement: Rule[Model], Element: null) * | * CompositeNode (GrammarElement: RuleCall[Child], Element: Child[myID]) * | * LeafNode (GrammarElement: RuleCall[ID], Element: null) * </pre> */ @Test public void testParseWithoutActionCall() throws Exception { XtextResource resource = helper.getResourceFromString("myID"); assertTrue(resource.getErrors().toString(), resource.getErrors().isEmpty()); Model model = (Model) resource.getContents().get(0); assertNotNull("model", model); assertEquals(model.eClass().getName(), ActionLangPackage.Literals.CHILD, model.eClass()); ICompositeNode node = NodeModelUtils.getNode(model); assertNotNull("node", node); assertEquals("node.grammarElement", grammarAccess.getModelAccess().getChildParserRuleCall_0(), node.getGrammarElement()); assertEquals(node.getChildren().toString(), 1, Iterables.size(node.getChildren())); INode childNode = node.getFirstChild(); assertTrue(childNode.toString(), childNode instanceof ILeafNode); assertEquals("childNode.grammarElement", grammarAccess.getChildAccess().getNameIDTerminalRuleCall_0(), childNode.getGrammarElement()); assertFalse("childNode.element", childNode.hasDirectSemanticElement()); ICompositeNode rootNode = resource.getParseResult().getRootNode(); assertNotNull("rootNode", rootNode); assertEquals("rootNode.grammarElement", grammarAccess.getModelRule(), rootNode.getGrammarElement()); assertEquals(rootNode.getChildren().toString(), 1, Iterables.size(rootNode.getChildren())); assertEquals("node is child of rootNode", rootNode, node.getParent()); assertFalse("rootNode.element", rootNode.hasDirectSemanticElement()); }
/** * @return the location data for the given diagnostic. */ protected IssueLocation getLocationData(EObject obj, EStructuralFeature structuralFeature, int index) { INode parserNode = NodeModelUtils.getNode(obj); if (parserNode != null) { if (structuralFeature != null) { List<INode> nodes = NodeModelUtils.findNodesForFeature(obj, structuralFeature); if (index < 0) // insignificant index index = 0; if (nodes.size()>index) parserNode = nodes.get(index); } return getLocationForNode(parserNode); } else if (obj.eContainer() != null) { EObject container = obj.eContainer(); EStructuralFeature containingFeature = obj.eContainingFeature(); return getLocationData(container, containingFeature, containingFeature.isMany() ? ((EList<?>) container.eGet(containingFeature)).indexOf(obj) : ValidationMessageAcceptor.INSIGNIFICANT_INDEX); } IssueLocation result = new IssueLocation(); result.lineNumber = 1; result.column = 1; result.offset = 0; result.length = 0; return result; }
@SuppressWarnings("deprecation") private List<String> getNodeSequence(EObject model) { List<String> result = Lists.newArrayList(); GrammarElementTitleSwitch titleSwitch = new GrammarElementTitleSwitch().showAssignments(); // System.out.println(NodeModelUtils.compactDump(NodeModelUtils.findActualNodeFor(model), true)); org.eclipse.xtext.serializer.sequencer.EmitterNodeIterator ni = new org.eclipse.xtext.serializer.sequencer.EmitterNodeIterator(NodeModelUtils.findActualNodeFor(model), null, true, true); while (ni.hasNext()) { INode next = ni.next(); if (next instanceof ILeafNode) result.add(titleSwitch.doSwitch(next.getGrammarElement()) + " -> " + next.getText()); if (next instanceof ICompositeNode) result.add(titleSwitch.doSwitch(next.getGrammarElement())); } return result; }
@Override public void setTarget(EObject object, EStructuralFeature feature) { EObject myObject = object; INode result = NodeModelUtils.getNode(myObject); while(result == null && myObject.eContainer() != null) { myObject = myObject.eContainer(); result = NodeModelUtils.getNode(myObject); } if (result == null) throw new IllegalStateException("Cannot find NodeAdapter for object: " + object); else { if (feature == null) { feature = myObject.eClass().getEStructuralFeature("name"); } if (feature != null) { List<INode> nodes = NodeModelUtils.findNodesForFeature(myObject, feature); if (nodes.size() == 1) { result = nodes.get(0); } } } setNode(result); }
@Override protected IssueLocation getLocationData(EObject obj, EStructuralFeature structuralFeature, int index) { if (NodeModelUtils.getNode(obj) == null) { ITextRegion location = locationInFileProvider.getSignificantTextRegion(obj); if (location != null) { ICompositeNode rootNode = NodeModelUtils.getNode(EcoreUtil.getRootContainer(obj)); if (rootNode != null) { ILeafNode leafNode = NodeModelUtils.findLeafNodeAtOffset(rootNode, location.getOffset()); return getLocationForNode(leafNode); } } else { return super.getLocationData(obj.eContainer(), null, index); } } return super.getLocationData(obj, structuralFeature, index); }
/** * Performs a special check on check catalogs: the first node belonging to check catalog and * having a multi-line comment as grammar element is used for {@link #getJavaDocComment(INode)}. * <p> * {@inheritDoc} */ @Override protected String findComment(final EObject object) { if (object instanceof CheckCatalog) { ICompositeNode node = NodeModelUtils.getNode(object); try { INode find = Iterables.find(node.getAsTreeIterable(), new Predicate<INode>() { public boolean apply(final INode abstractNode) { return abstractNode.getSemanticElement() instanceof CheckCatalog && abstractNode.getGrammarElement() == grammarAccess.getML_COMMENTRule(); } }); return getJavaDocComment(find); } catch (NoSuchElementException e) { return null; } } return super.findComment(object); }
/** * Returns the nearest multi line comment node that precedes the given object. * @since 2.3 * @return a list with exactly one node or an empty list if the object is undocumented. */ /* @NonNull */ @Override public List<INode> getDocumentationNodes(/* @NonNull */ EObject object) { ICompositeNode node = NodeModelUtils.getNode(object); List<INode> result = Collections.emptyList(); if (node != null) { // get the last multi line comment before a non hidden leaf node for (ILeafNode leafNode : node.getLeafNodes()) { if (!leafNode.isHidden()) break; if (leafNode.getGrammarElement() instanceof TerminalRule && ruleName.equalsIgnoreCase(((TerminalRule) leafNode.getGrammarElement()).getName())) { String comment = leafNode.getText(); if (commentStartTagRegex.matcher(comment).matches()) { result = Collections.<INode>singletonList(leafNode); } } } } return result; }
/** * Finds trailing comment for a given context object. I.e. the comment after / on the same line as the context object. * * @param context * the object * @return the documentation string */ protected String findTrailingComment(final EObject context) { StringBuilder returnValue = new StringBuilder(); ICompositeNode node = NodeModelUtils.getNode(context); final int contextEndLine = node.getEndLine(); if (node != null) { // process all leaf nodes first for (ILeafNode leave : node.getLeafNodes()) { addComment(returnValue, leave, contextEndLine); } // we also need to process siblings (leave nodes only) due to the fact that the last comment after // a given element is not a leaf node of that element anymore. INode sibling = node.getNextSibling(); while (sibling instanceof ILeafNode) { addComment(returnValue, (ILeafNode) sibling, contextEndLine); sibling = sibling.getNextSibling(); } } return returnValue.toString(); }
/** * Returns the smallest node that covers all assigned values of the given object. It handles the semantics of {@link Action * actions} and {@link RuleCall unassigned rule calls}. * * @return the minimal node that covers all assigned values of the given object. * @since 2.3 */ protected ICompositeNode findNodeFor(EObject semanticObject) { ICompositeNode result = NodeModelUtils.getNode(semanticObject); if (result != null) { ICompositeNode node = result; while (GrammarUtil.containingAssignment(node.getGrammarElement()) == null && node.getParent() != null && !node.getParent().hasDirectSemanticElement()) { ICompositeNode parent = node.getParent(); if (node.hasSiblings()) { for(INode sibling: parent.getChildren()) { EObject grammarElement = sibling.getGrammarElement(); if (grammarElement != null && GrammarUtil.containingAssignment(grammarElement) != null) { result = parent; } } } node = parent; } } return result; }
public void update(int offset, int replacedTextLength, String newText) { if (!isLoaded()) { throw new IllegalStateException("You can't update an unloaded resource."); } try { isUpdating = true; IParseResult oldParseResult = parseResult; ReplaceRegion replaceRegion = new ReplaceRegion(new TextRegion(offset, replacedTextLength), newText); IParseResult newParseResult; ParserRule oldEntryPoint = NodeModelUtils.getEntryParserRule(oldParseResult.getRootNode()); if (entryPoint == null || entryPoint == oldEntryPoint) { newParseResult = parser.reparse(oldParseResult, replaceRegion); } else { StringBuilder builder = new StringBuilder(oldParseResult.getRootNode().getText()); replaceRegion.applyTo(builder); newParseResult = parser.parse(entryPoint, new StringReader(builder.toString())); } updateInternalState(oldParseResult, newParseResult); } finally { isUpdating = false; } }
/** * @since 2.1 */ public INode getCrossReferenceNode(XtextResource resource, ITextRegion region) { IParseResult parseResult = resource.getParseResult(); if (parseResult != null) { ILeafNode leaf = NodeModelUtils.findLeafNodeAtOffset(parseResult.getRootNode(), region.getOffset()); INode crossRefNode = findCrossReferenceNode(leaf); // if not a cross reference position and the cursor is at the beginning of a node try the previous one. if (crossRefNode == null && leaf != null && region.getLength()==0 && leaf.getOffset() == region.getOffset()) { leaf = NodeModelUtils.findLeafNodeAtOffset(parseResult.getRootNode(), region.getOffset() - 1); return findCrossReferenceNode(leaf); } else if (crossRefNode != null && crossRefNode.getEndOffset() >= region.getOffset() + region.getLength()) { return crossRefNode; } } return null; }
/** * Persist list diagnostics into string to display the list of issue codes. * * @param diagnostics * list of diagnostics * @param displayPathToTargetObject * if true, the path through the object hierarchy is printed out up to the root node * @return * string with list of issue codes, separated with a line break */ // TODO (ACF-4153) generalize for all kinds of errors and move to AbstractXtextTest private String diagnosticsToString(final Diagnostic diagnostics, final boolean displayPathToTargetObject) { StringBuilder sb = new StringBuilder(); for (Diagnostic diagnostic : diagnostics.getChildren()) { if (diagnostic instanceof AbstractValidationDiagnostic) { AbstractValidationDiagnostic avd = (AbstractValidationDiagnostic) diagnostic; sb.append(" "); sb.append(avd.getIssueCode()); if (displayPathToTargetObject) { sb.append(" at line: "); sb.append(NodeModelUtils.findActualNodeFor(avd.getSourceEObject()).getStartLine()); sb.append(" on \n"); sb.append(pathFromRootAsString(avd.getSourceEObject(), " ")); } sb.append(LINE_BREAK); } } return sb.toString(); }
/** {@inheritDoc} */ @Override public List<INode> getDocumentationNodes(final EObject object) { ICompositeNode node = NodeModelUtils.getNode(object); if (node == null) { return ImmutableList.of(); } // get all single line comments before a non hidden leaf node List<INode> result = Lists.newArrayList(); for (ILeafNode leaf : node.getLeafNodes()) { if (!leaf.isHidden()) { break; } EObject grammarElement = leaf.getGrammarElement(); if (grammarElement instanceof AbstractRule && ruleName.equals(((AbstractRule) grammarElement).getName())) { String comment = leaf.getText(); if (getCommentPattern().matcher(comment).matches() && !comment.matches(ignore)) { result.add(leaf); } } } return result; }
/** * Creates a default styled string for the given {@link EObject} model element. * * @param eObject * the {@link EObject} model element * @return the styled string for the given {@link EObject} model element */ public Object getStyledLabel(final EObject eObject) { // first check if object is foreign to this grammar if (isForeignXtextObject(eObject)) { return getForeignObjectLabel(eObject); } // first check if object has a name String name = getNameOfObject(eObject); if (name != null) { return qualifiedStyledString(name, getTypeOfObject(eObject)); } // secondly check first parsed element (keyword / feature) ICompositeNode node = NodeModelUtils.getNode(eObject); if (node != null) { Iterator<ILeafNode> leafNodesIterator = node.getLeafNodes().iterator(); while (leafNodesIterator.hasNext()) { ILeafNode genericLeafNode = leafNodesIterator.next(); if (!(genericLeafNode instanceof HiddenLeafNode)) { LeafNode leafNode = (LeafNode) genericLeafNode; return getLabelName(leafNode.getText(), eObject.eClass().getName(), true); } } } // fallback return super.doGetText(eObject); }
@Override public IFormattedRegion format(ICompositeNode root, int offset, int length) { String indent = getIndentation(root, offset); TokenStringBuffer buf = new TokenStringBuffer(); ITokenStream out = offset == 0 ? buf : new FilterFirstWhitespaceStream(buf); ITokenStream fmt; if (formatter instanceof IFormatterExtension) { EObject semanticElement = NodeModelUtils.findActualSemanticObjectFor(root); if (semanticElement != null) fmt = ((IFormatterExtension) formatter).createFormatterStream(semanticElement, indent, out, false); else { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=380406 ITextRegion rootRegion = root.getTextRegion(); return new FormattedRegion(rootRegion.getOffset(), rootRegion.getLength(), root.getText()); } } else fmt = formatter.createFormatterStream(indent, out, false); try { ITextRegion range = nodeModelStreamer.feedTokenStream(fmt, root, offset, length); return new FormattedRegion(range.getOffset(), range.getLength(), buf.toString()); } catch (IOException e) { // this should never happen since TokenStringBuffer doesn't throw IOEs. throw new RuntimeException(e); } }
private void assertLastCompleteNode(final String model, final String expectation) { try { int offset = model.indexOf("<|>"); if ((offset == (-1))) { offset = model.length(); } int completionOffset = model.indexOf("<|>", offset); if ((completionOffset == (-1))) { completionOffset = offset; } final Tree tree = this.parseHelper.parse(model.replace("<|>", "")); final ICompositeNode nodeModel = NodeModelUtils.findActualNodeFor(tree); final INode completeNode = this.getTestee().getLastCompleteNodeByOffset(nodeModel, offset, completionOffset); this.assertNodeModel(expectation, completeNode); } catch (Throwable _e) { throw Exceptions.sneakyThrow(_e); } }