package org.jetbrains.ruby.codeInsight.types.signature; import java.util.*; public final class RSignatureFetcher { private int argc; private Set<String> kwArgs; public RSignatureFetcher(int argc, Set<String> kwArgs) { this.argc = argc; this.kwArgs = new HashSet<>(kwArgs); } // parameter information // // def m(a1, a2, ..., aM, # mandatory // b1=(...), b2=(...), ..., bN=(...), # optional // *c, # rest // d1, d2, ..., dO, # post // e1:(...), e2:(...), ..., eK:(...), # keyword // **f, # keyword_rest // &g) # block private List<Boolean> updateArgExists(int i, List<Boolean> flags) { if (argc <= 0) return flags; if (argc > kwArgs.size()) { argc--; } else { argc -= kwArgs.size(); kwArgs.clear(); } flags.set(i, Boolean.TRUE); return flags; } private List<Boolean> updateFlags(List<ParameterInfo> info, ParameterInfo.Type type, List<Boolean> flags) { for (int i = 0; i < info.size(); i++) { ParameterInfo parameterInfo = info.get(i); if (parameterInfo.getModifier() == type) { flags = updateArgExists(i, flags); } } return flags; } public List<Boolean> fetch(List<ParameterInfo> info) { List<Boolean> result = new ArrayList<>(Arrays.asList(new Boolean[info.size()])); Collections.fill(result, Boolean.FALSE); boolean keyflag = false; for (ParameterInfo argument : info) { if (argument.getModifier() == ParameterInfo.Type.KEYREQ) { keyflag = true; } if (argument.getModifier() == ParameterInfo.Type.KEY) { keyflag = true; } if (argument.getModifier() == ParameterInfo.Type.KEYREST) { keyflag = true; } } result = updateFlags(info, ParameterInfo.Type.REQ, result); if (kwArgs.size() == 0 || !keyflag) { result = updateFlags(info, ParameterInfo.Type.OPT, result); } else { for (int i = 0; i < info.size(); i++) { ParameterInfo parameterInfo = info.get(i); String argumentName = parameterInfo.getName(); if (parameterInfo.getModifier() == ParameterInfo.Type.KEY) { if (kwArgs.contains(argumentName)) { result.set(i, Boolean.TRUE); argc--; kwArgs.remove(argumentName); } } if (parameterInfo.getModifier() == ParameterInfo.Type.KEYREQ) { if (kwArgs.contains(argumentName)) { result.set(i, Boolean.TRUE); argc--; kwArgs.remove(argumentName); } } if (parameterInfo.getModifier() == ParameterInfo.Type.KEYREST) { if (!kwArgs.isEmpty()) { result.set(i, Boolean.TRUE); argc -= kwArgs.size(); } kwArgs.clear(); } } } for (int i = 0; i < info.size(); i++) { ParameterInfo parameterInfo = info.get(i); if (parameterInfo.getModifier() == ParameterInfo.Type.REST) { if (argc > 0) { result.set(i, Boolean.TRUE); argc = 0; kwArgs.clear(); } } } return result; } }