Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.millennialmedia.intellibot.psi.element.DefinedKeyword;
import com.millennialmedia.intellibot.psi.element.DefinedVariable;
import com.millennialmedia.intellibot.psi.element.KeywordFile;
import com.millennialmedia.intellibot.psi.util.PythonParser;
import com.millennialmedia.intellibot.psi.util.PerformanceCollector;
import com.millennialmedia.intellibot.psi.util.PerformanceEntity;
import com.millennialmedia.intellibot.psi.util.ReservedVariable;
Expand Down Expand Up @@ -44,13 +45,13 @@ public Collection<DefinedKeyword> getDefinedKeywords() {
PerformanceCollector debug = new PerformanceCollector(this, "get defined keywords");
Collection<DefinedKeyword> results = new HashSet<DefinedKeyword>();
for (PyFunction function : this.pythonFile.getTopLevelFunctions()) {
String keyword = functionToKeyword(function.getName());
String keyword = PythonParser.keywordName(function);
if (keyword != null) {
results.add(new KeywordDto(function, this.library, keyword, hasArguments(function.getParameterList().getParameters())));
results.add(new KeywordDto(function, this.library, keyword, PythonParser.keywordHasArguments(function)));
}
}
for (PyTargetExpression expression : this.pythonFile.getTopLevelAttributes()) {
String keyword = functionToKeyword(expression.getName());
String keyword = PythonParser.keywordName(expression);
if (keyword != null) {
results.add(new KeywordDto(expression, this.library, keyword, false));
}
Expand Down
64 changes: 6 additions & 58 deletions src/com/millennialmedia/intellibot/psi/ref/RobotPythonWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import com.millennialmedia.intellibot.psi.dto.VariableDto;
import com.millennialmedia.intellibot.psi.element.DefinedKeyword;
import com.millennialmedia.intellibot.psi.element.DefinedVariable;
import com.millennialmedia.intellibot.psi.util.PythonParser;
import com.millennialmedia.intellibot.psi.util.ReservedVariable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;

Expand All @@ -18,38 +18,13 @@
*/
public abstract class RobotPythonWrapper {

private static final String UNDERSCORE = "_";
private static final String SELF = "self";

protected static boolean hasArguments(@Nullable PyParameter[] parameters) {
if (parameters == null || parameters.length == 0) {
return false;
}

for (PyParameter parameter : parameters) {
String name = parameter.getName();
if (name != null && !SELF.equalsIgnoreCase(name)) {
return true;
}
}
return false;
}

protected static String functionToKeyword(@Nullable String function) {
if (function == null || isPrivate(function)) {
return null;
} else {
return function;
}
}

protected static void addDefinedVariables(@NotNull PyClass pythonClass, @NotNull final Collection<DefinedVariable> results) {
pythonClass.visitClassAttributes(
new Processor<PyTargetExpression>() {
@Override
public boolean process(PyTargetExpression expression) {
String keyword = expression.getName();
if (keyword != null && !isPrivate(keyword)) {
String keyword = PythonParser.keywordName(expression);
if (keyword != null) {
// not formatted ${X}, assume scalar
results.add(new VariableDto(expression, ReservedVariable.wrapToScalar(keyword), null));
}
Expand All @@ -61,43 +36,16 @@ public boolean process(PyTargetExpression expression) {
);
}

private static boolean isPrivate(@NotNull String keyword) {
// these keeps out intended private functions
return keyword.startsWith(UNDERSCORE) || keyword.startsWith("ROBOT_LIBRARY_");
}

protected static void addDefinedKeywords(@NotNull PyClass pythonClass, @NotNull final String namespace, @NotNull final Collection<DefinedKeyword> results) {
pythonClass.visitMethods(
new Processor<PyFunction>() {

@Override
public boolean process(PyFunction function) {
String keyword = functionToKeyword(function.getName());
String keyword = PythonParser.keywordName(function);
if (keyword != null) {
// Get info from @keyword
PyDecoratorList decorators = function.getDecoratorList();
if (decorators != null) {
PyDecorator keyword_decorator = decorators.findDecorator("keyword");
if (keyword_decorator != null) {
if (keyword_decorator.hasArgumentList()) {
// Get case 'name =' argument
PyExpression kwa = keyword_decorator.getKeywordArgument("name");
if (kwa != null) {
keyword = kwa.getText().replaceAll("^\"|\"$", "");
}
else {
// Otherwise, check if first argument is unnamed
PyExpression[] kda = keyword_decorator.getArguments();

// Argument exists and is unnamed
if (kda.length > 0 && kda[0].getName() == null) {
keyword = kda[0].getText().replaceAll("^\"|\"$", "");
}
}
}
}
}
results.add(new KeywordDto(function, namespace, keyword, hasArguments(function.getParameterList().getParameters())));
results.add(new KeywordDto(function, namespace, keyword, PythonParser.keywordHasArguments(function)));
}
return true;
}
Expand All @@ -110,7 +58,7 @@ public boolean process(PyFunction function) {

@Override
public boolean process(PyTargetExpression expression) {
String keyword = functionToKeyword(expression.getName());
String keyword = PythonParser.keywordName(expression);
if (keyword != null) {
results.add(new KeywordDto(expression, namespace, keyword, false));
}
Expand Down
91 changes: 91 additions & 0 deletions src/com/millennialmedia/intellibot/psi/util/PythonParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package com.millennialmedia.intellibot.psi.util;

import com.jetbrains.python.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class PythonParser {

public static boolean keywordHasArguments(PyFunction keyword_function) {
PyParameter[] parameters = keyword_function.getParameterList().getParameters();

if (parameters == null || parameters.length == 0) {
return false;
}

for (PyParameter parameter : parameters) {
String name = parameter.getName();
if (name != null && !"self".equalsIgnoreCase(name)) {
return true;
}
}
return false;
}

public static String keywordName(PyFunction function) {
String name = function.getName();
String decoratorName = null;

if (name == null || isPrivate(name)) {
return null;
}

// Get info from @keyword
PyDecorator keywordDecorator = getKeywordDecorator(function);
if (keywordDecorator != null) {
decoratorName = keywordNameFromDecorator(keywordDecorator);
}

return decoratorName != null ? decoratorName : name;
}

public static String keywordName(PyExpression expression) {
String name = expression.getName();

if (name == null || isPrivate(name)) {
return null;
}

return name;
}

public static boolean isPrivate(@NotNull String keyword) {
// these keeps out intended private functions
return keyword.startsWith("_") || keyword.startsWith("ROBOT_LIBRARY_");
}

private static String keywordNameFromDecorator(PyDecorator decorator) {
if (!decorator.hasArgumentList()) {
return null;
}

PyExpression keywordNameArgument = decorator.getKeywordArgument("name");

if (keywordNameArgument == null && decorator.getArguments()[0].getName() == null) {
keywordNameArgument = decorator.getArguments()[0];
}

if (keywordNameArgument != null) {
return keywordNameArgument.getText().replaceAll("^[\"|\']|[\"|\']$", "");
}

return null;
}

private static PyDecorator getKeywordDecorator(@NotNull PyFunction function) {
PyDecoratorList decorators = function.getDecoratorList();

if (decorators == null) {
return null;
}

for (PyDecorator decorator : decorators.getDecorators()) {
String decorator_name = decorator.getName();
if (decorator_name != null && decorator_name.matches("^(robot.)?(api.)?(deco.)?keyword")) {
return decorator;
}
}

return null;
}
}