Package org.cx4a.rsense.typing.runtime

Examples of org.cx4a.rsense.typing.runtime.SpecialMethod


            eventListener.update(new EventListener.Event(EventListener.EventType.METHOD_MISSING,
                                                         vertex));
    }

    private void init() {
        addSpecialMethod("new", new SpecialMethod() {
                public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
                    TypeSet accumulator = result.getAccumulator();
                    if (result.getPrevious() == null) {
                        TypeSet resultTypeSet = accumulator = new TypeSet();
                        TypeSet newReceivers = new TypeSet();
                        for (IRubyObject receiver : receivers) {
                            if (receiver instanceof RubyClass) {
                                RubyClass klass = (RubyClass) receiver;
                                if (klass.getMetaClass().searchMethod("new") == null) {
                                    if (klass == runtime.getProc()) {
                                        // Proc.new {}
                                        if (block instanceof Proc)
                                            resultTypeSet.add((Proc) block);
                                        else
                                            Logger.debug("Proc.new for no block is not supported yet");
                                    } else
                                        resultTypeSet.add(newInstanceOf((RubyClass) receiver));
                                } else {
                                    newReceivers.add(receiver);
                                }
                            }
                        }
                        if (!newReceivers.isEmpty()) {
                            result
                                .setResultTypeSet(resultTypeSet)
                                .setCallNextMethod(true)
                                .setNextMethodChange(true)
                                .setNextMethodName("new")
                                .setNextMethodReceivers(newReceivers)
                                .setNextMethodBlock(block);
                            return;
                        }
                    }
                    result
                        .setResultTypeSet(accumulator)
                        .setCallNextMethod(true)
                        .setNextMethodChange(true)
                        .setNextMethodName("initialize")
                        .setNextMethodReceivers(accumulator)
                        .setNextMethodBlock(block)
                        .setNextMethodNoReturn(true)
                        .setPrivateVisibility(true);
                }
            });

        addSpecialMethod("include", new SpecialMethod() {
                public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
                    boolean included = false;
                    if (args != null) {
                        for (Vertex arg : args) {
                            for (IRubyObject receiver : receivers) {
                                // FIXME log message
                                if (!(receiver instanceof RubyModule)) {
                                    // FIXME toplevel
                                    receiver = receiver.getMetaClass();
                                }
                                if (receiver instanceof RubyModule) {
                                    RubyModule module = (RubyModule) receiver;
                                    for (IRubyObject target : arg.getTypeSet()) {
                                        if (target instanceof RubyModule) {
                                            module.includeModule((RubyModule) target);
                                            included = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (!included) {
                        result.setCallNextMethod(true);
                    }
                }
            });

        addSpecialMethod("[]", new SpecialMethod() {
                public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
                    Collection<IRubyObject> arg = null;
                    TypeSet ts = new TypeSet();
                    for (IRubyObject receiver : receivers) {
                        if (receiver instanceof Hash) {
                            if (args != null && args.length > 0) {
                                Hash hash = (Hash) receiver;
                                Object key = Hash.getRealKey(args[0].getNode());
                                if (!hash.isModified() && key != null) {
                                    Vertex v = hash.get(key);
                                    if (v != null) {
                                        ts.addAll(v.getTypeSet());
                                    }
                                }
                            }
                        } else if (receiver instanceof Array) {
                            if (args != null && args.length > 0) {
                                Array array = (Array) receiver;
                                Integer n = Vertex.getFixnum(args[0]);
                                if (!array.isModified() && n != null) {
                                    Vertex v = array.getElement(n);
                                    if (v != null) {
                                        ts.addAll(v.getTypeSet());
                                    }
                                }
                            }
                        } else if (receiver instanceof Proc) {
                            if (arg == null) {
                                if (args == null) {
                                    arg = Arrays.asList((IRubyObject) RuntimeHelper.createArray(Graph.this, new Vertex[0]));
                                } else if (args.length == 1) {
                                    arg = args[0].getTypeSet();
                                } else { arg = Arrays.asList((IRubyObject) RuntimeHelper.createArray(Graph.this, args));
                                }
                            }
                            Vertex returnVertex = createFreeVertex();
                            RuntimeHelper.yield(Graph.this, (Proc) receiver, arg, true, returnVertex);
                            ts.addAll(returnVertex.getTypeSet());
                        }
                    }

                    if (ts.isEmpty()) {
                        result.setCallNextMethod(true);
                    } else {
                        result.setResultTypeSet(ts);
                    }
                }
            });

        addSpecialMethod("private", new SpecialMethod() {
                public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
                    RuntimeHelper.setMethodsVisibility(Graph.this, receivers, args, Visibility.PRIVATE);
                }
            });

        addSpecialMethod("protected", new SpecialMethod() {
                public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
                    RuntimeHelper.setMethodsVisibility(Graph.this, receivers, args, Visibility.PROTECTED);
                }
            });

        addSpecialMethod("public", new SpecialMethod() {
                public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
                    RuntimeHelper.setMethodsVisibility(Graph.this, receivers, args, Visibility.PUBLIC);
                }
            });

        addSpecialMethod("module_function", new SpecialMethod() {
                public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
                    RuntimeHelper.setMethodsVisibility(Graph.this, receivers, args, Visibility.MODULE_FUNCTION);
                }
            });

        addSpecialMethod("attr", new SpecialMethod() {
                public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
                    if (args != null && args.length > 0) {
                        RuntimeHelper.defineAttrs(Graph.this, receivers, new Vertex[] { args[0] }, true, args.length > 1);
                    }
                }
            });

        addSpecialMethod("attr_reader", new SpecialMethod() {
                public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
                    RuntimeHelper.defineAttrs(Graph.this, receivers, args, true, false);
                }
            });

        addSpecialMethod("attr_writer", new SpecialMethod() {
                public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
                    RuntimeHelper.defineAttrs(Graph.this, receivers, args, false, true);
                }
            });

        addSpecialMethod("attr_accessor", new SpecialMethod() {
                public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
                    RuntimeHelper.defineAttrs(Graph.this, receivers, args, true, true);
                }
            });

        addSpecialMethod("alias_method", new SpecialMethod() {
                public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
                    boolean callNextMethod = true;
                    if (args != null && args.length == 2) {
                        for (IRubyObject receiver : receivers) {
                            if (receiver instanceof RubyModule) {
                                callNextMethod = false;
                                String newName = Vertex.getStringOrSymbol(args[0]);
                                String oldName = Vertex.getStringOrSymbol(args[1]);
                                if (newName != null && oldName != null) {
                                    RubyModule module = (RubyModule) receiver;
                                    DynamicMethod method = module.getMethod(oldName);
                                    if (method instanceof Method)
                                        module.addMethod(newName, new AliasMethod(newName, (Method) method));
                                }
                            }
                        }
                    }
                    result.setCallNextMethod(callNextMethod);
                }
            });
       
        addSpecialMethod("unpack", new SpecialMethod() {
                public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
                    if (args != null && args.length > 0) {
                        String template = Vertex.getString(args[0]);
                        if (template != null) {
                            TypeSet ts = new TypeSet();
                            for (IRubyObject object : receivers) {
                                if (object.isKindOf(runtime.getString())) {
                                    List<Vertex> elements = new ArrayList<Vertex>();
                                    for (char c : template.toCharArray()) {
                                        RubyClass type = null;
                                        switch (c) {
                                        case 'a': case 'A': case 'Z': case 'b':
                                        case 'B': case 'h': case 'H': case 'm':
                                        case 'M': case 'p': case 'P': case 'u':
                                        case 'U':
                                            type = runtime.getString();
                                            break;
                                        case 'c': case 'C': case 's': case 'S':
                                        case 'i': case 'I': case 'l': case 'L':
                                        case 'q': case 'Q': case 'n': case 'N':
                                        case 'v': case 'V': case 'w': case 'x':
                                        case 'X':
                                            type = runtime.getInteger();
                                            break;
                                        case 'f': case 'd': case 'e': case 'E':
                                        case 'g': case 'G':
                                            type = runtime.getFloat();
                                            break;
                                        }
                                        if (type != null) {
                                            elements.add(createFreeSingleTypeVertex(newInstanceOf(type)));
                                        }
                                    }
                                    ts.add(RuntimeHelper.createArray(Graph.this, elements.toArray(new Vertex[0])));
                                }
                            }
                            if (ts.isEmpty()) {
                                result.setCallNextMethod(true);
                            } else {
                                result.setResultTypeSet(ts);
                            }
                        }
                    }
                }
            });

        addSpecialMethod("proc", new SpecialMethod() {
                public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
                    TypeSet ts = new TypeSet();
                    for (IRubyObject receiver : receivers) {
                        DynamicMethod method = receiver.getMetaClass().searchMethod("proc");
                        if (method != null && method.getModule() == runtime.getKernel()) {
                            if (block instanceof Proc)
                                ts.add((Proc) block);
                            else
                                Logger.debug("proc for no block is not supported yet");
                        }
                    }
                    if (ts.isEmpty())
                        result.setCallNextMethod(true);
                    else
                        result.setResultTypeSet(ts);
                }
            });

        addSpecialMethod("lambda", new SpecialMethod() {
                public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
                    TypeSet ts = new TypeSet();
                    for (IRubyObject receiver : receivers) {
                        DynamicMethod method = receiver.getMetaClass().searchMethod("lambda");
                        if (method != null && method.getModule() == runtime.getKernel()) {
                            if (block instanceof Proc)
                                ts.add((Proc) block);
                            else
                                Logger.debug("lambda for no block is not supported yet");
                        }
                    }
                    if (ts.isEmpty())
                        result.setCallNextMethod(true);
                    else
                        result.setResultTypeSet(ts);
                }
            });

        addSpecialMethod("call", new SpecialMethod() {
                public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
                    TypeSet ts = new TypeSet();
                    Vertex argVertex = null;
                    for (IRubyObject receiver : receivers) {
                        if (receiver instanceof Proc) {
View Full Code Here

TOP

Related Classes of org.cx4a.rsense.typing.runtime.SpecialMethod

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.