Skip to content

Commit 14119b8

Browse files
committed
Adding Powershell analyzer #1753
This is the initial introduction of the PowerShell script analyzer for OpenGrok.
1 parent ba21c3b commit 14119b8

File tree

13 files changed

+1380
-52
lines changed

13 files changed

+1380
-52
lines changed

build.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,8 @@ Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
246246
<run-jflex dir="${gen.analysis.dir}/javascript" name="JavaScriptXref"/>
247247
<run-jflex dir="${gen.analysis.dir}/lua" name="LuaSymbolTokenizer"/>
248248
<run-jflex dir="${gen.analysis.dir}/lua" name="LuaXref"/>
249+
<run-jflex dir="${gen.analysis.dir}/posh" name="PoshSymbolTokenizer"/>
250+
<run-jflex dir="${gen.analysis.dir}/posh" name="PoshXref"/>
249251
<run-jflex dir="${gen.analysis.dir}/python" name="PythonSymbolTokenizer"/>
250252
<run-jflex dir="${gen.analysis.dir}/python" name="PythonXref"/>
251253
<run-jflex dir="${gen.analysis.dir}/rust" name="RustSymbolTokenizer"/>

src/org/opensolaris/opengrok/analysis/AnalyzerGuru.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
import org.opensolaris.opengrok.analysis.json.JsonAnalyzerFactory;
8383
import org.opensolaris.opengrok.analysis.kotlin.KotlinAnalyzerFactory;
8484
import org.opensolaris.opengrok.analysis.sh.ShAnalyzerFactory;
85+
import org.opensolaris.opengrok.analysis.posh.PoshAnalyzerFactory;
8586
import org.opensolaris.opengrok.analysis.sql.PLSQLAnalyzerFactory;
8687
import org.opensolaris.opengrok.analysis.sql.SQLAnalyzerFactory;
8788
import org.opensolaris.opengrok.analysis.swift.SwiftAnalyzerFactory;
@@ -177,6 +178,7 @@ public class AnalyzerGuru {
177178
new CxxAnalyzerFactory(),
178179
new ErlangAnalyzerFactory(),
179180
new ShAnalyzerFactory(),
181+
new PoshAnalyzerFactory(),
180182
PlainAnalyzerFactory.DEFAULT_INSTANCE,
181183
new UuencodeAnalyzerFactory(),
182184
new GZIPAnalyzerFactory(),

src/org/opensolaris/opengrok/analysis/Ctags.java

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,8 @@ private void initialize() throws IOException {
213213

214214
command.add("--langdef=rust");
215215
command.add("--langmap=rust:+.rs");
216-
command.add("--regex-rust=/^[[:space:]]*(#\\[[^\\]]\\][[:space:]]*)*(pub[[:space:]]+)?(extern[[:space:]]+)?(\"[^\"]+\"[[:space:]]+)?(unsafe[[:space:]]+)?fn[[:space:]]+([[:alnum:]_]+)/\\6/h,functions,function definitions/");
216+
//command.add("--regex-rust=/^[[:space:]]*(#\\[[^\\]]\\][[:space:]]*)*(pub[[:space:]]+)?(extern[[:space:]]+)?(\"[^\"]+\"[[:space:]]+)?(unsafe[[:space:]]+)?fn[[:space:]]+([[:alnum:]_]+)/\\6/h,functions,function definitions/");
217+
command.add("--regex-rust=/^[[:space:]]*(#\\[[^]]+\\][[:space:]]*)*(pub[[:space:]]+)?(extern[[:space:]]+)?(\\\"[^\\\"]+\\\"[[:space:]]+)?(unsafe[[:space:]]+)?fn[[:space:]]+([[:alnum:]_]+)/\\6/h,functions,function definitions/");
217218
command.add("--regex-rust=/^[[:space:]]*(pub[[:space:]]+)?type[[:space:]]+([[:alnum:]_]+)/\\2/T,types,type definitions/");
218219
command.add("--regex-rust=/^[[:space:]]*(pub[[:space:]]+)?enum[[:space:]]+([[:alnum:]_]+)/\\2/g,enum,enumeration names/");
219220
command.add("--regex-rust=/^[[:space:]]*(pub[[:space:]]+)?struct[[:space:]]+([[:alnum:]_]+)/\\2/S,structure names/");
@@ -237,6 +238,24 @@ private void initialize() throws IOException {
237238
command.add("--regex-pascal=/^(uses|interface|implementation)$/\\1/s,Section/");
238239
command.add("--regex-pascal=/^unit[[:space:]]+([a-zA-Z0-9_<>, ]+)[;(]/\\1/u,unit/");
239240

241+
// PowerShell
242+
command.add("--langdef=Posh");
243+
command.add("--langmap=Posh:+.ps1,Posh:+.psm1");
244+
command.add("--kinddef-Posh=f,function,functions");
245+
command.add("--_fielddef-Posh=signature,signatures");
246+
command.add("--fields-Posh=+{signature}");
247+
248+
// escaped variable markers
249+
command.add("--regex-Posh=/`(\\$[[:alnum:]_]+([:.][[:alnum:]_]+)*)/\\1//{exclusive}");
250+
command.add("--regex-Posh=/`(\\$\\{[^}]+\\})/\\1//{exclusive}");
251+
command.add("--regex-Posh=/#.*(\\$[[:alnum:]_]+([:.][[:alnum:]_]+)*)/\\1//{exclusive}");
252+
command.add("--regex-Posh=/#.*(\\$\\{[^}]+\\})/\\1//{exclusive}");
253+
254+
command.add("--regex-Posh=/(\\$\\{[^}]+\\})/\\1/v,variable/");
255+
command.add("--regex-Posh=/(\\$[[:alnum:]_]+([:.][[:alnum:]_]+)*)/\\1/v,variable/");
256+
command.add("--regex-Posh=/^[[:space:]]*(function|filter)[[:space:]]+([^({[:space:]]+)[[:space:]]*(\\(([^)]+)\\))?/\\2/f/{icase}{exclusive}{_field=signature:(\\4)}");
257+
command.add("--regex-Posh=/^[[:space:]]*(:[^[:space:]]+)/\\1/l,label/");
258+
240259
//PLEASE add new languages ONLY with POSIX syntax (see above wiki link)
241260

242261
/* Add extra command line options for ctags. */
@@ -516,19 +535,43 @@ private void readTags(Definitions defs) {
516535
//TODO if some languages use different character for separating arguments, below needs to be adjusted
517536
String[] args = signature.split(",");
518537
for (String arg : args) {
519-
//log.fine("Param = "+ arg);
520-
int space = arg.lastIndexOf(' ');//TODO this is not the best way, but works to find the last string(name) in the argument, hence skipping type
521-
if (space > 0 && space < arg.length()) {
522-
String afters = arg.substring(space + 1);
523-
//FIXME this will not work for typeless languages such as python or assignments inside signature ... but since ctags doesn't provide signatures for python yet and assigning stuff in signature is not the case for c or java, we don't care ...
524-
String[] names = afters.split("[\\W]"); //this should just parse out variables, we assume first non empty text is the argument name
525-
for (String name : names) {
526-
if (name.length() > 0) {
527-
//log.fine("Param Def = "+ string);
528-
addTag(defs, seenSymbols, lnum, name, "argument",
538+
//TODO this algorithm assumes that data types occur to
539+
// the left of the argument name, so it will not
540+
// work for languages like rust, kotlin, etc. which
541+
// place the data type to the right of the argument name.
542+
// Need an attribute from ctags to indicate data type location.
543+
// ----------------------------------------------------------------
544+
// When no assignment of default values,
545+
// expecting: <type> <name>, or <name>
546+
//
547+
// When default value assignment applied to parameter,
548+
// expecting: <type> <name> = <value> or
549+
// <name> = <value>
550+
// (Note whitespace content made irrelevant)
551+
552+
// Need to ditch the default assignment value
553+
// so that the extraction loop below will work.
554+
// This assumes all languages use '=' to assign value.
555+
556+
if (arg.indexOf("=") != -1) {
557+
String[] a = arg.split("=");
558+
arg = a[0]; // throws away assigned value
559+
}
560+
561+
// Strip out all non 'word' class symbols
562+
// which leaves just names intact.
563+
String [] names = arg.trim().split("[\\W]");
564+
String name;
565+
566+
// Walk the array backwards from the end and
567+
// the parameter name should always be the first
568+
// non-empty element encountered.
569+
for (int ii=names.length-1; ii >= 0; ii--) {
570+
name = names[ii];
571+
if (name.length() > 0) {
572+
addTag(defs, seenSymbols, lnum, name, "argument",
529573
def.trim() + signature.trim(), null, signature);
530574
break;
531-
}
532575
}
533576
}
534577
}

src/org/opensolaris/opengrok/analysis/JFlexXref.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -539,10 +539,10 @@ protected void startNewLine() throws IOException {
539539
*/
540540
protected void writeSymbol(String symbol, Set<String> keywords, int line)
541541
throws IOException {
542-
writeSymbol(symbol, keywords, line, true);
542+
writeSymbol(symbol, keywords, line, true, false);
543543
}
544544

545-
/**
545+
/**
546546
* Write a symbol and generate links as appropriate.
547547
*
548548
* @param symbol the symbol to write
@@ -555,9 +555,27 @@ protected void writeSymbol(String symbol, Set<String> keywords, int line)
555555
protected void writeSymbol(
556556
String symbol, Set<String> keywords, int line, boolean caseSensitive)
557557
throws IOException {
558+
writeSymbol(symbol, keywords, line, caseSensitive, false);
559+
}
560+
561+
/**
562+
* Write a symbol and generate links as appropriate.
563+
*
564+
* @param symbol the symbol to write
565+
* @param keywords a set of keywords recognized by this analyzer (no links
566+
* will be generated if the symbol is a keyword)
567+
* @param line the line number on which the symbol appears
568+
* @param caseSensitive Whether the keyword list is case sensitive
569+
* @param quote Whether the symbol gets quoted in links or not
570+
* @throws IOException if an error occurs while writing to the stream
571+
*/
572+
protected void writeSymbol(
573+
String symbol, Set<String> keywords, int line, boolean caseSensitive, boolean quote)
574+
throws IOException {
558575
String[] strs = new String[1];
559576
strs[0] = "";
560577
String jsEscapedSymbol = symbol.replace("'", "\\'");
578+
String qt = (quote) ? "&quot;" : "";
561579

562580
String check = caseSensitive ? symbol : symbol.toLowerCase();
563581
if (keywords != null && keywords.contains( check )) {
@@ -596,7 +614,7 @@ protected void writeSymbol(
596614
out.append("<a href=\"");
597615
out.append(urlPrefix);
598616
out.append("refs=");
599-
out.append(symbol);
617+
out.append(qt+symbol+qt);
600618
appendProject();
601619
out.append("\" class=\"");
602620
out.append(style_class);
@@ -629,7 +647,7 @@ protected void writeSymbol(
629647
out.append("<a href=\"");
630648
out.append(urlPrefix);
631649
out.append("defs=");
632-
out.append(symbol);
650+
out.append(qt+symbol+qt);
633651
appendProject();
634652
out.append("\"");
635653
out.append(" class=\"intelliWindow-symbol\"");

0 commit comments

Comments
 (0)