Improving the Decompile tab appearance.
authorJan Lahoda <jlahoda@netbeans.org>
Thu, 01 Aug 2013 06:27:45 +0200
changeset 180007caf2c2b5d3a
parent 17999 5eed4a47f214
child 18001 00bdd5d60184
Improving the Decompile tab appearance.
java.debugjavac/nbproject/project.xml
java.debugjavac/src-decompile/org/netbeans/modules/java/debugjavac/impl/DecompilerImpl.java
java.debugjavac/src-decompile/org/netbeans/modules/java/debugjavac/impl/DesugarDecompilerImpl.java
java.debugjavac/src/org/netbeans/modules/java/debugjavac/DJavaDataObject.java
java.debugjavac/src/org/netbeans/modules/java/debugjavac/DecompiledTab.java
java.debugjavac/src/org/netbeans/modules/java/debugjavac/Decompiler.java
java.debugjavac/src/org/netbeans/modules/java/debugjavac/TopLevelLexer.java
java.debugjavac/src/org/netbeans/modules/java/debugjavac/TopLevelTokenId.java
     1.1 --- a/java.debugjavac/nbproject/project.xml	Wed Jul 31 22:18:31 2013 +0200
     1.2 +++ b/java.debugjavac/nbproject/project.xml	Thu Aug 01 06:27:45 2013 +0200
     1.3 @@ -52,6 +52,24 @@
     1.4                      <compile-dependency/>
     1.5                  </dependency>
     1.6                  <dependency>
     1.7 +                    <code-name-base>org.netbeans.modules.editor</code-name-base>
     1.8 +                    <build-prerequisite/>
     1.9 +                    <compile-dependency/>
    1.10 +                    <run-dependency>
    1.11 +                        <release-version>3</release-version>
    1.12 +                        <specification-version>1.75</specification-version>
    1.13 +                    </run-dependency>
    1.14 +                </dependency>
    1.15 +                <dependency>
    1.16 +                    <code-name-base>org.netbeans.modules.editor.lib</code-name-base>
    1.17 +                    <build-prerequisite/>
    1.18 +                    <compile-dependency/>
    1.19 +                    <run-dependency>
    1.20 +                        <release-version>3</release-version>
    1.21 +                        <specification-version>3.45</specification-version>
    1.22 +                    </run-dependency>
    1.23 +                </dependency>
    1.24 +                <dependency>
    1.25                      <code-name-base>org.netbeans.modules.editor.lib2</code-name-base>
    1.26                      <build-prerequisite/>
    1.27                      <compile-dependency/>
    1.28 @@ -60,6 +78,15 @@
    1.29                      </run-dependency>
    1.30                  </dependency>
    1.31                  <dependency>
    1.32 +                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
    1.33 +                    <build-prerequisite/>
    1.34 +                    <compile-dependency/>
    1.35 +                    <run-dependency>
    1.36 +                        <release-version>1</release-version>
    1.37 +                        <specification-version>1.33</specification-version>
    1.38 +                    </run-dependency>
    1.39 +                </dependency>
    1.40 +                <dependency>
    1.41                      <code-name-base>org.netbeans.modules.java.lexer</code-name-base>
    1.42                      <build-prerequisite/>
    1.43                      <compile-dependency/>
    1.44 @@ -112,6 +139,14 @@
    1.45                      </run-dependency>
    1.46                  </dependency>
    1.47                  <dependency>
    1.48 +                    <code-name-base>org.openide.dialogs</code-name-base>
    1.49 +                    <build-prerequisite/>
    1.50 +                    <compile-dependency/>
    1.51 +                    <run-dependency>
    1.52 +                        <specification-version>7.32</specification-version>
    1.53 +                    </run-dependency>
    1.54 +                </dependency>
    1.55 +                <dependency>
    1.56                      <code-name-base>org.openide.filesystems</code-name-base>
    1.57                      <build-prerequisite/>
    1.58                      <compile-dependency/>
     2.1 --- a/java.debugjavac/src-decompile/org/netbeans/modules/java/debugjavac/impl/DecompilerImpl.java	Wed Jul 31 22:18:31 2013 +0200
     2.2 +++ b/java.debugjavac/src-decompile/org/netbeans/modules/java/debugjavac/impl/DecompilerImpl.java	Thu Aug 01 06:27:45 2013 +0200
     2.3 @@ -83,11 +83,12 @@
     2.4  public class DecompilerImpl implements Decompiler {
     2.5  
     2.6      @Override
     2.7 -    public String decompile(FileObject source) {
     2.8 +    public Result decompile(FileObject source) {
     2.9          String code = Source.create(source).createSnapshot().getText().toString();
    2.10 -        StringWriter w = new StringWriter();
    2.11 +        StringWriter errors = new StringWriter();
    2.12 +        StringWriter decompiled = new StringWriter();
    2.13          try {
    2.14 -            final Map<String, byte[]> bytecode = compile(source, w, code);
    2.15 +            final Map<String, byte[]> bytecode = compile(source, errors, code);
    2.16  
    2.17              if (!bytecode.isEmpty()) {
    2.18                  for (final Entry<String, byte[]> e : bytecode.entrySet()) {
    2.19 @@ -102,7 +103,7 @@
    2.20                      options.add("-verbose");
    2.21                      options.add(e.getKey());
    2.22                      t.handleOptions(options.toArray(new String[0]));
    2.23 -                    t.getContext().put(PrintWriter.class, new PrintWriter(w));
    2.24 +                    t.getContext().put(PrintWriter.class, new PrintWriter(decompiled));
    2.25                      ClassFileInfo cfi = t.read(new SimpleJavaFileObject(URI.create("mem://mem"), Kind.CLASS) {
    2.26                          @Override public InputStream openInputStream() throws IOException {
    2.27                              return new ByteArrayInputStream(e.getValue());
    2.28 @@ -113,12 +114,12 @@
    2.29                  }
    2.30              }
    2.31          } catch (IOException | ConstantPoolException ex) {
    2.32 -            ex.printStackTrace(new PrintWriter(w));
    2.33 -            Exceptions.printStackTrace(ex);
    2.34 +            ex.printStackTrace(new PrintWriter(errors));
    2.35          } catch (BadArgs ex) {
    2.36              Exceptions.printStackTrace(ex);
    2.37          }
    2.38 -        return w.toString();
    2.39 +        
    2.40 +        return new Result(errors.toString(), decompiled.toString(), "text/x-java-bytecode");
    2.41      }
    2.42      
    2.43      private static Map<String, byte[]> compile(FileObject source, final StringWriter errors, final String code) throws IOException {
     3.1 --- a/java.debugjavac/src-decompile/org/netbeans/modules/java/debugjavac/impl/DesugarDecompilerImpl.java	Wed Jul 31 22:18:31 2013 +0200
     3.2 +++ b/java.debugjavac/src-decompile/org/netbeans/modules/java/debugjavac/impl/DesugarDecompilerImpl.java	Thu Aug 01 06:27:45 2013 +0200
     3.3 @@ -74,28 +74,25 @@
     3.4  public class DesugarDecompilerImpl implements Decompiler {
     3.5  
     3.6      @Override
     3.7 -    public String decompile(FileObject source) {
     3.8 +    public Result decompile(FileObject source) {
     3.9          final String code = Source.create(source).createSnapshot().getText().toString();
    3.10 +        StringWriter errors = new StringWriter();
    3.11 +        StringWriter decompiled = new StringWriter();
    3.12          
    3.13          try {
    3.14 -            final StringWriter out = new StringWriter();
    3.15 -            DiagnosticListener<JavaFileObject> errorsListener = Utilities.errorReportingDiagnosticListener(out);
    3.16 +            DiagnosticListener<JavaFileObject> errorsListener = Utilities.errorReportingDiagnosticListener(errors);
    3.17              JavaFileObject file = Utilities.sourceFileObject(code);
    3.18              JavacTask task = JavacTool.create().getTask(null, 
    3.19                      null,
    3.20                      errorsListener, Utilities.commandLineParameters(source), null, Arrays.asList(file));
    3.21  
    3.22 -            JavaCompilerOverride.preRegister(((JavacTaskImpl) task).getContext(), out);
    3.23 +            JavaCompilerOverride.preRegister(((JavacTaskImpl) task).getContext(), decompiled);
    3.24              task.generate();
    3.25 -
    3.26 -            return out.toString();
    3.27          } catch (IOException ex) {
    3.28 -            Exceptions.printStackTrace(ex);
    3.29 -            StringWriter w = new StringWriter();
    3.30 -            PrintWriter pw = new PrintWriter(w);
    3.31 -            ex.printStackTrace(pw);
    3.32 -            return w.toString();
    3.33 +            ex.printStackTrace(new PrintWriter(errors));
    3.34          }
    3.35 +        
    3.36 +        return new Result(errors.toString(), decompiled.toString(), "text/x-java");
    3.37      }
    3.38      
    3.39      @Override
    3.40 @@ -129,7 +126,7 @@
    3.41              if (first != null) {
    3.42                  out.write("package ");
    3.43                  out.write(first.fst.toplevel.pid.toString());
    3.44 -                out.write("\n");
    3.45 +                out.write(";\n");
    3.46  
    3.47                  boolean firstImport = true;
    3.48  
    3.49 @@ -141,7 +138,7 @@
    3.50                              out.write("static ");
    3.51                          }
    3.52                          out.write(importTree.getQualifiedIdentifier().toString());
    3.53 -                        out.write("\n");
    3.54 +                        out.write(";\n");
    3.55                          firstImport = false;
    3.56                      }
    3.57                  }
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/java.debugjavac/src/org/netbeans/modules/java/debugjavac/DJavaDataObject.java	Thu Aug 01 06:27:45 2013 +0200
     4.3 @@ -0,0 +1,79 @@
     4.4 +/*
     4.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     4.6 + *
     4.7 + * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
     4.8 + *
     4.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    4.10 + * Other names may be trademarks of their respective owners.
    4.11 + *
    4.12 + * The contents of this file are subject to the terms of either the GNU
    4.13 + * General Public License Version 2 only ("GPL") or the Common
    4.14 + * Development and Distribution License("CDDL") (collectively, the
    4.15 + * "License"). You may not use this file except in compliance with the
    4.16 + * License. You can obtain a copy of the License at
    4.17 + * http://www.netbeans.org/cddl-gplv2.html
    4.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    4.19 + * specific language governing permissions and limitations under the
    4.20 + * License.  When distributing the software, include this License Header
    4.21 + * Notice in each file and include the License file at
    4.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    4.23 + * particular file as subject to the "Classpath" exception as provided
    4.24 + * by Oracle in the GPL Version 2 section of the License file that
    4.25 + * accompanied this code. If applicable, add the following below the
    4.26 + * License Header, with the fields enclosed by brackets [] replaced by
    4.27 + * your own identifying information:
    4.28 + * "Portions Copyrighted [year] [name of copyright owner]"
    4.29 + *
    4.30 + * If you wish your version of this file to be governed by only the CDDL
    4.31 + * or only the GPL Version 2, indicate your decision by adding
    4.32 + * "[Contributor] elects to include this software in this distribution
    4.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    4.34 + * single choice of license, a recipient has the option to distribute
    4.35 + * your version of this file under either the CDDL, the GPL Version 2 or
    4.36 + * to extend the choice of license to its licensees as provided above.
    4.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    4.38 + * Version 2 license, then the option applies only if the new code is
    4.39 + * made subject to such option by the copyright holder.
    4.40 + *
    4.41 + * Contributor(s):
    4.42 + *
    4.43 + * Portions Copyrighted 2013 Sun Microsystems, Inc.
    4.44 + */
    4.45 +package org.netbeans.modules.java.debugjavac;
    4.46 +
    4.47 +import java.io.IOException;
    4.48 +import org.openide.filesystems.FileObject;
    4.49 +import org.openide.filesystems.MIMEResolver;
    4.50 +import org.openide.loaders.DataObject;
    4.51 +import org.openide.loaders.DataObjectExistsException;
    4.52 +import org.openide.loaders.MultiDataObject;
    4.53 +import org.openide.loaders.MultiFileLoader;
    4.54 +import org.openide.util.NbBundle.Messages;
    4.55 +
    4.56 +@Messages({
    4.57 +    "LBL_DJava_LOADER=Files of DJava"
    4.58 +})
    4.59 +@MIMEResolver.ExtensionRegistration(
    4.60 +        displayName = "#LBL_DJava_LOADER",
    4.61 +        mimeType = "text/x-java-decompiled",
    4.62 +        extension = {"djava"}
    4.63 +        )
    4.64 +@DataObject.Registration(
    4.65 +        mimeType = "text/x-java-decompiled",
    4.66 +//        iconBase = "SET/PATH/TO/ICON/HERE",
    4.67 +        displayName = "#LBL_DJava_LOADER",
    4.68 +        position = 300
    4.69 +        )
    4.70 +public class DJavaDataObject extends MultiDataObject {
    4.71 +
    4.72 +    public DJavaDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException {
    4.73 +        super(pf, loader);
    4.74 +        registerEditor("text/x-java-decompiled", false);
    4.75 +    }
    4.76 +
    4.77 +    @Override
    4.78 +    protected int associateLookup() {
    4.79 +        return 1;
    4.80 +    }
    4.81 +
    4.82 +}
     5.1 --- a/java.debugjavac/src/org/netbeans/modules/java/debugjavac/DecompiledTab.java	Wed Jul 31 22:18:31 2013 +0200
     5.2 +++ b/java.debugjavac/src/org/netbeans/modules/java/debugjavac/DecompiledTab.java	Thu Aug 01 06:27:45 2013 +0200
     5.3 @@ -58,6 +58,7 @@
     5.4  import javax.swing.JScrollPane;
     5.5  import javax.swing.text.BadLocationException;
     5.6  import javax.swing.text.Document;
     5.7 +import javax.swing.text.StyledDocument;
     5.8  import org.netbeans.api.annotations.common.CheckForNull;
     5.9  import org.netbeans.api.java.source.CancellableTask;
    5.10  import org.netbeans.api.java.source.CompilationInfo;
    5.11 @@ -68,6 +69,10 @@
    5.12  import org.netbeans.core.spi.multiview.CloseOperationState;
    5.13  import org.netbeans.core.spi.multiview.MultiViewElement;
    5.14  import org.netbeans.core.spi.multiview.MultiViewElementCallback;
    5.15 +import org.netbeans.editor.GuardedDocument;
    5.16 +import org.netbeans.modules.editor.NbEditorDocument;
    5.17 +import org.netbeans.modules.editor.NbEditorKit;
    5.18 +import org.netbeans.modules.java.debugjavac.Decompiler.Result;
    5.19  import org.netbeans.modules.parsing.spi.TaskIndexingMode;
    5.20  import org.openide.awt.UndoRedo;
    5.21  import org.openide.cookies.EditorCookie;
    5.22 @@ -79,6 +84,7 @@
    5.23  import org.openide.filesystems.FileUtil;
    5.24  import org.openide.loaders.DataObject;
    5.25  import org.openide.modules.InstalledFileLocator;
    5.26 +import org.openide.text.NbDocument;
    5.27  import org.openide.util.Exceptions;
    5.28  import org.openide.util.Lookup;
    5.29  import org.openide.util.lookup.Lookups;
    5.30 @@ -103,7 +109,7 @@
    5.31  
    5.32          if (result == null && create) {
    5.33              try {
    5.34 -                FileObject decompiledFO = FileUtil.createMemoryFileSystem().getRoot().createData(source.getNameExt());
    5.35 +                FileObject decompiledFO = FileUtil.createMemoryFileSystem().getRoot().createData(source.getName(), "djava");
    5.36  
    5.37                  decompiledFO.setAttribute(ATTR_DECOMPILED, Boolean.TRUE);
    5.38  
    5.39 @@ -180,7 +186,7 @@
    5.40      
    5.41      private static void doDecompileIntoDocument(FileObject source) {
    5.42          FileObject decompiled = findDecompiled(source, true);
    5.43 -        Document doc = decompiledCodeDocument(source);
    5.44 +        final Document doc = decompiledCodeDocument(source);
    5.45          
    5.46          if (doc == null || doc.getProperty(DECOMPILE_TAB_ACTIVE) != Boolean.TRUE) return ;
    5.47          
    5.48 @@ -192,25 +198,39 @@
    5.49                  return ;
    5.50              }
    5.51  
    5.52 -            String decompiledCode;
    5.53 +            final String decompiledCode;
    5.54              
    5.55              if (((CompilerDescription) compilerDescription).isValid()) {
    5.56                  Decompiler decompiler = findDecompiler((CompilerDescription) compilerDescription, (String) decompilerId);
    5.57 -                decompiledCode = decompiler.decompile(source);
    5.58 +                Result decompileResult = decompiler.decompile(source);
    5.59 +                decompiledCode = (decompileResult.decompiledOutput != null ? "#Section(" + decompileResult.decompiledMimeType + ") Output:\n" + decompileResult.decompiledOutput + "\n" : "") +
    5.60 +                                 (decompileResult.compileErrors != null ? "#Section(text/plaing) Processing Errors:\n" + decompileResult.compileErrors + "\n" : "");
    5.61              } else {
    5.62                  decompiledCode = "Unusable compiler";
    5.63              }
    5.64  
    5.65 -            doc.remove(0, doc.getLength());
    5.66 -            doc.insertString(0, decompiledCode, null);
    5.67 +            NbDocument.runAtomic((StyledDocument) doc, new Runnable() {
    5.68 +                @Override public void run() {
    5.69 +                    try {
    5.70 +                        doc.remove(0, doc.getLength());
    5.71 +                        if (doc instanceof GuardedDocument) {
    5.72 +                            ((GuardedDocument) doc).getGuardedBlockChain().removeEmptyBlocks();
    5.73 +                        }
    5.74 +                        doc.insertString(0, decompiledCode, null);
    5.75 +                        if (doc instanceof GuardedDocument) {
    5.76 +                            ((GuardedDocument) doc).getGuardedBlockChain().addBlock(0, doc.getLength(), true);
    5.77 +                        }
    5.78 +                    } catch (BadLocationException ex) {
    5.79 +                        Exceptions.printStackTrace(ex);
    5.80 +                    }
    5.81 +                }
    5.82 +            });
    5.83              
    5.84              SaveCookie sc = DataObject.find(findDecompiled(source)).getLookup().lookup(SaveCookie.class);
    5.85              
    5.86              if (sc != null) sc.save();
    5.87          } catch (IOException ex) {
    5.88              Exceptions.printStackTrace(ex);
    5.89 -        } catch (BadLocationException ex) {
    5.90 -            Exceptions.printStackTrace(ex);
    5.91          }
    5.92      }
    5.93  
    5.94 @@ -229,7 +249,7 @@
    5.95          final FileObject decompiled = findDecompiled(d.getPrimaryFile(), true);
    5.96          return new MultiViewElement() {
    5.97              private JEditorPane pane;
    5.98 -            private JScrollPane scrollPane;
    5.99 +            private JComponent scrollPane;
   5.100              private final FileChangeListener fileListener = new FileChangeAdapter() {
   5.101                  @Override public void fileAttributeChanged(FileAttributeEvent fe) {
   5.102                      doDecompileIntoDocument(d.getPrimaryFile());
   5.103 @@ -239,10 +259,16 @@
   5.104              public JComponent getVisualRepresentation() {
   5.105                  if (pane == null) {
   5.106                      pane = new JEditorPane();
   5.107 +                    pane.setContentType("text/x-java-decompiled");
   5.108 +                    pane.setEditorKit(new NbEditorKit() {
   5.109 +                        @Override public String getContentType() {
   5.110 +                            return "text/x-java-decompiled";
   5.111 +                        }
   5.112 +                    });
   5.113                      Document doc = decompiledCodeDocument(d.getPrimaryFile());
   5.114                      if (doc != null)
   5.115                          pane.setDocument(doc);
   5.116 -                    scrollPane = new JScrollPane(pane);
   5.117 +                    scrollPane = doc instanceof NbEditorDocument ? (JComponent) ((NbEditorDocument) doc).createEditor(pane) : new JScrollPane(pane);
   5.118                  }
   5.119                  return scrollPane;
   5.120              }
   5.121 @@ -309,7 +335,7 @@
   5.122  
   5.123              @Override
   5.124              public CloseOperationState canCloseElement() {
   5.125 -                return null;
   5.126 +                return CloseOperationState.STATE_OK;
   5.127              }
   5.128              
   5.129          };
     6.1 --- a/java.debugjavac/src/org/netbeans/modules/java/debugjavac/Decompiler.java	Wed Jul 31 22:18:31 2013 +0200
     6.2 +++ b/java.debugjavac/src/org/netbeans/modules/java/debugjavac/Decompiler.java	Thu Aug 01 06:27:45 2013 +0200
     6.3 @@ -50,5 +50,16 @@
     6.4  public interface Decompiler {
     6.5      public String id();
     6.6      public String displayName();
     6.7 -    public String decompile(FileObject source);
     6.8 +    public Result decompile(FileObject source);
     6.9 +    
    6.10 +    public final class Result {
    6.11 +        public final String compileErrors;
    6.12 +        public final String decompiledOutput;
    6.13 +        public final String decompiledMimeType;
    6.14 +        public Result(String compileErrors, String decompiledOutput, String decompiledMimeType) {
    6.15 +            this.compileErrors = compileErrors.trim().isEmpty() ? null : compileErrors;
    6.16 +            this.decompiledOutput = decompiledOutput.trim().isEmpty() ? null : decompiledOutput;
    6.17 +            this.decompiledMimeType = decompiledMimeType;
    6.18 +        }
    6.19 +    }
    6.20  }
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/java.debugjavac/src/org/netbeans/modules/java/debugjavac/TopLevelLexer.java	Thu Aug 01 06:27:45 2013 +0200
     7.3 @@ -0,0 +1,111 @@
     7.4 +/*
     7.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     7.6 + *
     7.7 + * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
     7.8 + *
     7.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    7.10 + * Other names may be trademarks of their respective owners.
    7.11 + *
    7.12 + * The contents of this file are subject to the terms of either the GNU
    7.13 + * General Public License Version 2 only ("GPL") or the Common
    7.14 + * Development and Distribution License("CDDL") (collectively, the
    7.15 + * "License"). You may not use this file except in compliance with the
    7.16 + * License. You can obtain a copy of the License at
    7.17 + * http://www.netbeans.org/cddl-gplv2.html
    7.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    7.19 + * specific language governing permissions and limitations under the
    7.20 + * License.  When distributing the software, include this License Header
    7.21 + * Notice in each file and include the License file at
    7.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    7.23 + * particular file as subject to the "Classpath" exception as provided
    7.24 + * by Oracle in the GPL Version 2 section of the License file that
    7.25 + * accompanied this code. If applicable, add the following below the
    7.26 + * License Header, with the fields enclosed by brackets [] replaced by
    7.27 + * your own identifying information:
    7.28 + * "Portions Copyrighted [year] [name of copyright owner]"
    7.29 + *
    7.30 + * If you wish your version of this file to be governed by only the CDDL
    7.31 + * or only the GPL Version 2, indicate your decision by adding
    7.32 + * "[Contributor] elects to include this software in this distribution
    7.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    7.34 + * single choice of license, a recipient has the option to distribute
    7.35 + * your version of this file under either the CDDL, the GPL Version 2 or
    7.36 + * to extend the choice of license to its licensees as provided above.
    7.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    7.38 + * Version 2 license, then the option applies only if the new code is
    7.39 + * made subject to such option by the copyright holder.
    7.40 + *
    7.41 + * Contributor(s):
    7.42 + *
    7.43 + * Portions Copyrighted 2013 Sun Microsystems, Inc.
    7.44 + */
    7.45 +package org.netbeans.modules.java.debugjavac;
    7.46 +
    7.47 +import java.util.regex.Matcher;
    7.48 +import java.util.regex.Pattern;
    7.49 +import org.netbeans.api.lexer.Token;
    7.50 +import org.netbeans.spi.lexer.Lexer;
    7.51 +import org.netbeans.spi.lexer.LexerInput;
    7.52 +import org.netbeans.spi.lexer.LexerRestartInfo;
    7.53 +import org.netbeans.spi.lexer.TokenFactory;
    7.54 +
    7.55 +/**
    7.56 + *
    7.57 + * @author lahvac
    7.58 + */
    7.59 +public class TopLevelLexer implements Lexer<TopLevelTokenId> {
    7.60 +    
    7.61 +    private static final Pattern SECTION_PATTERN = Pattern.compile("#Section\\(([^)]*)\\)[^\n]*\n");
    7.62 +    private final TokenFactory<TopLevelTokenId> factory;
    7.63 +    private final LexerInput input;
    7.64 +    private TopLevelTokenId futureToken;
    7.65 +
    7.66 +    public TopLevelLexer(LexerRestartInfo<TopLevelTokenId> restart) {
    7.67 +        this.factory = restart.tokenFactory();
    7.68 +        this.input = restart.input();
    7.69 +        this.futureToken = restart.state() != null ? (TopLevelTokenId) restart.state() : TopLevelTokenId.OTHER;
    7.70 +    }
    7.71 +    
    7.72 +    @Override
    7.73 +    public Token<TopLevelTokenId> nextToken() {
    7.74 +        StringBuilder text = new StringBuilder();
    7.75 +        int read;
    7.76 +        
    7.77 +        while ((read = input.read()) != LexerInput.EOF) {
    7.78 +            text.append((char) read);
    7.79 +            
    7.80 +            Matcher m = SECTION_PATTERN.matcher(text);
    7.81 +            
    7.82 +            if (m.find()) {
    7.83 +                if (m.start() == 0) {
    7.84 +                    String mimeType = m.group(1);
    7.85 +                    
    7.86 +                    switch (mimeType) {
    7.87 +                        case "text/x-java": futureToken = TopLevelTokenId.JAVA; break;
    7.88 +                        case "text/x-java-bytecode": futureToken = TopLevelTokenId.ASM; break;
    7.89 +                        default: futureToken = TopLevelTokenId.OTHER; break;
    7.90 +                    }
    7.91 +                    
    7.92 +                    return factory.createToken(TopLevelTokenId.SECTION_HEADER);
    7.93 +                } else {
    7.94 +                    input.backup(input.readLength() - m.start());
    7.95 +                    break;
    7.96 +                }
    7.97 +            }
    7.98 +        }
    7.99 +        
   7.100 +        if (input.readLength() > 0)
   7.101 +            return factory.createToken(futureToken);
   7.102 +        
   7.103 +        return null;
   7.104 +    }
   7.105 +
   7.106 +    @Override
   7.107 +    public Object state() {
   7.108 +        return futureToken;
   7.109 +    }
   7.110 +
   7.111 +    @Override
   7.112 +    public void release() {}
   7.113 +    
   7.114 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/java.debugjavac/src/org/netbeans/modules/java/debugjavac/TopLevelTokenId.java	Thu Aug 01 06:27:45 2013 +0200
     8.3 @@ -0,0 +1,98 @@
     8.4 +/*
     8.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     8.6 + *
     8.7 + * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
     8.8 + *
     8.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    8.10 + * Other names may be trademarks of their respective owners.
    8.11 + *
    8.12 + * The contents of this file are subject to the terms of either the GNU
    8.13 + * General Public License Version 2 only ("GPL") or the Common
    8.14 + * Development and Distribution License("CDDL") (collectively, the
    8.15 + * "License"). You may not use this file except in compliance with the
    8.16 + * License. You can obtain a copy of the License at
    8.17 + * http://www.netbeans.org/cddl-gplv2.html
    8.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    8.19 + * specific language governing permissions and limitations under the
    8.20 + * License.  When distributing the software, include this License Header
    8.21 + * Notice in each file and include the License file at
    8.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    8.23 + * particular file as subject to the "Classpath" exception as provided
    8.24 + * by Oracle in the GPL Version 2 section of the License file that
    8.25 + * accompanied this code. If applicable, add the following below the
    8.26 + * License Header, with the fields enclosed by brackets [] replaced by
    8.27 + * your own identifying information:
    8.28 + * "Portions Copyrighted [year] [name of copyright owner]"
    8.29 + *
    8.30 + * If you wish your version of this file to be governed by only the CDDL
    8.31 + * or only the GPL Version 2, indicate your decision by adding
    8.32 + * "[Contributor] elects to include this software in this distribution
    8.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    8.34 + * single choice of license, a recipient has the option to distribute
    8.35 + * your version of this file under either the CDDL, the GPL Version 2 or
    8.36 + * to extend the choice of license to its licensees as provided above.
    8.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    8.38 + * Version 2 license, then the option applies only if the new code is
    8.39 + * made subject to such option by the copyright holder.
    8.40 + *
    8.41 + * Contributor(s):
    8.42 + *
    8.43 + * Portions Copyrighted 2013 Sun Microsystems, Inc.
    8.44 + */
    8.45 +package org.netbeans.modules.java.debugjavac;
    8.46 +
    8.47 +import java.util.Arrays;
    8.48 +import java.util.Collection;
    8.49 +import org.netbeans.api.editor.mimelookup.MimeRegistration;
    8.50 +import org.netbeans.api.lexer.InputAttributes;
    8.51 +import org.netbeans.api.lexer.Language;
    8.52 +import org.netbeans.api.lexer.LanguagePath;
    8.53 +import org.netbeans.api.lexer.Token;
    8.54 +import org.netbeans.api.lexer.TokenId;
    8.55 +import org.netbeans.spi.lexer.EmbeddingPresence;
    8.56 +import org.netbeans.spi.lexer.LanguageEmbedding;
    8.57 +import org.netbeans.spi.lexer.LanguageHierarchy;
    8.58 +import org.netbeans.spi.lexer.Lexer;
    8.59 +import org.netbeans.spi.lexer.LexerRestartInfo;
    8.60 +
    8.61 +/**
    8.62 + *
    8.63 + * @author lahvac
    8.64 + */
    8.65 +public enum TopLevelTokenId implements TokenId {
    8.66 +    SECTION_HEADER,
    8.67 +    JAVA,
    8.68 +    ASM,
    8.69 +    OTHER;
    8.70 +
    8.71 +    @Override
    8.72 +    public String primaryCategory() {
    8.73 +        return this == SECTION_HEADER ? "comment" : "code";
    8.74 +    }
    8.75 +    
    8.76 +    private static final Language<TopLevelTokenId> LANGUAGE = new LanguageHierarchy<TopLevelTokenId>() {
    8.77 +        @Override protected Collection<TopLevelTokenId> createTokenIds() {
    8.78 +            return Arrays.asList(TopLevelTokenId.values());
    8.79 +        }
    8.80 +        @Override protected Lexer<TopLevelTokenId> createLexer(LexerRestartInfo<TopLevelTokenId> info) {
    8.81 +            return new TopLevelLexer(info);
    8.82 +        }
    8.83 +        @Override protected String mimeType() {
    8.84 +            return "text/x-java-decompiled";
    8.85 +        }
    8.86 +        @Override protected LanguageEmbedding<?> embedding(Token<TopLevelTokenId> token, LanguagePath languagePath, InputAttributes inputAttributes) {
    8.87 +            switch (token.id()) {
    8.88 +                case JAVA:
    8.89 +                    return LanguageEmbedding.create(Language.find("text/x-java"), 0, 0);
    8.90 +                default:
    8.91 +                    return null;
    8.92 +            }
    8.93 +        }
    8.94 +
    8.95 +    }.language();
    8.96 +    
    8.97 +    @MimeRegistration(mimeType="text/x-java-decompiled", service=Language.class)
    8.98 +    public static final Language<TopLevelTokenId> language() {
    8.99 +        return LANGUAGE;
   8.100 +    }
   8.101 +}