You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by jt...@apache.org on 2019/04/14 07:24:48 UTC

[incubator-netbeans] branch master updated: Adding Java-level registration for TextMate grammers, adding the textmate.lexer javadoc into the IDE javadocs.

This is an automated email from the ASF dual-hosted git repository.

jtulach pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-netbeans.git


The following commit(s) were added to refs/heads/master by this push:
     new 9653e3d  Adding Java-level registration for TextMate grammers, adding the textmate.lexer javadoc into the IDE javadocs.
     new 0041f4c  Merge pull request #1200 from jlahoda/textmate-javadoc
9653e3d is described below

commit 9653e3d8995ef69b3d34114befc47d65d2bda95e
Author: Jan Lahoda <jl...@netbeans.org>
AuthorDate: Sat Apr 13 15:40:52 2019 +0200

    Adding Java-level registration for TextMate grammers, adding the textmate.lexer javadoc into the IDE javadocs.
---
 ide/textmate.lexer/apichanges.xml                  | 105 +++++++++
 ide/textmate.lexer/arch.xml                        |  10 +-
 ide/textmate.lexer/manifest.mf                     |   2 +-
 ide/textmate.lexer/nbproject/project.properties    |   1 +
 ide/textmate.lexer/nbproject/project.xml           |   9 +-
 .../lexer/CreateRegistrationProcessor.java         | 247 +++++++++++++++++++++
 .../textmate/lexer/api/GrammarRegistration.java    |  45 ++++
 .../textmate/lexer/api/GrammarRegistrations.java   |  37 +++
 .../lexer/CreateRegistrationProcessorTest.java     |  94 ++++++++
 nbbuild/build.properties                           |   1 +
 nbbuild/javadoctools/links.xml                     |   1 +
 nbbuild/javadoctools/properties.xml                |   1 +
 nbbuild/javadoctools/replaces.xml                  |   1 +
 13 files changed, 551 insertions(+), 3 deletions(-)

diff --git a/ide/textmate.lexer/apichanges.xml b/ide/textmate.lexer/apichanges.xml
new file mode 100644
index 0000000..397d1af
--- /dev/null
+++ b/ide/textmate.lexer/apichanges.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+
+<?xml-stylesheet href="../o.n.co../../nbbuild/javadoctools/apichanges.xsl" type="text/xsl"?>
+<!DOCTYPE apichanges PUBLIC "-//NetBeans//DTD API changes list 1.0//EN" "../../nbbuild/javadoctools/apichanges.dtd">
+
+<!-- INFO FOR PEOPLE ADDING CHANGES:
+[most of contents snipped - see openide's apichanges for how-to instructions]
+<change>
+    <api name="compiler"/>
+    <summary>Some brief description here, can use <b>XHTML</b></summary>
+    <version major="1" minor="99"/>
+    <date day="13" month="6" year="2001"/>
+    <author login="jrhacker"/>
+    <compatibility addition="yes"/>
+    <description>
+        The main description of the change here.
+        Again can use full <b>XHTML</b> as needed.
+    </description>
+    <class package="org.openide.compiler" name="DoWhatIWantCompiler"/>
+    <issue number="14309"/>
+</change>
+-->
+
+<apichanges>
+
+<!-- First, a list of API names you may use: -->
+<apidefs>
+        <apidef name="TextmateLexer">Textmate Lexer</apidef>
+</apidefs>
+
+<!-- ACTUAL CHANGES BEGIN HERE: -->
+
+<changes>
+    <change id="annotation_registration" >
+        <api name="TextmateLexer"/>
+        <summary>Annotation to register Textmate grammars added.</summary>
+        <version major="1" minor="2"/>
+        <date day="20" month="4" year="2019"/>
+        <author login="jlahoda"/>
+        <compatibility addition="yes"/>
+        <description>
+            <p>
+                Annotation that allows to register the Textmate grammars in Java source code has been added.
+            </p>
+        </description>
+    </change>
+</changes>
+
+  <!-- Now the surrounding HTML text and document structure: -->
+
+  <htmlcontents>
+<!--
+
+                            NO NO NO NO NO!
+
+         ==============>    DO NOT EDIT ME!  <======================
+
+          AUTOMATICALLY GENERATED FROM APICHANGES.XML, DO NOT EDIT
+
+                SEE xml/api/doc/changes/apichanges.xml
+
+-->
+    <head>
+      <title>Options Dialog API changes by date</title>
+      <link rel="stylesheet" href="prose.css" type="text/css"/>
+    </head>
+    <body>
+
+<p class="overviewlink"><a href="overview-summary.html">Overview</a></p>
+
+<h1>Introduction</h1>
+
+<p>This document lists changes made to the Textmade Lexer APIs. Please ask on the 
+    <code>dev@netbeans.apache.org</code>
+    mailing list if you have any questions about the details of a
+    change, or are wondering how to convert existing code to be compatible.
+</p>
+
+      <hr/><standard-changelists module-code-name="org.netbeans.modules.textmate.lexer/0"/>
+
+      <hr/><p>@FOOTER@</p>
+
+    </body>
+  </htmlcontents>
+</apichanges>
diff --git a/ide/textmate.lexer/arch.xml b/ide/textmate.lexer/arch.xml
index 9e275fe..ec22011 100644
--- a/ide/textmate.lexer/arch.xml
+++ b/ide/textmate.lexer/arch.xml
@@ -131,6 +131,14 @@
     &lt;/folder&gt;
           </pre>
       </usecase>
+      <usecase id="register-grammar-using-java-api" name="Register grammar using Java API">
+          To register a new TextMate grammar using Java API, add the GrammarRegistration
+          annotation to an appropriate package-info file, or an appropriate Java class.
+          For example:
+          <pre>
+    {@literal @}GrammarRegistration(mimeType="text/x-kotlin", grammar="path/to/Kotlin.tmLanguage.json")
+          </pre>
+      </usecase>
   </p>
  </answer>
 
@@ -374,7 +382,7 @@
 -->
  <answer id="deploy-dependencies">
   <p>
-   No real dependencies needed currently.
+   Nothing.
   </p>
  </answer>
 
diff --git a/ide/textmate.lexer/manifest.mf b/ide/textmate.lexer/manifest.mf
index 2736967..4a250e4 100644
--- a/ide/textmate.lexer/manifest.mf
+++ b/ide/textmate.lexer/manifest.mf
@@ -3,5 +3,5 @@ AutoUpdate-Show-In-Client: false
 OpenIDE-Module: org.netbeans.modules.textmate.lexer/0
 OpenIDE-Module-Layer: org/netbeans/modules/textmate/lexer/resources/layer.xml
 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/textmate/lexer/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.1
+OpenIDE-Module-Specification-Version: 1.2
 
diff --git a/ide/textmate.lexer/nbproject/project.properties b/ide/textmate.lexer/nbproject/project.properties
index 3576ad1..4dec2bb 100644
--- a/ide/textmate.lexer/nbproject/project.properties
+++ b/ide/textmate.lexer/nbproject/project.properties
@@ -18,6 +18,7 @@ is.autoload=true
 javac.source=1.8
 javac.compilerargs=-Xlint -Xlint:-serial
 javadoc.arch=${basedir}/arch.xml
+javadoc.apichanges=${basedir}/apichanges.xml
 release.external/joni-2.1.11.jar=modules/ext/joni-2.1.11.jar
 release.external/jcodings-1.0.41.jar=modules/ext/jcodings-1.0.41.jar
 release.external/org.eclipse.tm4e.core_0.2.0.201809031154.jar=modules/ext/org.eclipse.tm4e.core_0.2.0.201809031154.jar
diff --git a/ide/textmate.lexer/nbproject/project.xml b/ide/textmate.lexer/nbproject/project.xml
index cac8085..07a07fe 100644
--- a/ide/textmate.lexer/nbproject/project.xml
+++ b/ide/textmate.lexer/nbproject/project.xml
@@ -182,9 +182,16 @@
                         <recursive/>
                         <compile-dependency/>
                     </test-dependency>
+                    <test-dependency>
+                        <code-name-base>org.openide.util.lookup</code-name-base>
+                        <compile-dependency/>
+                        <test/>
+                    </test-dependency>
                 </test-type>
             </test-dependencies>
-            <public-packages/>
+            <public-packages>
+                <package>org.netbeans.modules.textmate.lexer.api</package>
+            </public-packages>
             <class-path-extension>
                 <runtime-relative-path>ext/joni-2.1.11.jar</runtime-relative-path>
                 <binary-origin>external/joni-2.1.11.jar</binary-origin>
diff --git a/ide/textmate.lexer/src/org/netbeans/modules/textmate/lexer/CreateRegistrationProcessor.java b/ide/textmate.lexer/src/org/netbeans/modules/textmate/lexer/CreateRegistrationProcessor.java
new file mode 100644
index 0000000..9996d35
--- /dev/null
+++ b/ide/textmate.lexer/src/org/netbeans/modules/textmate/lexer/CreateRegistrationProcessor.java
@@ -0,0 +1,247 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.netbeans.modules.textmate.lexer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map.Entry;
+import java.util.Set;
+import javax.annotation.processing.Completion;
+import javax.annotation.processing.Processor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.TypeElement;
+import org.eclipse.tm4e.core.registry.IRegistryOptions;
+import org.eclipse.tm4e.core.registry.Registry;
+import org.openide.filesystems.annotations.LayerBuilder;
+import org.openide.filesystems.annotations.LayerGeneratingProcessor;
+import org.openide.filesystems.annotations.LayerGenerationException;
+import org.openide.util.Exceptions;
+import org.openide.util.Lookup;
+import org.openide.util.NbCollections;
+import org.openide.util.lookup.ServiceProvider;
+
+/**
+ *
+ * @author Jan Lahoda
+ */
+@SupportedAnnotationTypes({"org.netbeans.modules.textmate.lexer.api.GrammarRegistration", "org.netbeans.modules.textmate.lexer.api.GrammarRegistrations"})
+@SupportedSourceVersion(SourceVersion.RELEASE_8)
+@ServiceProvider(service=Processor.class)
+public class CreateRegistrationProcessor extends LayerGeneratingProcessor {
+
+    @Override
+    protected boolean handleProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) throws LayerGenerationException {
+        TypeElement grammarRegistration = processingEnv.getElementUtils().getTypeElement("org.netbeans.modules.textmate.lexer.api.GrammarRegistration");
+
+        for (Element el : roundEnv.getElementsAnnotatedWith(grammarRegistration)) {
+            for (AnnotationMirror am : el.getAnnotationMirrors()) {
+                if (!grammarRegistration.equals(am.getAnnotationType().asElement())) {
+                    continue;
+                }
+
+                process(el, am);
+            }
+        }
+
+        TypeElement grammarRegistrations = processingEnv.getElementUtils().getTypeElement("org.netbeans.modules.textmate.lexer.api.GrammarRegistrations");
+
+        for (Element el : roundEnv.getElementsAnnotatedWith(grammarRegistrations)) {
+            for (AnnotationMirror am : el.getAnnotationMirrors()) {
+                if (!grammarRegistrations.equals(am.getAnnotationType().asElement())) {
+                    continue;
+                }
+
+                for (Entry<? extends ExecutableElement, ? extends AnnotationValue> e : am.getElementValues().entrySet()) {
+                    if (!e.getKey().getSimpleName().contentEquals("value")) continue;
+
+                    for (AnnotationMirror r : NbCollections.iterable(NbCollections.checkedIteratorByFilter(((Iterable) e.getValue().getValue()).iterator(), AnnotationMirror.class, true))) {
+                        process(el, r);
+                    }
+                }
+            }
+        }
+
+        return true;
+    }
+
+    private void process(Element toRegister, AnnotationMirror mimeRegistration) throws LayerGenerationException {
+        String grammar = null;
+        String mimeType = null;
+        for (Entry<? extends ExecutableElement, ? extends AnnotationValue> e : mimeRegistration.getElementValues().entrySet()) {
+            Name simpleName = e.getKey().getSimpleName();
+            if (simpleName.contentEquals("grammar")) {
+                grammar = (String) e.getValue().getValue();
+                continue;
+            }
+            if (simpleName.contentEquals("mimeType")) {
+                mimeType = (String) e.getValue().getValue();
+                continue;
+            }
+        }
+
+        if (mimeType != null && grammar != null) {
+            if (mimeType.length() != 0) mimeType = "/" + mimeType;
+
+            LayerBuilder layer = layer(toRegister);
+            javax.tools.FileObject file = layer.validateResource(grammar, toRegister, null, null, false);
+            try (InputStream in = file.openInputStream()) {
+                IRegistryOptions opts = new IRegistryOptions() {
+                    @Override
+                    public String getFilePath(String scopeName) {
+                        return null;
+                    }
+                    @Override
+                    public InputStream getInputStream(String scopeName) throws IOException {
+                        return null;
+                    }
+                    @Override
+                    public Collection<String> getInjections(String scopeName) {
+                        return null;
+                    }
+                };
+                String scopeName = new Registry(opts).loadGrammarFromPathSync(grammar, in).getScopeName();
+                String simpleName = grammar.lastIndexOf('/') != (-1) ? grammar.substring(grammar.lastIndexOf('/') + 1) : grammar;
+                layer.file("Editors" + mimeType + "/" + simpleName)
+                     .url("nbresloc:/" + grammar)
+                     .stringvalue("textmate-grammar", scopeName).write();    //NOI18N
+            } catch (Exception ex) {
+                throw (LayerGenerationException) new LayerGenerationException(ex.getMessage()).initCause(ex);
+            }
+        }
+    }
+
+    @Override
+    public Iterable<? extends Completion> getCompletions(Element annotated, AnnotationMirror annotation, ExecutableElement attr, String userText) {
+        if (processingEnv == null || annotated == null) {
+            return Collections.emptyList();
+        }
+
+        if (   annotation == null
+            || !"org.netbeans.modules.textmate.lexer.api.GrammarRegistration".contentEquals(((TypeElement) annotation.getAnnotationType().asElement()).getQualifiedName())) {
+            return Collections.emptyList();
+        }
+
+        if ("mimeType".contentEquals(attr.getSimpleName())) { // NOI18N
+            return completeMimePath(annotated, annotation, attr, userText);
+        }
+
+        return Collections.emptyList();
+    }
+    
+    private static final String[] DEFAULT_COMPLETIONS = {"text/plain", "text/xml", "text/x-java"}; // NOI18N
+    private Processor COMPLETIONS;
+    private Iterable<? extends Completion> completeMimePath(
+        Element element, AnnotationMirror annotation,
+        ExecutableElement attr, String userText
+    ) {
+        if (userText == null) {
+            userText = "";
+        }
+        if (userText.startsWith("\"")) {
+            userText = userText.substring(1);
+        }
+
+        Set<Completion> res = new HashSet<Completion>();
+        if (COMPLETIONS == null) {
+            String pathCompletions = System.getProperty("org.openide.awt.ActionReference.completion");
+            if (pathCompletions != null) {
+                ClassLoader l = Lookup.getDefault().lookup(ClassLoader.class);
+                if (l == null) {
+                    l = Thread.currentThread().getContextClassLoader();
+                }
+                if (l == null) {
+                    l = CreateRegistrationProcessor.class.getClassLoader();
+                }
+                try {
+                    COMPLETIONS = (Processor)Class.forName(pathCompletions, true, l).newInstance();
+                } catch (Exception ex) {
+                    Exceptions.printStackTrace(ex);
+                    // no completions, OK
+                    COMPLETIONS = this;
+                }
+            } else {
+                return res;
+            }
+        }
+        if (COMPLETIONS != null && COMPLETIONS != this) {
+            COMPLETIONS.init(processingEnv);
+            for (Completion completion : COMPLETIONS.getCompletions(element, annotation, attr, "Editors/" + userText)) {
+                String v = completion.getValue();
+                if (v == null) {
+                    continue;
+                }
+                String[] arr = v.split("/");
+                if (arr.length > 3 || arr.length < 2) {
+                    continue;
+                }
+                if (!arr[0].equals("\"Editors")) {
+                    continue;
+                }
+                if (arr[1].length() == 0 || Character.isUpperCase(arr[1].charAt(0))) {
+                    // upper case means folders created by @MimeLocation very likelly
+                    continue;
+                }
+                if (arr.length > 2) {
+                    res.add(new TypeCompletion('"' + arr[1] + '/' + arr[2]));
+                } else {
+                    res.add(new TypeCompletion('"' + arr[1] + '/'));
+                }
+            }
+        }
+        if (res.isEmpty()) {
+            for (String c : DEFAULT_COMPLETIONS) {
+                if (c.startsWith(userText)) {
+                    res.add(new TypeCompletion("\"" + c));
+                }
+            }
+        }
+        
+        return res;
+    }
+
+    private static final class TypeCompletion implements Completion {
+
+        private final String type;
+
+        public TypeCompletion(String type) {
+            this.type = type;
+        }
+
+        public String getValue() {
+            return type;
+        }
+
+        public String getMessage() {
+            return null;
+        }
+
+    }
+}
diff --git a/ide/textmate.lexer/src/org/netbeans/modules/textmate/lexer/api/GrammarRegistration.java b/ide/textmate.lexer/src/org/netbeans/modules/textmate/lexer/api/GrammarRegistration.java
new file mode 100644
index 0000000..8a98445
--- /dev/null
+++ b/ide/textmate.lexer/src/org/netbeans/modules/textmate/lexer/api/GrammarRegistration.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.textmate.lexer.api;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Target;
+
+/** Register the given Textmate grammar for use in the IDE.
+ * 
+ * @since 1.2
+ */
+@Repeatable(GrammarRegistrations.class)
+@Target({ElementType.PACKAGE, ElementType.TYPE})
+public @interface GrammarRegistration {
+
+    /** The mime-type under which the grammar should be registered.
+     *
+     * @return mime-type
+     */
+    public String mimeType();
+
+    /** The grammar to register.
+     *
+     * @return grammar
+     */
+    public String grammar();
+
+}
diff --git a/ide/textmate.lexer/src/org/netbeans/modules/textmate/lexer/api/GrammarRegistrations.java b/ide/textmate.lexer/src/org/netbeans/modules/textmate/lexer/api/GrammarRegistrations.java
new file mode 100644
index 0000000..7c7463b
--- /dev/null
+++ b/ide/textmate.lexer/src/org/netbeans/modules/textmate/lexer/api/GrammarRegistrations.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.textmate.lexer.api;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/** Register multiple grammars.
+ * 
+ * @since 1.2
+ */
+@Target({ElementType.PACKAGE, ElementType.TYPE})
+public @interface GrammarRegistrations {
+
+    /**The grammar registration to delegate to.
+     *
+     * @return grammar resitrations
+     */
+    public GrammarRegistration[] value();
+
+}
diff --git a/ide/textmate.lexer/test/unit/src/org/netbeans/modules/textmate/lexer/CreateRegistrationProcessorTest.java b/ide/textmate.lexer/test/unit/src/org/netbeans/modules/textmate/lexer/CreateRegistrationProcessorTest.java
new file mode 100644
index 0000000..a9cbdc9
--- /dev/null
+++ b/ide/textmate.lexer/test/unit/src/org/netbeans/modules/textmate/lexer/CreateRegistrationProcessorTest.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.textmate.lexer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.Writer;
+import org.netbeans.junit.NbTestCase;
+import org.netbeans.modules.textmate.lexer.api.GrammarRegistration;
+import org.openide.util.test.AnnotationProcessorTestUtils;
+
+/**
+ *
+ * @author Jaroslav Tulach <jt...@netbeans.org>
+ */
+public class CreateRegistrationProcessorTest extends NbTestCase {
+    
+    public CreateRegistrationProcessorTest(String n) {
+        super(n);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        clearWorkDir();
+    }
+    
+    public void testGrammarOK() throws Exception {
+        System.setProperty("executed", "false");
+        AnnotationProcessorTestUtils.makeSource(getWorkDir(),
+                                                "Test",
+                                                "import " + GrammarRegistration.class.getCanonicalName() + ";\n" +
+                                                "@GrammarRegistration(mimeType=\"text/test\",grammar=\"grammar.json\")\n" +
+                                                "public class Test {}\n");
+        try (Writer w = new FileWriter(new File(getWorkDir(), "grammar.json"))) {
+            w.write("{ \"scopeName\": \"test\", " +
+                    " \"patterns\": [\n" +
+                    "]}\n");
+        }
+
+        File outDir = new File(getWorkDir(), "out");
+
+        outDir.mkdirs();
+
+        assertTrue("Compiles OK",
+            AnnotationProcessorTestUtils.runJavac(getWorkDir(), null, outDir, null, System.err)
+            );
+        
+        try (Reader r = new InputStreamReader(new FileInputStream(new File(new File(outDir, "META-INF"), "generated-layer.xml")), "UTF-8")) {
+            StringBuilder content = new StringBuilder();
+            int read;
+            
+            while ((read = r.read()) != (-1)) {
+                content.append((char) read);
+            }
+
+            assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+                         "<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.2//EN\"\n" +
+                         "                            \"http://www.netbeans.org/dtds/filesystem-1_2.dtd\">\n" +
+                         "<filesystem>\n" +
+                         "    <folder name=\"Editors\">\n" +
+                         "        <folder name=\"text\">\n" +
+                         "            <folder name=\"test\">\n" +
+                         "                <file name=\"grammar.json\" url=\"nbresloc:/grammar.json\">\n" +
+                         "                    <!--Test-->\n" +
+                         "                    <attr name=\"textmate-grammar\" stringvalue=\"test\"/>\n" +
+                         "                </file>\n" +
+                         "            </folder>\n" +
+                         "        </folder>\n" +
+                         "    </folder>\n" +
+                         "</filesystem>\n",
+                         content.toString());
+        }
+    }
+    
+}
diff --git a/nbbuild/build.properties b/nbbuild/build.properties
index ae896db..c6ac7f7 100644
--- a/nbbuild/build.properties
+++ b/nbbuild/build.properties
@@ -178,6 +178,7 @@ config.javadoc.devel=\
     refactoring.api,\
     refactoring.java,\
     server,\
+    textmate.lexer,\
     versioning,\
     bugtracking,\
     sampler,\
diff --git a/nbbuild/javadoctools/links.xml b/nbbuild/javadoctools/links.xml
index d62f1da..1725127 100644
--- a/nbbuild/javadoctools/links.xml
+++ b/nbbuild/javadoctools/links.xml
@@ -234,3 +234,4 @@
 <link href="${javadoc.docs.org-netbeans-libs-graalsdk}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-libs-graalsdk"/>
 <link href="${javadoc.docs.org-netbeans-modules-gradle}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-gradle"/>
 <link href="${javadoc.docs.org-netbeans-modules-gradle-java}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-gradle-java"/>
+<link href="${javadoc.docs.org-netbeans-modules-textmate-lexer}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-textmate-lexer"/>
diff --git a/nbbuild/javadoctools/properties.xml b/nbbuild/javadoctools/properties.xml
index 0efd98d..55a1e74 100644
--- a/nbbuild/javadoctools/properties.xml
+++ b/nbbuild/javadoctools/properties.xml
@@ -232,3 +232,4 @@
 <property name="javadoc.docs.org-netbeans-libs-graalsdk" value="${javadoc.web.root}/org-netbeans-libs-graalsdk"/>
 <property name="javadoc.docs.org-netbeans-modules-gradle" value="${javadoc.web.root}/org-netbeans-modules-gradle"/>
 <property name="javadoc.docs.org-netbeans-modules-gradle-java" value="${javadoc.web.root}/org-netbeans-modules-gradle-java"/>
+<property name="javadoc.docs.org-netbeans-modules-textmate-lexer" value="${javadoc.web.root}/org-netbeans-modules-textmate-lexer"/>
diff --git a/nbbuild/javadoctools/replaces.xml b/nbbuild/javadoctools/replaces.xml
index a82beeb..62208cc 100644
--- a/nbbuild/javadoctools/replaces.xml
+++ b/nbbuild/javadoctools/replaces.xml
@@ -232,3 +232,4 @@
 <replacefilter token="@org-netbeans-libs-graalsdk@" value="${javadoc.docs.org-netbeans-libs-graalsdk}"/>
 <replacefilter token="@org-netbeans-modules-gradle@" value="${javadoc.docs.org-netbeans-modules-gradle}"/>
 <replacefilter token="@org-netbeans-modules-gradle-java@" value="${javadoc.docs.org-netbeans-modules-gradle-java}"/>
+<replacefilter token="@org-netbeans-modules-textmate-lexer@" value="${javadoc.docs.org-netbeans-modules-textmate-lexer}"/>


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists