/* * Copyright 2011-2017 Kay Stenschke * * Licensed 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 com.kstenschke.shifter.models.shiftableTypes; import com.kstenschke.shifter.utils.UtilsArray; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * DocCommentType class */ public class DocCommentTag { private final String[] tagsJavaScript; private final String[] tagsJava; private final String[] tagsPHP; /** * Constructor */ public DocCommentTag() { tagsJavaScript = new String[]{"author", "class", "constructor", "deprecated", "exception", "method", "module", "namespace", "param", "private", "property", "returns", "see", "this", "throws", "type", "version"}; tagsJava = new String[]{"author", "version", "param", "return", "exception", "throws", "see", "since", "serial", "deprecated"}; tagsPHP = new String[]{"abstract", "access", "author", "constant", "deprecated", "final", "global", "magic", "module", "param", "package", "return", "see", "static", "subpackage", "throws", "todo", "var", "version"}; } /** * @return Array String array w/ all recognized doc comment tags */ private String[] getAllTags() { return UtilsArray.mergeArrays(this.tagsJavaScript, this.tagsJava, this.tagsPHP); } /** * @return String Pipe-separated list (as string) w/ all recognized doc comment tags */ public String getAllTagsPiped() { String[] allTags = this.getAllTags(); return UtilsArray.implode(allTags, "|"); } /** * Check whether given String looks like a doc comment line * * @param line Line the caret is at * @return boolean */ private boolean isDocCommentLineContext(String line) { String allTagsPiped = this.getAllTagsPiped(); String regExPatternLine = "\\s+\\*\\s+@(" + allTagsPiped + ")"; Matcher m = Pattern.compile(regExPatternLine).matcher(line.toLowerCase()); return m.find(); } /** * @param prefixChar Prefix character * @param line Whole line containing the word * @return boolean Does the given String represent a data type (number / integer / string /...) from a doc comment (param / return /...)? */ public boolean isDocCommentTag(String prefixChar, String line) { return "@".equals(prefixChar) && this.isDocCommentLineContext(line); } /** * @param word String to be shifted * @param isUp Shift up or down? * @param filename Filename of the edited file * @param textAfterCaret Document text after the caret * @return Shifting result */ public String getShifted(String word, boolean isUp, String filename, String textAfterCaret) { String[] commentTags = this.getTagsByFilename(filename); int amountTags = commentTags.length; if (amountTags > 0) { String wordLower = word.toLowerCase(); List<String> commentTagsList = Arrays.asList(commentTags); int curIndex = commentTagsList.indexOf(wordLower); if (curIndex > -1) { curIndex = NumericValue.moduloShiftInteger(curIndex, amountTags, isUp); String shiftedWord = commentTagsList.get(curIndex); if ("method".equals(shiftedWord)) { shiftedWord = shiftedWord + parseNextMethod(textAfterCaret); } return shiftedWord; } } return word; } /** * Find first JavaScript function's name out of given code * * @param jsCode JavaScript source code to be analyzed * @return String JavaScript method name */ private String parseNextMethod(String jsCode) { List<String> allMatches = new ArrayList<String>(); String regExPattern = "[a-zA-Z_$][0-9a-zA-Z_$]*\\s*:\\s*function"; Matcher m = Pattern.compile(regExPattern).matcher(jsCode); while (m.find()) { if (!allMatches.contains(m.group())) { allMatches.add(m.group()); } } return allMatches.isEmpty() ? "" : "\t" + (allMatches.get(0).replace("function", "").replace(":", "").trim()); } /** * Return array of data shiftableTypes of detected language of edited file * * @param filename Filename of edited file * @return String[] */ private String[] getTagsByFilename(String filename) { if (filename != null) { String filenameLower = filename.toLowerCase(); if (filenameLower.endsWith(".js")) { // JavaScript comment shiftableTypes return this.tagsJavaScript; } if (filenameLower.endsWith(".java")) { // Java comment tags in the recommended order return this.tagsJava; } } return this.tagsPHP; } }