parent
c21b15ccaa
commit
81e0f94dd4
|
@ -14,16 +14,19 @@ bool AcController::getAcState() {
|
|||
|
||||
engineTooSlow = rpm < 500;
|
||||
|
||||
if (engineTooSlow) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto maxRpm = engineConfiguration->maxAcRpm;
|
||||
engineTooFast = maxRpm != 0 && maxRpmDeadband.gt(rpm, maxRpm);
|
||||
if (engineTooFast) {
|
||||
invokeMethodRed();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (engineTooSlow) {
|
||||
invokeMethod();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
auto clt = Sensor::get(SensorType::Clt);
|
||||
|
||||
noClt = !clt;
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
package com.rusefi;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.rusefi.livedata.ParseResult;
|
||||
import com.rusefi.livedata.generated.CPP14Parser;
|
||||
import com.rusefi.livedata.generated.CPP14ParserBaseListener;
|
||||
import com.rusefi.ui.livedata.Range;
|
||||
import com.rusefi.ui.livedata.SourceCodePainter;
|
||||
import com.rusefi.ui.livedata.VariableValueSource;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.Stack;
|
||||
|
||||
import static com.devexperts.logging.Logging.getLogging;
|
||||
|
||||
public class CodeWalkthrough {
|
||||
private static final Logging log = getLogging(CodeWalkthrough.class);
|
||||
// inactive statements within inactive branch of code - light red
|
||||
public static final Color INACTIVE_BRANCH = new Color(255, 102, 102);
|
||||
// active statements - light green
|
||||
public static final Color ACTIVE_STATEMENT = new Color(102, 255, 102);
|
||||
// cost past active return statement
|
||||
public static final Color PASSIVE_CODE = Color.lightGray;
|
||||
|
||||
static {
|
||||
log.configureDebugEnabled(true);
|
||||
}
|
||||
|
||||
private static final String CONFIG_MAGIC_PREFIX = "engineConfiguration";
|
||||
|
||||
public static ParseResult applyVariables(VariableValueSource valueSource, String sourceCode, SourceCodePainter painter, ParseTree tree) {
|
||||
Stack<Boolean> currentState = new Stack<>();
|
||||
|
||||
java.util.List<TerminalNode> allTerminals = new java.util.ArrayList<>();
|
||||
|
||||
new ParseTreeWalker().walk(new CPP14ParserBaseListener() {
|
||||
@Override
|
||||
public void enterFunctionDefinition(CPP14Parser.FunctionDefinitionContext ctx) {
|
||||
// new method is starting new all over
|
||||
resetState(currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterDeclarationStatement(CPP14Parser.DeclarationStatementContext ctx) {
|
||||
super.enterDeclarationStatement(ctx);
|
||||
colorStatement(ctx, painter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterJumpStatement(CPP14Parser.JumpStatementContext ctx) {
|
||||
super.enterJumpStatement(ctx);
|
||||
colorStatement(ctx, painter);
|
||||
if ("return".equalsIgnoreCase(ctx.getStart().getText()) &&
|
||||
!currentState.isEmpty() &&
|
||||
getOverallState(currentState)) {
|
||||
// we have experienced 'return' in 'green' active flow looks like end of execution for this method?
|
||||
currentState.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterStatement(CPP14Parser.StatementContext ctx) {
|
||||
String origin = getOrigin(ctx, sourceCode);
|
||||
// System.out.println("enter statement [" + origin + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTerminal(TerminalNode node) {
|
||||
allTerminals.add(node);
|
||||
if ("else".equalsIgnoreCase(node.getSymbol().getText())) {
|
||||
if (log.debugEnabled())
|
||||
log.debug("CONDITIONAL ELSE terminal, flipping condition");
|
||||
|
||||
if (currentState.isEmpty())
|
||||
return;
|
||||
|
||||
Boolean onTop = currentState.pop();
|
||||
currentState.add(!onTop);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterCondition(CPP14Parser.ConditionContext ctx) {
|
||||
String conditionVariable = ctx.getText();
|
||||
System.out.println("CONDITIONAL: REQUESTING VALUE " + conditionVariable);
|
||||
// System.out.println("exp " + getOrigin(ctx.expression(), s));
|
||||
|
||||
Boolean state = (Boolean) valueSource.getValue(conditionVariable);
|
||||
if (state == null) {
|
||||
// todo: fail on unknown condition variables
|
||||
return;
|
||||
}
|
||||
if (log.debugEnabled())
|
||||
log.debug("CURRENT STATE ADD " + state);
|
||||
currentState.add(state);
|
||||
if (state) {
|
||||
painter.paintBackground(Color.GREEN, new Range(ctx));
|
||||
} else {
|
||||
painter.paintBackground(Color.RED, new Range(ctx));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitSelectionStatement(CPP14Parser.SelectionStatementContext ctx) {
|
||||
super.exitSelectionStatement(ctx);
|
||||
if (currentState.isEmpty())
|
||||
return; // we are here if some conditional variables were not resolved
|
||||
currentState.pop();
|
||||
if (log.debugEnabled())
|
||||
log.debug("CONDITIONAL: EXIT");
|
||||
}
|
||||
|
||||
|
||||
private void colorStatement(ParserRuleContext ctx, SourceCodePainter painter) {
|
||||
Color color;
|
||||
if (currentState.isEmpty()) {
|
||||
color = PASSIVE_CODE; // we are past return or past error
|
||||
} else {
|
||||
boolean isAlive = getOverallState(currentState);
|
||||
color = isAlive ? ACTIVE_STATEMENT : INACTIVE_BRANCH;
|
||||
}
|
||||
painter.paintBackground(color, new Range(ctx));
|
||||
}
|
||||
}, tree);
|
||||
|
||||
java.util.List<Token> configTokens = new java.util.ArrayList<>();
|
||||
|
||||
for (int i = 0; i < allTerminals.size() - 3; i++) {
|
||||
|
||||
if (allTerminals.get(i).getText().equals(CONFIG_MAGIC_PREFIX) &&
|
||||
allTerminals.get(i + 1).getText().equals("->")
|
||||
) {
|
||||
Token token = allTerminals.get(i + 2).getSymbol();
|
||||
painter.paintForeground(Color.BLUE, new Range(token, token));
|
||||
configTokens.add(token);
|
||||
}
|
||||
}
|
||||
return new ParseResult(configTokens);
|
||||
}
|
||||
|
||||
private static void resetState(Stack<Boolean> currentState) {
|
||||
currentState.clear();
|
||||
currentState.add(Boolean.TRUE);
|
||||
}
|
||||
|
||||
private static boolean getOverallState(Stack<Boolean> currentState) {
|
||||
for (boolean value : currentState) {
|
||||
if (!value)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getOrigin(ParserRuleContext ctx, String s) {
|
||||
Range range = new Range(ctx);
|
||||
return s.substring(range.getStart(), range.getStop());
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.rusefi.livedata;
|
|||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.opensr5.ConfigurationImage;
|
||||
import com.rusefi.CodeWalkthrough;
|
||||
import com.rusefi.binaryprotocol.BinaryProtocol;
|
||||
import com.rusefi.binaryprotocol.BinaryProtocolState;
|
||||
import com.rusefi.config.Field;
|
||||
|
@ -9,7 +10,6 @@ import com.rusefi.config.generated.Fields;
|
|||
import com.rusefi.enums.live_data_e;
|
||||
import com.rusefi.livedata.generated.CPP14Lexer;
|
||||
import com.rusefi.livedata.generated.CPP14Parser;
|
||||
import com.rusefi.livedata.generated.CPP14ParserBaseListener;
|
||||
import com.rusefi.ui.UIContext;
|
||||
import com.rusefi.ui.livedata.Range;
|
||||
import com.rusefi.ui.livedata.SourceCodePainter;
|
||||
|
@ -19,8 +19,6 @@ import com.rusefi.ui.livedocs.LiveDocsRegistry;
|
|||
import com.rusefi.ui.livedocs.RefreshActions;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
@ -28,7 +26,6 @@ import javax.swing.text.*;
|
|||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Stack;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static com.devexperts.logging.Logging.getLogging;
|
||||
|
@ -40,7 +37,6 @@ import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
|
|||
* @see LiveDataParserPanelSandbox
|
||||
*/
|
||||
public class LiveDataParserPanel {
|
||||
private static final String CONFIG_MAGIC_PREFIX = "engineConfiguration";
|
||||
private static final Logging log = getLogging(LiveDataParserPanel.class);
|
||||
|
||||
{
|
||||
|
@ -134,75 +130,6 @@ public class LiveDataParserPanel {
|
|||
return parser.translationUnit();
|
||||
}
|
||||
|
||||
public static ParseResult applyVariables(VariableValueSource valueSource, String sourceCode, SourceCodePainter painter, ParseTree tree) {
|
||||
Stack<Boolean> currentState = new Stack<>();
|
||||
currentState.add(Boolean.TRUE);
|
||||
|
||||
java.util.List<TerminalNode> allTerminals = new java.util.ArrayList<>();
|
||||
|
||||
new ParseTreeWalker().walk(new CPP14ParserBaseListener() {
|
||||
@Override
|
||||
public void enterStatement(CPP14Parser.StatementContext ctx) {
|
||||
String origin = getOrigin(ctx, sourceCode);
|
||||
// System.out.println("enter statement [" + origin + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTerminal(TerminalNode node) {
|
||||
allTerminals.add(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterCondition(CPP14Parser.ConditionContext ctx) {
|
||||
String conditionVariable = ctx.getText();
|
||||
// System.out.println("REQUESTING VALUE " + conditionVariable);
|
||||
// System.out.println("exp " + getOrigin(ctx.expression(), s));
|
||||
|
||||
Boolean state = (Boolean) valueSource.getValue(conditionVariable);
|
||||
if (state == null) {
|
||||
// todo: fail on unknown condition variables
|
||||
return;
|
||||
}
|
||||
if (state) {
|
||||
painter.paintBackground(Color.GREEN, new Range(ctx));
|
||||
} else {
|
||||
painter.paintBackground(Color.RED, new Range(ctx));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterSelectionStatement(CPP14Parser.SelectionStatementContext ctx) {
|
||||
super.enterSelectionStatement(ctx);
|
||||
// System.out.println("Else terminal " + ctx.Else());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterJumpStatement(CPP14Parser.JumpStatementContext ctx) {
|
||||
|
||||
}
|
||||
}, tree);
|
||||
|
||||
java.util.List<Token> configTokens = new java.util.ArrayList<>();
|
||||
|
||||
for (int i = 0; i < allTerminals.size() - 3; i++) {
|
||||
|
||||
if (allTerminals.get(i).getText().equals(CONFIG_MAGIC_PREFIX) &&
|
||||
allTerminals.get(i + 1).getText().equals("->")
|
||||
) {
|
||||
Token token = allTerminals.get(i + 2).getSymbol();
|
||||
painter.paintForeground(Color.BLUE, new Range(token, token));
|
||||
configTokens.add(token);
|
||||
}
|
||||
}
|
||||
return new ParseResult(configTokens);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getOrigin(ParserRuleContext ctx, String s) {
|
||||
Range range = new Range(ctx);
|
||||
return s.substring(range.getStart(), range.getStop());
|
||||
}
|
||||
|
||||
public JPanel getContent() {
|
||||
return content;
|
||||
}
|
||||
|
@ -218,7 +145,7 @@ public class LiveDataParserPanel {
|
|||
|
||||
// todo: technically we do not need to do the complete re-compile on fresh data arrival just repaint!
|
||||
// todo: split compilation and painting/repainting
|
||||
parseResult = applyVariables(valueSource, sourceCode, new SourceCodePainter() {
|
||||
parseResult = CodeWalkthrough.applyVariables(valueSource, sourceCode, new SourceCodePainter() {
|
||||
@Override
|
||||
public void paintBackground(Color color, Range range) {
|
||||
AttributeSet s = sc.addAttribute(oldSet, StyleConstants.Background, color);
|
||||
|
|
|
@ -17,12 +17,7 @@ public class LiveDataParserSandbox {
|
|||
values.put("engineTooSlow", Boolean.TRUE);
|
||||
values.put("engineTooFast", Boolean.FALSE);
|
||||
|
||||
VariableValueSource valueSource = new VariableValueSource() {
|
||||
@Override
|
||||
public Object getValue(String name) {
|
||||
return values.get(name);
|
||||
}
|
||||
};
|
||||
VariableValueSource valueSource = name -> values.get(name);
|
||||
|
||||
new FrameHelper(JDialog.EXIT_ON_CLOSE).showFrame(new LiveDataParserPanel(new UIContext(), valueSource, "ac_control.cpp").getContent());
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.rusefi.ui.livedata;
|
||||
|
||||
import com.rusefi.CodeWalkthrough;
|
||||
import com.rusefi.livedata.LiveDataParserPanel;
|
||||
import com.rusefi.livedata.LiveDataView;
|
||||
import com.rusefi.livedata.ParseResult;
|
||||
|
@ -31,9 +32,8 @@ public class LiveDataParserTest {
|
|||
String sourceCode = "bool AcState::getAcState() {\n" +
|
||||
"\tauto rpm = Sensor::getOrZero(SensorType::Rpm);\n" +
|
||||
"\n" +
|
||||
"\tengineTooSlow = rpm < 500;\n" +
|
||||
"\n" +
|
||||
"\tif (engineTooSlow) {\n" +
|
||||
"\t\tinvokeMethod();\n" +
|
||||
"\t\treturn true;\n" +
|
||||
"\t} else {\n " +
|
||||
"auto ff2 = engineConfiguration->Alternatorcontrolpin;\n" +
|
||||
|
@ -43,18 +43,30 @@ public class LiveDataParserTest {
|
|||
"\t\treturn false;\n" +
|
||||
"\t} \n " +
|
||||
"return ff;\n" +
|
||||
"}";
|
||||
"}\n" +
|
||||
"bool AcState::getAcState2() {\n" +
|
||||
"return ff;\n" +
|
||||
"}\n";
|
||||
|
||||
SourceCodePainter painter = mock(SourceCodePainter.class);
|
||||
ParseTree tree = LiveDataParserPanel.getParseTree(sourceCode);
|
||||
|
||||
System.out.println("******************************************* Just print everything for educational purposes");
|
||||
new ParseTreeWalker().walk(new PrintCPP14ParserListener(), tree);
|
||||
|
||||
System.out.println("******************************************* Now running FOR REAL");
|
||||
|
||||
LiveDataParserPanel.applyVariables(valueSource, sourceCode, painter, tree);
|
||||
|
||||
CodeWalkthrough.applyVariables(valueSource, sourceCode, painter, tree);
|
||||
verify(painter, times(2)).paintForeground(eq(Color.blue), any());
|
||||
|
||||
verify(painter).paintBackground(eq(Color.red), any());
|
||||
verify(painter).paintBackground(eq(Color.green), any());
|
||||
|
||||
verify(painter, times(4)).paintBackground(eq(CodeWalkthrough.ACTIVE_STATEMENT), any());
|
||||
verify(painter, times(1)).paintBackground(eq(CodeWalkthrough.INACTIVE_BRANCH), any());
|
||||
|
||||
verify(painter, times(3)).paintBackground(eq(CodeWalkthrough.PASSIVE_CODE), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -63,7 +75,7 @@ public class LiveDataParserTest {
|
|||
assertTrue(sourceCode.length() > 100);
|
||||
|
||||
ParseTree tree = LiveDataParserPanel.getParseTree(sourceCode);
|
||||
ParseResult parseResult = LiveDataParserPanel.applyVariables(VariableValueSource.VOID, sourceCode, SourceCodePainter.VOID, tree);
|
||||
ParseResult parseResult = CodeWalkthrough.applyVariables(VariableValueSource.VOID, sourceCode, SourceCodePainter.VOID, tree);
|
||||
assertFalse(parseResult.getConfigTokens().isEmpty());
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue