Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3.1.0 alpha.1 #126

Merged
merged 16 commits into from
Jun 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
0514da3
#113 rule added in the shell extension
brigittehuynh Jun 20, 2018
d405079
#52 Added import of Function class from the shell metrics package
brigittehuynh Jun 24, 2018
9438962
#113 Corrected violation location text and added function violation
brigittehuynh Jun 24, 2018
56fe25d
#113 Version of the test file to test function location management
brigittehuynh Jun 24, 2018
cf6b4f2
#113 #52 #49 Added an overload of the Function class to allow local and
brigittehuynh Jun 24, 2018
2e53a69
#113 Added treatment of local and global variables. Changed Function
brigittehuynh Jun 24, 2018
65db141
#113 Updated Unit Tests to take function localization into account
brigittehuynh Jun 24, 2018
c19b747
#120 Added COM.PRES.LengthLine to available Shell rules
brigittehuynh Jun 24, 2018
2c3ff3b
#120 Added localization management with the Function class
brigittehuynh Jun 24, 2018
a7f6fba
#120 Added comment and string management to avoid problems run into when
brigittehuynh Jun 25, 2018
0a52366
#120 Unit test updated to test violation localization and string and
brigittehuynh Jun 25, 2018
638edeb
#113 Update of plugin dependancies to correctly take metrics into
brigittehuynh Jun 25, 2018
83a419f
#122 Added the SH.REF.Export rule
brigittehuynh Jun 25, 2018
f12c2fa
#122 Added violation location and string handling and updated unit tests
brigittehuynh Jun 25, 2018
a660bb6
#122 Changed the var format in EXPORT to the FNAME format that is better
brigittehuynh Jun 25, 2018
7635229
#122 Updated a string and a comment to contain function to test that
brigittehuynh Jun 25, 2018
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
1 change: 1 addition & 0 deletions fr.cnes.analysis.tools.shell.metrics/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ Require-Bundle: org.eclipse.core.runtime,
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-Vendor: CNES
Export-Package: fr.cnes.analysis.tools.shell.metrics
3 changes: 2 additions & 1 deletion fr.cnes.analysis.tools.shell.rules/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ Bundle-SymbolicName: fr.cnes.analysis.tools.shell.rules;singleton:=true
Bundle-Version: 3.0.1.qualifier
Bundle-Activator: fr.cnes.analysis.tools.shell.rules.Activator
Require-Bundle: org.eclipse.core.runtime,
fr.cnes.analysis.tools.analyzer;bundle-version="2.0.0"
fr.cnes.analysis.tools.analyzer;bundle-version="2.0.0",
fr.cnes.analysis.tools.shell.metrics;bundle-version="3.0.1"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-Vendor: CNES
181 changes: 161 additions & 20 deletions fr.cnes.analysis.tools.shell.rules/lex/COMDATAInitialisation.lex
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@ import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.EmptyStackException;
import java.util.Stack;

import org.eclipse.core.runtime.Path;

import fr.cnes.analysis.tools.analyzer.datas.AbstractChecker;
import fr.cnes.analysis.tools.analyzer.datas.CheckResult;
import fr.cnes.analysis.tools.analyzer.exception.JFlexException;
import fr.cnes.analysis.tools.shell.metrics.Function;

%%

Expand All @@ -40,21 +43,44 @@ import fr.cnes.analysis.tools.analyzer.exception.JFlexException;
%type List<CheckResult>


%state COMMENT, NAMING, WRITE, STRING, FORLOOP, READ
%state COMMENT, NAMING, WRITE, STRING, FORLOOP, READ, BEGINFUNC

COMMENT_WORD = \#
FUNC = "function"
SPACE = [\ \r\t\f]
VAR = [a-zA-Z][a-zA-Z0-9\_]*
FUNCT = {FNAME}{SPACE}*[\(]{SPACE}*[\)]
FUNCTION = "function"
FNAME = [a-zA-Z0-9\.\!\-\_\@\?\+]+
NAME = [a-zA-Z\_][a-zA-Z0-9\_]*
SPACE = [\ \r\t\f\space]
SHELL_VAR = ([0-9]+|[\-\@\?\#\!\_\*\$])
EXPANDED_VAR = [\$][\{](([\:]{SPACE}*[\-])|[a-zA-Z0-9\_\:\%\=\+\?\/\!\-\,\^\#\*\@]|([\[](([\:]{SPACE}*[\-])|[a-zA-Z0-9\_\/\:\%\=\+\?\!\$\-\,\^\#\*\@\[\]\{\}])+[\]]))+[\}]
VAR = {NAME}|{EXPANDED_VAR}|([\$]({NAME}|{SHELL_VAR}))

FUNCSTART = \{ | \( | \(\( | \[\[ | "if" | "select" | "for" | "while" | "until"
FUNCEND = \} | \) | \)\) | \]\] | "fi" | "done"


FILEEXIST = \[{SPACE}+{OPTION}{SPACE}+(\")?(\{)?\$(\{)?{VAR}(\})?(\")?
OPTION = \- ("a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "k" |
"p" | "r" | "s" | "u" | "w" | "x" | "O" | "G" | "L" |
"N" | "S" | "z" | "n")


%{
String location = "MAIN PROGRAM";
List<String> variables = new ArrayList<String>();
/* MAINPROGRAM: constant for main program localisation */
private static final String MAINPROGRAM = "MAIN PROGRAM";

/* FunctionWithVariables is used here with only initialized variables in locals and glabals */
private Stack<FunctionWithVariables> functionStack = new Stack<>();

/* location: the current function name, or main program, that is the initial value */
private String location = MAINPROGRAM;
/* functionLine: the beginning line of the function */
int functionLine = 0;

/* parsedFileName: name of the current file */
private String parsedFileName;

List<String> globalVariables = new ArrayList<String>();

public COMDATAInitialisation() {
/** Initialize list with system variables **/
Expand All @@ -64,15 +90,80 @@ OPTION = \- ("a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "k" |
"MACHTYPE", "OLDPWD", "OSTYPE", "PATH", "PIPESTATUS", "PPID", "PROMPT_COMMAND",
"PS1", "PS2", "PS3", "PS4", "PWD", "REPLY", "SECONDS", "SHELLOPTS", "SHLVL", "TMOUT",
"UID" };
variables.addAll(Arrays.asList(systemVariables));
globalVariables.addAll(Arrays.asList(systemVariables));
}

@Override
public void setInputFile(final File file) throws FileNotFoundException {
super.setInputFile(file);
this.parsedFileName = file.toString();
this.zzReader = new FileReader(new Path(file.getAbsolutePath()).toOSString());
}


private void endLocation() throws JFlexException {
try{
Function functionFinished = functionStack.pop();
if (!functionStack.empty()) {
/* there is a current function: change location to this function */
location = functionStack.peek().getName();
} else {
/* we are in the main program: change location to main */
location = MAINPROGRAM;
}
}catch(EmptyStackException e){
final String errorMessage = e.getMessage();
throw new JFlexException(this.getClass().getName(), parsedFileName,
errorMessage, yytext(), yyline, yycolumn);
}
}

/**
* checkVariable: checks for violations on the current variable name (var).
* Called from YYINITIAL and STRING.
*/
private void checkVariable(final String var) throws JFlexException {
boolean found = false;
if(!functionStack.empty()){
/* we are in a function */
if (functionStack.peek().getLocalVariables().contains(var))
found = true;
if (functionStack.peek().getGlobalVariables().contains(var))
found = true;
}
if(!found && !globalVariables.contains(var)) {
setError(location,"The variable $" + var + " is used before being initialized." , yyline+1);
}
}

/**
* addVariable: adds the current variable name (var) to the list of variables : glabals if
* in main, locals if in funtion.
* Called from YYINITIAL, WRITE, FORLOOP and READ.
*/
private void addVariable(final String var) throws JFlexException {
if(!functionStack.empty()){
/* we are in a function */
functionStack.peek().getLocalVariables().add(var);
} else {
/* we are in main */
globalVariables.add(var);
}
}

/**
* setGlobals: adds the current globals to the globals of pFunction.
* If there is a higher level function, its locals are also added.
* Called from BEGINFUNC.
*/
private void setGlobals(FunctionWithVariables pFunction) throws JFlexException {
if(!functionStack.empty()){
/* we are in a function: add the locals of the current function as globals of the new function */
pFunction.getGlobalVariables().addAll(functionStack.peek().getLocalVariables());
}
/* in all cases add the current globals */
pFunction.getGlobalVariables().addAll(globalVariables);
}

%}

%eofval{
Expand Down Expand Up @@ -102,9 +193,15 @@ OPTION = \- ("a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "k" |
/************************/
<NAMING>
{
{VAR} {location = location + yytext(); yybegin(YYINITIAL);}
\n {yybegin(YYINITIAL);}
. {}
{VAR} {
location = yytext();
functionLine = yyline+1;
yybegin(BEGINFUNC);
}
\n {
yybegin(YYINITIAL);
}
. {}
}

/************************/
Expand All @@ -113,18 +210,41 @@ OPTION = \- ("a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "k" |
<YYINITIAL>
{
{COMMENT_WORD} {yybegin(COMMENT);}
{FUNC} {location = yytext(); yybegin(NAMING);}
/** variables initialisation **/
{FUNCTION} {yybegin(NAMING);}
{FUNCT} {
functionLine = yyline+1;
location = yytext().substring(0,yytext().length()-2).trim();
yybegin(BEGINFUNC);
}
{FUNCSTART} {
if(!functionStack.empty()){
if(functionStack.peek().getFinisher().equals(Function.finisherOf(yytext()))){
functionStack.peek().addStarterRepetition();
}
}
}
{FUNCEND} {
if(!functionStack.empty()){
if(functionStack.peek().isFinisher(yytext())){
if(functionStack.peek().getStarterRepetition()>0) {
functionStack.peek().removeStarterRepetition();
} else {
endLocation();
}
}
}
}
/** variables initialisation **/
{VAR}{SPACE}*\= {String var = yytext().substring(0,yytext().length()-1).trim();
variables.add(var);}
addVariable(var);}
/** Varible use found **/
\${VAR} {String var = yytext().substring(1);
if(!variables.contains(var)) setError(location,"The variable $" + var + " is used before being initialized." , yyline+1);}
checkVariable(var);}
"tee" | \>\> {yybegin(WRITE);}
"for" {yybegin(FORLOOP);}
"read" {yybegin(READ);}
{FILEEXIST} {String var = yytext().replaceAll("\"", "").replaceAll("\\{", "").replaceAll("\\}", "").split("\\$")[1];
variables.add(var);}
addVariable(var);}
{VAR} {}
\" {yybegin(STRING);}
. {}
Expand All @@ -137,7 +257,7 @@ OPTION = \- ("a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "k" |
{
\-{VAR} {}
\$(\{)?{VAR} {String var = yytext().substring(1).replace("{","");
variables.add(var);}
addVariable(var);}
\n | \; {yybegin(YYINITIAL);}
. {}
}
Expand All @@ -147,7 +267,7 @@ OPTION = \- ("a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "k" |
/************************/
<FORLOOP>
{
{VAR} {variables.add(yytext()); yybegin(YYINITIAL);}
{VAR} {addVariable(yytext()); yybegin(YYINITIAL);}
\n | \; {yybegin(YYINITIAL);}
. {}
}
Expand All @@ -159,7 +279,7 @@ OPTION = \- ("a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "k" |
{
\\\$ {}
\$(\{)?{VAR} {String var = yytext().substring(1).replace("{","");
if(!variables.contains(var)) setError(location,"The variable $" + var + " is used before being initialized." , yyline+1);}
checkVariable(var);}
\n | \; | \" {yybegin(YYINITIAL);}
. {}
}
Expand All @@ -169,11 +289,32 @@ OPTION = \- ("a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "k" |
/************************/
<READ>
{
{VAR} {variables.add(yytext()); }
{VAR} {addVariable(yytext()); }
\n | \; {yybegin(YYINITIAL);}
. {}
}

/************************/
/* BEGINFUNC STATE */
/************************/
/*
* This state target is to retrieve the function starter. For more information on fonction starter, have a look on {@link Function} class.
* Pending this starter, the function ender can be defined.
*
*/
<BEGINFUNC>
{
\(\) {}
{FUNCSTART} {
FunctionWithVariables function;
function = new FunctionWithVariables(location, functionLine, yytext());
setGlobals(function);
functionStack.push(function);
yybegin(YYINITIAL);
}
[^]|{SPACE} {}
}


/************************/
/* ERROR STATE */
Expand Down
Loading