Skip to content

Commit

Permalink
Provide completion from some built-in functions that return an associ…
Browse files Browse the repository at this point in the history
…ative array
  • Loading branch information
klesun committed Aug 27, 2018
1 parent 25bd5a6 commit 74263ff
Show file tree
Hide file tree
Showing 4 changed files with 310 additions and 3 deletions.
7 changes: 5 additions & 2 deletions resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<idea-plugin>
<id>lv.midiana.misc.phpstorm-plugins.deep-keys</id>
<name>deep-assoc-completion</name>
<version>2018.08.15.001</version>
<version>2018.08.28.002</version>
<vendor email="safronevev@gmail.com" url="http://midiana.lv/entry/phpstorm-deep-keys">Klesun</vendor>

<description><![CDATA[
Expand Down Expand Up @@ -37,7 +37,10 @@ This plugin greatly extends phpstorm's typing with associative array support<br/

<change-notes><![CDATA[
<ul>
<li>Fix null-pointer exception in DeepObjMemberGoToDecl.java</li>
<li>Provide completion from some built-in functions that return an associative array</li>
<li>#46 Fix: do not suggest class names in @return php doc type part</li>
<li>Resolve new static() expression</li>
<li>#43 Optimize: do not resolve property object if IDEA type already knows the class</li>
</ul>
]]>
</change-notes>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ private Opt<List<String>> extractTypedFqnPart(String docValue, Project project,
.flt(p -> metMatcher.prefixMatches(p))
.map(f -> f + "()"));
})
, () -> Tls.regex(" *([A-Za-z][A-Za-z0-9_]+?)(IntellijIdeaRulezzz.*)?", docValue)
, () -> Tls.regex(" *([A-Z][A-Za-z0-9_]+?)(IntellijIdeaRulezzz.*)?", docValue)
// have to complete class
.fop(m -> m.gat(0))
.map(CamelHumpMatcher::new)
Expand Down
153 changes: 153 additions & 0 deletions src/org/klesun/deep_assoc_completion/resolvers/FuncCallRes.java
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,159 @@ private L<DeepType> findBuiltInFuncCallType(FunctionReferenceImpl call)
DeepType arrt = new DeepType(call, PhpType.ARRAY);
arrt.listElTypes.add(() -> new MultiType(list(new DeepType(call, PhpType.STRING))));
result.add(arrt);
} else if (name.equals("curl_getinfo") && !callCtx.getArg(1).has()) {
DeepType arrt = new DeepType(call, PhpType.ARRAY);
arrt.addKey("url", call);
arrt.addKey("content_type", call);
arrt.addKey("http_code", call);
arrt.addKey("header_size", call);
arrt.addKey("request_size", call);
arrt.addKey("filetime", call);
arrt.addKey("ssl_verify_result", call);
arrt.addKey("redirect_count", call);
arrt.addKey("total_time", call);
arrt.addKey("namelookup_time", call);
arrt.addKey("connect_time", call);
arrt.addKey("pretransfer_time", call);
arrt.addKey("size_upload", call);
arrt.addKey("size_download", call);
arrt.addKey("speed_download", call);
arrt.addKey("speed_upload", call);
arrt.addKey("download_content_length", call);
arrt.addKey("upload_content_length", call);
arrt.addKey("starttransfer_time", call);
arrt.addKey("redirect_time", call);
arrt.addKey("certinfo", call);
arrt.addKey("redirect_url", call);
result.add(arrt);
} else if (name.equals("stream_get_meta_data")) {
DeepType arrt = new DeepType(call, PhpType.ARRAY);
arrt.addKey("timed_out", call);
arrt.addKey("blocked", call);
arrt.addKey("eof", call);
arrt.addKey("wrapper_type", call);
arrt.addKey("stream_type", call);
arrt.addKey("mode", call);
arrt.addKey("unread_bytes", call);
arrt.addKey("seekable", call);
arrt.addKey("uri", call);
result.add(arrt);
} else if (name.equals("mysqli_get_links_stats")) {
DeepType arrt = new DeepType(call, PhpType.ARRAY);
arrt.addKey("total", call);
arrt.addKey("active_plinks", call);
arrt.addKey("cached_plinks", call);
result.add(arrt);
} else if (name.equals("localeconv")) {
DeepType arrt = new DeepType(call, PhpType.ARRAY);
arrt.addKey("decimal_point", call);
arrt.addKey("thousands_sep", call);
arrt.addKey("int_curr_symbol", call);
arrt.addKey("currency_symbol", call);
arrt.addKey("mon_decimal_point", call);
arrt.addKey("mon_thousands_sep", call);
arrt.addKey("positive_sign", call);
arrt.addKey("negative_sign", call);
arrt.addKey("int_frac_digits", call);
arrt.addKey("frac_digits", call);
arrt.addKey("p_cs_precedes", call);
arrt.addKey("p_sep_by_space", call);
arrt.addKey("n_cs_precedes", call);
arrt.addKey("n_sep_by_space", call);
arrt.addKey("p_sign_posn", call);
arrt.addKey("n_sign_posn", call);
arrt.addKey("grouping", call);
arrt.addKey("mon_grouping", call);
result.add(arrt);
} else if (name.equals("proc_get_status")) {
DeepType arrt = new DeepType(call, PhpType.ARRAY);
arrt.addKey("command", call);
arrt.addKey("pid", call);
arrt.addKey("running", call);
arrt.addKey("signaled", call);
arrt.addKey("stopped", call);
arrt.addKey("exitcode", call);
arrt.addKey("termsig", call);
arrt.addKey("stopsig", call);
result.add(arrt);
} else if (name.equals("getrusage")) {
DeepType arrt = new DeepType(call, PhpType.ARRAY);
arrt.addKey("ru_oublock", call);
arrt.addKey("ru_inblock", call);
arrt.addKey("ru_msgsnd", call);
arrt.addKey("ru_msgrcv", call);
arrt.addKey("ru_maxrss", call);
arrt.addKey("ru_ixrss", call);
arrt.addKey("ru_idrss", call);
arrt.addKey("ru_minflt", call);
arrt.addKey("ru_majflt", call);
arrt.addKey("ru_nsignals", call);
arrt.addKey("ru_nvcsw", call);
arrt.addKey("ru_nivcsw", call);
arrt.addKey("ru_nswap", call);
arrt.addKey("ru_utime.tv_usec", call);
arrt.addKey("ru_utime.tv_sec", call);
arrt.addKey("ru_stime.tv_usec", call);
arrt.addKey("ru_stime.tv_sec", call);
result.add(arrt);
} else if (name.equals("error_get_last")) {
DeepType arrt = new DeepType(call, PhpType.ARRAY);
arrt.addKey("type", call);
arrt.addKey("message", call);
arrt.addKey("file", call);
arrt.addKey("line", call);
result.add(arrt);
} else if (name.equals("dns_get_record")) {
DeepType assoct = new DeepType(call, PhpType.ARRAY);
assoct.addKey("host", call);
assoct.addKey("class", call);
assoct.addKey("ttl", call);
assoct.addKey("type", call);
assoct.addKey("mname", call);
assoct.addKey("rname", call);
assoct.addKey("serial", call);
assoct.addKey("refresh", call);
assoct.addKey("retry", call);
assoct.addKey("expire", call);
assoct.addKey("minimum", call);
assoct.addKey("flags", call);
assoct.addKey("tag", call);
assoct.addKey("value", call);
DeepType arrt = new DeepType(call, PhpType.ARRAY);
arrt.listElTypes.add(() -> new MultiType(list(assoct)));
result.add(arrt);
} else if (list("stat", "fstat", "lstat").contains(name)) {
DeepType arrt = new DeepType(call, PhpType.ARRAY);
arrt.addKey("dev", call);
arrt.addKey("ino", call);
arrt.addKey("mode", call);
arrt.addKey("nlink", call);
arrt.addKey("uid", call);
arrt.addKey("gid", call);
arrt.addKey("rdev", call);
arrt.addKey("size", call);
arrt.addKey("atime", call);
arrt.addKey("mtime", call);
arrt.addKey("ctime", call);
arrt.addKey("blksize", call);
arrt.addKey("blocks", call);
result.add(arrt);
} else if (name.equals("ob_get_status")) {
DeepType assoct = new DeepType(call, PhpType.ARRAY);
assoct.addKey("name", call);
assoct.addKey("type", call);
assoct.addKey("flags", call);
assoct.addKey("level", call);
assoct.addKey("chunk_size", call);
assoct.addKey("buffer_size", call);
assoct.addKey("buffer_used", call);
if (!callCtx.getArg(0).has()) {
result.add(assoct);
} else {
DeepType arrt = new DeepType(call, PhpType.ARRAY);
arrt.listElTypes.add(() -> new MultiType(list(assoct)));
result.add(arrt);
}
} else {
// try to get type info from standard_2.php
opt(call.resolve())
Expand Down
151 changes: 151 additions & 0 deletions tests/src/DeepTest/UnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2051,6 +2051,157 @@ public function provideStackOverflowArrayCombine()
return $list;
}

public function provideAssocBuiltIns($handle)
{
$curlInfo = curl_getinfo($handle);
$list[] = [$curlInfo, [
'url' => [],
'content_type' => [],
'http_code' => [],
'header_size' => [],
'request_size' => [],
'filetime' => [],
'ssl_verify_result' => [],
'redirect_count' => [],
'total_time' => [],
'namelookup_time' => [],
'connect_time' => [],
'pretransfer_time' => [],
'size_upload' => [],
'size_download' => [],
'speed_download' => [],
'speed_upload' => [],
'download_content_length' => [],
'upload_content_length' => [],
'starttransfer_time' => [],
'redirect_time' => [],
'certinfo' => [],
'redirect_url' => [],
]];
$streamMeta = stream_get_meta_data(STDIN);
$list[] = [$streamMeta, [
'timed_out' => [], // false,
'blocked' => [], // true,
'eof' => [], // false,
'wrapper_type' => [], // 'PHP',
'stream_type' => [], // 'STDIO',
'mode' => [], // 'r',
'unread_bytes' => [], // 0,
'seekable' => [], // true,
'uri' => [], // 'php://stdin',
]];
$sqlLinks = mysqli_get_links_stats();
$list[] = [$sqlLinks, [
'total' => [],
'active_plinks' => [],
'cached_plinks' => [],
]];
$localeMeta = localeconv();
$list[] = [$localeMeta, [
'decimal_point' => [], // '.',
'thousands_sep' => [], // '',
'int_curr_symbol' => [], // '',
'currency_symbol' => [], // '',
'mon_decimal_point' => [], // '',
'mon_thousands_sep' => [], // '',
'positive_sign' => [], // '',
'negative_sign' => [], // '',
'int_frac_digits' => [], // 127,
'frac_digits' => [], // 127,
'p_cs_precedes' => [], // 127,
'p_sep_by_space' => [], // 127,
'n_cs_precedes' => [], // 127,
'n_sep_by_space' => [], // 127,
'p_sign_posn' => [], // 127,
'n_sign_posn' => [], // 127,
'grouping' => [], // [],
'mon_grouping' => [], // [],
]];
$procMeta = proc_get_status($handle);
$list[] = [$procMeta, [
'command' => [], // string - The command string that was passed to proc_open().
'pid' => [], // int - process id
'running' => [], // bool - TRUE if the process is still running, FALSE if it has terminated.
'signaled' => [], // bool - TRUE if the child process has been terminated by an uncaught signal. Always set to FALSE on Windows.
'stopped' => [], // bool - TRUE if the child process has been stopped by a signal. Always set to FALSE on Windows.
'exitcode' => [], // int - The exit code returned by the process (which is only meaningful if running is FALSE). Only first call of this function return real value, next calls return -1.
'termsig' => [], // int - The number of the signal that caused the child process to terminate its execution (only meaningful if signaled is TRUE).
'stopsig' => [], // int - The number of the signal that caused the child process to stop its execution (only meaningful if stopped is TRUE).
]];
$rusage = getrusage();
$list[] = [$rusage, [
'ru_oublock' => [], // 528,
'ru_inblock' => [], // 0,
'ru_msgsnd' => [], // 0,
'ru_msgrcv' => [], // 0,
'ru_maxrss' => [], // 24176,
'ru_ixrss' => [], // 0,
'ru_idrss' => [], // 0,
'ru_minflt' => [], // 1650,
'ru_majflt' => [], // 0,
'ru_nsignals' => [], // 0,
'ru_nvcsw' => [], // 224,
'ru_nivcsw' => [], // 0,
'ru_nswap' => [], // 0,
'ru_utime.tv_usec' => [], // 52714,
'ru_utime.tv_sec' => [], // 0,
'ru_stime.tv_usec' => [], // 11714,
'ru_stime.tv_sec' => [], // 0,
]];
$lastError = error_get_last();
$list[] = [$lastError, [
'type' => [], // 2,
'message' => [], // 'proc_get_status() expects parameter 1 to be resource, null given',
'file' => [], // 'php shell code',
'line' => [], // 1,
]];
$dnsRecord = dns_get_record('google.com');
$list[] = [$dnsRecord[rand()], [
'host' => [], // 'google.com',
'class' => [], // 'IN',
'ttl' => [], // 60,
'type' => [], // 'SOA',
'mname' => [], // 'ns1.google.com',
'rname' => [], // 'dns-admin.google.com',
'serial' => [], // 210413966,
'refresh' => [], // 900,
'retry' => [], // 900,
'expire' => [], // 1800,
'minimum' => [],
'flags' => [], // 0,
'tag' => [], // 'issue',
'value' => [], // 'pki.goog▒',
]];
$stat = stat('/home/klesun'); // same for fstat(), lstat()
$list[] = [$stat, [
'dev' => [], // 2049,
'ino' => [], // 13238274,
'mode' => [], // 16877,
'nlink' => [], // 30,
'uid' => [], // 1000,
'gid' => [], // 1000,
'rdev' => [], // 0,
'size' => [], // 4096,
'atime' => [], // 1535395568,
'mtime' => [], // 1535390333,
'ctime' => [], // 1535390333,
'blksize' => [], // 4096,
'blocks' => [], // 8,
]];
$stat = ob_get_status(); // array of assoc arrays if true passed
$list[] = [$stat, [
'name' => [], // 'default output handler',
'type' => [], // 0,
'flags' => [], // 20592,
'level' => [], // 0,
'chunk_size' => [], // 0,
'buffer_size' => [], // 16384,
'buffer_used' => [], // 1,
]];

return $list;
}

//=============================
// following are not implemented yet
//=============================
Expand Down

2 comments on commit 74263ff

@King2500
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! 👍

Also possible:

getimagesize:

  • Numeric indexes 0-3
  • Keys mime, channels, bits

parse_url:

  • scheme
  • host
  • port
  • user
  • pass
  • path
  • query
  • fragment

@klesun
Copy link
Owner Author

@klesun klesun commented on 74263ff Aug 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.