add interface declaration support

This commit is contained in:
CaiHQ 2023-06-06 11:38:02 +08:00
parent c24242ab87
commit c65e459208
7 changed files with 1120 additions and 857 deletions

View File

@ -18,6 +18,7 @@ public class ContractNode {
private final List<FunctionNode> functions; private final List<FunctionNode> functions;
private final Map<String, FunctionNode> functionMap; private final Map<String, FunctionNode> functionMap;
private final Set<String> dependentContracts; private final Set<String> dependentContracts;
private final Map<String, InterfaceNode> interfaceMap;
public Map<String, REventSemantics> events; public Map<String, REventSemantics> events;
public Map<String, REventSemantics> logs; public Map<String, REventSemantics> logs;
public List<AnnotationNode> annotations; public List<AnnotationNode> annotations;
@ -36,6 +37,7 @@ public class ContractNode {
clzs = new ArrayList<>(); clzs = new ArrayList<>();
functions = new ArrayList<>(); functions = new ArrayList<>();
functionMap = new HashMap<>(); functionMap = new HashMap<>();
interfaceMap = new HashMap<>();
isBundle = false; isBundle = false;
events = new HashMap<>(); events = new HashMap<>();
logs = new HashMap<>(); logs = new HashMap<>();
@ -50,6 +52,10 @@ public class ContractNode {
getFunctions().add(function); getFunctions().add(function);
} }
public void addInterface(InterfaceNode interfaceNode) {
interfaceMap.put(interfaceNode.functionName, interfaceNode);
}
public void addClass(ClassNode clzNode) { public void addClass(ClassNode clzNode) {
getClzs().add(clzNode); getClzs().add(clzNode);
} }
@ -118,6 +124,9 @@ public class ContractNode {
functions.add(fn); functions.add(fn);
functionMap.put(fn.functionName, fn); functionMap.put(fn.functionName, fn);
} }
for (InterfaceNode interfaceNode : contract.interfaceMap.values()) {
interfaceMap.put(interfaceNode.functionName, interfaceNode);
}
clzs.addAll(contract.clzs); clzs.addAll(contract.clzs);
this.events.putAll(contract.events); this.events.putAll(contract.events);
this.logs.putAll(contract.logs); this.logs.putAll(contract.logs);
@ -241,4 +250,22 @@ public class ContractNode {
functions.addProperty(dependentFunctionName, dependentFunctionNode.plainText()); functions.addProperty(dependentFunctionName, dependentFunctionNode.plainText());
} }
} }
public void mergeInterfaceAnnotationIntoFunction() {
for (InterfaceNode node : interfaceMap.values()) {
FunctionNode functionNode = functionMap.get(node.functionName);
if (functionNode != null) {
Set<String> funAnno = new HashSet<>();
for (AnnotationNode annotationNode : functionNode.annotations) {
funAnno.add(annotationNode.type);
}
for (AnnotationNode annotationNode : node.annotations) {
if (funAnno.contains(annotationNode.type))
throw new RuntimeException("duplicated annotation:" + node.functionName + " -> " + annotationNode.getType());
}
functionNode.annotations.addAll(node.annotations);
} else throw new RuntimeException("unimplemented functions:" + node.functionName);
}
}
} }

View File

@ -40,6 +40,7 @@ public class ContractZipBundle {
} }
cn.merge(contract); cn.merge(contract);
} }
cn.mergeInterfaceAnnotationIntoFunction();
return cn; return cn;
} }
} }

View File

@ -0,0 +1,156 @@
package org.bdware.sc.node;
import org.bdware.sc.bean.DoipOperationInfo;
import org.bdware.sc.bean.JoinInfo;
import org.bdware.sc.bean.RouteInfo;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
public class InterfaceNode extends Script {
private final List<AnnotationHook> beforeInvoke;
private final List<AnnotationHook> afterInvoke;
public String functionName;
public List<AnnotationNode> annotations;
boolean isStatic;
String fileName;
EnumSet<LogType> logTypes;
// boolean logToChain;
LogLocation logLocation = new LogLocation();
private RouteInfo routeInfo;
private JoinInfo joinInfo;
private DoipOperationInfo doipOperationInfo;
private boolean isHandler;
private boolean isDoipOperation;
public InterfaceNode(String name, String fileName) {
this.functionName = name;
this.fileName = fileName;
this.annotations = new ArrayList<>();
this.logTypes = EnumSet.noneOf(LogType.class);
beforeInvoke = new ArrayList<>();
afterInvoke = new ArrayList<>();
}
public DoipOperationInfo getDoipOperationInfo() {
return doipOperationInfo;
}
public void setDoipOperationInfo(DoipOperationInfo doipOperationInfo) {
this.doipOperationInfo = doipOperationInfo;
}
public void setIsDoipOperation(boolean doipOperation) {
isDoipOperation = doipOperation;
}
public boolean isDoipOperation() {
return isDoipOperation;
}
public boolean isHandler() {
return isHandler;
}
public void setHandler(boolean handler) {
isHandler = handler;
}
public String getFileName() {
return fileName;
}
public void addAnnotation(AnnotationNode annNode) {
annotations.add(annNode);
}
public void addLogType(LogType v) {
if (v == null) {
return;
}
logTypes.add(v);
}
public EnumSet<LogType> getLogTypes() {
return logTypes;
}
public boolean getLogToBDContract() {
return logLocation.logToBDContract;
}
public void setLogToBDContract(boolean b) {
logLocation.logToBDContract = b;
}
public boolean getLogToNamedLedger() {
return logLocation.logToNamedLedger;
}
public void setLogToNamedLedger(boolean b) {
logLocation.logToNamedLedger = b;
}
public void addLedgerName(String name) {
if (logLocation.ledgerNames == null) {
logLocation.ledgerNames = new ArrayList<>();
}
logLocation.ledgerNames.add(name);
}
public List<String> getLedgerNames() {
return logLocation.ledgerNames;
}
public void appendAfterInvokeHandler(AnnotationHook handler) {
afterInvoke.add(handler);
}
public List<AnnotationHook> afterExecutionAnnotations() {
return afterInvoke;
}
public void appendBeforeInvokeHandler(AnnotationHook handler) {
beforeInvoke.add(handler);
}
public List<AnnotationHook> beforeExecutionAnnotations() {
return beforeInvoke;
}
public RouteInfo getRouteInfo() {
return routeInfo;
}
public void setRouteInfo(RouteInfo routeInfo) {
this.routeInfo = routeInfo;
}
public JoinInfo getJoinInfo() {
return this.joinInfo;
}
public void setJoinInfo(JoinInfo joinInfo1) {
this.joinInfo = joinInfo1;
}
public String getFunctionName() {
return functionName;
}
public void setFunctionName(String functionName) {
this.functionName = functionName;
}
public AnnotationNode getAnnotation(String annotationName) {
for (AnnotationNode node : annotations)
if (node.getType() != null && node.getType().equals(annotationName))
return node;
return null;
}
}

View File

@ -110,6 +110,10 @@ public class ContractReader extends YJSParserBaseVisitor<ContractNode> {
(null != eventGlobalOrLocalContext && (null != eventGlobalOrLocalContext &&
eventGlobalOrLocalContext.getText().equals("global")); eventGlobalOrLocalContext.getText().equals("global"));
node.addEvent(event.Identifier().getText(), semantics, isGlobal); node.addEvent(event.Identifier().getText(), semantics, isGlobal);
} else if (null != clzOrFunction.interfaceDeclaration()) {
InterfaceDeclarationContext interfaces = clzOrFunction.interfaceDeclaration();
InterfaceReader reader = new InterfaceReader(fileName);
node.addInterface(reader.visitInterfaceDeclaration(interfaces));
} }
} }
// ctx.getSourceInterval() // ctx.getSourceInterval()

View File

@ -0,0 +1,64 @@
package org.bdware.sc.visitor;
import org.antlr.v4.runtime.misc.Interval;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.node.AnnotationNode;
import org.bdware.sc.node.InterfaceNode;
import org.bdware.sc.parser.YJSParser.AnnotationContext;
import org.bdware.sc.parser.YJSParser.AnnotationLiteralContext;
import org.bdware.sc.parser.YJSParser.InterfaceDeclarationContext;
import org.bdware.sc.parser.YJSParserBaseVisitor;
import java.util.ArrayList;
import java.util.List;
public class InterfaceReader extends YJSParserBaseVisitor<InterfaceNode> {
private static final Logger LOGGER = LogManager.getLogger(InterfaceReader.class);
InterfaceNode node;
String fileName;
// Stack<String> regStack;
int regID;
public InterfaceReader(String fileName) {
this.fileName = fileName;
}
@Override
public InterfaceNode visitInterfaceDeclaration(InterfaceDeclarationContext ctx) {
node = new InterfaceNode(ctx.Identifier().toString(), fileName);
node.setLine(ctx.start.getLine());
node.setPos(ctx.start.getCharPositionInLine());
node.setInterval(
new Interval(ctx.Interface().getSourceInterval().a, ctx.getSourceInterval().b));
List<AnnotationContext> annotations = new ArrayList<>();
if (null != ctx.annotations()) {
annotations = ctx.annotations().annotation();
}
for (AnnotationContext annotation : annotations) {
AnnotationNode annNode = new AnnotationNode(annotation.Identifier().toString());
if (null != annotation.annotationArgs())
for (AnnotationLiteralContext tNode :
annotation.annotationArgs().annotationLiteral()) {
if (null != tNode.numericLiteral()) {
annNode.addArg(tNode.numericLiteral().getText());
LOGGER.debug(
"------AnnotationNumericArgs:" + tNode.numericLiteral().getText());
} else if (null != tNode.StringLiteral()) {
annNode.addArg(tNode.StringLiteral().getText());
LOGGER.debug(
"------AnnotationStringArgs:" + tNode.StringLiteral().getText());
} else {
annNode.addArg(tNode.objectLiteral().getText());
LOGGER.debug(
"------AnnotationObjectArgs:" + tNode.objectLiteral().getText());
}
}
node.addAnnotation(annNode);
}
return node;
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff