ide/editor/src/main/java/org/apidesign/bck2brwsr/ide/editor/JSEmbeddingProvider.java
Added EmbeddingProvider for JavaScriptBody.
2 * To change this template, choose Tools | Templates
3 * and open the template in the editor.
5 package org.apidesign.bck2brwsr.ide.editor;
7 import com.sun.source.tree.AnnotationTree;
8 import com.sun.source.tree.AssignmentTree;
9 import com.sun.source.tree.CompilationUnitTree;
10 import com.sun.source.tree.ExpressionTree;
11 import com.sun.source.tree.LiteralTree;
12 import com.sun.source.tree.MethodTree;
13 import com.sun.source.util.SourcePositions;
14 import com.sun.source.util.TreePath;
15 import com.sun.source.util.TreePathScanner;
16 import com.sun.source.util.Trees;
17 import java.io.IOException;
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.Collections;
21 import java.util.List;
22 import java.util.concurrent.atomic.AtomicBoolean;
23 import javax.lang.model.element.TypeElement;
24 import javax.swing.text.Document;
25 import org.netbeans.api.editor.mimelookup.MimeRegistration;
26 import org.netbeans.api.java.source.CompilationInfo;
27 import org.netbeans.api.java.source.JavaParserResultTask;
28 import org.netbeans.api.java.source.JavaSource;
29 import org.netbeans.api.lexer.Language;
30 import org.netbeans.api.lexer.TokenHierarchy;
31 import org.netbeans.api.lexer.TokenSequence;
32 import org.netbeans.modules.parsing.api.Snapshot;
33 import org.netbeans.modules.parsing.spi.Parser;
34 import org.netbeans.modules.parsing.spi.Scheduler;
35 import org.netbeans.modules.parsing.spi.SchedulerEvent;
36 import org.netbeans.modules.parsing.spi.SchedulerTask;
37 import org.netbeans.modules.parsing.spi.TaskFactory;
38 import org.openide.util.Exceptions;
42 * @author Tomas Zezula
44 public final class JSEmbeddingProvider extends JavaParserResultTask<Parser.Result> {
46 private static final int PRIORITY = 1000;
47 private static final String JS_ANNOTATION = "org.apidesign.bck2brwsr.core.JavaScriptBody"; //NOI18N
48 private static final String BODY = "body"; //NOI18N
49 private static final String JAVA_MIME_TYPE = "text/x-java"; //NOI18N
50 private static final String JAVASCRIPT_MIME_TYPE = "text/javascript"; //NOI18N
51 private final AtomicBoolean canceled = new AtomicBoolean();
53 private JSEmbeddingProvider() {
54 super(JavaSource.Phase.ELEMENTS_RESOLVED);
58 public int getPriority() {
63 public void cancel() {
68 public Class<? extends Scheduler> getSchedulerClass() {
69 return Scheduler.EDITOR_SENSITIVE_TASK_SCHEDULER;
73 public void run(Parser.Result t, SchedulerEvent se) {
75 final CompilationInfo ci = CompilationInfo.get(t);
76 final CompilationUnitTree cu = ci.getCompilationUnit();
77 final Trees trees = ci.getTrees();
78 final SourcePositions sp = trees.getSourcePositions();
79 final Finder f = new Finder(trees);
80 final List<LiteralTree> result = new ArrayList<LiteralTree>();
82 if (!result.isEmpty()) {
84 final TokenHierarchy<Document> tk = TokenHierarchy.get(ci.getDocument());
85 final Language<?> java = Language.find(JAVA_MIME_TYPE);
86 final Language<?> javaScript = Language.find(JAVASCRIPT_MIME_TYPE);
87 if (java != null && javaScript != null) {
88 final TokenSequence<?> seq = tk.tokenSequence(java);
90 for (LiteralTree lt : result) {
91 final int start = (int) sp.getStartPosition(cu, lt);
92 final int end = (int) sp.getEndPosition(cu, lt);
94 while (seq.moveNext() && seq.offset() < end) {
95 seq.createEmbedding(javaScript, 1, 1, true);
100 } catch (IOException ioe) {
101 Exceptions.printStackTrace(ioe);
109 private static final class Finder extends TreePathScanner<Void, List<? super LiteralTree>> {
111 private final Trees trees;
112 private CompilationUnitTree cu;
113 private boolean inEmbedding;
115 Finder(final Trees trees) {
120 public Void visitCompilationUnit(
121 final CompilationUnitTree unit,
124 return super.visitCompilationUnit(unit, p);
130 public Void visitMethod(
132 final List<? super LiteralTree> p) {
133 for (AnnotationTree a : m.getModifiers().getAnnotations()) {
134 final TypeElement ae = (TypeElement) trees.getElement(TreePath.getPath(cu, a.getAnnotationType()));
135 if (ae != null && JS_ANNOTATION.contentEquals(ae.getQualifiedName())) {
136 final List<? extends ExpressionTree> args = a.getArguments();
137 for (ExpressionTree kvp : args) {
138 if (kvp instanceof AssignmentTree) {
139 final AssignmentTree assignemt = (AssignmentTree) kvp;
140 if (BODY.equals(assignemt.getVariable().toString())) {
143 scan(assignemt.getExpression(), p);
156 public Void visitLiteral(LiteralTree node, List<? super LiteralTree> p) {
160 return super.visitLiteral(node, p);
166 service = TaskFactory.class,
167 mimeType = JAVA_MIME_TYPE)
168 public static final class Factory extends TaskFactory {
170 public Collection<? extends SchedulerTask> create(Snapshot snpsht) {
171 return Collections.singleton(new JSEmbeddingProvider());