use of cfml.parsing.cfscript.script.CFFunctionParameter in project CFLint by cflint.
the class CFLint method process.
private void process(final CFScriptStatement expression, final Context context) {
if (expression == null) {
return;
}
if (expression != null && expression.getToken() != null) {
final List<Object> checkItem = Arrays.asList(expression, expression.getToken());
if (processed.contains(checkItem)) {
if (!quiet) {
System.err.println("Attempt to process expression twice aborted. This may be a parsing bug in " + context.getFilename() + " : " + (expression.getToken() != null ? expression.getToken().getLine() : ""));
}
return;
}
processed.add(checkItem);
}
final Element elem = context.getElement();
try {
if (expression instanceof CFCompoundStatement) {
scanExpression(expression, context, elem);
for (final CFScriptStatement statement : ((CFCompoundStatement) expression).getStatements()) {
process(statement, context);
}
} else if (expression instanceof CFExpressionStatement) {
scanExpression(expression, context, elem);
registerRuleOverrides(context, (CFExpressionStatement) expression);
process(((CFExpressionStatement) expression).getExpression(), elem, context);
} else if (expression instanceof CFPropertyStatement) {
try {
final CFPropertyStatement propertyStatement = (CFPropertyStatement) expression;
CFExpression value = propertyStatement.getPropertyName();
if (value == null) {
for (final Entry<CFIdentifier, CFExpression> entry : propertyStatement.getAttributes().entrySet()) {
if (CF.NAME.equalsIgnoreCase(entry.getKey().getName())) {
value = entry.getValue();
}
}
}
if (value != null) {
final String name = value.Decompile(0);
handler.addVariable(name.substring(1, name.length() - 1));
}
} catch (final Exception e) {
e.printStackTrace();
}
scanExpression(expression, context, elem);
} else if (expression instanceof CFCompDeclStatement) {
final CFCompDeclStatement compDeclStatement = (CFCompDeclStatement) expression;
final Context componentContext = context.subContext(null);
componentContext.setInComponent(true);
componentContext.setContextType(ContextType.COMPONENT);
for (final Entry<CFExpression, CFExpression> entry : compDeclStatement.getAttributes().entrySet()) {
if (entry.getKey() != null && entry.getKey().Decompile(0).equalsIgnoreCase(CF.NAME)) {
componentContext.setComponentName(entry.getValue().Decompile(0));
}
}
// Register any overrides from multi-line comments.
registerRuleOverrides(componentContext, expression.getToken());
// do startComponent notifications
doStructureStart(elem, componentContext, expression.getClass());
scanExpression(compDeclStatement, componentContext, elem);
// process the component declaration
if (compDeclStatement.getBody() instanceof CFCompoundStatement) {
// Process property expressions first
for (final CFScriptStatement subscript : compDeclStatement.getBody().decomposeScript()) {
if (subscript instanceof CFPropertyStatement) {
process(subscript, componentContext);
}
}
for (final CFScriptStatement subscript : compDeclStatement.getBody().decomposeScript()) {
if (!(subscript instanceof CFPropertyStatement)) {
process(subscript, componentContext);
}
}
} else {
process(compDeclStatement.getBody(), componentContext);
}
// do endComponent notifications
for (final CFLintStructureListener structurePlugin : getStructureListeners(extensions)) {
try {
structurePlugin.endComponent(componentContext, bugs);
for (final ContextMessage message : componentContext.getMessages()) {
reportRule(elem, null, componentContext, (CFLintScanner) structurePlugin, message);
}
componentContext.getMessages().clear();
} catch (final Exception e) {
printException(e);
final ContextMessage cm = new ContextMessage(PARSE_ERROR, null, null, context.startLine());
reportRule(currentElement, null, context, null, cm);
}
}
} else if (expression instanceof CFForStatement) {
scanExpression(expression, context, elem);
process(((CFForStatement) expression).getInit(), elem, context);
process(((CFForStatement) expression).getCond(), elem, context);
process(((CFForStatement) expression).getNext(), elem, context);
process(((CFForStatement) expression).getBody(), context);
} else if (expression instanceof CFWhileStatement) {
scanExpression(expression, context, elem);
process(((CFWhileStatement) expression).getCond(), elem, context);
process(((CFWhileStatement) expression).getBody(), context);
} else if (expression instanceof CFForInStatement) {
scanExpression(expression, context, elem);
final Context forInitContext = context.subContext(elem);
forInitContext.setInAssignmentExpression(true);
process(((CFForInStatement) expression).getVariable(), elem, forInitContext);
process(((CFForInStatement) expression).getStructure(), elem, context);
process(((CFForInStatement) expression).getBody(), context);
} else if (expression instanceof CFIfStatement) {
scanExpression(expression, context, elem);
final CFIfStatement cfif = (CFIfStatement) expression;
process(cfif.getCond(), elem, context);
process(cfif.getThenStatement(), context);
process(cfif.getElseStatement(), context);
} else if (expression instanceof CFSwitchStatement) {
scanExpression(expression, context, elem);
final CFSwitchStatement cfswitch = (CFSwitchStatement) expression;
process(cfswitch.getVariable(), elem, context);
for (final CFCase _case : cfswitch.getCases()) {
process(_case, context);
}
} else if (expression instanceof CFCase) {
scanExpression(expression, context, elem);
final CFCase cfcase = (CFCase) expression;
for (final CFScriptStatement cfstatement : cfcase.getStatements()) {
process(cfstatement, context);
}
} else if (expression instanceof CFTryCatchStatement) {
scanExpression(expression, context, elem);
final CFTryCatchStatement cftry = (CFTryCatchStatement) expression;
process(cftry.getBody(), context);
for (final CFCatchStatement stmt : cftry.getCatchStatements()) {
handler.push(CF.CFCATCH);
if (stmt.getVariable() != null && stmt.getVariable().getName() != null) {
handler.addVariable(stmt.getVariable().getName());
}
process(stmt.getCatchBody(), context);
handler.pop();
}
process(cftry.getFinallyStatement(), context);
} else if (expression instanceof CFReturnStatement) {
scanExpression(expression, context, elem);
final CFReturnStatement cfreturn = (CFReturnStatement) expression;
final CFExpression subExpression = cfreturn.getExpression();
process(subExpression, elem, context);
} else if (expression instanceof CFFuncDeclStatement) {
final CFFuncDeclStatement function = (CFFuncDeclStatement) expression;
final Context functionContext = context.subContext(null);
functionContext.setContextType(ContextType.FUNCTION);
functionContext.setFunctionInfo(function);
registerRuleOverrides(functionContext, function.getToken());
handler.push(CF.FUNCTION);
for (final CFFunctionParameter param : function.getFormals()) {
handler.addArgument(param.getName());
}
doStructureStart(elem, functionContext, CFFuncDeclStatement.class);
scanExpression(expression, functionContext, elem);
final Context functionBodyContext = functionContext.subContext(null);
process(function.getBody(), functionBodyContext);
for (final CFLintStructureListener structurePlugin : getStructureListeners(extensions)) {
try {
structurePlugin.endFunction(functionContext, bugs);
for (final ContextMessage message : functionContext.getMessages()) {
reportRule(elem, null, functionContext, (CFLintScanner) structurePlugin, message);
}
functionContext.getMessages().clear();
} catch (final Exception e) {
printException(e);
final ContextMessage cm = new ContextMessage(PARSE_ERROR, null, null, context.startLine());
reportRule(currentElement, null, context, null, cm);
}
}
handler.pop();
} else if (expression instanceof CFIncludeStatement) {
scanExpression(expression, context, elem);
final CFExpression includeExpr = ((CFIncludeStatement) expression).getTemplate();
if (includeExpr instanceof CFStringExpression) {
final List<CFExpression> subExpressions = ((CFStringExpression) includeExpr).getSubExpressions();
if (subExpressions.size() == 1 && subExpressions.get(0) instanceof CFLiteral) {
final String path = ((CFLiteral) subExpressions.get(0)).getVal();
final File include = new File(new File(context.getFilename()).getParentFile(), path);
if (include.exists() || strictInclude) {
try {
if (includeFileStack.contains(include)) {
if (!quiet) {
System.err.println("Terminated a recursive call to include file " + include);
}
} else {
includeFileStack.push(include);
process(FileUtil.loadFile(include), context.getFilename());
includeFileStack.pop();
}
} catch (final CFLintScanException ex) {
if (!quiet) {
System.err.println("Invalid include file " + context.getFilename());
}
final int line = context.startLine();
final ContextMessage cm = new ContextMessage(PARSE_ERROR, null, null, line);
reportRule(currentElement, "Invalid include file " + expression.getClass(), context, null, cm);
}
}
} else if (strictInclude) {
if (!quiet) {
System.err.println("Unable to resolve template value " + context.getFilename());
}
final int line = context.startLine();
final ContextMessage cm = new ContextMessage(PARSE_ERROR, null, null, line);
reportRule(currentElement, "Unable to resolve template value " + expression.getClass(), context, null, cm);
}
}
} else {
scanExpression(expression, context, elem);
for (CFScriptStatement childExpression : expression.decomposeScript()) {
process(childExpression, context);
}
}
} catch (final StackOverflowError soe) {
if (!quiet) {
System.err.println("Stack overflow in " + context.getFilename());
}
final int line = context.startLine();
final ContextMessage cm = new ContextMessage(PARSE_ERROR, null, null, line);
reportRule(currentElement, "Stack overflow on " + expression.getClass(), context, null, cm);
}
// Process any messages added by downstream parsing.
for (final ContextMessage message : context.getMessages()) {
reportRule(elem, null, context, message.getSource(), message);
}
context.getMessages().clear();
}
use of cfml.parsing.cfscript.script.CFFunctionParameter in project CFLint by cflint.
the class ArgDefConditionChecker method expression.
@Override
public void expression(final CFScriptStatement expression, final Context context, final BugList bugs) {
if (expression instanceof CFFuncDeclStatement) {
final CFFuncDeclStatement function = (CFFuncDeclStatement) expression;
final String code = function.Decompile(0);
for (final CFFunctionParameter argument : function.getFormals()) {
final String name = argument.getName();
final boolean checked = isCheck(code, name);
if (!argument.toString().contains(CF.REQUIRED) && !argument.toString().contains("=") && !checked) {
context.addMessage("ARG_DEFAULT_MISSING", name);
}
}
}
}
use of cfml.parsing.cfscript.script.CFFunctionParameter in project CFLint by cflint.
the class ArgumentNameChecker method expression.
/**
* Parse a CFScript function declaration to see if any of the arguments names are invalid.
*/
@Override
public void expression(final CFScriptStatement expression, final Context context, final BugList bugs) {
if (expression instanceof CFFuncDeclStatement) {
final CFFuncDeclStatement function = (CFFuncDeclStatement) expression;
for (final CFFunctionParameter argument : function.getFormals()) {
final int lineNo = argument.getToken().getLine() + context.startLine() - 1;
final int offset = context.offset() + argument.getOffset();
checkNameForBugs(context, argument.getName(), context.getFilename(), context.getFunctionName(), lineNo, offset, bugs, argument);
}
}
}
use of cfml.parsing.cfscript.script.CFFunctionParameter in project CFLint by cflint.
the class UnusedArgumentChecker method expression.
@Override
public void expression(final CFScriptStatement expression, final Context context, final BugList bugs) {
if (expression instanceof CFFuncDeclStatement) {
final CFFuncDeclStatement function = (CFFuncDeclStatement) expression;
for (final CFFunctionParameter argument : function.getFormals()) {
final String name = argument.getName().toLowerCase();
// CF variable names are not case sensitive
ArgInfo argInfo = new ArgInfo();
argInfo.casedName = argument.getName();
argInfo.argumentLineNo = function.getLine();
argInfo.argumentOffset = context.offset() + argument.getOffset();
argInfo.type = argument.getType();
currentArgs.put(name, argInfo);
if (isUsed(function.Decompile(0), name)) {
argInfo.used = true;
}
}
}
}
use of cfml.parsing.cfscript.script.CFFunctionParameter in project CFLint by cflint.
the class ArgHintChecker method expression.
/**
* Parse a CFScript function declaration to see if any of the arguments hints are missing.
*/
@Override
public void expression(final CFScriptStatement expression, final Context context, final BugList bugs) {
if (expression instanceof CFFuncDeclStatement) {
final CFFuncDeclStatement funcDeclStatement = (CFFuncDeclStatement) expression;
final String multiLineText = PrecedingCommentReader.getMultiLine(context, expression.getToken());
final String mlText = multiLineText == null ? null : multiLineText.replaceFirst("^/\\*", "").replaceAll("\\*/$", "").trim();
final Map<String, String> annotations = new HashMap<>();
if (mlText != null && !mlText.isEmpty()) {
readCommentAnnotations(mlText, annotations);
}
for (final CFFunctionParameter expr : funcDeclStatement.getFormals()) {
if (expr != null && expr.getName() != null && !annotations.containsKey(expr.getName().toLowerCase())) {
context.addMessage("ARG_HINT_MISSING_SCRIPT", expr.getName());
}
}
}
}
Aggregations