/** * 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; }
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); } } }
/** * Retrieves a comment for the given object. * * @param object * an object * @return the comment corresponding to the closest JavaDoc-like comment */ protected String findComment(final EObject object) { String returnValue = null; ICompositeNode node = NodeModelUtils.getNode(object); if (node != null) { // get the last multi line comment before a non hidden leaf node for (INode abstractNode : node.getAsTreeIterable()) { String comment = getJavaDocComment(abstractNode); if (comment != null) { returnValue = comment; break; } } } return returnValue; }
/** {@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; }
private String textWithoutComments(final INode node) { String _switchResult = null; boolean _matched = false; if (node instanceof ILeafNode) { if (((!((ILeafNode)node).isHidden()) || (((ILeafNode)node).getText().trim().length() == 0))) { _matched=true; _switchResult = ((ILeafNode)node).getText(); } } if (!_matched) { if (node instanceof ICompositeNode) { _matched=true; final Function1<INode, String> _function = (INode it) -> { return this.textWithoutComments(it); }; _switchResult = IterableExtensions.join(IterableExtensions.<INode, String>map(((ICompositeNode)node).getChildren(), _function)); } } if (!_matched) { _switchResult = ""; } return _switchResult; }
protected void assertSameStructure(ICompositeNode first, ICompositeNode second) { BidiTreeIterator<INode> firstIter = first.getAsTreeIterable().iterator(); BidiTreeIterator<INode> secondIter = second.getAsTreeIterable().iterator(); while(firstIter.hasNext()) { assertTrue(secondIter.hasNext()); INode firstNext = firstIter.next(); INode secondNext = secondIter.next(); assertEquals(firstNext.getGrammarElement(), secondNext.getGrammarElement()); assertEquals(firstNext.getClass(), secondNext.getClass()); assertEquals(firstNext.getTotalOffset(), secondNext.getTotalOffset()); assertEquals(firstNext.getTotalLength(), secondNext.getTotalLength()); assertEquals(firstNext.getText(), secondNext.getText()); } assertEquals(firstIter.hasNext(), secondIter.hasNext()); }
public static String getTypeRefName(TypeRef typeRef) { if (typeRef.getClassifier() != null) return typeRef.getClassifier().getName(); final ICompositeNode node = NodeModelUtils.getNode(typeRef); if (node != null) { final BidiIterator<INode> leafNodes = node.getAsTreeIterable().iterator(); while (leafNodes.hasPrevious()) { INode previous = leafNodes.previous(); if (previous instanceof ILeafNode && !((ILeafNode) previous).isHidden()) { String result = previous.getText(); if (result != null && result.startsWith("^")) { result = result.substring(1); } return result; } } } return null; }
public ILeafNode immediatelyFollowingKeyword(final INode node, final String kw) { ILeafNode _xblockexpression = null; { INode current = node; while ((current instanceof ICompositeNode)) { current = ((ICompositeNode)current).getLastChild(); } final INode current1 = current; final Function1<ILeafNode, Boolean> _function = (ILeafNode it) -> { return Boolean.valueOf(((!Objects.equal(current1, it)) && (it.getGrammarElement() instanceof Keyword))); }; final ILeafNode result = this.findNextLeaf(current1, _function); ILeafNode _xifexpression = null; if (((result != null) && Objects.equal(result.getText(), kw))) { _xifexpression = result; } _xblockexpression = _xifexpression; } return _xblockexpression; }
protected XClosure builder(final List<XExpression> params) { XClosure _xifexpression = null; XExpression _last = IterableExtensions.<XExpression>last(params); boolean _tripleNotEquals = (_last != null); if (_tripleNotEquals) { XClosure _xblockexpression = null; { INode _nodeForEObject = this._nodeModelAccess.nodeForEObject(IterableExtensions.<XExpression>last(params)); final EObject grammarElement = ((ICompositeNode) _nodeForEObject).getFirstChild().getGrammarElement(); XClosure _xifexpression_1 = null; if (((Objects.equal(grammarElement, this._xbaseGrammarAccess.getXMemberFeatureCallAccess().getMemberCallArgumentsXClosureParserRuleCall_1_1_4_0()) || Objects.equal(grammarElement, this._xbaseGrammarAccess.getXFeatureCallAccess().getFeatureCallArgumentsXClosureParserRuleCall_4_0())) || Objects.equal(grammarElement, this._xbaseGrammarAccess.getXConstructorCallAccess().getArgumentsXClosureParserRuleCall_5_0()))) { XExpression _last_1 = IterableExtensions.<XExpression>last(params); _xifexpression_1 = ((XClosure) _last_1); } _xblockexpression = _xifexpression_1; } _xifexpression = _xblockexpression; } return _xifexpression; }
/** * Collects import declarations in XtextResource for the given range (selectedRegion) */ public void collectImports(final XtextResource state, final ITextRegion selectedRegion, final ImportsAcceptor acceptor) { ICompositeNode rootNode = state.getParseResult().getRootNode(); final EObject selectedSemanticObj = this.findActualSemanticObjectFor(rootNode, selectedRegion); final Iterable<ILeafNode> contentsIterator = NodeModelUtils.findActualNodeFor(selectedSemanticObj).getLeafNodes(); for (final ILeafNode node : contentsIterator) { { final ITextRegion nodeRegion = node.getTotalTextRegion(); boolean _contains = selectedRegion.contains(nodeRegion); if (_contains) { final EObject semanticElement = node.getSemanticElement(); if ((semanticElement != null)) { this.visit(semanticElement, NodeModelUtils.findActualNodeFor(semanticElement), acceptor); } } if ((node.isHidden() && this.grammarAccess.getML_COMMENTRule().equals(node.getGrammarElement()))) { this.addJavaDocReferences(node, selectedRegion, acceptor); } } } }
private INode findPrevious(INode node) { ICompositeNode parent = node.getParent(); if (parent == null) { return null; } INode predecessor = node.getPreviousSibling(); if (predecessor != null) { while (predecessor instanceof ICompositeNode && !prunedComposites.contains(predecessor)) { INode lastChild = ((ICompositeNode) predecessor).getLastChild(); if (lastChild == null) { return predecessor; } predecessor = lastChild; } return predecessor; } return parent; }
protected boolean shouldUseParent(ICompositeNode result, int offset, ILeafNode leaf) { if (leaf.getTotalEndOffset() == offset) { return true; } if (result.getGrammarElement() instanceof RuleCall) { RuleCall rc = (RuleCall) result.getGrammarElement(); if (!rc.getArguments().isEmpty()) { return true; } Assignment assignment = GrammarUtil.containingAssignment(rc); if (assignment != null && (GrammarUtil.isMultipleCardinality(assignment) || (assignment.eContainer() instanceof AbstractElement && GrammarUtil .isMultipleCardinality((AbstractElement) assignment.eContainer())))) { return true; } } return false; }
@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()); }
@Test public void testManyValuedResolveProxiesReference() throws Exception { final EObject foo = newEObject("Foo"); final List<EObject> bars = Lists.newArrayList(newEObject("Bar"), newEObject("Bar")); final Iterator<EObject> barsIterator = bars.iterator(); final Resource resource = new ResourceImpl(URI.createURI("http://foo/bar.ecore")) { @Override public EObject getEObject(String uriFragment) { return barsIterator.next(); } }; resourceSet.getResources().add(resource); resource.getContents().add(foo); final EReference eReference = (EReference) foo.eClass().getEStructuralFeature("many"); assertFalse(eReference.isResolveProxies()); final INode leafNode = newCrossReferenceAssignmentNode(eReference.getName()); final INode leafNode2 = newCrossReferenceAssignmentNode(eReference.getName()); final ICompositeNode adapter = newSimpleNodeAdapter(leafNode, leafNode2); foo.eAdapters().add((Adapter) adapter); linker.linkModel(foo, new ListBasedDiagnosticConsumer()); assertEquals(bars, foo.eGet(eReference, false)); }
@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); } }
@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); }
@Test public void testPartialParseConcreteRuleFirstToken_02() throws Exception { with(PartialParserTestLanguageStandaloneSetup.class); String model = "container c1 {\n" + " children {\n" + " -> C ( ch1 )\n" + " }" + "}"; XtextResource resource = getResourceFromString(model); assertTrue(resource.getErrors().isEmpty()); ICompositeNode root = resource.getParseResult().getRootNode(); ILeafNode children = findLeafNodeByText(root, model, "children"); // change the model and undo the change resource.update(model.indexOf("n {") + 2, 1, " {"); resource.update(model.indexOf("n {") + 2, 2, "{"); assertSame(root, resource.getParseResult().getRootNode()); assertNotSame(children, findLeafNodeByText(root, model, "children")); }
protected void compareWithFullParse(String model, int offset, int length, String newText) throws Exception { XtextResource resource = getResourceFromStringAndExpect(model, UNKNOWN_EXPECTATION); resource.update(offset, length, newText); String text = resource.getParseResult().getRootNode().getText(); XtextResource newResource = getResourceFromStringAndExpect(text, UNKNOWN_EXPECTATION); assertEquals(text, resource.getContents().size(), newResource.getContents().size()); EcoreUtil.resolveAll(resource); EcoreUtil.resolveAll(newResource); for(int i = 0; i < resource.getContents().size(); i++) { assertEquals(text, EmfFormatter.objToStr(newResource.getContents().get(i)), EmfFormatter.objToStr(resource.getContents().get(i))); } ICompositeNode rootNode = resource.getParseResult().getRootNode(); ICompositeNode newRootNode = newResource.getParseResult().getRootNode(); Iterator<INode> iterator = rootNode.getAsTreeIterable().iterator(); Iterator<INode> newIterator = newRootNode.getAsTreeIterable().iterator(); while(iterator.hasNext()) { assertTrue(newIterator.hasNext()); assertEqualNodes(text, iterator.next(), newIterator.next()); } assertFalse(iterator.hasNext()); assertFalse(newIterator.hasNext()); }
@Before public void setUp() throws Exception { nodes = new INode[NUM_NODES]; NodeModelBuilder builder = new NodeModelBuilder(); nodes[0] = new CompositeNode(); nodes[1] = new CompositeNode(); nodes[2] = new HiddenLeafNode(); nodes[3] = new LeafNode(); nodes[4] = new HiddenLeafNode(); nodes[5] = new CompositeNode(); nodes[6] = new LeafNode(); nodes[7] = new CompositeNode(); nodes[8] = new HiddenLeafNode(); nodes[9] = new LeafNode(); builder.addChild((ICompositeNode)nodes[0], (AbstractNode)nodes[1]); builder.addChild((ICompositeNode)nodes[0], (AbstractNode)nodes[5]); builder.addChild((ICompositeNode)nodes[0], (AbstractNode)nodes[7]); builder.addChild((ICompositeNode)nodes[0], (AbstractNode)nodes[9]); builder.addChild((ICompositeNode)nodes[1], (AbstractNode)nodes[2]); builder.addChild((ICompositeNode)nodes[1], (AbstractNode)nodes[3]); builder.addChild((ICompositeNode)nodes[1], (AbstractNode)nodes[4]); builder.addChild((ICompositeNode)nodes[5], (AbstractNode)nodes[6]); builder.addChild((ICompositeNode)nodes[7], (AbstractNode)nodes[8]); }
@Test public void testIgnoreEmptyLines_1() { StringConcatenation _builder = new StringConcatenation(); _builder.append("first"); _builder.newLine(); _builder.append("\t"); _builder.newLine(); _builder.append("second"); _builder.newLine(); final ICompositeNode tree = this.getRootNode(_builder); StringConcatenation _builder_1 = new StringConcatenation(); _builder_1.append("[ID:first][-WS:"); _builder_1.newLine(); _builder_1.append("\\t"); _builder_1.newLine(); _builder_1.append("][ID:second][-WS:"); _builder_1.newLine(); _builder_1.append("]"); _builder_1.newLine(); NodeModelTest.assertEquals(_builder_1.toString().trim(), this.asText(tree)); }
/** * Returns N4JSEObjectNode instead of simple EObjectNode to allow for attaching additional information such as * inheritance state of members. */ @Override public N4JSEObjectNode createEObjectNode(IOutlineNode parentNode, EObject modelElement, ImageDescriptor imageDescriptor, Object text, boolean isLeaf) { N4JSEObjectNode eObjectNode = new N4JSEObjectNode(modelElement, parentNode, imageDescriptor, text, isLeaf); ICompositeNode parserNode = NodeModelUtils.getNode(modelElement); if (parserNode != null) eObjectNode.setTextRegion(parserNode.getTextRegion()); if (isLocalElement(parentNode, modelElement)) eObjectNode.setShortTextRegion(getLocationInFileProvider().getSignificantTextRegion(modelElement)); return eObjectNode; }
/** * Returns with the length of the node including all hidden leaf nodes but the {@link LeafNodeWithSyntaxError} one, * that was created for the automatic semicolon insertion. */ private int getLengthWithoutAutomaticSemicolon(final INode node) { if (node instanceof ILeafNode) { return node.getLength(); } int length = 0; for (final INode leafNode : ((ICompositeNode) node).getLeafNodes()) { if (!isIgnoredSyntaxErrorNode(leafNode, SEMICOLON_INSERTED)) { length += leafNode.getLength(); } } return length; }
/** * Returns a (maybe new) RepoRelativePath with line number of the given test member. */ public RepoRelativePath withLine(SyntaxRelatedTElement testMember) { ICompositeNode node = NodeModelUtils.getNode(testMember.getAstElement()); if (node != null) { final int line = node.getStartLine(); final RepoRelativePath rrp = new RepoRelativePath(repositoryName, pathInRepository, projectName, pathInProject, line); return rrp; } return this; }
private String getDocumentation(/* @NonNull */EObject object) { if (object.eContainer() == null) { // if a comment is at the beginning of the file it will be returned for // the root element (e.g. Script in N4JS) as well -> avoid this! return null; } ICompositeNode node = NodeModelUtils.getNode(object); if (node != null) { // get the last multi line comment before a non hidden leaf node for (ILeafNode leafNode : node.getLeafNodes()) { if (!leafNode.isHidden()) break; EObject grammarElem = leafNode.getGrammarElement(); if (grammarElem instanceof TerminalRule && "ML_COMMENT".equalsIgnoreCase(((TerminalRule) grammarElem).getName())) { String comment = leafNode.getText(); if (commentStartTagRegex.matcher(comment).matches()) { return leafNode.getText(); } } } } return null; }
/** * Checks that no "with" is used and that list of implemented interfaces is separated with commas and not with * keywords. These checks (with some warnings created instead of errors) should help the transition from roles to * interfaces. However, they may be useful later on as well, e.g., if an interface is manually refactored into a * class or vice versa. * <p> * Note that "with" is used in Dart for roles, so maybe it is useful to have a user-friendly message instead of a * parser error. */ @Check public void checkClassDefinition(N4ClassDefinition n4ClassDefinition) { holdsNoKeywordInsteadOfComma(n4ClassDefinition); ICompositeNode node = NodeModelUtils.findActualNodeFor(n4ClassDefinition); ILeafNode keywordNode = findSecondLeafWithKeyword(n4ClassDefinition, "{", node, "extends", false); if (keywordNode != null) { TClass tclass = n4ClassDefinition.getDefinedTypeAsClass(); if (tclass == null) { return; // avoid consequential errors } if (StreamSupport.stream(tclass.getImplementedInterfaceRefs().spliterator(), false).allMatch( superTypeRef -> superTypeRef.getDeclaredType() instanceof TInterface)) { List<? extends IdentifiableElement> interfaces = StreamSupport.stream( tclass.getImplementedInterfaceRefs().spliterator(), false) .map(ref -> (TInterface) (ref.getDeclaredType())).collect(Collectors.toList()); String message = getMessageForSYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP( validatorMessageHelper.description(tclass), "extend", "interface" + (interfaces.size() > 1 ? "s " : " ") + validatorMessageHelper.names(interfaces), "implements"); addIssue(message, n4ClassDefinition, keywordNode.getTotalOffset(), keywordNode.getLength(), SYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP); } } }
private boolean holdsNoKeywordInsteadOfComma(EObject semanticElement) { ICompositeNode node = NodeModelUtils.findActualNodeFor(semanticElement); List<ILeafNode> commaAlternatives = filterLeafsWithKeywordInsteadOfComma(semanticElement, "{", node, "extends", "implements", "with"); boolean result = true; for (ILeafNode n : commaAlternatives) { addIssue(getMessageForSYN_KW_INSTEAD_OF_COMMA_WARN(n.getText()), semanticElement, n.getTotalOffset(), n.getLength(), SYN_KW_INSTEAD_OF_COMMA_WARN); result = false; } return result; }
/** * Returns nodes which represent keywords and specified in keywords. * * @param keywords * keywords in natural order used in Arrays#s */ protected List<ILeafNode> filterLeafsWithKeywordInsteadOfComma(EObject semanticElement, String stopAtKeyword, ICompositeNode node, final String... keywords) { List<ILeafNode> filteredLeaves = null; for (BidiTreeIterator<INode> iter = node.getAsTreeIterable().iterator(); iter.hasNext();) { INode child = iter.next(); EObject childSemElement = child.getSemanticElement(); if (child != node && childSemElement != null && childSemElement != semanticElement) { iter.prune(); } else if (child instanceof ILeafNode) { ILeafNode leaf = (ILeafNode) child; EObject grammarElement = leaf.getGrammarElement(); if (grammarElement instanceof Keyword) { String value = ((Keyword) grammarElement).getValue(); if (stopAtKeyword.equals(value)) { break; } if (Arrays.binarySearch(keywords, value) >= 0) { if (grammarElement.eContainer() instanceof Alternatives) { AbstractElement first = ((Alternatives) (grammarElement.eContainer())).getElements().get(0); boolean inCommaAlternative = (first instanceof Keyword && ",".equals(((Keyword) first) .getValue())); if (inCommaAlternative) { if (filteredLeaves == null) { filteredLeaves = new ArrayList<>(5); } filteredLeaves.add(leaf); } } } } } } return filteredLeaves == null ? Collections.emptyList() : filteredLeaves; }
/** * Returns documentation nodes for N4JS AST and type elements (in which case the method returns the nodes of the * corresponding AST element). If the AST element has no documentation nodes itself, but is an exportable element, * then the documentation of the export statement is returned if present. */ @Override public List<INode> getDocumentationNodes(EObject object) { final EObject astNode = N4JSASTUtils.getCorrespondingASTNode(object); if (astNode != null) { List<INode> nodes = super.getDocumentationNodes(astNode); if (nodes.isEmpty() && astNode instanceof VariableDeclaration) { TypeRef typeRef = ((VariableDeclaration) astNode).getDeclaredTypeRef(); if (typeRef != null) { nodes = getDocumentationNodes(typeRef); } } if (nodes.isEmpty()) { if (astNode instanceof ExportedVariableDeclaration && astNode.eContainer() instanceof ExportedVariableStatement) { EList<VariableDeclaration> decls = ((ExportedVariableStatement) astNode.eContainer()).getVarDecl(); if (decls.size() == 1) { return getDocumentationNodes(astNode.eContainer()); } } if (astNode instanceof ExportableElement && astNode.eContainer() instanceof ExportDeclaration) { nodes = super.getDocumentationNodes(astNode.eContainer()); } } if (nodes.isEmpty()) { // failure case, was ASI grabbing the doc? // backward search for first non-hidden element, over-stepping if it is a LeafNodeWithSyntaxError from // ASI. ICompositeNode ptNodeOfASTNode = NodeModelUtils.getNode(astNode); LeafNode lNode = searchLeafNodeDocumentation(ptNodeOfASTNode); if (lNode != null) { return Collections.<INode> singletonList(lNode); } } return nodes; } return super.getDocumentationNodes(object); }
/** * Test if directParent is in parent-chain. * * @param child * child to test. * @param directParent * parent to look for * @return true if any parent of child (including child) equals to directParent */ private boolean hasAsParent(INode child, ICompositeNode directParent) { INode parent = child; while (parent != null) { if (parent == directParent) return true; parent = parent.getParent(); } return false; }
/** * Installs only a proxy for EObjects that have a representation in the Xtext document node model. */ private void installProxies(N4JSResource resource, EObject obj, IDiagnosticProducer producer) { ICompositeNode node = NodeModelUtils.getNode(obj); if (node == null) return; installProxies(resource, obj, producer, node, false); }
/** * Installs proxies for all non containment references and only if the node representing the EObject that contains * the cross reference has got leaf nodes (as a leaf node represents the cross reference). * * @param resource * the N4JSResource * @param obj * the EObject containing the cross reference * @param producer * the error/warning producer * @param parentNode * the node representing obj inside the node model */ private void installProxies(N4JSResource resource, EObject obj, IDiagnosticProducer producer, ICompositeNode parentNode, boolean dontCheckParent) { final EClass eClass = obj.eClass(); if (eClass.getEAllReferences().size() - eClass.getEAllContainments().size() == 0) return; for (INode node = parentNode.getFirstChild(); node != null; node = node.getNextSibling()) { EObject grammarElement = node.getGrammarElement(); if (grammarElement instanceof CrossReference && hasLeafNodes(node)) { producer.setNode(node); CrossReference crossReference = (CrossReference) grammarElement; final EReference eRef = GrammarUtil.getReference(crossReference, eClass); if (eRef == null) { ParserRule parserRule = GrammarUtil.containingParserRule(crossReference); final String feature = GrammarUtil.containingAssignment(crossReference).getFeature(); throw new IllegalStateException("Couldn't find EReference for crossreference '" + eClass.getName() + "::" + feature + "' in parser rule '" + parserRule.getName() + "'."); } createAndSetProxy(resource, obj, node, eRef, crossReference, producer); afterCreateAndSetProxy(obj, node, eRef, crossReference, producer); } else if (grammarElement instanceof RuleCall && node instanceof ICompositeNode) { RuleCall ruleCall = (RuleCall) grammarElement; AbstractRule calledRule = ruleCall.getRule(); if (calledRule instanceof ParserRule && ((ParserRule) calledRule).isFragment()) { installProxies(resource, obj, producer, (ICompositeNode) node, true); } } } if (!dontCheckParent && shouldCheckParentNode(parentNode)) { installProxies(resource, obj, producer, parentNode.getParent(), dontCheckParent); } }
/** * The node itself has content or if it is a composite node its last child node is a leaf (i.e. this child node has * no further child nodes). */ @Override protected boolean hasLeafNodes(INode node) { if (node.getTotalLength() > 0) return true; if (node instanceof ICompositeNode) { return ((ICompositeNode) node).getLastChild() instanceof ILeafNode; } return false; }
@Override public boolean isValidLineForBreakPoint(XtextResource resource, int line) { IParseResult parseResult = resource.getParseResult(); if (parseResult == null) return false; ICompositeNode node = parseResult.getRootNode(); return isValidLineForBreakpoint(node, line); }
/** * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=236425 * @throws Exception */ @Test public void testBug236425() throws Exception { with(ReferenceGrammarTestLanguageStandaloneSetup.class); String model = "spielplatz 100 }"; EObject object = getModelAndExpect(model, 1); ICompositeNode node = NodeModelUtils.getNode(object).getRootNode(); assertEquals(1, Iterables.size(allSyntaxErrors(node))); }
public String toNodeType(final IGrammarConstraintProvider.ConstraintElementType type) { String _switchResult = null; if (type != null) { switch (type) { case ASSIGNED_ACTION_CALL: case ASSIGNED_CROSSREF_DATATYPE_RULE_CALL: case ASSIGNED_CROSSREF_ENUM_RULE_CALL: case ASSIGNED_CROSSREF_KEYWORD: case ASSIGNED_DATATYPE_RULE_CALL: case ASSIGNED_ENUM_RULE_CALL: case ASSIGNED_PARSER_RULE_CALL: _switchResult = ICompositeNode.class.getSimpleName(); break; case ASSIGNED_CROSSREF_TERMINAL_RULE_CALL: case ASSIGNED_KEYWORD: case ASSIGNED_TERMINAL_RULE_CALL: _switchResult = ILeafNode.class.getSimpleName(); break; default: _switchResult = (("<error, unknown type \'" + type) + "\'>"); break; } } else { _switchResult = (("<error, unknown type \'" + type) + "\'>"); } return _switchResult; }