Source Code Cross Referenced for LinkNode.java in  » Web-Framework » anvil » anvil » script » expression » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Framework » anvil » anvil.script.expression 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $Id: LinkNode.java,v 1.39 2002/09/16 08:05:05 jkl Exp $
0003:         *
0004:         * Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
0005:         *
0006:         * Use is subject to license terms, as defined in
0007:         * Anvil Sofware License, Version 1.1. See LICENSE 
0008:         * file, or http://njet.org/license-1.1.txt
0009:         */
0010:        package anvil.script.expression;
0011:
0012:        import anvil.Location;
0013:        import anvil.core.Any;
0014:        import anvil.core.LangModule;
0015:        import anvil.core.Modules;
0016:        import anvil.core.reflect.Reflection;
0017:        import anvil.codec.Code;
0018:        import anvil.script.compiler.ByteCompiler;
0019:        import anvil.ErrorListener;
0020:        import anvil.script.CompilableFunction;
0021:        import anvil.script.Context;
0022:        import anvil.script.Import;
0023:        import anvil.script.Imported;
0024:        import anvil.script.Type;
0025:        import anvil.script.InterfaceType;
0026:        import anvil.script.VariableType;
0027:        import anvil.script.LocalVariableType;
0028:        import anvil.script.ConstantVariableType;
0029:        import anvil.script.StaticVariableType;
0030:        import anvil.script.MethodType;
0031:        import anvil.script.MemberVariableType;
0032:        import anvil.script.Name;
0033:        import anvil.script.NamespaceType;
0034:        import anvil.script.ClassType;
0035:        import anvil.script.Scope;
0036:        import anvil.script.ReferenceResolver;
0037:        import anvil.script.ReflectedJava;
0038:        import anvil.script.NativeJava;
0039:        import anvil.script.Grammar;
0040:        import anvil.script.Synthetic;
0041:        import anvil.script.statements.Statement;
0042:        import anvil.script.statements.FunctionStatement;
0043:        import anvil.script.statements.ClassStatement;
0044:        import anvil.script.statements.LocalVariableStatement;
0045:        import anvil.script.statements.ModuleStatement;
0046:        import anvil.script.parser.ParserBaseConstants;
0047:        import anvil.server.Zone;
0048:        import java.io.IOException;
0049:        import java.util.ArrayList;
0050:
0051:        /**
0052:         * class LinkNode
0053:         *
0054:         * @author: Jani Lehtimäki
0055:         */
0056:        public class LinkNode extends Node implements  ReferenceResolver {
0057:
0058:            public static final int GET = 0;
0059:            public static final int ASSIGN = 1;
0060:            public static final int DECLARE = 2;
0061:            public static final int NEW = 3;
0062:            public static final int SUPER = 4;
0063:
0064:            protected ModuleStatement _script;
0065:            protected Statement _statement;
0066:            protected Location _location;
0067:            protected Name _name;
0068:            protected int _index = 0;
0069:            protected Parent _args;
0070:            protected int _role;
0071:
0072:            public LinkNode(Statement stmt, Location location, Name name,
0073:                    Parent args, int role) {
0074:                super ();
0075:                _script = stmt.getModuleStatement();
0076:                _statement = stmt;
0077:                _location = location;
0078:                _name = name;
0079:                _args = args;
0080:                _role = role;
0081:            }
0082:
0083:            public LinkNode(Statement stmt, Location location, Name name) {
0084:                super ();
0085:                _script = stmt.getModuleStatement();
0086:                _statement = stmt;
0087:                _location = location;
0088:                _name = name;
0089:                _args = null;
0090:                _role = GET;
0091:            }
0092:
0093:            public void setRole(int role) {
0094:                _role = role;
0095:            }
0096:
0097:            public int typeOf() {
0098:                return Node.EXPR_LINK;
0099:            }
0100:
0101:            public boolean isConstant() {
0102:                return false;
0103:            }
0104:
0105:            public Node optimize() {
0106:                if (_args != null) {
0107:                    _args.optimize();
0108:                }
0109:                return this ;
0110:            }
0111:
0112:            public String toString() {
0113:                return toString(true);
0114:            }
0115:
0116:            public String toString(boolean withArgs) {
0117:                StringBuffer buffer = new StringBuffer(32);
0118:                _name.toString(0, buffer);
0119:                if (withArgs && _args != null) {
0120:                    buffer.append(_args.toString());
0121:                }
0122:                return buffer.toString();
0123:            }
0124:
0125:            protected Parent consumeArgs() {
0126:                Parent p = _args;
0127:                _args = null;
0128:                return p;
0129:            }
0130:
0131:            public boolean hasArgs() {
0132:                return (_args != null);
0133:            }
0134:
0135:            protected String consumeSymbol() {
0136:                if (_index < _name.size()) {
0137:                    return _name.get(_index++);
0138:                } else {
0139:                    return null;
0140:                }
0141:            }
0142:
0143:            protected String peekSymbol() {
0144:                if (_index < _name.size()) {
0145:                    return _name.get(_index);
0146:                } else {
0147:                    return null;
0148:                }
0149:            }
0150:
0151:            protected int peekKind() {
0152:                if (_index < _name.size()) {
0153:                    return _name.getKind(_index);
0154:                } else {
0155:                    return 0;
0156:                }
0157:            }
0158:
0159:            protected int symbolsLeft() {
0160:                return _name.size() - _index;
0161:            }
0162:
0163:            protected boolean hasMoreSymbols() {
0164:                return _index < _name.size();
0165:            }
0166:
0167:            protected void checkArguments(ErrorListener context,
0168:                    CompilableFunction function) {
0169:                Parent args = _args;
0170:                boolean hassplices = args.hasSplices();
0171:                boolean hasnamed = args.hasNamedParameters();
0172:                int n = args.childs();
0173:                if (hasnamed) {
0174:                    if (hassplices) {
0175:                        context
0176:                                .error(_location,
0177:                                        "Splices and named parameters cannot be used together");
0178:                    } else {
0179:                        ArrayList fixed = new ArrayList();
0180:                        int min = function.getMinimumParameterCount();
0181:                        int max = function.getParameterCount();
0182:                        boolean[] consumed = new boolean[n];
0183:                        int p = 0;
0184:                        for (int i = 0; i < max; i++) {
0185:                            int argtype = function.getParameterType(i);
0186:                            String argname = function.getParameterName(i);
0187:                            Any argdefault = function.getParameterDefault(i);
0188:                            switch (argtype) {
0189:                            case CompilableFunction.PARAMETER_CONTEXT:
0190:                                break;
0191:                            case CompilableFunction.PARAMETER_ARRAY:
0192:                            case CompilableFunction.PARAMETER_ANYLIST:
0193:                            case CompilableFunction.PARAMETER_LIST:
0194:                            case CompilableFunction.PARAMETER_REST:
0195:                                break;
0196:                            default: {
0197:                                Node node = null;
0198:                                int index = args.findNamedIndex(argname);
0199:                                if (index == -1) {
0200:                                    while (p < n) {
0201:                                        if (!consumed[p]) {
0202:                                            Node child = args.getChild(p);
0203:                                            if (child.typeOf() != EXPR_NAMED) {
0204:                                                node = child;
0205:                                                consumed[p++] = true;
0206:                                                break;
0207:                                            }
0208:                                        }
0209:                                        p++;
0210:                                    }
0211:                                } else {
0212:                                    if (!consumed[index]) {
0213:                                        consumed[index] = true;
0214:                                        node = ((NamedNode) args
0215:                                                .getChild(index)).getChild();
0216:                                    } else {
0217:                                        context
0218:                                                .error(
0219:                                                        _location,
0220:                                                        "Named parameter '"
0221:                                                                + argname
0222:                                                                + "' appears more than once");
0223:                                    }
0224:                                }
0225:                                if (node != null) {
0226:                                    fixed.add(node);
0227:                                } else {
0228:                                    if (fixed.size() < min) {
0229:                                        context.error(_location,
0230:                                                "Couldn't match for parameter #"
0231:                                                        + i + " '" + argname
0232:                                                        + "'");
0233:                                    } else {
0234:                                        fixed.add(new ConstantNode(argdefault));
0235:                                    }
0236:                                }
0237:                            }
0238:                                break;
0239:                            }
0240:                        }
0241:                        for (int i = 0; i < n; i++) {
0242:                            if (!consumed[i]) {
0243:                                Node node = args.getChild(i);
0244:                                if (node.typeOf() == EXPR_NAMED) {
0245:                                    NamedNode named = (NamedNode) node;
0246:                                    context.error(_location,
0247:                                            "Supplied named parameter #"
0248:                                                    + (i + 1) + " with name '"
0249:                                                    + named.getName()
0250:                                                    + "' was not matched");
0251:                                    node = named.getChild();
0252:                                }
0253:                                fixed.add(node);
0254:                            }
0255:                        }
0256:                        _args = new ExpressionList((Node[]) fixed
0257:                                .toArray(new Node[fixed.size()]));
0258:                    }
0259:                } else {
0260:                    if (!hassplices) {
0261:                        if (n < function.getMinimumParameterCount()) {
0262:                            context.error(_location,
0263:                                    "Too few parameters in call to '"
0264:                                            + function + "'");
0265:                        }
0266:                    }
0267:                }
0268:            }
0269:
0270:            protected Type lookupLibrary(ErrorListener context) {
0271:                Zone zone = _script.getAddress().getZone();
0272:                Modules modules = zone.getModules();
0273:                Type type = modules.lookupDeclaration(_name.get(_index - 1));
0274:                if (type != null) {
0275:                    return type;
0276:                }
0277:
0278:                StringBuffer libname = new StringBuffer(32);
0279:                int i = _index;
0280:                int length = _name.size();
0281:                int foundIndex = -1;
0282:                Scope foundScope = null;
0283:                libname.append(_name.get(i - 1));
0284:                while (i <= length) {
0285:                    String name = libname.toString();
0286:                    Scope scope = zone.findJava(name);
0287:                    if (scope != null) {
0288:                        foundIndex = i;
0289:                        foundScope = scope;
0290:                    }
0291:                    if (i >= length) {
0292:                        break;
0293:                    }
0294:                    libname.append('.');
0295:                    libname.append(_name.get(i));
0296:                    i++;
0297:                }
0298:                if (foundIndex != -1) {
0299:                    _index = foundIndex;
0300:                    return foundScope;
0301:                }
0302:                return null;
0303:            }
0304:
0305:            protected Node explicitThisConstruct(ErrorListener listener,
0306:                    ClassType classtype) {
0307:
0308:                ClassType context = _statement.getClassStatement();
0309:
0310:                if (!hasMoreSymbols()) {
0311:                    return new ThisNode(context, classtype);
0312:                }
0313:
0314:                Type type = classtype.lookupDeclaration(peekSymbol());
0315:                if (type == null) {
0316:                    listener.error(_location, "Undefined entity '" + _name
0317:                            + "'");
0318:                    return null;
0319:                }
0320:                switch (type.getType()) {
0321:                case Type.METHOD: {
0322:                    MethodType method = (MethodType) type;
0323:
0324:                    consumeSymbol();
0325:                    if (hasMoreSymbols()) {
0326:                        //methodname
0327:                        return new DelegateNode(
0328:                                new ThisNode(context, classtype), method);
0329:                    } else {
0330:                        if (hasArgs()) {
0331:                            //methodname(...)
0332:                            checkArguments(listener, method);
0333:                            return new StaticInvokeNode(classtype, context,
0334:                                    method, consumeArgs());
0335:                        } else {
0336:                            //methodname
0337:                            return new DelegateNode(new ThisNode(context,
0338:                                    classtype), method);
0339:                        }
0340:                    }
0341:                }
0342:
0343:                case Type.MEMBER_VARIABLE: {
0344:                    MemberVariableType member = (MemberVariableType) type;
0345:                    consumeSymbol();
0346:                    return new MemberVariableNode(classtype, context, member);
0347:                }
0348:
0349:                case Type.CONSTANT_VARIABLE: {
0350:                    String symbol = consumeSymbol();
0351:                    if (_role != GET) {
0352:                        listener.error(_location,
0353:                                "Attempting to assign to constant '" + symbol
0354:                                        + "'");
0355:                    }
0356:                    return new ConstantVariableNode((ConstantVariableType) type);
0357:                }
0358:
0359:                case Type.STATIC_VARIABLE: {
0360:                    consumeSymbol();
0361:                    return new StaticVariableNode((StaticVariableType) type);
0362:                }
0363:
0364:                case Type.IMPORT: {
0365:                    listener
0366:                            .error(_location,
0367:                                    "Imported entities are not available from explicit 'this' construct");
0368:                    return null;
0369:                }
0370:
0371:                default: {
0372:                    return new ThisNode(context, classtype);
0373:                }
0374:                }
0375:            }
0376:
0377:            protected Node classConstruct(ErrorListener listener, Scope scope) {
0378:                if (!hasMoreSymbols()) {
0379:                    return new TypeNode(scope);
0380:                }
0381:
0382:                if (peekKind() == ParserBaseConstants.THIS) {
0383:                    if (scope.getType() == Type.CLASS) {
0384:                        consumeSymbol();
0385:                        return explicitThisConstruct(listener,
0386:                                (ClassType) scope);
0387:                    } else {
0388:                        listener.error(_location, "Left of 'this' in '" + _name
0389:                                + "' does not point into class");
0390:                    }
0391:                }
0392:
0393:                String symbol = peekSymbol();
0394:                Type type = scope.lookupDeclaration(symbol);
0395:                if (type == null) {
0396:                    return new TypeNode(scope);
0397:                }
0398:                switch (type.getType()) {
0399:                case Type.CLASS:
0400:                case Type.INTERFACE: {
0401:                    consumeSymbol();
0402:                    if (hasMoreSymbols()) {
0403:                        return classConstruct(listener, (Scope) type);
0404:                    } else {
0405:                        return new TypeNode(type);
0406:                    }
0407:                }
0408:
0409:                case Type.MEMBER_VARIABLE:
0410:                case Type.METHOD:
0411:                case Type.INTERFACE_METHOD:
0412:                case Type.FUNCTION:
0413:                case Type.CONSTRUCTOR: {
0414:                    consumeSymbol();
0415:                    return new TypeNode(type);
0416:                }
0417:
0418:                case Type.STATIC_VARIABLE: {
0419:                    consumeSymbol();
0420:                    return new StaticVariableNode((StaticVariableType) type);
0421:                }
0422:
0423:                case Type.CONSTANT_VARIABLE: {
0424:                    consumeSymbol();
0425:                    if (_role != GET) {
0426:                        listener.error(_location,
0427:                                "Attempting to assign to constant '" + symbol
0428:                                        + "'");
0429:                    }
0430:                    return new ConstantVariableNode((ConstantVariableType) type);
0431:                }
0432:
0433:                case Type.IMPORT: {
0434:                    listener
0435:                            .error(_location,
0436:                                    "Imported entities are not available from explicit class construct");
0437:                    return null;
0438:                }
0439:
0440:                default: {
0441:                    return new TypeNode(scope);
0442:                }
0443:                }
0444:            }
0445:
0446:            protected Type followImports(ErrorListener listener, Type type) {
0447:                while (type.getType() == Type.IMPORT) {
0448:                    Imported imported = (Imported) type;
0449:                    if (imported.getModule() != _script) {
0450:                        listener.error(_location, "Attempting to refer to '"
0451:                                + imported + "' in another module");
0452:                        return null;
0453:                    }
0454:                    type = imported.getPointedType();
0455:                }
0456:                return type;
0457:            }
0458:
0459:            protected Node onFunction(ErrorListener listener, Type type) {
0460:                if (type instanceof  FunctionStatement) {
0461:                    FunctionStatement function = (FunctionStatement) type;
0462:                    if (function.getContext() != null) {
0463:                        if (hasArgs()) {
0464:                            return new InlinedCallNode(_statement
0465:                                    .getFunctionStatement(), function,
0466:                                    consumeArgs());
0467:                        } else {
0468:                            return new InlinedFunctionNode(_statement
0469:                                    .getFunctionStatement(), function);
0470:                        }
0471:                    }
0472:                }
0473:                if (hasMoreSymbols()) {
0474:                    return new TypeNode((CompilableFunction) type);
0475:                    //functioname[.field...]
0476:                } else {
0477:                    if (hasArgs()) {
0478:                        //functioname(...)
0479:                        CompilableFunction function = (CompilableFunction) type;
0480:                        checkArguments(listener, function);
0481:                        return new CallNode(function, consumeArgs());
0482:                    } else {
0483:                        //functioname
0484:                        return new TypeNode((CompilableFunction) type);
0485:                    }
0486:                }
0487:            }
0488:
0489:            protected Node construct(ErrorListener listener, Scope scope) {
0490:                String symbol = peekSymbol();
0491:                Type type;
0492:                if (scope != null) {
0493:                    consumeSymbol();
0494:                    type = scope.lookupDeclaration(symbol);
0495:                    if (type == null) {
0496:                        listener.error(_location, "Entity '" + _name
0497:                                + "' is undeclared");
0498:                        return null;
0499:                    }
0500:
0501:                } else {
0502:                    switch (_role) {
0503:                    case DECLARE: {
0504:                        consumeSymbol();
0505:                        FunctionStatement function = _statement
0506:                                .getFunctionStatement();
0507:                        type = function.lookupDeclaration(symbol);
0508:                        if (type == null) {
0509:                            type = function.declare(symbol);
0510:                        }
0511:                    }
0512:                        break;
0513:
0514:                    case ASSIGN: {
0515:                        consumeSymbol();
0516:                        type = _statement.lookupAnyDeclaration(symbol);
0517:                        if (type == null) {
0518:                            consumeSymbol();
0519:                            FunctionStatement function = _statement
0520:                                    .getFunctionStatement();
0521:                            if (function != null) {
0522:                                type = function.declare(symbol);
0523:                            } else {
0524:                                listener.error(_location, "Entity '" + _name
0525:                                        + "' is undeclared");
0526:                                return null;
0527:                            }
0528:                        }
0529:                    }
0530:                        break;
0531:
0532:                    default: {
0533:                        type = _statement.lookupAnyDeclaration(symbol);
0534:                        if (type == null) {
0535:                            type = LangModule.__module__
0536:                                    .lookupDeclaration(symbol);
0537:                            if (type == null) {
0538:                                consumeSymbol();
0539:                                type = lookupLibrary(listener);
0540:                                if (type == null) {
0541:                                    listener.error(_location, "Entity '"
0542:                                            + _name + "' is undeclared");
0543:                                    return null;
0544:                                }
0545:                                symbol = type.getName();
0546:
0547:                            } else {
0548:                                type = LangModule.__module__;
0549:                                symbol = type.getName();
0550:
0551:                            }
0552:                        } else {
0553:                            consumeSymbol();
0554:                        }
0555:                    }
0556:                        break;
0557:                    }
0558:
0559:                }
0560:
0561:                type = followImports(listener, type);
0562:                if (type == null) {
0563:                    return null;
0564:                }
0565:
0566:                if (type instanceof  ReflectedJava) {
0567:                    if (type instanceof  Reflection) {
0568:                        return new JavaClassNode(type.getName());
0569:                    } else {
0570:                        return new JavaClassNode(type.getParent().getName());
0571:                    }
0572:                }
0573:
0574:                switch (type.getType()) {
0575:                case Type.MODULE:
0576:                case Type.NAMESPACE: {
0577:                    if (!hasMoreSymbols()) {
0578:                        return new TypeNode(type);
0579:                    }
0580:                    return construct(listener, (Scope) type);
0581:                }
0582:
0583:                case Type.INTERFACE:
0584:                case Type.CLASS: {
0585:                    return classConstruct(listener, (Scope) type);
0586:                }
0587:
0588:                case Type.GLOBAL_NAMESPACE: {
0589:                    return GlobalNamespaceNode.INSTANCE;
0590:                }
0591:
0592:                case Type.SYSTEM_NAMESPACE: {
0593:                    return new NamespaceNode((NamespaceType) type);
0594:                }
0595:
0596:                case Type.FUNCTION: {
0597:                    return onFunction(listener, type);
0598:                }
0599:
0600:                case Type.INTERFACE_METHOD: {
0601:                    return new TypeNode(type);
0602:                }
0603:
0604:                case Type.METHOD: {
0605:                    MethodType method = (MethodType) type;
0606:                    ClassStatement context = _statement.getClassStatement();
0607:
0608:                    if (type instanceof  FunctionStatement) {
0609:                        FunctionStatement function = (FunctionStatement) type;
0610:                        if (function.getContext() != null) {
0611:                            if (hasArgs()) {
0612:                                return new InlinedCallNode(_statement
0613:                                        .getFunctionStatement(), function,
0614:                                        consumeArgs());
0615:                            } else {
0616:                                return new InlinedFunctionNode(_statement
0617:                                        .getFunctionStatement(), function);
0618:                            }
0619:                        }
0620:                    }
0621:                    if (hasMoreSymbols()) {
0622:                        return new TypeNode(type);
0623:                    } else {
0624:                        Grammar.checkInstanceAmbiguity(listener, _location,
0625:                                context, method);
0626:                        if (hasArgs()) {
0627:                            //methodname(...)
0628:                            checkArguments(listener, method);
0629:                            return new StaticInvokeNode(method.getClassType(),
0630:                                    context, method, consumeArgs());
0631:                        } else {
0632:                            //methodname
0633:                            return new DelegateNode(new ThisNode(context,
0634:                                    method.getClassType()), method);
0635:                        }
0636:                    }
0637:                }
0638:
0639:                case Type.CONSTRUCTOR: {
0640:                    if (!hasMoreSymbols()) {
0641:                        if (hasArgs()) {
0642:                            listener
0643:                                    .error(_location,
0644:                                            "Trying to call constructor '"
0645:                                                    + type + "'");
0646:                            return null;
0647:                        }
0648:                    }
0649:                    return new TypeNode(type);
0650:                }
0651:
0652:                case Type.CONSTANT_VARIABLE: {
0653:                    if (_role != GET) {
0654:                        listener.error(_location,
0655:                                "Attempting to assign to constant '" + symbol
0656:                                        + "'");
0657:                    }
0658:                    return new ConstantVariableNode((ConstantVariableType) type);
0659:                }
0660:
0661:                case Type.STATIC_VARIABLE: {
0662:                    return new StaticVariableNode((StaticVariableType) type);
0663:                }
0664:
0665:                case Type.MEMBER_VARIABLE: {
0666:                    ClassStatement context = _statement.getClassStatement();
0667:                    MemberVariableType member = (MemberVariableType) type;
0668:                    Grammar.checkInstanceAmbiguity(listener, _location,
0669:                            context, member);
0670:                    return new MemberVariableNode(context, member);
0671:                }
0672:
0673:                case Type.FUNCTION_PARAMETER:
0674:                case Type.LOCAL_VARIABLE: {
0675:                    FunctionStatement context = _statement
0676:                            .getFunctionStatement();
0677:                    if (type.getParent() != context) {
0678:                        return new EscapedVariableNode(symbol,
0679:                                (LocalVariableStatement) type, context);
0680:                    } else {
0681:                        return new VariableNode((LocalVariableStatement) type);
0682:                    }
0683:                }
0684:                }
0685:
0686:                return null;
0687:            }
0688:
0689:            protected Node super Construct(ErrorListener context) {
0690:                consumeSymbol();
0691:                ClassType classtype = _statement.getClassStatement();
0692:                boolean in_method = (_statement.getFunctionStatement() != null);
0693:
0694:                if (classtype == null) {
0695:                    context.error(_location,
0696:                            "Cannot use 'super' outside the scope of class");
0697:                    return null;
0698:                }
0699:
0700:                if (classtype.getBase() == null) {
0701:                    context.error(_location,
0702:                            "Cannot use 'super' in classes without base class");
0703:                    return null;
0704:                }
0705:
0706:                if ((symbolsLeft() == 0) && hasArgs() && in_method) {
0707:                    if (_role != SUPER) {
0708:                        context
0709:                                .error(
0710:                                        _location,
0711:                                        "Superclass constructor invoke must appear as first statement in the body of constructor");
0712:                        return null;
0713:                    }
0714:
0715:                    ClassType base = classtype.getBaseClass();
0716:                    CompilableFunction constructor = base.getConstructor();
0717:                    if (constructor == null) {
0718:                        context.error(_location, "Base class '" + base
0719:                                + "' does not have constructor");
0720:                        return null;
0721:                    }
0722:                    checkArguments(context, constructor);
0723:                    return new ConstructorInvokeNode(classtype, consumeArgs());
0724:                }
0725:
0726:                if (symbolsLeft() < 1) {
0727:                    context.error(_location, "Invalid use of 'super'.");
0728:                    return null;
0729:                }
0730:
0731:                String symbol = consumeSymbol();
0732:                Type type = classtype.lookupInheritedDeclaration(symbol);
0733:                if (type == null) {
0734:                    context
0735:                            .error(_location, "Undefined entity '" + _name
0736:                                    + "'");
0737:                    return null;
0738:                }
0739:
0740:                switch (type.getType()) {
0741:                case Type.INTERFACE_METHOD: {
0742:                    context.error(_location,
0743:                            "Illegal access to interface method with 'super'");
0744:                    return null;
0745:                }
0746:
0747:                case Type.METHOD:
0748:                    if (!hasArgs()) {
0749:                        return new TypeNode(type);
0750:                    }
0751:                    if (_statement.isStaticRegion()) {
0752:                        context.error(_location, "Attempting to invoke '"
0753:                                + type + "' from static region");
0754:                    }
0755:                    MethodType ctor = (MethodType) type;
0756:                    checkArguments(context, ctor);
0757:                    return new SuperInvokeNode(ctor, consumeArgs());
0758:
0759:                case Type.FUNCTION:
0760:                    if (!hasArgs()) {
0761:                        return new TypeNode(type);
0762:                    }
0763:                    CompilableFunction function = (CompilableFunction) type;
0764:                    checkArguments(context, function);
0765:                    return new CallNode(function, consumeArgs());
0766:
0767:                case Type.CONSTANT_VARIABLE:
0768:                    return new ConstantVariableNode((ConstantVariableType) type);
0769:
0770:                case Type.STATIC_VARIABLE:
0771:                    return new StaticVariableNode((StaticVariableType) type);
0772:
0773:                case Type.MEMBER_VARIABLE:
0774:                    if (_statement.isStaticRegion()) {
0775:                        context.error(_location,
0776:                                "Attempting to refer to member variable '"
0777:                                        + type + "' from static region");
0778:                    }
0779:                    if (!in_method) {
0780:                        break;
0781:                    }
0782:                    return new MemberVariableNode(null,
0783:                            (MemberVariableType) type);
0784:
0785:                case Type.IMPORT:
0786:                    context
0787:                            .error(_location,
0788:                                    "Imported entities may not be referred with 'super'");
0789:                    return null;
0790:
0791:                default:
0792:                    break;
0793:                }
0794:                context.error(_location, "Invalid use of 'super'");
0795:                return null;
0796:            }
0797:
0798:            protected Node newConstruct(ErrorListener listener, ClassType target) {
0799:
0800:                if (!hasMoreSymbols()) {
0801:                    listener.error(_location,
0802:                            "Syntax error: class name expected after 'new'");
0803:                    return null;
0804:                }
0805:
0806:                Type type;
0807:                String symbol;
0808:
0809:                if (peekKind() == ParserBaseConstants.MODULE) {
0810:                    consumeSymbol();
0811:                    type = _script;
0812:                } else {
0813:                    symbol = consumeSymbol();
0814:                    type = _statement.lookupAnyDeclaration(symbol);
0815:                    if (type == null) {
0816:                        type = LangModule.__module__.lookupDeclaration(symbol);
0817:                        if (type == null) {
0818:                            type = lookupLibrary(listener);
0819:                        }
0820:                    }
0821:                }
0822:
0823:                while (true) {
0824:
0825:                    if (type == null) {
0826:                        listener.error(_location, "Entity '"
0827:                                + _name.toString(1) + "' is undeclared");
0828:                        return null;
0829:                    }
0830:
0831:                    type = followImports(listener, type);
0832:                    if (type == null) {
0833:                        return null;
0834:                    }
0835:
0836:                    if (type instanceof  ReflectedJava) {
0837:                        if (type instanceof  Reflection) {
0838:                            return new JavaClassNode(type.getName());
0839:                        } else {
0840:                            return new JavaClassNode(type.getParent().getName());
0841:                        }
0842:                    }
0843:
0844:                    switch (type.getType()) {
0845:                    case Type.MODULE:
0846:                    case Type.NAMESPACE: {
0847:                        if (hasMoreSymbols()) {
0848:                            symbol = consumeSymbol();
0849:                            type = ((Scope) type).lookupDeclaration(symbol);
0850:                            break;
0851:                        }
0852:                        listener.error(_location, "Entity '"
0853:                                + _name.toString(1) + "' is not a class");
0854:                        return null;
0855:                    }
0856:
0857:                    case Type.CLASS: {
0858:                        ClassType clazz = (ClassType) type;
0859:                        if (hasMoreSymbols()) {
0860:                            symbol = consumeSymbol();
0861:                            type = clazz.lookupDeclaration(symbol);
0862:                            break;
0863:                        }
0864:                        if (!hasArgs()) {
0865:                            listener.error(_location,
0866:                                    "Syntax error: argument list expected after '"
0867:                                            + _name.toString(1) + "'");
0868:                            return null;
0869:                        }
0870:                        CompilableFunction constructor = clazz.getConstructor();
0871:                        if (constructor == null) {
0872:                            listener.error(_location, "Class '" + clazz
0873:                                    + "' does not have constructor");
0874:                            return null;
0875:                        }
0876:                        ClassType context = _statement.getClassStatement();
0877:                        checkArguments(listener, constructor);
0878:                        Grammar.checkInstanceAccess(listener, _location,
0879:                                _statement, clazz);
0880:                        //Grammar.checkInstanceAmbiguity(listener, _location, context, clazz);
0881:                        return new NewNode(context, clazz, constructor,
0882:                                consumeArgs());
0883:                    }
0884:
0885:                    default:
0886:                        listener.error(_location, "Entity '"
0887:                                + _name.toString(1) + "' is not a class");
0888:                        return null;
0889:                    }
0890:                }
0891:            }
0892:
0893:            protected Node doLink(ErrorListener listener) {
0894:                ClassType classtype;
0895:                switch (peekKind()) {
0896:                case ParserBaseConstants.SYMBOL: {
0897:                    String symbol = peekSymbol();
0898:                    if (symbol.equals("__FILE__")) {
0899:                        consumeSymbol();
0900:                        if (_role != GET) {
0901:                            listener
0902:                                    .error(_location,
0903:                                            "Pseudo variable '__FILE__' can only be referred");
0904:                        }
0905:                        return new ConstantNode(Any.create(_location.getURL()
0906:                                .toString()));
0907:                    } else if (symbol.equals("__LINE__")) {
0908:                        consumeSymbol();
0909:                        if (_role != GET) {
0910:                            listener
0911:                                    .error(_location,
0912:                                            "Pseudo variable '__LINE__' can only be referred");
0913:                        }
0914:                        return new ConstantNode(Any.create(_location.getLine()));
0915:                    }
0916:                }
0917:                case ParserBaseConstants.STATIC:
0918:                    // symbol
0919:                    return construct(listener, null);
0920:
0921:                case ParserBaseConstants.MODULE:
0922:                    // module
0923:                    consumeSymbol();
0924:                    if (!hasMoreSymbols()) {
0925:                        return new TypeNode(_script);
0926:                    }
0927:                    return construct(listener, _script);
0928:
0929:                case ParserBaseConstants.CLASS:
0930:                    // class
0931:                    consumeSymbol();
0932:                    classtype = _statement.getClassStatement();
0933:                    if (classtype != null) {
0934:                        return classConstruct(listener, classtype);
0935:                    } else {
0936:                        listener.error(_location,
0937:                                "Cannot use 'class' outside classes");
0938:                        return null;
0939:                    }
0940:
0941:                case ParserBaseConstants.FUNCTION: {
0942:                    // function
0943:                    consumeSymbol();
0944:                    FunctionStatement function = _statement
0945:                            .getFunctionStatement();
0946:                    if (function != null) {
0947:                        return onFunction(listener, function);
0948:                    } else {
0949:                        listener.error(_location,
0950:                                "Cannot use 'function' outside functions");
0951:                        return null;
0952:                    }
0953:                }
0954:
0955:                case ParserBaseConstants.THIS:
0956:                case ParserBaseConstants.DOT:
0957:                    // this
0958:                    // <dot> <symbol> ...
0959:                    consumeSymbol();
0960:                    classtype = _statement.getClassStatement();
0961:                    if (classtype != null) {
0962:                        if (_statement.isStaticRegion()) {
0963:                            listener.error(_location,
0964:                                    "Cannot use 'this' in static region");
0965:                        }
0966:                        if (hasMoreSymbols()) {
0967:                            return explicitThisConstruct(listener, classtype);
0968:                            //return construct(listener, classtype);
0969:                        } else {
0970:                            return ThisNode.INSTANCE;
0971:                        }
0972:                    } else {
0973:                        listener.error(_location,
0974:                                "Cannot use 'this' outside classes");
0975:                        return null;
0976:                    }
0977:
0978:                case ParserBaseConstants.SUPER:
0979:                    // super.method(...)
0980:                    return super Construct(listener);
0981:
0982:                case ParserBaseConstants.NEW:
0983:                    // new ...
0984:                    consumeSymbol(); // new
0985:                    return newConstruct(listener, null);
0986:
0987:                }
0988:                return null;
0989:            }
0990:
0991:            public Node link(ErrorListener listener) {
0992:                Node node = doLink(listener);
0993:                if (node == null) {
0994:                    node = ConstantNode.UNDEFINED;
0995:                }
0996:                if (node instanceof  TypeNode) {
0997:                    Type type = ((TypeNode) node).getType();
0998:                    if (type instanceof  Synthetic) {
0999:                        listener.error(_location,
1000:                                "Cannot refer to synthetic entities");
1001:                        node = ConstantNode.UNDEFINED;
1002:                    }
1003:                }
1004:                if (hasMoreSymbols()) {
1005:                    while (hasMoreSymbols()) {
1006:                        if (symbolsLeft() == 1 && hasArgs()) {
1007:                            // *.symbol(...)
1008:                            Parent args = consumeArgs();
1009:                            if (args.hasNamedParameters()) {
1010:                                listener
1011:                                        .error(_location,
1012:                                                "Named parameters are ignored in anonymous invokes");
1013:                            }
1014:                            node = new InvokeNode(node, consumeSymbol(), args);
1015:                        } else {
1016:                            // *.symbol
1017:                            node = new AttributeNode(node, consumeSymbol());
1018:                        }
1019:                    }
1020:                } else {
1021:                    // *.(...)
1022:                    if (hasArgs()) {
1023:                        Parent args = consumeArgs();
1024:                        if (args.hasNamedParameters()) {
1025:                            listener
1026:                                    .error(_location,
1027:                                            "Named parameters are ignored in anonymous calls");
1028:                        }
1029:                        node = new DynamicCallNode(node, args);
1030:                    }
1031:                }
1032:                return node;
1033:            }
1034:
1035:            public String getReference() {
1036:                return toString();
1037:            }
1038:
1039:            public Location getLocation() {
1040:                return _location;
1041:            }
1042:
1043:            public Type resolveReference(ErrorListener listener) {
1044:                Type type;
1045:                if (peekKind() == ParserBaseConstants.MODULE) {
1046:                    consumeSymbol();
1047:                    type = _script;
1048:                } else {
1049:                    String symbol = peekSymbol();
1050:                    type = _statement.lookupAnyDeclaration(symbol);
1051:                    if (type == null) {
1052:                        type = LangModule.__module__.lookupDeclaration(symbol);
1053:                        if (type == null) {
1054:                            consumeSymbol();
1055:                            type = lookupLibrary(listener);
1056:                        } else {
1057:                            type = LangModule.__module__;
1058:                            symbol = type.getName();
1059:                        }
1060:                    } else {
1061:                        consumeSymbol();
1062:                    }
1063:                }
1064:
1065:                while (true) {
1066:
1067:                    if (type == null) {
1068:                        listener.error(_location, "Entity '" + _name
1069:                                + "' is undeclared");
1070:                        return null;
1071:                    }
1072:
1073:                    type = followImports(listener, type);
1074:                    if (type == null) {
1075:                        return null;
1076:                    }
1077:
1078:                    switch (type.getType()) {
1079:                    case Type.MODULE:
1080:                    case Type.CLASS:
1081:                    case Type.INTERFACE:
1082:                    case Type.NAMESPACE: {
1083:                        if (hasMoreSymbols()) {
1084:                            type = ((Scope) type)
1085:                                    .lookupDeclaration(consumeSymbol());
1086:                            break;
1087:                        } else {
1088:                            return type;
1089:                        }
1090:                    }
1091:
1092:                    default: {
1093:                        if (hasMoreSymbols()) {
1094:                            listener.error(_location, "Entity '" + _name
1095:                                    + "' is undeclared");
1096:                        }
1097:                        return type;
1098:                    }
1099:                    }
1100:                }
1101:            }
1102:
1103:            public Any eval() {
1104:                return Any.UNDEFINED;
1105:            }
1106:
1107:            public void compile(ByteCompiler context, int operation) {
1108:                context.getCode().aconst_null();
1109:            }
1110:
1111:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.