use of de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberExpression in project cpg by Fraunhofer-AISEC.
the class StaticImportsTest method testAsteriskImport.
@Test
void testAsteriskImport() throws Exception {
List<TranslationUnitDeclaration> result = TestUtils.analyze("java", topLevel.resolve("asterisk"), true);
List<MethodDeclaration> methods = TestUtils.subnodesOfType(result, MethodDeclaration.class);
MethodDeclaration main = TestUtils.findByUniqueName(methods, "main");
List<RecordDeclaration> records = TestUtils.subnodesOfType(result, RecordDeclaration.class);
RecordDeclaration A = TestUtils.findByUniqueName(records, "A");
RecordDeclaration B = TestUtils.findByUniqueName(records, "B");
for (CallExpression call : TestUtils.subnodesOfType(main, CallExpression.class)) {
switch(call.getName()) {
case "a":
assertEquals(List.of(TestUtils.findByUniqueName(methods, "a")), call.getInvokes());
assertTrue(((MethodDeclaration) call.getInvokes().get(0)).isStatic());
break;
case "b":
List<MethodDeclaration> bs = methods.stream().filter(m -> m.getName().equals("b") && m.isStatic()).collect(Collectors.toList());
assertEquals(call.getInvokes(), bs.stream().filter(b -> b.hasSignature(call.getSignature())).collect(Collectors.toList()));
break;
case "nonStatic":
MethodDeclaration nonStatic = TestUtils.findByUniqueName(B.getMethods(), "nonStatic");
assertTrue(nonStatic.isInferred());
assertEquals(List.of(nonStatic), call.getInvokes());
}
}
List<FieldDeclaration> testFields = TestUtils.subnodesOfType(A, FieldDeclaration.class);
FieldDeclaration staticField = TestUtils.findByUniqueName(testFields, "staticField");
FieldDeclaration nonStaticField = TestUtils.findByUniqueName(testFields, "nonStaticField");
assertTrue(staticField.getModifiers().contains("static"));
assertFalse(nonStaticField.getModifiers().contains("static"));
List<MemberExpression> declaredReferences = TestUtils.subnodesOfType(main, MemberExpression.class);
MemberExpression usage = TestUtils.findByUniqueName(declaredReferences, "staticField");
assertEquals(staticField, usage.getRefersTo());
MemberExpression nonStatic = TestUtils.findByUniqueName(declaredReferences, "nonStaticField");
assertNotEquals(nonStaticField, nonStatic.getRefersTo());
assertTrue(nonStatic.getRefersTo().isInferred());
}
use of de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberExpression in project cpg by Fraunhofer-AISEC.
the class StaticImportsTest method testSingleStaticImport.
@Test
void testSingleStaticImport() throws Exception {
List<TranslationUnitDeclaration> result = TestUtils.analyze("java", topLevel.resolve("single"), true);
List<MethodDeclaration> methods = TestUtils.subnodesOfType(result, MethodDeclaration.class);
MethodDeclaration test = TestUtils.findByUniqueName(methods, "test");
MethodDeclaration main = TestUtils.findByUniqueName(methods, "main");
CallExpression call = TestUtils.subnodesOfType(main, CallExpression.class).get(0);
assertEquals(List.of(test), call.getInvokes());
List<FieldDeclaration> testFields = TestUtils.subnodesOfType(result, FieldDeclaration.class).stream().filter(f -> f.getName().equals("test")).collect(Collectors.toList());
assertEquals(1, testFields.size());
FieldDeclaration staticField = testFields.get(0);
assertTrue(staticField.getModifiers().contains("static"));
List<MemberExpression> memberExpressions = TestUtils.subnodesOfType(main, MemberExpression.class);
MemberExpression usage = TestUtils.findByUniqueName(memberExpressions, "test");
assertEquals(staticField, usage.getRefersTo());
}
use of de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberExpression in project cpg by Fraunhofer-AISEC.
the class VRUtil method assertUsageOfMemberAndBase.
/**
* Asserts that {@code usingNode} uses/references the provided {@code usedBase} and {@code
* usedMember}. If {@link VRUtil#ENFORCE_MEMBER_EXPRESSION} is true, {@code usingNode} must be a
* {@link MemberExpression} where {@link MemberExpression#base} uses {@code usedBase} and {@link
* MemberExpression#refersTo} uses {@code usedMember}. Using is checked as preformed per {@link
* VRUtil#assertUsageOf(Node,Node)}
*
* @param usingNode - Node that uses some member
* @param usedBase - The expected base that is used
* @param usedMember - THe expected member that is used
*/
public static void assertUsageOfMemberAndBase(Node usingNode, Node usedBase, Node usedMember) {
assertNotNull(usingNode);
if (!(usingNode instanceof MemberExpression) && !ENFORCE_MEMBER_EXPRESSION) {
// Assumtion here is that the target of the member portion of the expression and not the base
// is resolved
assertUsageOf(usingNode, usedMember);
} else {
assertTrue(usingNode instanceof MemberExpression);
MemberExpression memberExpression = (MemberExpression) usingNode;
Node base = memberExpression.getBase();
assertUsageOf(base, usedBase);
assertUsageOf(memberExpression.getRefersTo(), usedMember);
}
}
use of de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberExpression in project cpg by Fraunhofer-AISEC.
the class VariableUsageResolver method resolveFieldUsages.
protected void resolveFieldUsages(Node current, RecordDeclaration curClass) {
if (current instanceof MemberExpression) {
MemberExpression memberExpression = (MemberExpression) current;
Declaration baseTarget = null;
if (memberExpression.getBase() instanceof DeclaredReferenceExpression) {
DeclaredReferenceExpression base = (DeclaredReferenceExpression) memberExpression.getBase();
if (lang instanceof JavaLanguageFrontend && base.getName().equals("super")) {
if (curClass != null && !curClass.getSuperClasses().isEmpty()) {
var superType = curClass.getSuperClasses().get(0);
var superRecord = recordMap.get(superType);
if (superRecord == null) {
log.error("Could not find referring super type {} for {} in the record map. Will set the super type to java.lang.Object", superType.getTypeName(), curClass.getName());
base.setType(TypeParser.createFrom(Object.class.getName(), true));
} else {
baseTarget = superRecord.getThis();
base.setRefersTo(baseTarget);
}
} else {
// no explicit super type -> java.lang.Object
Type objectType = TypeParser.createFrom(Object.class.getName(), true);
base.setType(objectType);
}
} else {
baseTarget = resolveBase((DeclaredReferenceExpression) memberExpression.getBase());
base.setRefersTo(baseTarget);
}
if (baseTarget instanceof EnumDeclaration) {
String name = memberExpression.getName();
Optional<EnumConstantDeclaration> memberTarget = ((EnumDeclaration) baseTarget).getEntries().stream().filter(e -> e.getName().equals(name)).findFirst();
if (memberTarget.isPresent()) {
memberExpression.setRefersTo(memberTarget.get());
return;
}
} else if (baseTarget instanceof RecordDeclaration) {
Type baseType = TypeParser.createFrom(baseTarget.getName(), true);
if (!recordMap.containsKey(baseType)) {
final Type containingT = baseType;
Optional<Type> fqnResolvedType = recordMap.keySet().stream().filter(t -> t.getName().endsWith("." + containingT.getName())).findFirst();
if (fqnResolvedType.isPresent()) {
baseType = fqnResolvedType.get();
}
}
memberExpression.setRefersTo(resolveMember(baseType, memberExpression));
return;
}
}
Type baseType = memberExpression.getBase().getType();
if (!recordMap.containsKey(baseType)) {
final Type containingT = baseType;
Optional<Type> fqnResolvedType = recordMap.keySet().stream().filter(t -> t.getName().endsWith("." + containingT.getName())).findFirst();
if (fqnResolvedType.isPresent()) {
baseType = fqnResolvedType.get();
}
}
memberExpression.setRefersTo(resolveMember(baseType, memberExpression));
}
}
use of de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberExpression in project cpg by Fraunhofer-AISEC.
the class VariableUsageResolver method resolveLocalVarUsage.
protected void resolveLocalVarUsage(RecordDeclaration currentClass, Node parent, Node current) {
if (lang == null) {
Util.errorWithFileLocation(current, log, "Could not resolve local variable usage: language frontend is null");
return;
}
if (current instanceof DeclaredReferenceExpression && !(current instanceof MemberExpression)) {
DeclaredReferenceExpression ref = (DeclaredReferenceExpression) current;
if (parent instanceof MemberCallExpression && current == ((MemberCallExpression) parent).getMember() && !(ref.getType() instanceof FunctionPointerType)) {
// function pointer call
return;
}
// only consider resolving, if the language frontend did not specify a resolution
Optional<? extends Declaration> refersTo = ref.getRefersTo() == null ? Optional.ofNullable(lang.getScopeManager().resolveReference(ref)) : Optional.of(ref.getRefersTo());
Type recordDeclType = null;
if (currentClass != null) {
recordDeclType = TypeParser.createFrom(currentClass.getName(), true);
}
if (ref.getType() instanceof FunctionPointerType && refersTo.isEmpty()) {
refersTo = resolveFunctionPtr(recordDeclType, ref);
}
// only add new nodes for non-static unknown
if (refersTo.isEmpty() && !(((DeclaredReferenceExpression) current).isStaticAccess()) && recordDeclType != null && recordMap.containsKey(recordDeclType)) {
// Maybe we are referring to a field instead of a local var
if (current.getName().contains(lang.getNamespaceDelimiter())) {
List<String> path = Arrays.asList(current.getName().split(Pattern.quote(lang.getNamespaceDelimiter())));
recordDeclType = TypeParser.createFrom(String.join(lang.getNamespaceDelimiter(), path.subList(0, path.size() - 1)), true);
}
ValueDeclaration field = resolveMember(recordDeclType, (DeclaredReferenceExpression) current);
if (field != null) {
refersTo = Optional.of(field);
}
}
// just enables CXX static fields
if (refersTo.isEmpty() && current.getName().contains(lang.getNamespaceDelimiter())) {
var path = Arrays.asList(current.getName().split(Pattern.quote(lang.getNamespaceDelimiter())));
recordDeclType = TypeParser.createFrom(String.join(lang.getNamespaceDelimiter(), path.subList(0, path.size() - 1)), true);
var field = resolveMember(recordDeclType, (DeclaredReferenceExpression) current);
if (field != null) {
refersTo = Optional.of(field);
}
}
if (refersTo.isPresent()) {
ref.setRefersTo(refersTo.get());
} else {
warnWithFileLocation(current, log, "Did not find a declaration for {}", ref.getName());
}
}
}
Aggregations