package me.tomassetti.turin.parser.ast.expressions; import com.google.common.collect.ImmutableList; import me.tomassetti.jvm.JvmFieldDefinition; import me.tomassetti.jvm.JvmMethodDefinition; import me.tomassetti.jvm.JvmType; import me.tomassetti.turin.definitions.TypeDefinition; import me.tomassetti.turin.resolvers.SymbolResolver; import me.tomassetti.turin.parser.ast.Node; import me.tomassetti.turin.symbols.FormalParameter; import me.tomassetti.turin.typesystem.TypeUsage; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; public class StaticFieldAccess extends Expression { private TypeIdentifier subject; private String field; public StaticFieldAccess(TypeIdentifier subject, String field) { this.subject = subject; this.subject.setParent(this); this.field = field; } @Override public String toString() { return "StaticFieldAccess{" + "subject=" + subject + ", field='" + field + '\'' + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; StaticFieldAccess that = (StaticFieldAccess) o; if (!field.equals(that.field)) return false; if (!subject.equals(that.subject)) return false; return true; } @Override public int hashCode() { int result = subject.hashCode(); result = 31 * result + field.hashCode(); return result; } @Override public TypeUsage calcType() { TypeDefinition typeDefinition = typeDefinition(symbolResolver()); TypeUsage fieldType = typeDefinition.getFieldType(field, true); return fieldType; } @Override public Optional<List<? extends FormalParameter>> findFormalParametersFor(InvokableExpr invokable) { TypeDefinition typeDefinition = typeDefinition(symbolResolver()); if (invokable instanceof Creation) { //return Optional.of(typeDefinition.getConstructorParams(invokable.getActualParams())); throw new UnsupportedOperationException(); } else if (invokable instanceof FunctionCall) { return Optional.of(typeDefinition.getMethodParams(field, invokable.getActualParams(), true)); } else { throw new UnsupportedOperationException(invokable.getClass().getCanonicalName()); } } @Override public JvmMethodDefinition findMethodFor(List<ActualParam> actualParams, SymbolResolver resolver, boolean staticContext) { TypeDefinition typeDefinition = typeDefinition(resolver); List<JvmType> argsTypes = actualParams.stream().map((ap)->ap.getValue().calcType().jvmType()).collect(Collectors.toList()); return typeDefinition.findMethodFor(field, argsTypes, staticContext); } private TypeDefinition typeDefinitionCache; private TypeDefinition typeDefinition(SymbolResolver resolver) { if (typeDefinitionCache == null) { typeDefinitionCache = resolver.getTypeDefinitionIn(subject.qualifiedName(), this); } return typeDefinitionCache; } @Override public Iterable<Node> getChildren() { return ImmutableList.of(subject); } public JvmFieldDefinition toJvmField(SymbolResolver resolver) { TypeDefinition typeDefinition = typeDefinition(resolver); TypeUsage fieldType = typeDefinition.getFieldType(field, true); return new JvmFieldDefinition(typeDefinition.getQualifiedName().replaceAll("\\.", "/"), field, fieldType.jvmType().getSignature(), true); } }