diff options
author | Henrik Rentz-Reichert | 2018-07-06 17:02:57 +0000 |
---|---|---|
committer | Gerrit Code Review @ Eclipse.org | 2018-07-06 17:02:57 +0000 |
commit | bed42b94fbf934db15e792b247ee747f0c37ebf4 (patch) | |
tree | 06bb329b49a8d94cbf4ab99c7932b88f349c49f5 | |
parent | a276257dc95ffd20597aea3daddd01016eaed008 (diff) | |
parent | e93813322f3616c94f86f41e2a36aef0e46f9285 (diff) | |
download | org.eclipse.etrice-newfsmgen_finalize.tar.gz org.eclipse.etrice-newfsmgen_finalize.tar.xz org.eclipse.etrice-newfsmgen_finalize.zip |
Merge "Bug 536769 - [room.ui] Use new DC tools for content assist" into newfsmgen_finalizenewfsmgen_finalize
28 files changed, 704 insertions, 115 deletions
diff --git a/plugins/org.eclipse.etrice.core.room.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.etrice.core.room.ui/META-INF/MANIFEST.MF index 1db465e7e..adb6cff77 100644 --- a/plugins/org.eclipse.etrice.core.room.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.etrice.core.room.ui/META-INF/MANIFEST.MF @@ -23,7 +23,9 @@ Require-Bundle: org.eclipse.etrice.core.fsm.ui;bundle-version="1.1.2", org.eclipse.core.filesystem;bundle-version="1.3.0", org.eclipse.help, com.google.inject, - org.eclipse.etrice.expressions.ui + org.eclipse.etrice.expressions.ui, + org.eclipse.etrice.ui.behavior.fsm;bundle-version="1.1.1", + org.eclipse.etrice.dctools;bundle-version="1.1.1" Import-Package: org.apache.log4j Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Export-Package: org.eclipse.etrice.core.ui, diff --git a/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/contentassist/RoomProposalProvider.java b/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/contentassist/RoomProposalProvider.java index 2bb423390..30b9f23df 100644 --- a/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/contentassist/RoomProposalProvider.java +++ b/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/contentassist/RoomProposalProvider.java @@ -226,17 +226,21 @@ public class RoomProposalProvider extends AbstractRoomProposalProvider { @Inject RoomExpressionProposalProvider expressionProposalAdapter; + //@Inject private DCUtil util; @Override public void complete_CC_STRING(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - String text = context.getCurrentNode().getText(); - int localOffset = context.getOffset() - context.getCurrentNode().getOffset(); - int globalOffset = context.getOffset(); if (context.getCurrentNode().getSemanticElement() instanceof DetailCode) { + String text = context.getCurrentNode().getText(); + int localOffset = context.getOffset() - context.getCurrentNode().getOffset(); + int globalOffset = context.getOffset(); DetailCode detailCode = (DetailCode) context.getCurrentNode().getSemanticElement(); IDetailExpressionProvider exprPovider = UIExpressionUtil.getExpressionProvider(detailCode); for(ICompletionProposal proposal : expressionProposalAdapter.createProposals(exprPovider, text, localOffset, globalOffset)) acceptor.accept(proposal); + + // new implementation TODO + //util.getProposals(context.getCurrentNode(), context.getOffset()); } super.complete_CC_STRING(model, ruleCall, context, acceptor); diff --git a/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/highlight/HighlightingAstVisitor.xtend b/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/highlight/HighlightingAstVisitor.xtend new file mode 100644 index 000000000..f20a4621d --- /dev/null +++ b/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/highlight/HighlightingAstVisitor.xtend @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2011 protos software gmbh (http://www.protos.de). + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * CONTRIBUTORS: + * Henrik Rentz-Reichert (initial contribution) + * + *******************************************************************************/ + +package org.eclipse.etrice.core.ui.highlight + +import org.eclipse.etrice.core.room.Attribute +import org.eclipse.etrice.core.room.InterfaceItem +import org.eclipse.etrice.core.room.MessageData +import org.eclipse.etrice.core.room.Operation +import org.eclipse.etrice.core.room.VarDecl +import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstIdentifierNode +import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstNode +import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstOtherNode +import org.eclipse.etrice.dctools.fsm.ast.util.IDCAstNodeVisitor +import org.eclipse.xtext.ide.editor.syntaxcoloring.IHighlightedPositionAcceptor +import org.eclipse.xtext.nodemodel.INode +import org.eclipse.etrice.dctools.ast.DCUtil +import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstOperationCallNode +import org.eclipse.etrice.core.room.Message + +class HighlightingAstVisitor implements IDCAstNodeVisitor { + + IHighlightedPositionAcceptor acceptor + int baseOffset + + static def highlight(INode node, IHighlightedPositionAcceptor acceptor, DCUtil util) { + val ast = util.parseAndLink(node) + val offset = util.getDelimiterAdjustedOffset(node) + val visitor = new HighlightingAstVisitor(acceptor, offset) + ast.visit(visitor) + } + + private new(IHighlightedPositionAcceptor acceptor, int baseOffset) { + this.acceptor = acceptor + this.baseOffset = baseOffset + } + + override boolean visitBegin(DCAstNode node) { + var int begin + var int length + val highlightId = switch node { + DCAstOtherNode: { + begin = node.token.begin + length = node.token.length + switch node.token.token.kind { + case COMMENT: RoomHighlightingConfiguration.COMMENT_ID + case STRING: RoomHighlightingConfiguration.STRING_ID + case NUMBER: RoomHighlightingConfiguration.NUMBER_ID + case KEYWORD: RoomHighlightingConfiguration.KEYWORD_ID + default: null + } + } + DCAstIdentifierNode: { + begin = node.token.begin + length = node.token.length + switch DCUtil.getLinkedObject(node) { + Attribute, + MessageData, + VarDecl: RoomHighlightingConfiguration.HL_EXPR_ATTRIBUTE_ID + InterfaceItem: RoomHighlightingConfiguration.HL_EXPR_INTERFACE_ITEM_ID + Operation: RoomHighlightingConfiguration.HL_EXPR_OPERATION_ID + default: null + } + } + DCAstOperationCallNode: { + begin = node.idNode.token.begin + length = node.idNode.token.length + switch node.linkedObject { + Message: RoomHighlightingConfiguration.HL_EXPR_OPERATION_ID + default: null + } + } + } + if (highlightId !== null) { + acceptor.addPosition(baseOffset + begin, length, highlightId) + } + return true + } + + override void visitEnd(DCAstNode node) { + } +} diff --git a/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/highlight/RoomSemanticHighlightingCalculator.java b/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/highlight/RoomSemanticHighlightingCalculator.java index fff548b74..8c915a7af 100644 --- a/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/highlight/RoomSemanticHighlightingCalculator.java +++ b/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/highlight/RoomSemanticHighlightingCalculator.java @@ -15,25 +15,18 @@ package org.eclipse.etrice.core.ui.highlight; import org.eclipse.emf.ecore.EObject; import org.eclipse.etrice.core.common.ui.highlight.BaseSemanticHighlighter; import org.eclipse.etrice.core.converter.RoomValueConverterService; -import org.eclipse.etrice.core.fsm.fSM.DetailCode; import org.eclipse.etrice.core.services.RoomGrammarAccess; -import org.eclipse.etrice.core.ui.util.UIExpressionUtil; -import org.eclipse.etrice.core.ui.util.UIExpressionUtil.ExpressionCache; -import org.eclipse.etrice.expressions.detailcode.IDetailExpressionProvider; -import org.eclipse.etrice.expressions.ui.highlight.ExpressionRuleFactory; -import org.eclipse.etrice.expressions.ui.highlight.TargetLanguageRuleFactory; -import org.eclipse.jface.text.Document; -import org.eclipse.jface.text.rules.IRule; -import org.eclipse.jface.text.rules.IToken; -import org.eclipse.jface.text.rules.RuleBasedScanner; -import org.eclipse.jface.text.rules.Token; +import org.eclipse.etrice.dctools.ast.DCUtil; +import org.eclipse.etrice.dctools.fsm.ast.DCLanguage; +import org.eclipse.etrice.ui.behavior.fsm.Activator; +import org.eclipse.etrice.ui.behavior.fsm.actioneditor.preferences.PreferenceConstants; +import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.xtext.RuleCall; import org.eclipse.xtext.ide.editor.syntaxcoloring.IHighlightedPositionAcceptor; import org.eclipse.xtext.nodemodel.INode; import org.eclipse.xtext.resource.XtextResource; import org.eclipse.xtext.util.CancelIndicator; -import com.google.common.collect.Iterables; import com.google.inject.Inject; /** @@ -41,19 +34,24 @@ import com.google.inject.Inject; * */ public class RoomSemanticHighlightingCalculator extends BaseSemanticHighlighter { - - @Inject - RoomGrammarAccess grammar; - @Inject - RoomValueConverterService converterService; + @Inject RoomGrammarAccess grammar; + @Inject RoomValueConverterService converterService; + @Inject DCUtil detailCodeUtil; + DCLanguage language = null; + + public RoomSemanticHighlightingCalculator() { + } @Override public void provideHighlightingFor(XtextResource resource, IHighlightedPositionAcceptor acceptor, CancelIndicator cancelIndicator) { if (resource == null || resource.getParseResult() == null) return; + + if (language==null) { + setLanguage(); + } - ExpressionCache expressionCache = new ExpressionCache(); INode root = resource.getParseResult().getRootNode(); for (INode node : root.getAsTreeIterable()) { if(cancelIndicator.isCanceled()) @@ -68,39 +66,22 @@ public class RoomSemanticHighlightingCalculator extends BaseSemanticHighlighter acceptor.addPosition(node.getOffset(), node.getLength(), RoomHighlightingConfiguration.HL_ANNOTATION_ID); } else if(ruleCall.getRule() == grammar.getCC_STRINGRule()) { - detailCodeHighlight(node, acceptor, expressionCache); + HighlightingAstVisitor.highlight(node, acceptor, detailCodeUtil); } } } } - - protected void detailCodeHighlight(INode node, IHighlightedPositionAcceptor acceptor, ExpressionCache cache) { - final String text = converterService.getCC_StringConverter().stripDelim(node.getText()); - final int offset = node.getOffset() + converterService.getCC_StringConverter().getDelim().length(); - - DetailCode dc = null; - if(node.getParent().getSemanticElement() instanceof DetailCode) { - dc = (DetailCode) node.getParent().getSemanticElement(); + + private void setLanguage() { + IPreferenceStore preferenceStore = Activator.getDefault().getPreferenceStore(); + String lang = preferenceStore.getString(PreferenceConstants.EDITOR_LANGUAGE); + if (lang.equals(PreferenceConstants.JAVA_LANGUAGE)) { + language = DCLanguage.JAVA_LANGUAGE; } - IDetailExpressionProvider exprProvider = UIExpressionUtil.getExpressionProvider(dc, null, cache); - XtextHighlightStyles styles = new XtextHighlightStyles(); - RuleBasedScanner scanner = new RuleBasedScanner(); - scanner.setRules(Iterables.toArray(Iterables.concat( - TargetLanguageRuleFactory.getGeneralLiteralRules(styles), - ExpressionRuleFactory.getInitialExpressionRules(exprProvider, styles), - TargetLanguageRuleFactory.getGeneralKeywordRules(styles)) - , IRule.class)); - scanner.setRange(new Document(text), 0, text.length()); - - IToken lastToken = null; - while(lastToken != Token.EOF) { - lastToken = scanner.nextToken(); - if(lastToken != null && lastToken.getData() != null) { - acceptor.addPosition(offset + scanner.getTokenOffset(), scanner.getTokenLength(), (String) lastToken.getData()); - } + else { + language = DCLanguage.CPP_LANGUAGE; } - + detailCodeUtil.setLanguage(language); } - } diff --git a/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/hover/RoomHoverProvider.xtend b/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/hover/RoomHoverProvider.xtend index 8a0234f4c..1d61abca7 100644 --- a/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/hover/RoomHoverProvider.xtend +++ b/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/hover/RoomHoverProvider.xtend @@ -13,11 +13,10 @@ package org.eclipse.etrice.core.ui.hover import com.google.inject.Inject -import org.eclipse.emf.ecore.EObject import org.eclipse.etrice.core.common.ui.hover.KeywordEObjectTextHover import org.eclipse.etrice.core.fsm.fSM.DetailCode import org.eclipse.etrice.core.services.RoomGrammarAccess -import org.eclipse.etrice.core.ui.util.UIExpressionUtil +import org.eclipse.etrice.dctools.ast.DCUtil import org.eclipse.jface.text.Region import org.eclipse.xtext.RuleCall import org.eclipse.xtext.nodemodel.util.NodeModelUtils @@ -26,8 +25,8 @@ import org.eclipse.xtext.util.Tuples class RoomHoverProvider extends KeywordEObjectTextHover { - @Inject - RoomGrammarAccess grammar + @Inject RoomGrammarAccess grammar + @Inject DCUtil util override protected getXtextElementAt(XtextResource resource, int offset) { // lookup expression @@ -36,9 +35,13 @@ class RoomHoverProvider extends KeywordEObjectTextHover { val leafNode = NodeModelUtils.findLeafNodeAtOffset(parseResult.rootNode, offset) if(leafNode?.grammarElement instanceof RuleCall) { if((leafNode.grammarElement as RuleCall).rule == grammar.CC_STRINGRule && leafNode.semanticElement instanceof DetailCode){ - val exprFeature = UIExpressionUtil.findAtOffset(leafNode, offset) - if(exprFeature?.data instanceof EObject) - return Tuples.create(exprFeature.data as EObject, new Region(offset, exprFeature.id.length)) +// println("RoomHoverProvider at offset " + offset + " " + leafNode.offset + " " + leafNode.text.substring(offset - leafNode.offset)) + val result = util.findAtOffset(leafNode, offset) + if (result!==null) { +// val begin = result.begin +// println("RoomHoverProvider hit " + (leafNode.offset + result.begin) +" " + result.length + " " + leafNode.text.substring(begin, begin + result.length)) + return Tuples.create(result.object, new Region(leafNode.offset + result.begin, result.length)) + } } } } diff --git a/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/linking/RoomHyperlinkHelper.java b/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/linking/RoomHyperlinkHelper.java index 6e2c361e3..c04199f13 100644 --- a/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/linking/RoomHyperlinkHelper.java +++ b/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/linking/RoomHyperlinkHelper.java @@ -21,8 +21,8 @@ import org.eclipse.etrice.core.room.ActorRef; import org.eclipse.etrice.core.room.RefSegment; import org.eclipse.etrice.core.room.util.RoomHelpers; import org.eclipse.etrice.core.services.RoomGrammarAccess; -import org.eclipse.etrice.core.ui.util.UIExpressionUtil; -import org.eclipse.etrice.expressions.detailcode.IDetailExpressionProvider.ExpressionFeature; +import org.eclipse.etrice.dctools.ast.DCUtil; +import org.eclipse.etrice.dctools.ast.DCUtil.FindResult; import org.eclipse.jface.text.Region; import org.eclipse.xtext.AbstractRule; import org.eclipse.xtext.RuleCall; @@ -42,6 +42,7 @@ public class RoomHyperlinkHelper extends ImportAwareHyperlinkHelper { @Inject private RoomGrammarAccess grammar; @Inject private RoomHelpers roomHelpers; + @Inject private DCUtil util; @Override public void createHyperlinksByOffset(XtextResource resource, int offset, IHyperlinkAcceptor acceptor) { @@ -67,12 +68,16 @@ public class RoomHyperlinkHelper extends ImportAwareHyperlinkHelper { } } - if(leaf.getGrammarElement() instanceof RuleCall) { - if(((RuleCall) leaf.getGrammarElement()).getRule() == grammar.getCC_STRINGRule() && leaf.getSemanticElement() instanceof DetailCode) { - ExpressionFeature exprFeature = UIExpressionUtil.findAtOffset(leaf, offset); - if(exprFeature != null && exprFeature.getData() instanceof EObject) { - Region region = new Region(leaf.getOffset(), leaf.getLength()); - createHyperlinksTo(resource, region, (EObject) exprFeature.getData(), acceptor); + if (leaf.getGrammarElement() instanceof RuleCall) { + if (((RuleCall) leaf.getGrammarElement()).getRule() == grammar.getCC_STRINGRule() + && leaf.getSemanticElement() instanceof DetailCode) { + // System.out.println("RoomHyperlinkHelper at offset " + offset + " " + leaf.getOffset() + " " + leaf.getText().substring(offset - leaf.getOffset())); + FindResult result = util.findAtOffset(leaf, offset); + if (result != null) { + // int begin = result.getBegin(); + // System.out.println("RoomHyperlinkHelper hit " + (leaf.getOffset() + result.getBegin()) +" " + result.getLength() + " " + leaf.getText().substring(begin, begin + result.getLength())); + Region region = new Region(leaf.getOffset() + result.getBegin(), result.getLength()); + createHyperlinksTo(resource, region, result.getObject(), acceptor); } } } @@ -85,12 +90,13 @@ public class RoomHyperlinkHelper extends ImportAwareHyperlinkHelper { ActorContainerClass lastAcContainer = roomHelpers.getParentContainer(aim); ActorRef lastRef = null; for (RefSegment ref : aim.getPath().getRefs()) { - for (ActorRef r : lastAcContainer.getActorRefs()) + for (ActorRef r : lastAcContainer.getActorRefs()) { if (r.getName().equals(ref.getRef())) { lastRef = r; lastAcContainer = lastRef.getType(); break; } + } } return lastRef; diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/CandidateMap.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/CandidateMap.xtend index 178ad0200..9251fd45b 100644 --- a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/CandidateMap.xtend +++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/CandidateMap.xtend @@ -17,4 +17,15 @@ import org.eclipse.emf.ecore.EObject class CandidateMap extends HashMap<String, EObject> { + def CandidateMap getMatches(String prefix) { + val result = new CandidateMap + + for (entry : entrySet) { + if (entry.key.startsWith(prefix)) { + result.put(entry.key, entry.value) + } + } + + return result + } }
\ No newline at end of file diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/DCNodeAtOffset.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/DCNodeAtOffset.xtend new file mode 100644 index 000000000..d59d0bc8e --- /dev/null +++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/DCNodeAtOffset.xtend @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2011 protos software gmbh (http://www.protos.de). + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * CONTRIBUTORS: + * Henrik Rentz-Reichert (initial contribution) + * + *******************************************************************************/ + +package org.eclipse.etrice.dctools.fsm.ast + +import org.eclipse.etrice.dctools.fsm.ast.util.IDCAstNodeVisitor +import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstNode +import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstMatchNode +import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstTextNode +import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstBracketNode + +class DCNodeAtOffset implements IDCAstNodeVisitor { + + int offset + DCAstTextNode result = null + + private new (int offset) { + this.offset = offset + } + + static def find(DCAstMatchNode ast, int offset) { + val visitor = new DCNodeAtOffset(offset) + ast.visit(visitor) + return visitor.result + } + + override visitBegin(DCAstNode node) { + if (result===null) { + if (node instanceof DCAstTextNode) { + if (node.begin<=offset && offset<node.end) { + result = node + } + } + if (node instanceof DCAstBracketNode) { + // also test the closing bracket + if (node.posClose>=0) { + if (node.posClose==offset) { + result = node + } + } + } + } + return result===null + } + + override visitEnd(DCAstNode node) { + } + +}
\ No newline at end of file diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/DCParser.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/DCParser.xtend index 4eaa04710..0a190c8d4 100644 --- a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/DCParser.xtend +++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/DCParser.xtend @@ -166,19 +166,21 @@ class DCParser { var b = token.token as DCBracketToken if (b.bracketKind==left) { val contents = Match(parent) + val leftPos = token.begin token = read if (token!==null) { if (token.token instanceof DCBracketToken) { + val rightPos = token.begin b = token.token as DCBracketToken if (b.bracketKind==right) { - return new DCAstBracketNode(parent, type, contents) + return new DCAstBracketNode(parent, type, contents, leftPos, rightPos) } } unread // second token } else { // we reached the end without a matching right bracket - return new DCAstBracketNode(parent, type, contents, false) + return new DCAstBracketNode(parent, type, contents, leftPos) } unread(contents) } @@ -203,7 +205,7 @@ class DCParser { var token = read while (token!==null) { if (token.token.kind==Kind.PERIOD) { - val pNode = new DCAstPeriodNode(null) + val pNode = new DCAstPeriodNode(null, token.begin) val wsNode = Whitespace(null) val cNode = Call(null) val wsNode2 = Whitespace(null) @@ -327,7 +329,7 @@ class DCParser { if (count>0) { val ws = text.substring(begin, end) - return new DCAstWhitespaceNode(parent, count, ws) + return new DCAstWhitespaceNode(parent, count, begin, ws) } return null diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCSpecialCharRule.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCSpecialCharRule.xtend index 09fa428c9..2169be9e8 100644 --- a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCSpecialCharRule.xtend +++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCSpecialCharRule.xtend @@ -20,12 +20,12 @@ import org.eclipse.jface.text.rules.Token class DCSpecialCharRule implements IRule { + public static val char SEP = ';' + public static val char PERIOD = '.' + val period = new DCToken(Kind.PERIOD) val sep = new DCToken(Kind.STATEMENT_SEP) - val char SEP = ';' - val char PERIOD = '.' - override evaluate(ICharacterScanner scanner) { val c = scanner.read as char diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstBracketNode.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstBracketNode.xtend index 99a2bccfa..660f8f632 100644 --- a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstBracketNode.xtend +++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstBracketNode.xtend @@ -16,7 +16,7 @@ import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstNode import org.eclipse.xtend.lib.annotations.Accessors @Accessors -class DCAstBracketNode extends DCAstNode { +class DCAstBracketNode extends DCAstTextNode { enum BracketType { ROUND, @@ -25,22 +25,24 @@ class DCAstBracketNode extends DCAstNode { } BracketType type + int posClose boolean closed - new(DCAstNode parent, BracketType type, DCAstNode contents) { - this(parent, type, contents, true) - } - - new(DCAstNode parent, BracketType type, DCAstNode contents, boolean closed) { - super(parent, 2) + new(DCAstNode parent, BracketType type, DCAstNode contents, int posOpen, int posClose) { + super(parent, 2, posOpen, posOpen+1) this.type = type - this.closed = closed + this.posClose = posClose + this.closed = posClose>=0 if (contents!==null) { contents.parent = this } } + new(DCAstNode parent, BracketType type, DCAstNode contents, int posOpen) { + this(parent, type, contents, posOpen, -1) + } + def left() { switch type { case CURLY: "{" @@ -69,4 +71,5 @@ class DCAstBracketNode extends DCAstNode { println(indent + "DCAstBracketNode " + this.toString) } + override def String getText() { toString } }
\ No newline at end of file diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstIdentifierBracketNode.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstIdentifierBracketNode.xtend index 94d5d31b0..51c69e5af 100644 --- a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstIdentifierBracketNode.xtend +++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstIdentifierBracketNode.xtend @@ -33,7 +33,7 @@ abstract class DCAstIdentifierBracketNode extends DCAstNode { } def String id() { - idNode.identifier + idNode.id } def String ws() { diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstIdentifierNode.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstIdentifierNode.xtend index 84c932de9..b330891b5 100644 --- a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstIdentifierNode.xtend +++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstIdentifierNode.xtend @@ -16,19 +16,21 @@ import org.eclipse.etrice.dctools.fsm.ast.tokens.DCTextToken import org.eclipse.xtend.lib.annotations.Accessors @Accessors -class DCAstIdentifierNode extends DCAstNode { +class DCAstIdentifierNode extends DCAstTextNode { - String identifier + String id DCTextToken token - new(DCAstNode parent, String identifier, DCTextToken token) { - super(parent, 1) - this.identifier = identifier + new(DCAstNode parent, String id, DCTextToken token) { + super(parent, 1, token.begin, token.begin+token.length) + this.id = id this.token = token } override protected doPrint(String indent) { - println(indent + "DCAstIdentifierNode '" + identifier + "'" + linkedObjectText) + println(indent + "DCAstIdentifierNode '" + id + "'" + linkedObjectText) } + override getText() { id } + }
\ No newline at end of file diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstOtherNode.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstOtherNode.xtend index 1ebd19329..ee93222d4 100644 --- a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstOtherNode.xtend +++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstOtherNode.xtend @@ -16,13 +16,13 @@ import org.eclipse.etrice.dctools.fsm.ast.tokens.DCTextToken import org.eclipse.xtend.lib.annotations.Accessors @Accessors -class DCAstOtherNode extends DCAstNode { +class DCAstOtherNode extends DCAstTextNode { String text DCTextToken token new(DCAstNode parent, String text, DCTextToken token) { - super(parent, 1) + super(parent, 1, token.begin, token.begin+token.length) this.text = text this.token = token } diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstPeriodNode.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstPeriodNode.xtend index 535d401dc..a29d353f8 100644 --- a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstPeriodNode.xtend +++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstPeriodNode.xtend @@ -13,14 +13,17 @@ package org.eclipse.etrice.dctools.fsm.ast.nodes import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstNode +import org.eclipse.etrice.dctools.fsm.ast.internal.DCSpecialCharRule -class DCAstPeriodNode extends DCAstNode { +class DCAstPeriodNode extends DCAstTextNode { - new(DCAstNode parent) { - super(parent, 1) + new(DCAstNode parent, int pos) { + super(parent, 1, pos, pos+1) } override protected doPrint(String indent) { println(indent + "DCAstPeriodNode") } + + override String getText() { String.valueOf(DCSpecialCharRule.PERIOD) } }
\ No newline at end of file diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstTextNode.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstTextNode.xtend new file mode 100644 index 000000000..c008b3599 --- /dev/null +++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstTextNode.xtend @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2011 protos software gmbh (http://www.protos.de). + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * CONTRIBUTORS: + * Henrik Rentz-Reichert (initial contribution) + * + *******************************************************************************/ + +package org.eclipse.etrice.dctools.fsm.ast.nodes + +import org.eclipse.xtend.lib.annotations.Accessors + +@Accessors +abstract class DCAstTextNode extends DCAstNode { + + int begin + int end + + new(DCAstNode parent, int readTokens, int begin, int end) { + super(parent, readTokens) + this.begin = begin + this.end = end + } + + abstract def String getText() +}
\ No newline at end of file diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstWhitespaceNode.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstWhitespaceNode.xtend index c0017774f..1ff691fac 100644 --- a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstWhitespaceNode.xtend +++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstWhitespaceNode.xtend @@ -16,16 +16,18 @@ import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstNode import org.eclipse.xtend.lib.annotations.Accessors @Accessors -class DCAstWhitespaceNode extends DCAstNode { +class DCAstWhitespaceNode extends DCAstTextNode { String text - new(DCAstNode parent, int readTokens, String text) { - super(parent, readTokens) + new(DCAstNode parent, int readTokens, int pos, String text) { + super(parent, readTokens, pos, pos+text.length) this.text = text } override protected doPrint(String indent) { println(indent + "DCAstWhitespaceNode '" + text + "'") } + + override getText() { text } }
\ No newline at end of file diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/util/DCAstPrinter.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/util/DCAstPrinter.xtend index d5e7435cf..7811910eb 100644 --- a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/util/DCAstPrinter.xtend +++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/util/DCAstPrinter.xtend @@ -31,7 +31,7 @@ class DCAstPrinter implements IDCAstNodeVisitor { switch node { DCAstBracketNode: sb.append(node.left) - DCAstIdentifierNode: sb.append(node.identifier) + DCAstIdentifierNode: sb.append(node.id) DCAstPeriodNode: sb.append(".") DCAstWhitespaceNode: sb.append(node.text) DCAstOtherNode: sb.append(node.text) diff --git a/plugins/org.eclipse.etrice.dctools/META-INF/MANIFEST.MF b/plugins/org.eclipse.etrice.dctools/META-INF/MANIFEST.MF index 809caa340..f5a1bf949 100644 --- a/plugins/org.eclipse.etrice.dctools/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.etrice.dctools/META-INF/MANIFEST.MF @@ -8,12 +8,16 @@ Automatic-Module-Name: org.eclipse.etrice.dctools Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Require-Bundle: com.google.guava, org.eclipse.emf.ecore, + org.eclipse.jface.text, org.eclipse.xtext.xbase.lib, org.eclipse.xtend.lib, org.eclipse.xtend.lib.macro, + org.eclipse.xtext.ui, org.eclipse.etrice.core.fsm, org.eclipse.etrice.core.room, org.eclipse.etrice.dctools.fsm;visibility:=reexport, - org.eclipse.etrice.generator.fsm -Export-Package: org.eclipse.etrice.dctools.ast + org.eclipse.etrice.generator.fsm, + org.eclipse.etrice.core.genmodel.fsm +Export-Package: org.eclipse.etrice.dctools, + org.eclipse.etrice.dctools.ast diff --git a/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/GenModelAccess.xtend b/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/GenModelAccess.xtend new file mode 100644 index 000000000..340b069b8 --- /dev/null +++ b/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/GenModelAccess.xtend @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2011 protos software gmbh (http://www.protos.de). + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * CONTRIBUTORS: + * Henrik Rentz-Reichert (initial contribution) + * + *******************************************************************************/ + +package org.eclipse.etrice.dctools + +import java.util.Map +import org.eclipse.etrice.core.RoomStandaloneSetup +import org.eclipse.etrice.core.fsm.fSM.ModelComponent +import org.eclipse.etrice.core.genmodel.fsm.ExtendedFsmGenBuilder +import org.eclipse.etrice.core.genmodel.fsm.fsmgen.GraphContainer + +class GenModelAccess { + + Map<ModelComponent, GraphContainer> cache = newHashMap + + def public GraphContainer get(ModelComponent mc) { + if(!cache.containsKey(mc)) { + val injector = new RoomStandaloneSetup().createInjector + val builder = new ExtendedFsmGenBuilder(injector); + val gc = builder.createTransformedModel(mc) + builder.withCommonData(gc) + cache.put(mc, gc) + } + + return cache.get(mc) + } +}
\ No newline at end of file diff --git a/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/DCLinker.xtend b/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/DCLinker.xtend index 30ea98b41..d703ea1ff 100644 --- a/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/DCLinker.xtend +++ b/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/DCLinker.xtend @@ -99,20 +99,21 @@ class DCLinker implements IDCAstNodeVisitor { } protected def dispatch void link(DCAstIdentifierNode node) { - val candidates = getCandidates(FeatureType.SCALAR) - node.linkedObject = candidates.get(node.identifier) - replaceContext(node.linkedObject) + node.doLink(FeatureType.SCALAR, node.id) } protected def dispatch void link(DCAstArrayAccessNode node) { - val candidates = getCandidates(FeatureType.ARRAY) - node.linkedObject = candidates.get(node.id) - replaceContext(node.linkedObject) + node.doLink(FeatureType.ARRAY, node.id) } protected def dispatch void link(DCAstOperationCallNode node) { - val candidates = getCandidates(FeatureType.OPERATION) - node.linkedObject = candidates.get(node.id) + node.doLink(FeatureType.OPERATION, node.id) + } + + protected def void doLink(DCAstNode node, FeatureType ft, String name) { + val candidates = getCandidates(ft) + node.linkedObject = candidates.get(name) + node.linkedData = candidates replaceContext(node.linkedObject) } diff --git a/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/DCUtil.xtend b/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/DCUtil.xtend new file mode 100644 index 000000000..e2f580939 --- /dev/null +++ b/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/DCUtil.xtend @@ -0,0 +1,148 @@ +/******************************************************************************* + * Copyright (c) 2011 protos software gmbh (http://www.protos.de). + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * CONTRIBUTORS: + * Henrik Rentz-Reichert (initial contribution) + * + *******************************************************************************/ + +package org.eclipse.etrice.dctools.ast + +import com.google.inject.Inject +import java.util.List +import org.eclipse.emf.ecore.EObject +import org.eclipse.etrice.core.converter.RoomValueConverterService +import org.eclipse.etrice.core.fsm.fSM.DetailCode +import org.eclipse.etrice.core.fsm.fSM.TransitionBase +import org.eclipse.etrice.core.genmodel.fsm.FsmGenExtensions +import org.eclipse.etrice.core.room.ActorClass +import org.eclipse.etrice.core.room.MessageData +import org.eclipse.etrice.core.room.RoomClass +import org.eclipse.etrice.dctools.GenModelAccess +import org.eclipse.etrice.dctools.ast.internal.DCProposalConfig +import org.eclipse.etrice.dctools.fsm.ast.CandidateMap +import org.eclipse.etrice.dctools.fsm.ast.DCLanguage +import org.eclipse.etrice.dctools.fsm.ast.DCNodeAtOffset +import org.eclipse.etrice.dctools.fsm.ast.DCParser +import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstIdentifierNode +import org.eclipse.jface.text.contentassist.ICompletionProposal +import org.eclipse.xtend.lib.annotations.Accessors +import org.eclipse.xtext.EcoreUtil2 +import org.eclipse.xtext.nodemodel.ILeafNode +import org.eclipse.xtext.nodemodel.INode + +class DCUtil { + + @Accessors + static class FindResult { + val EObject object + val int begin + val int length + } + + @Inject RoomValueConverterService converterService + @Inject DCProposalConfig proposalConfig + + val genModelAccess = new GenModelAccess + DCLanguage language = DCLanguage.C_LANGUAGE + + new() { + } + + def setLanguage(DCLanguage language) { + this.language = language + } + + def FindResult findAtOffset(ILeafNode textNode, int offset) { + val ast = textNode.parseAndLink + val astNode = DCNodeAtOffset.find(ast, offset - textNode.delimiterAdjustedOffset) + if (astNode instanceof DCAstIdentifierNode) { + val object = getLinkedObject(astNode) + if (object !==null) { + return new FindResult(object, astNode.begin + converterService.CC_StringConverter.delim.length, astNode.end-astNode.begin) + } + } + return null + } + + def getDelimiterAdjustedOffset(INode astNode) { + astNode.offset + converterService.CC_StringConverter.delim.length + } + + def parseAndLink(INode astNode) { + val text = converterService.CC_StringConverter.stripDelim(astNode.getText()); + val parser = new DCParser(language) + val ast = parser.parse(text) + + if (astNode.parent.semanticElement instanceof DetailCode) { + val dc = astNode.parent.semanticElement as DetailCode + + var DCLinker linker = null; + + // lets check whether we have a transition and determine common data + val transition = EcoreUtil2.getContainerOfType(dc, TransitionBase) + if (transition!==null) { + val roomClass = EcoreUtil2.getContainerOfType(dc, RoomClass) + if (roomClass instanceof ActorClass) { + val gc = genModelAccess.get(roomClass) + val link = FsmGenExtensions.getLinkFor(gc, transition) + if (link!==null) { + linker = new DCLinker(dc, link.commonData as MessageData) + } + } + } + + // if we have no common data we use a plain linker + if (linker===null) { + linker = new DCLinker(dc) + } + + ast.visit(linker) + + return ast + } + else { + return null + } + } + + def List<ICompletionProposal> getProposals(INode textNode, int offset) { + val ast = textNode.parseAndLink + // note: we subtract 1 to get the token to the left of the caret + val astNode = DCNodeAtOffset.find(ast, offset - textNode.delimiterAdjustedOffset - 1) + if (astNode instanceof DCAstIdentifierNode) { + val candidates = astNode.candidates + if (candidates!==null) { + val begin = astNode.begin + converterService.CC_StringConverter.delim.length + val end = offset - textNode.offset + val prefix = textNode.text.substring(begin, end) + val matches = candidates.getMatches(prefix) + return matches.entrySet.map[match | proposalConfig.doCreateProposal(prefix, match.key, match.value, offset)].toList + } + } + + newArrayList + } + + static def EObject getLinkedObject(DCAstIdentifierNode astNode) { + if (astNode.linkedObject!==null) { + astNode.linkedObject + } + else if (astNode.parent!==null) { + astNode.parent.linkedObject + } + } + + static def CandidateMap getCandidates(DCAstIdentifierNode astNode) { + if (astNode.linkedData instanceof CandidateMap) { + astNode.linkedData as CandidateMap + } + else if (astNode.parent!==null && astNode.parent.linkedData instanceof CandidateMap) { + astNode.parent.linkedData as CandidateMap + } + } +} diff --git a/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/internal/DCProposalConfig.xtend b/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/internal/DCProposalConfig.xtend new file mode 100644 index 000000000..8f28887cd --- /dev/null +++ b/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/internal/DCProposalConfig.xtend @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2011 protos software gmbh (http://www.protos.de). + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * CONTRIBUTORS: + * Henrik Rentz-Reichert (initial contribution) + * + *******************************************************************************/ + +package org.eclipse.etrice.dctools.ast.internal + +import com.google.inject.Singleton +import com.google.inject.Inject +import org.eclipse.jface.viewers.ILabelProvider +import org.eclipse.etrice.core.room.util.RoomHelpers +import org.eclipse.emf.ecore.EObject +import org.eclipse.jface.viewers.StyledString +import org.eclipse.swt.graphics.Image +import org.eclipse.xtext.ui.editor.contentassist.ConfigurableCompletionProposal +import org.eclipse.xtext.ui.editor.contentassist.PrefixMatcher +import org.eclipse.jface.text.contentassist.ICompletionProposal +import org.eclipse.swt.graphics.Point +import org.eclipse.etrice.core.room.Operation +import org.eclipse.etrice.core.room.Message +import org.eclipse.etrice.core.room.Attribute +import org.eclipse.etrice.core.room.InterfaceItem +import org.eclipse.etrice.core.room.Port + +@Singleton +class DCProposalConfig { + + @Inject + protected ILabelProvider labelProvider + + @Inject + protected RoomHelpers roomHelpers + + @Inject + protected PrefixMatcher prefixMatcher + + def ICompletionProposal doCreateProposal(String prefix, String proposal, EObject object, int globalOffset) { + new ConfigurableCompletionProposal(proposal, globalOffset - prefix.length, prefix.length, proposal.length, object.image, object.displayString, null, null) => [ + matcher = prefixMatcher + autoInsertable = false + // TODO adjust length to existing text + replaceContextLength = proposal.length + ] + } + + def Pair<String, Point> getPostfixReplacement(EObject object) { + val brackets = switch object { + Operation, + Message: + #['(', ')'] + + Attribute case object.size>0, + Port case object.multiplicity>0: + #['[', ']'] + } + + if (brackets===null) { + return "" -> null + } + + val replacement = switch object { + Operation: + object.arguments.map[name].join(', ') + + Message case object.data !== null: + object.data.refType.type.name + + Attribute, // fall through + InterfaceItem: + '0' + + default: + '' + } + + replacement.wrap(brackets.head, brackets.last) + } + + private def Pair<String, Point> wrap(String text, String left, String right) { + val selection = if (!text.empty) new Point(1, text.length) + left + text + right -> selection + } + + private def StyledString getDisplayString(EObject object) { + + } + + private def Image getImage(EObject object) { + + } +}
\ No newline at end of file diff --git a/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/internal/DCTranslatorVisitor.xtend b/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/internal/DCTranslatorVisitor.xtend index afd514a07..c307273d1 100644 --- a/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/internal/DCTranslatorVisitor.xtend +++ b/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/internal/DCTranslatorVisitor.xtend @@ -62,7 +62,7 @@ class DCTranslatorVisitor implements IDCAstNodeVisitor { else { if (!node.skipOutput) { switch node { - DCAstIdentifierNode: currentSB.append(node.identifier) + DCAstIdentifierNode: currentSB.append(node.id) DCAstPeriodNode: currentSB.append(".") DCAstWhitespaceNode: currentSB.append(node.text) DCAstOtherNode: currentSB.append(node.text) @@ -159,7 +159,7 @@ class DCTranslatorVisitor implements IDCAstNodeVisitor { val translated = if (ifItemNode instanceof DCAstIdentifierNode) { // accessed as scalar (means broadcast for replicated port) - val inst = ifItemNode.identifier + val inst = ifItemNode.id translationProvider.getInterfaceItemMessageText(ifItem, msg, inst, args, null, msgNode.originalText) } else if (ifItemNode instanceof DCAstArrayAccessNode) { diff --git a/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestConstants.xtend b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestConstants.xtend index 8a38916a8..34894c598 100644 --- a/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestConstants.xtend +++ b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestConstants.xtend @@ -32,7 +32,7 @@ interface TestConstants { static val TEST_MEMBER_ACCESS = "field.member" static val TEST_ARRAY_MEMBER_ACCESS = "field[1+2].member" static val TEST_ARRAY_MEMBER_ACCESS_AND_CALL = TEST_ARRAY_MEMBER_ACCESS + ".op()" - static val TEST_SPACY_ARRAY_MEMBER_ACCESS_AND_CALL = "field [ 1 + 2 ]\n\t. member . op ( )" + static val TEST_SPACIOUS_ARRAY_MEMBER_ACCESS_AND_CALL = "field [ 1 + 2 ]\n\t. member . op ( )" static val TEST_CODE = "DC var = new DC(); port.message(var);" static val TEST_CODE1 = "field.member1.member2[3].operation(x+4)" static val TEST_CODE2 = ''' diff --git a/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCNodeAtOffset.xtend b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCNodeAtOffset.xtend new file mode 100644 index 000000000..6b52257c5 --- /dev/null +++ b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCNodeAtOffset.xtend @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2011 protos software gmbh (http://www.protos.de). + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * CONTRIBUTORS: + * Henrik Rentz-Reichert (initial contribution) + * + *******************************************************************************/ + +package org.eclipse.etrice.dctools.tests + +import org.eclipse.etrice.dctools.fsm.ast.DCParser +import org.junit.Before +import org.eclipse.etrice.dctools.fsm.ast.DCLanguage +import static org.eclipse.etrice.dctools.tests.TestConstants.* +import org.junit.Test +import org.eclipse.etrice.dctools.fsm.ast.DCNodeAtOffset +import static org.junit.Assert.* +import static org.hamcrest.CoreMatchers.* +import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstOtherNode +import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstIdentifierNode +import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstBracketNode + +class TestDCNodeAtOffset { + + DCParser parser + + @Before + def void createParser() { + parser = new DCParser(DCLanguage.C_LANGUAGE) + } + + @Test + def void testString() { + val ast = parser.parse(TEST_STRING) + val result = DCNodeAtOffset.find(ast, 3) + assertNotNull(result) + assertTrue(result instanceof DCAstOtherNode) + assertThat(result.text, is(TEST_STRING)) + } + + @Test + def void testMemberAccess() { + val ast = parser.parse(TEST_MEMBER_ACCESS) + var result = DCNodeAtOffset.find(ast, 8) + assertNotNull(result) + assertTrue(result instanceof DCAstIdentifierNode) + assertThat(result.text, is("member")) + + result = DCNodeAtOffset.find(ast, 4) + assertNotNull(result) + assertTrue(result instanceof DCAstIdentifierNode) + assertThat(result.text, is("field")) + } + + @Test + def void testArrayMemberAccess() { + val ast = parser.parse(TEST_ARRAY_MEMBER_ACCESS) + var result = DCNodeAtOffset.find(ast, 14) + assertNotNull(result) + assertTrue(result instanceof DCAstIdentifierNode) + assertThat(result.text, is("member")) + + result = DCNodeAtOffset.find(ast, 4) + assertNotNull(result) + assertTrue(result instanceof DCAstIdentifierNode) + assertThat(result.text, is("field")) + + result = DCNodeAtOffset.find(ast, 7) + assertNotNull(result) + assertTrue(result instanceof DCAstOtherNode) + assertThat(result.text, is("+")) + } + + @Test + def void testCode() { + val ast = parser.parse(TEST_CODE) + var result = DCNodeAtOffset.find(ast, 16) + assertNotNull(result) + assertTrue(result instanceof DCAstBracketNode) + if (result instanceof DCAstBracketNode) { + assertThat(result.text, is("()")) + assertThat(result.begin, is(15)) + assertThat(result.end, is(16)) + assertThat(result.posClose, is(16)) + } + } + + @Test + def void testCode2() { + val ast = parser.parse(TEST_CODE2) + + // note: because line breaks differ on UNIX and Windows we can't use a constant offset here + val pos = TEST_CODE2.indexOf("456")+2 + + var result = DCNodeAtOffset.find(ast, pos) + assertNotNull(result) + assertTrue(result instanceof DCAstOtherNode) + assertThat(result.text, is("456")) + } +} diff --git a/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCParser.xtend b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCParser.xtend index df0e392ab..b9e944961 100644 --- a/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCParser.xtend +++ b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCParser.xtend @@ -149,7 +149,7 @@ class TestDCParser { // it is an identifier node node = node.children.get(0) assertTrue(node instanceof DCAstIdentifierNode) - assertThat((node as DCAstIdentifierNode).identifier, is(TEST_IDENTIFIER)) + assertThat((node as DCAstIdentifierNode).id, is(TEST_IDENTIFIER)) prettyPrint("testIdentifier", TEST_IDENTIFIER, result, 1, 3) } @@ -257,11 +257,11 @@ class TestDCParser { } @Test - def void testSpacyArrayMemberAccessAndCall() { - val result = parser.parse(TEST_SPACY_ARRAY_MEMBER_ACCESS_AND_CALL) + def void testSpaciousArrayMemberAccessAndCall() { + val result = parser.parse(TEST_SPACIOUS_ARRAY_MEMBER_ACCESS_AND_CALL) assertNotNull(result) - prettyPrint("testSpacyArrayMemberAccessAndCall", TEST_SPACY_ARRAY_MEMBER_ACCESS_AND_CALL, result, 23, 27) + prettyPrint("testSpacyArrayMemberAccessAndCall", TEST_SPACIOUS_ARRAY_MEMBER_ACCESS_AND_CALL, result, 23, 27) } @Test diff --git a/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCScanner.xtend b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCScanner.xtend index 8f164b578..f28da318b 100644 --- a/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCScanner.xtend +++ b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCScanner.xtend @@ -166,8 +166,8 @@ class TestDCScanner { } @Test - def void testSpacyArrayMemberAccessAndCall() { - val tokens = scanner.scan(TEST_SPACY_ARRAY_MEMBER_ACCESS_AND_CALL) + def void testSpaciousArrayMemberAccessAndCall() { + val tokens = scanner.scan(TEST_SPACIOUS_ARRAY_MEMBER_ACCESS_AND_CALL) assertThat(tokens.size, is(23)) var pos = 0 |