Java tutorial
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2015 Everlaw. All rights reserved. * * Oracle and Java are registered trademarks of Oracle and/or its affiliates. * Other names may be trademarks of their respective owners. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common * Development and Distribution License("CDDL") (collectively, the * "License"). You may not use this file except in compliance with the * License. You can obtain a copy of the License at * http://www.netbeans.org/cddl-gplv2.html * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the * specific language governing permissions and limitations under the * License. When distributing the software, include this License Header * Notice in each file and include the License file at * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the GPL Version 2 section of the License file that * accompanied this code. If applicable, add the following below the * License Header, with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * If you wish your version of this file to be governed by only the CDDL * or only the GPL Version 2, indicate your decision by adding * "[Contributor] elects to include this software in this distribution * under the [CDDL or GPL Version 2] license." If you do not indicate a * single choice of license, a recipient has the option to distribute * your version of this file under either the CDDL, the GPL Version 2 or * to extend the choice of license to its licensees as provided above. * However, if you add GPL Version 2 code and therefore, elected the GPL * Version 2 license, then the option applies only if the new code is * made subject to such option by the copyright holder. */ package netbeanstypescript; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.ImageIcon; import org.json.simple.JSONObject; import org.netbeans.modules.csl.api.*; import org.netbeans.modules.csl.spi.ParserResult; import org.openide.filesystems.FileObject; /** * * @author jeffrey */ public class TSStructureScanner implements StructureScanner { static class TSStructureItem extends TSElementHandle implements StructureItem { String typeExtends; String type; Object overrides; FileObject fileObj; TSStructureItem parent; int numOfName; List<TSStructureItem> children; TSStructureItem(JSONObject item) { super(new OffsetRange(((Number) item.get("start")).intValue(), ((Number) item.get("end")).intValue()), item); typeExtends = (String) item.get("extends"); type = (String) item.get("type"); overrides = item.get("overrides"); } @Override public String getSortText() { return name; } @Override public String getHtml(HtmlFormatter hf) { if (modifiers.contains(Modifier.DEPRECATED)) { hf.deprecated(true); hf.appendText(name); hf.deprecated(false); } else { hf.appendText(name); } if (typeExtends != null) { hf.appendText(" :: "); hf.type(true); hf.appendText(typeExtends); hf.type(false); } if (type != null) { hf.appendText(" : "); hf.type(true); hf.appendText(type); hf.type(false); } return hf.getText(); } @Override public ElementHandle getElementHandle() { return this; } @Override public FileObject getFileObject() { return fileObj; } @Override public String getMimeType() { return "text/typescript"; } @Override public boolean isLeaf() { return children.isEmpty(); } @Override public List<? extends StructureItem> getNestedItems() { return children; } @Override public long getPosition() { return textSpan.getStart(); } @Override public long getEndPosition() { return textSpan.getEnd(); } @Override public ImageIcon getCustomIcon() { return getIcon(); } @Override public boolean equals(Object obj) { if (!(obj instanceof TSStructureItem)) return false; TSStructureItem left = this; TSStructureItem right = (TSStructureItem) obj; while (left != right) { if (left == null || right == null) return false; if (left.kind != right.kind) return false; if (!left.name.equals(right.name)) return false; if (left.numOfName != right.numOfName) return false; left = left.parent; right = right.parent; } return true; } @Override public int hashCode() { return Objects.hash(kind, name, numOfName); } } private List<TSStructureItem> convertStructureItems(FileObject fileObj, TSStructureItem parent, Object arr) { if (arr == null) { return Collections.emptyList(); } List<TSStructureItem> items = new ArrayList<>(); Map<String, Integer> nameCounts = new HashMap<>(); for (JSONObject elem : (List<JSONObject>) arr) { TSStructureItem item = new TSStructureItem(elem); Integer numOfName = nameCounts.get(item.name); if (numOfName == null) numOfName = 0; nameCounts.put(item.name, numOfName + 1); item.fileObj = fileObj; item.parent = parent; item.numOfName = numOfName; item.children = convertStructureItems(fileObj, item, elem.get("children")); items.add(item); } return items; } @Override public List<? extends StructureItem> scan(ParserResult pr) { FileObject fo = pr.getSnapshot().getSource().getFileObject(); return convertStructureItems(fo, null, TSService.call("getStructureItems", fo)); } private final Pattern editorFolds = Pattern.compile("</?editor-fold\\b.*\\s*"); @Override public Map<String, List<OffsetRange>> folds(ParserResult pr) { Object arr = TSService.call("getFolds", pr.getSnapshot().getSource().getFileObject()); if (arr == null) { return Collections.emptyMap(); } List<OffsetRange> ranges = new ArrayList<>(); CharSequence text = pr.getSnapshot().getText(); for (JSONObject span : (List<JSONObject>) arr) { int start = ((Number) span.get("start")).intValue(); int end = ((Number) span.get("end")).intValue(); if (text.charAt(start) == '/') { // ts.OutliningElementsCollector creates folds for sequences of multiple //-comments // preceding a declaration, but this can prevent NetBeans's <editor-fold> directives // from working. Remove all lines up to and including the last such directive. int startDelta = 0; for (Matcher m = editorFolds.matcher(text.subSequence(start, end)); m.find();) { startDelta = m.end(); } start += startDelta; // There may be only a single line left - for consistency, don't fold it if (text.subSequence(start, end).toString().indexOf('\n') < 0) { continue; } } ranges.add(new OffsetRange(start, end)); } return Collections.singletonMap("codeblocks", ranges); } @Override public Configuration getConfiguration() { return new Configuration(true, true); } }