private void parseKeywordAndArgs() { if (!keyword_parsed) { keyword_parsed = true; ParsedString keywordOrSetting = line.arguments.get(argOff); keywordSequence_isSetting = keywordOrSetting.getValue().startsWith("["); if (keywordSequence_isSetting) { keywordSequence_keywordCallState = KeywordCallState.UNDETERMINED_NOT_FOR_NOINDENT; // TODO // possibly // should // be // KEYWORD_NOT_FOR_NOINDENT keywordSequence_settingType = keywordSequenceSettingTypes.get(keywordOrSetting.getValue()); if (keywordSequence_settingType == null) { keywordSequence_settingType = SettingType.UNKNOWN; } keywordOrSetting.setType(ArgumentType.SETTING_KEY); prepareNextToken(); } else { keywordSequence_keywordCallState = KeywordCallState.UNDETERMINED; parseKeywordCall(lastRealType.isTestCaseLine()); } } else { if (keywordSequence_isSetting) { parseKeywordSequenceSetting(); } else { parseKeywordCall(lastRealType.isTestCaseLine()); } } }
private void parseTableBeginToken() { assert argOff == 0; ParsedString table = line.arguments.get(0); table.setType(ArgumentType.TABLE); prepareNextLine(); return; }
void prepareNextLine() { assert argOff >= 0; assert argOff <= argLen; // if previous line ended with comment, add it to queue now if (lineEndsWithComment) { ParsedString comment = line.arguments.get(argLen); if (comment.getValue().startsWith("#")) { comment.setType(ArgumentType.COMMENT); } } // next line line = getNextNonemptyLine(); if (line != null) { argLen = line.arguments.size(); lineEndsWithComment = line.arguments.get(argLen - 1).getValue().startsWith("#"); if (lineEndsWithComment) { --argLen; // exclude now, deal with it later (see top of method) } } else { // for (RobotLine line : lines) { // System.out.println(line); // } lines = null; lineIterator = null; argLen = 0; lineEndsWithComment = false; } argOff = 0; }
private void setUpKeywordArgPos(ParsedString keyword) { keywordSequence_keywordArgPos = KEYWORD_ARG_POS_NONE; if (keywordsTakingKeywords.containsKey(keyword.getValue())) { int keywordArgumentPosition = keywordsTakingKeywords.get(keyword.getValue()); keywordSequence_keywordArgPos = keywordArgumentPosition; if (keywordArgumentPosition != KEYWORD_ARG_POS_ALL) { keywordSequence_currentArgPos = 1; } } }
private void parseVariableTableLineToken() { switch (argOff) { case 0: ParsedString variable = line.arguments.get(0); variable.setType(ArgumentType.VARIABLE_KEY); prepareNextToken(); return; default: parseVariableArgs(); return; } }
private void parseTestCaseOrKeywordTableBegin(LineType type) { if (argOff == 0) { keyword_parsed = false; lookForLocalTestTemplate(); ParsedString newName = line.arguments.get(0); if (!newName.isEmpty()) { boolean isTestCase = type == LineType.TESTCASE_TABLE_TESTCASE_BEGIN; newName.setType(isTestCase ? ArgumentType.NEW_TESTCASE : ArgumentType.NEW_KEYWORD); } prepareNextToken(); return; } parseTestCaseOrKeywordLineToken(); return; }
@Override protected void addProposal(ParsedString proposal, FileWithType proposalLocation) { String proposalString = proposal.getValue().toLowerCase(); boolean proposalExisted = addedProposals.contains(proposalString); super.addProposal(proposal, proposalLocation); if (proposalExisted) { for (RobotCompletionProposal robotCompletionProposal : proposals) { setPrefixRequiredIfNeeded(proposalString, robotCompletionProposal); } } }
/** * Splits a line from a robot TXT file into arguments. Only supports the * tab-or-multiple-whitespace separator right now. * * @param line * @param charPos the file character position of the first character of the line * @return */ static List<ParsedString> splitLineIntoArguments(String line, int charPos) { String origLine = line; // remove trailing empty cells and whitespace line = rtrim(line); if (line == null) { return Collections.emptyList(); } // split line by tab-or-multiwhitespace Matcher m = SEPARATOR_RE.matcher(line); List<ParsedString> arguments = new ArrayList<ParsedString>(); int lastEnd = 0; while (true) { // if next cell starts with #, the rest of the line is a comment boolean isComment = lastEnd < line.length() && line.charAt(lastEnd) == '#'; boolean isLastArgument = isComment || !m.find(); int nextStart = !isLastArgument ? m.start() : line.length(); if (lastEnd == 0 && nextStart > 0 && line.charAt(0) == ' ') { /* * spec says all arguments are trimmed - this is the only case when additional trimming is needed. */ ++lastEnd; } ParsedString parsedString = new ParsedString(line.substring(lastEnd, nextStart), charPos + lastEnd); int nextLen = (!isLastArgument ? m.end() : origLine.length()) - nextStart; if (nextLen >= 1 && origLine.charAt(nextStart) == ' ') { parsedString.setHasSpaceAfter(true); } arguments.add(parsedString); if (isLastArgument) { // last argument break; } lastEnd = m.end(); } return arguments; }
private void parseSettingTableLineToken() { switch (argOff) { case 0: { ParsedString setting = line.arguments.get(0); setting.setType(ArgumentType.SETTING_KEY); setting_type = settingTypes.get(setting.getValue()); if (setting_type == null) { setting_type = SettingType.UNKNOWN; } setting_gotFirstArg = false; // TODO possibly should be KEYWORD_NOT_FOR_NOINDENT: keywordSequence_keywordCallState = KeywordCallState.UNDETERMINED_NOT_FOR_NOINDENT; prepareNextToken(); return; } default: { parseSettingArgs(); return; } } }
private KeywordCallState scanLine( KeywordCallState initialKeywordCallState, RobotLine scanLine, int scanOff) { assert initialKeywordCallState.isUndetermined(); for (; scanOff < scanLine.arguments.size(); ++scanOff) { ParsedString parsedString = scanLine.arguments.get(scanOff); if (parsedString.isEmpty()) { if (initialKeywordCallState == KeywordCallState.UNDETERMINED) { // no variables yet continue; } else { // no equal sign found before first non-variable parameter return initialKeywordCallState == KeywordCallState.UNDETERMINED_NOT_FOR_NOINDENT ? KeywordCallState.KEYWORD_NOT_FOR_NOINDENT : KeywordCallState.KEYWORD; } } String arg = parsedString.getValue(); switch (arg.charAt(0)) { case '$': case '@': // TODO ensure it's a proper lvalue initialKeywordCallState = KeywordCallState.UNDETERMINED_GOTVARIABLE; break; default: // non-variable and no prior lvalue indication, so.. return initialKeywordCallState == KeywordCallState.UNDETERMINED_NOT_FOR_NOINDENT ? KeywordCallState.KEYWORD_NOT_FOR_NOINDENT : KeywordCallState.KEYWORD; } if (arg.endsWith("=")) { return initialKeywordCallState == KeywordCallState.UNDETERMINED_NOT_FOR_NOINDENT ? KeywordCallState.LVALUE_NOINDENT : KeywordCallState.LVALUE; } } return initialKeywordCallState; }
@Override public VisitorInterest visitMatch(ParsedString proposal, FileWithType proposalLocation) { if (userInput == null) { addProposal(proposal, proposalLocation); } else { String userInputString = userInput.getValue().toLowerCase(); String proposalString = proposal.getValue().toLowerCase(); if (proposalString.contains(userInputString) || matchesWithoutPrefix(userInputString, proposalString, proposalLocation)) { addProposal(proposal, proposalLocation); } // if (KeywordMatchResult.DIFFERENT == match(proposalString, lookFor(userInputString))) { // if (!prefixesMatch(userInputString, proposalLocation)) { // return VisitorInterest.CONTINUE; // } // if (KeywordMatchResult.DIFFERENT == match(proposalString, // lookFor(valueWithoutPrefix(userInputString)))) // { // return VisitorInterest.CONTINUE; // } // } } return VisitorInterest.CONTINUE; }
/** * Before this is called the first time, keywordSequence_keywordCallState must be initialized to * either UNDETERMINED, UNDETERMINED_NOINDENT, KEYWORD_NOINDENT, KEYWORD_NOT_FOR_NOINDENT * * @param templatesEnabled whether the template flags {@link #globalTemplateAtLine} and {@link * #localTemplateAtLine} affect keyword calls during this invocation */ private void parseKeywordCall(boolean templatesEnabled) { if (keywordSequence_keywordCallState.isUndetermined()) { keywordSequence_keywordCallState = determineInitialKeywordCallState(keywordSequence_keywordCallState); } switch (keywordSequence_keywordCallState) { case LVALUE_NOINDENT: case LVALUE: { ParsedString variable = line.arguments.get(argOff); if (!variable.isEmpty() || keywordSequence_keywordCallState == KeywordCallState.LVALUE_NOINDENT) { variable.setType(ArgumentType.KEYWORD_LVALUE); if (variable.getValue().endsWith("=")) { keywordSequence_keywordCallState = KeywordCallState.KEYWORD_NOT_FOR_NOINDENT; } } prepareNextToken(); return; } case KEYWORD_NOT_FOR_NOINDENT: case KEYWORD: { ParsedString keyword = line.arguments.get(argOff); if (!keyword.isEmpty() || keywordSequence_keywordCallState == KeywordCallState.KEYWORD_NOT_FOR_NOINDENT) { if (keyword.getValue().equals(":FOR") && keywordSequence_keywordCallState != KeywordCallState.KEYWORD_NOT_FOR_NOINDENT) { keyword.setType(ArgumentType.FOR_PART); keywordSequence_keywordCallState = KeywordCallState.FOR_VARS; } else { if (templatesEnabled && isTemplateActive()) { keyword.setType(ArgumentType.KEYWORD_ARG); // TODO support "Run Keyword If" etc as template keyword keywordSequence_keywordArgPos = KEYWORD_ARG_POS_NONE; } else if (NONE_STR.equals(keyword.getValue())) { // TODO verify what is this branch about keyword.setType(ArgumentType.SETTING_VAL); keywordSequence_keywordArgPos = KEYWORD_ARG_POS_NONE; } else { keyword.setType(ArgumentType.KEYWORD_CALL); setUpKeywordArgPos(keyword); } keywordSequence_keywordCallState = KeywordCallState.KEYWORD_ARGS; } } prepareNextToken(); return; } case FOR_VARS: { ParsedString arg = line.arguments.get(argOff); String argVal = arg.getValue(); if (argVal.equals("IN") || argVal.equals("IN RANGE")) { arg.setType(ArgumentType.FOR_PART); keywordSequence_keywordCallState = KeywordCallState.FOR_ARGS; prepareNextToken(); return; } arg.setType(ArgumentType.KEYWORD_LVALUE); prepareNextToken(); return; } case FOR_ARGS: { setArgTypesToEol(ArgumentType.KEYWORD_ARG); prepareNextLine(); return; } case KEYWORD_ARGS: { ParsedString arg = line.arguments.get(argOff); boolean isKeyword; switch (keywordSequence_keywordArgPos) { case KEYWORD_ARG_POS_NONE: isKeyword = false; break; case KEYWORD_ARG_POS_ALL: isKeyword = true; break; default: isKeyword = keywordSequence_currentArgPos++ == keywordSequence_keywordArgPos; if (isKeyword) { setUpKeywordArgPos(arg); } break; } if (isKeyword) { arg.setType(ArgumentType.KEYWORD_CALL_DYNAMIC); } else { arg.setType(ArgumentType.KEYWORD_ARG); } prepareNextToken(); return; } default: throw new RuntimeException(); } }
private void parseSettingArgs() { switch (setting_type) { case UNKNOWN: { prepareNextLine(); return; } case STRING: { setArgTypesToEol(ArgumentType.SETTING_VAL); prepareNextLine(); return; } case FILE: { ParsedString file = line.arguments.get(argOff); file.setType(ArgumentType.SETTING_FILE); prepareNextLine(); return; } case FILE_ARGS: { if (!setting_gotFirstArg) { ParsedString file = line.arguments.get(argOff); file.setType(ArgumentType.SETTING_FILE); prepareNextToken(); setting_gotFirstArg = true; setting_withNameState = WithNameState.NONE; return; } else { switch (setting_withNameState) { case NONE: ParsedString arg = line.arguments.get(argOff); if (arg.getValue().equals("WITH NAME")) { setting_withNameState = WithNameState.GOT_KEY; arg.setType(ArgumentType.SETTING_FILE_WITH_NAME_KEY); } else { arg.setType(ArgumentType.SETTING_FILE_ARG); } prepareNextToken(); return; case GOT_KEY: ParsedString name = line.arguments.get(argOff); name.setType(ArgumentType.SETTING_FILE_WITH_NAME_VALUE); setting_withNameState = WithNameState.GOT_VALUE; prepareNextLine(); return; case GOT_VALUE: prepareNextLine(); return; } } throw new RuntimeException(); } case KEYWORD_ARGS: { parseKeywordCall(false); return; } } throw new RuntimeException(); }
static int determineContinuationLineArgOff(RobotLine theLine) { List<ParsedString> arguments = theLine.arguments; ParsedString parsedString = arguments.get(0); String value = parsedString.getValue(); return value.equals(PreParser.CONTINUATION_STR) ? 1 : 2; }
@Override public String toString() { return parsedString.getValue(); }