All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.python.indexer.ast.NAttribute Maven / Gradle / Ivy

Go to download

Jython is an implementation of the high-level, dynamic, object-oriented language Python written in 100% Pure Java, and seamlessly integrated with the Java platform. It thus allows you to run Python on any Java platform.

There is a newer version: 2.7.4
Show newest version
/**
 * Copyright 2009, Google Inc.  All rights reserved.
 * Licensed to PSF under a Contributor Agreement.
 */
package org.python.indexer.ast;

import org.python.indexer.Indexer;
import org.python.indexer.NBinding;
import org.python.indexer.Scope;
import org.python.indexer.types.NType;
import org.python.indexer.types.NUnionType;
import org.python.indexer.types.NUnknownType;

import static org.python.indexer.NBinding.Kind.ATTRIBUTE;

public class NAttribute extends NNode {

    static final long serialVersionUID = -1120979305017812255L;

    public NNode target;
    public NName attr;

    public NAttribute(NNode target, NName attr) {
        this(target, attr, 0, 1);
    }

    public NAttribute(NNode target, NName attr, int start, int end) {
        super(start, end);
        setTarget(target);
        setAttr(attr);
        addChildren(target, attr);
    }

    public String getAttributeName() {
        return attr.id;
    }

    /**
     * Sets the attribute node.  Used when constructing the AST.
     * @throws IllegalArgumentException if the param is null
     */
    public void setAttr(NName attr) {
        if (attr == null) {
            throw new IllegalArgumentException("param cannot be null");
        }
        this.attr = attr;
    }

    public NName getAttr() {
        return attr;
    }

    /**
     * Sets the target node.  Used when constructing the AST.
     * @throws IllegalArgumentException if the param is null
     */
    public void setTarget(NNode target) {
        if (target == null) {
            throw new IllegalArgumentException("param cannot be null");
        }
        this.target = target;
    }

    public NNode getTarget() {
        return target;
    }

    /**
     * Assign some definite value to the attribute.  Used during the name
     * resolution pass.  This method is called when this node is in the lvalue of
     * an assignment, in which case it is called in lieu of {@link #resolve}.

*/ public void setAttr(Scope s, NType v) throws Exception { setType(new NUnknownType()); NType targetType = resolveExpr(target, s); if (targetType.isUnionType()) { targetType = targetType.asUnionType().firstKnownNonNullAlternate(); if (targetType == null) { return; } } targetType = targetType.follow(); if (targetType == Indexer.idx.builtins.None) { return; } NBinding b = targetType.getTable().putAttr(attr.id, attr, v, ATTRIBUTE); if (b != null) { setType(attr.setType(b.followType())); } } @Override public NType resolve(Scope s) throws Exception { setType(new NUnknownType()); NType targetType = resolveExpr(target, s); if (targetType.isUnionType()) { NType ret = new NUnknownType(); for (NType tp : targetType.asUnionType().getTypes()) { resolveAttributeOnType(tp); ret = NUnionType.union(ret, getType()); } setType(attr.setType(ret.follow())); } else { resolveAttributeOnType(targetType); } return getType(); } private void resolveAttributeOnType(NType targetType) { NType ttype = targetType.follow(); NBinding b = ttype.getTable().lookupAttr(attr.id); if (b == null) { b = makeProvisionalBinding(ttype); } if (b != null) { Indexer.idx.putLocation(attr, b); setType(attr.setType(b.getType())); } } /** * If we can't find the attribute in the target type, create a temp binding * for the attribute. If later on the target type defines the attribute, * that definition replaces the temp binding, and any references to the temp * binding are updated to refer to the new definition. * *

We never create temp bindings for attributes of native types, as * the attributes of native types are expected to be fully resolved. * *

This strategy is a temporary solution for inferring the types of * attributes on targets that are not yet resolved. This whole approach * needs to be replaced by dataflow analysis. */ private NBinding makeProvisionalBinding(NType targetType) { if (targetType.isNative()) { return null; } Scope targetScope = targetType.getTable(); // XXX: Eventually we need to fix out all the cases where the path is // is empty here. For now, avoid an IndexingException. if ("".equals(targetScope.getPath())) { return null; } NType utype = new NUnknownType(); NBinding b = targetScope.putAttr(attr.id, null, utype, ATTRIBUTE); if (b != null) { b.setProvisional(true); utype.getTable().setPath(b.getQname()); } return b; } @Override public String toString() { return ""; } @Override public void visit(NNodeVisitor v) { if (v.visit(this)) { visitNode(target, v); visitNode(attr, v); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy