package de.peeeq.wurstscript.attributes; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList.Builder; import de.peeeq.wurstscript.ast.*; import de.peeeq.wurstscript.attributes.names.FuncLink; import de.peeeq.wurstscript.attributes.names.NameLink; import de.peeeq.wurstscript.types.WurstType; import de.peeeq.wurstscript.types.WurstTypeClass; public class UsedGlobalVariables { public static ImmutableList getUsedGlobals(ExprOrStatements e) { ImmutableList.Builder result = ImmutableList.builder(); if (e instanceof FunctionCall) { FunctionCall funcCall = (FunctionCall) e; FuncLink f = funcCall.attrFuncLink(); if (f != null) { result.addAll(f.getDef().attrUsedGlobalVariables()); } } else if (e instanceof ExprNewObject) { ExprNewObject exprNewObject = (ExprNewObject) e; ConstructorDef constr = exprNewObject.attrConstructorDef(); if (constr != null) { result.addAll(constr.getBody().attrUsedGlobalVariables()); } } else if (e instanceof ExprDestroy) { ExprDestroy stmtDestroy = (ExprDestroy) e; WurstType t = stmtDestroy.getDestroyedObj().attrTyp(); if (t instanceof WurstTypeClass) { WurstTypeClass ct = (WurstTypeClass) t; OnDestroyDef ondestr = ct.getClassDef().getOnDestroy(); result.addAll(ondestr.getBody().attrUsedGlobalVariables()); } } else if (e instanceof NameRef) { NameRef nameRef = (NameRef) e; NameLink def = nameRef.attrNameLink(); if (def.getDef() instanceof GlobalVarDef) { GlobalVarDef varDef = (GlobalVarDef) def.getDef(); result.add(varDef); } } // check children: for (int i = 0; i < e.size(); i++) { Element child = e.get(i); if (child instanceof ExprOrStatements) { ExprOrStatements child2 = (ExprOrStatements) child; result.addAll(child2.attrUsedGlobalVariables()); } } return result.build(); } public static ImmutableList getUsedGlobals(FunctionImplementation func) { return func.getBody().attrUsedGlobalVariables(); } public static ImmutableList getUsedGlobals(NativeFunc nativeFunc) { return ImmutableList.of(); } public static ImmutableList getUsedGlobals(TupleDef tupleDef) { return ImmutableList.of(); } // ---- public static ImmutableList getReadGlobals(ExprOrStatements e) { Builder result = ImmutableList.builder(); collectReadGlobals(e, result); return result.build(); } private static void collectReadGlobals(Element e, Builder result) { if (e instanceof FunctionCall) { FunctionCall funcRef = (FunctionCall) e; FuncLink f = funcRef.attrFuncLink(); if (f != null) { result.addAll(f.getDef().attrReadGlobalVariables()); } } else if (e instanceof ExprNewObject) { ExprNewObject exprNewObject = (ExprNewObject) e; ConstructorDef constr = exprNewObject.attrConstructorDef(); if (constr != null) { result.addAll(constr.getBody().attrReadGlobalVariables()); } } else if (e instanceof ExprDestroy) { ExprDestroy stmtDestroy = (ExprDestroy) e; WurstType t = stmtDestroy.getDestroyedObj().attrTyp(); if (t instanceof WurstTypeClass) { WurstTypeClass ct = (WurstTypeClass) t; OnDestroyDef ondestr = ct.getClassDef().getOnDestroy(); result.addAll(ondestr.getBody().attrReadGlobalVariables()); } } else if (e instanceof NameRef) { NameRef nameRef = (NameRef) e; if (e.getParent() instanceof StmtSet && ((StmtSet) e.getParent()).getUpdatedExpr() == e) { // write access } else { NameLink def = nameRef.attrNameLink(); if (def.getDef() instanceof GlobalVarDef) { GlobalVarDef varDef = (GlobalVarDef) def.getDef(); result.add(varDef); } } } else if (e instanceof ExprClosure) { // do not collect vars in closures, because closures are usually called later return; } // check children: for (int i = 0; i < e.size(); i++) { Element child = e.get(i); if (child instanceof ExprOrStatements) { ExprOrStatements child2 = (ExprOrStatements) child; result.addAll(child2.attrReadGlobalVariables()); } else { collectReadGlobals(child, result); } } } public static ImmutableList getReadGlobals(FunctionImplementation func) { return func.getBody().attrReadGlobalVariables(); } public static ImmutableList getReadGlobals(NativeFunc nativeFunc) { return ImmutableList.of(); } public static ImmutableList getReadGlobals(TupleDef tupleDef) { return ImmutableList.of(); } public static ImmutableList getReadGlobals(InitBlock initBlock) { return initBlock.getBody().attrReadGlobalVariables(); } }