Example usage for org.antlr.v4.runtime Token getLine

List of usage examples for org.antlr.v4.runtime Token getLine

Introduction

In this page you can find the example usage for org.antlr.v4.runtime Token getLine.

Prototype

int getLine();

Source Link

Document

The line number on which the 1st character of this token was matched, line=1..n

Usage

From source file:info.fulloo.trygve.parser.Pass2Listener.java

License:Open Source License

private <ExprType> Expression messageSendGetObject(final Token ctxGetStart, final ExprType ctx_abelianAtom,
        final Builtin_type_nameContext ctx_builtin_typeName) {
    // Pop the expression for the indicated object and message
    final Type nearestEnclosingMegaType = Expression.nearestEnclosingMegaTypeOf(currentScope_);
    final StaticScope nearestMethodScope = Expression.nearestEnclosingMethodScopeAround(currentScope_);

    Expression object = null;/*from   www .j ava 2 s. c  om*/
    if (ctx_abelianAtom != null) {
        // Error stumbling check
        if (parsingData_.currentExpressionExists()) {
            if (null == parsingData_.peekExpression()) {
                // Get rid of the null junk (error stumbling logic)
                @SuppressWarnings("unused")
                final Object unused = parsingData_.popRawExpression();

                // Come in with a suitable substitute
                object = new ErrorExpression(null);
            } else {
                object = parsingData_.popExpression();
            }
        } else {
            return new ErrorExpression(null); // get out
        }
    } else if (ctx_builtin_typeName != null) {
        // e.g. String.join
        final String typeName = ctx_builtin_typeName.getText();
        final Type theType = currentScope_.lookupTypeDeclarationRecursive(typeName);
        final Type classType = StaticScope.globalScope().lookupTypeDeclaration("Class");
        object = new IdentifierExpression(theType.name(), classType, classType.enclosedScope().parentScope(),
                ctxGetStart.getLine());
    } else if (null != nearestEnclosingMegaType) {
        object = new IdentifierExpression("this", nearestEnclosingMegaType, nearestMethodScope,
                ctxGetStart.getLine());
    } else {
        object = new ErrorExpression(null);
    }
    object.setResultIsConsumed(true);

    return object;
}

From source file:info.fulloo.trygve.parser.Pass2Listener.java

License:Open Source License

private Expression messageSendGenerateCall(final Token ctxGetStart, final Expression object,
        final MethodDeclaration methodDeclaration, final Message message, final Type returnType,
        final MethodSignature methodSignature) {
    Expression retval = null;//  w w w  . j a v a2  s.  c  o m
    if (null != methodSignature) {
        MethodInvocationEnvironmentClass originMethodClass = MethodInvocationEnvironmentClass.Unknown;

        if (null != currentScope_.associatedDeclaration()) {
            originMethodClass = currentScope_.methodInvocationEnvironmentClass();
        } else {
            final Type anotherType = object.enclosingMegaType();
            if (null != anotherType) {
                final StaticScope anotherScope = anotherType.enclosedScope();
                originMethodClass = anotherScope.methodInvocationEnvironmentClass();
            } else {
                originMethodClass = MethodInvocationEnvironmentClass.ClassEnvironment; // outermost scope
            }
        }

        MethodInvocationEnvironmentClass targetMethodClass = MethodInvocationEnvironmentClass.Unknown;
        if (null != object && null != object.type()) {
            if (object.type() instanceof StagePropType) {
                targetMethodClass = MethodInvocationEnvironmentClass.RoleEnvironment;
            } else if (object.type() instanceof RoleType) {
                targetMethodClass = MethodInvocationEnvironmentClass.RoleEnvironment;
            } else if (object.type() instanceof ContextType) {
                targetMethodClass = MethodInvocationEnvironmentClass.ContextEnvironment;
            } else if (object.type() instanceof InterfaceType) {
                // Interfaces wrap classes
                targetMethodClass = MethodInvocationEnvironmentClass.ClassEnvironment;
            } else if (object.type() instanceof ArrayType) {
                // Arrays kind of behave like classes, certainly as regards dispatching
                targetMethodClass = MethodInvocationEnvironmentClass.ClassEnvironment;
            } else if (null != methodDeclaration) {
                targetMethodClass = methodDeclaration.enclosingScope().methodInvocationEnvironmentClass();
            } else {
                targetMethodClass = MethodInvocationEnvironmentClass.Unknown;
            }

            // Double-check to make sure that, if this is going through a Role
            // interface, whether it is actually a "requires" declaration
            if (MethodInvocationEnvironmentClass.RoleEnvironment == targetMethodClass) {
                final RoleType roleType = (RoleType) object.type();
                final RoleDeclaration roleDecl = (RoleDeclaration) roleType.associatedDeclaration();
                final MethodSignature requiredSignatureDecl = roleDecl
                        .lookupRequiredMethodSignatureDeclaration(message.selectorName());
                if (null != requiredSignatureDecl) {
                    // It could be a context, but we can't tell here. We must wait until
                    // run-time and adjust
                    targetMethodClass = MethodInvocationEnvironmentClass.ClassEnvironment;
                }
            }
        } else if (null != methodDeclaration) {
            targetMethodClass = methodDeclaration.enclosingScope().methodInvocationEnvironmentClass();
        } else {
            targetMethodClass = MethodInvocationEnvironmentClass.Unknown;
        }

        checkForMessageSendViolatingConstness(methodSignature, ctxGetStart);

        boolean isPolymorphic = true;
        if (amInConstructor()) {
            if (object instanceof IdentifierExpression) {
                if (((IdentifierExpression) object).name().equals("this")) {
                    isPolymorphic = false;
                }
            }
        }
        retval = new MessageExpression(object, message, returnType, ctxGetStart.getLine(),
                methodSignature.isStatic(), originMethodClass, targetMethodClass, isPolymorphic);
        if (null == methodDeclaration) {
            // Could be a "required" method in a Role. It's O.K.
            assert true;
        } else {
            final boolean accessOK = currentScope_.canAccessDeclarationWithAccessibility(methodDeclaration,
                    methodDeclaration.accessQualifier(), ctxGetStart.getLine());
            if (accessOK == false) {
                errorHook6p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "Cannot access method `",
                        methodDeclaration.name(), "' with `", methodDeclaration.accessQualifier().asString(),
                        "' access qualifier.", "");
            }
        }
    } else {
        // Stumble elegantly
        retval = new ErrorExpression(object);
    }

    return retval;
}

From source file:info.fulloo.trygve.parser.Pass2Listener.java

License:Open Source License

@Override
public <ExprType> Expression messageSend(final Token ctxGetStart, final ExprType ctx_abelianAtom,
        final Builtin_type_nameContext ctx_builtin_typeName) {
    // | expr '.' message
    // | message//w ww. j  a  v  a 2 s.  co m
    // Certified Pass 2 version.
    // REFACTOR! TODO

    MethodDeclaration methodDeclaration = null;
    Expression retval = null;
    final StaticScope nearestMethodScope = Expression.nearestEnclosingMethodScopeAround(currentScope_);
    final Type nearestEnclosingMegaType = Expression.nearestEnclosingMegaTypeOf(currentScope_);
    Expression object = messageSendGetObject(ctxGetStart, ctx_abelianAtom, ctx_builtin_typeName);

    Message message = parsingData_.popMessage();

    if (null == message) {
        return new ErrorExpression(object); // yuk. refactor.
    }

    if (null == nearestEnclosingMegaType && object instanceof NullExpression) {
        errorHook5p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "Invoking method `",
                message.selectorName(), "' on implied object `this' in a non-object context.", "");
        ;
    } else if (null != object) {
        // For future reference, we don't want to do this if the
        // method is static. Of course, we can't in general know
        // that until we look it up, and we can't look it up
        // until we have its signature, and we can't have its
        // signature until we know whether it takes a "this"
        // parameter... Maybe the answer is to pass a parameter
        // even for static functions (the class object)
        message.addActualThisParameter(object);
    }

    Type objectType = null == object ? null : object.type();
    if (null == objectType) {
        objectType = parsingData_.globalScope().lookupTypeDeclaration("Object");
    }
    assert null != objectType;

    MethodSignature methodSignature = null;
    boolean isOKMethodSignature = false;

    if (objectType.name().equals("Class")) {
        // Static method invocation. The "object" is really a class name.

        assert object instanceof IdentifierExpression;
        final Type type = currentScope_.lookupTypeDeclarationRecursive(object.name());
        methodDeclaration = type.enclosedScope().lookupMethodDeclaration(message.selectorName(),
                message.argumentList(), false);
        if (null == methodDeclaration) {
            methodDeclaration = type.enclosedScope().lookupMethodDeclarationWithConversionIgnoringParameter(
                    message.selectorName(), message.argumentList(), false, /*parameterToIgnore*/ null);
        }
        if (null == methodDeclaration) {
            errorHook5p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "Cannot find declaration of ",
                    object.name() + ".", message.selectorName(), ".");
        } else {
            methodSignature = methodDeclaration.signature();
            isOKMethodSignature = null != methodSignature;
        }
    } else if (objectType instanceof RoleType || objectType instanceof StagePropType) {
        Type wannabeContextType = nearestEnclosingMegaType;
        if (wannabeContextType instanceof RoleType) {
            final RoleType nearestEnclosingRoleOrStageProp = (RoleType) nearestEnclosingMegaType;
            wannabeContextType = Expression
                    .nearestEnclosingMegaTypeOf(nearestEnclosingRoleOrStageProp.enclosingScope());
            assert wannabeContextType instanceof ContextType;

            if (nearestEnclosingMegaType instanceof RoleType
                    || nearestEnclosingMegaType instanceof StagePropType) {
                // Don't allow Role methods directly to invoke Context methods.
                contextInvocationCheck(nearestEnclosingMegaType, message, objectType, wannabeContextType,
                        ctxGetStart);

                // Don't allow Role methods directly to invoke other Roles' "requires" methods.
                otherRolesRequiresInvocationCheck(nearestEnclosingMegaType, message, objectType,
                        wannabeContextType, ctxGetStart);

                if (((RoleType) objectType).isArray()) {
                    if (object instanceof RoleArrayIndexExpression) {
                        // o.k.
                    } else if (object.name().equals("this")) {
                        // then it's not really a Role method, but a requires method
                        // (hope and pray)
                    } else {
                        // Then this is trying to invoke a Role vector method
                        // without specifying the individual vector method

                        // This makes sense only if we are calling a method in the same Role
                        // as holds this method
                        final String objectTypePathName = object.type().pathName();
                        if (nearestEnclosingMegaType.pathName().equals(objectTypePathName) == false) {
                            errorHook6p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(),
                                    "Trying to access method `", message.selectorName(), "' of another Role (`",
                                    object.name(), "') with indexing the Role vector to yield a Role-player.",
                                    "");
                        } else {
                            final IndexExpression theIndex = new IndexExpression(
                                    nearestEnclosingRoleOrStageProp.associatedDeclaration(), currentContext_);
                            object = new RoleArrayIndexExpression(object.name(), object, theIndex);

                            // Woops  message is wrong. Replace its "this"
                            message.replaceActualThisParameter(object);
                        }
                    }
                }
            }
        } else if (wannabeContextType instanceof ContextType) {
            // We don't want Context methods to be able directly
            // to call requires methods of Roles
            final RoleType objectTypeAsRoleType = (RoleType) objectType;

            if (((RoleType) objectType).isArray()) {
                if (object instanceof RoleArrayIndexExpression) {
                    // o.k.
                } else {
                    // Then this is trying to invoke a Role vector method
                    // without specifying the individual vector method
                    errorHook5p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(),
                            "Trying to access a Role method `", message.selectorName(), "' on the vector ID `",
                            object.name() + "'.");
                }
            }

            final RoleDeclaration roleDecl = (RoleDeclaration) objectTypeAsRoleType.associatedDeclaration();
            final MethodSignature signatureInRequiresSection = declarationForMessageFromRequiresSectionOfRole(
                    message, roleDecl);
            if (null != signatureInRequiresSection) {
                // Is O.K. if it is also declared in the Role interface
                final MethodSignature signatureInRoleInterface = roleDecl
                        .lookupPublishedSignatureDeclaration(signatureInRequiresSection);
                if (null == signatureInRoleInterface) {
                    final StaticScope currentMethodScope = Expression
                            .nearestEnclosingMethodScopeAround(currentScope_);
                    errorHook6p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "Context script `",
                            currentMethodScope.associatedDeclaration().name(),
                            "' may enact only Role scripts. Script `",
                            message.selectorName() + message.argumentList().selflessGetText(),
                            "' is an instance script from a class and is inaccessible to Context `",
                            wannabeContextType.name() + "'.");
                }
            }
        }

        // Look this thing up in the "required" interface to see
        // if it's really a Role method or just a latently bound
        // instance method in an object bound to this role
        assert objectType instanceof RoleType;
        final RoleType roleType = (RoleType) objectType;
        methodSignature = roleType.lookupMethodSignatureDeclaration(message.selectorName());
        if (null != methodSignature) {
            // Then it may be in the "required" declarations and is NOT a role method per se
            isOKMethodSignature = true;

            // But this check may be useful...
            final MethodSignature publishedSignature = roleType.associatedDeclaration()
                    .lookupPublishedSignatureDeclaration(methodSignature);
            if (null != publishedSignature && publishedSignature.isUnusedInThisContext()) {
                final FormalParameterList formalParameterList = publishedSignature.formalParameterList();
                errorHook6p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "Script `",
                        message.selectorName() + formalParameterList.selflessGetText(),
                        "' is declared as unused in `", objectType.name(), "' at line ",
                        Integer.toString(publishedSignature.lineNumber()) + ".");
            }
        } else {
            // If we're calling from a Context script to a script of one of its Roles,
            // we want to pass "this" in the "current$context" slot. Otherwise, if it's
            // from another Role, just use "current$context". There should be no other
            // possibilities
            final Type enclosingType = Expression.nearestEnclosingMegaTypeOf(currentScope_);

            String nameOfContextIdentifier;
            if (enclosingType instanceof ContextType) {
                nameOfContextIdentifier = "this";
            } else if (enclosingType instanceof RoleType) {
                nameOfContextIdentifier = "current$context";
            } else {
                nameOfContextIdentifier = "current$context"; // arbitrary.
                assert false;
            }

            final Expression currentContext = new IdentifierExpression(nameOfContextIdentifier,
                    wannabeContextType, nearestMethodScope, ctxGetStart.getLine());
            final ActualArgumentList saveArgumentList = message.argumentList().copy();
            message.argumentList().addFirstActualParameter(currentContext);
            currentContext.setResultIsConsumed(true);

            // NOTE: Leaves methodSignature null.
            // We need it for call of checkForMessageSendViolatingConstness below.
            methodDeclaration = objectType.enclosedScope().lookupMethodDeclaration(message.selectorName(),
                    message.argumentList(), false);
            if (null != methodDeclaration) {
                // Null check is related to error stumbling
                methodSignature = methodDeclaration.signature();
            } else {
                // It's a Role. Could be a call to assert or something like that
                // in the base class
                final ClassDeclaration objectDecl = currentScope_.lookupClassDeclarationRecursive("Object");
                assert null != objectDecl;
                methodDeclaration = processReturnTypeLookupMethodDeclarationIgnoringRoleStuffIn(objectDecl,
                        message.selectorName(), message.argumentList());

                if (null != methodDeclaration) {
                    // I THINK that the right thing to do at this point is to pull
                    // the context out of the signature. Luckily, we copied the
                    // parameter list above...

                    message = new Message(message.selectorName(), saveArgumentList, message.lineNumber(),
                            message.enclosingMegaType());
                    methodSignature = methodDeclaration.signature();
                }
            }
        }
    } else if (objectType instanceof ClassType || objectType instanceof ContextType) {
        final ClassOrContextType classObjectType = (ClassOrContextType) objectType;
        final StaticScope classScope = null == nearestEnclosingMegaType ? null
                : nearestEnclosingMegaType.enclosedScope();
        final TemplateInstantiationInfo templateInstantiationInfo = null == classScope ? null
                : classScope.templateInstantiationInfo();

        final ActualOrFormalParameterList argumentList = null != message && null != message.argumentList()
                ? message.argumentList().mapTemplateParameters(templateInstantiationInfo)
                : null;
        methodDeclaration = null != classObjectType && null != classObjectType.enclosedScope()
                ? classObjectType.enclosedScope().lookupMethodDeclarationRecursive(message.selectorName(),
                        argumentList, false)
                : null;
        if (null == methodDeclaration) {
            // Check the base class
            if (null != classObjectType && null != classObjectType.enclosedScope()) {
                ClassType baseClassType = classObjectType.baseClass();
                while (null != baseClassType) {
                    final StaticScope baseClassScope = baseClassType.enclosedScope();
                    assert null != baseClassScope;
                    methodDeclaration = baseClassScope.lookupMethodDeclarationWithConversionIgnoringParameter(
                            message.selectorName(), argumentList, false, /*parameterToIgnore*/ null);
                    if (null != methodDeclaration) {
                        break;
                    }
                    baseClassType = baseClassType.baseClass();
                }
            }
            if (null == methodDeclaration) {
                // If we're inside of a template, many argument types won't match.
                // Try anyhow and see if we can find something.

                methodDeclaration = null != classObjectType && null != classObjectType.enclosedScope()
                        ? classObjectType.enclosedScope().lookupMethodDeclarationRecursive(
                                message.selectorName(), argumentList, true)
                        : null;
                if (null == methodDeclaration) {
                    // Mainly for error recovery (bad argument to method / method not declared)
                    errorHook5p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "Script `", message.getText(),
                            "' not declared in class `", classObjectType.name() + "'.");
                    return new ErrorExpression(null); // punt
                } else {
                    methodSignature = methodDeclaration.signature();
                }
            } else {
                methodSignature = methodDeclaration.signature();
            }
        } else {
            methodSignature = methodDeclaration.signature();
        }
    } else if (objectType instanceof BuiltInType) {
        final BuiltInType classObjectType = (BuiltInType) objectType;
        final StaticScope classScope = null == nearestEnclosingMegaType ? null
                : nearestEnclosingMegaType.enclosedScope();
        final TemplateInstantiationInfo templateInstantiationInfo = null == classScope ? null
                : classScope.templateInstantiationInfo();
        final ActualOrFormalParameterList argumentList = null != message && null != message.argumentList()
                ? message.argumentList().mapTemplateParameters(templateInstantiationInfo)
                : null;
        methodDeclaration = null != classObjectType && null != classObjectType.enclosedScope()
                ? classObjectType.enclosedScope().lookupMethodDeclarationRecursive(message.selectorName(),
                        argumentList, false)
                : null;
        if (null == methodDeclaration) {
            // If we're inside of a template, many argument types won't match.
            // Try anyhow and see if we can find something.
            methodDeclaration = null != classObjectType && null != classObjectType.enclosedScope()
                    ? classObjectType.enclosedScope().lookupMethodDeclarationRecursive(message.selectorName(),
                            argumentList, true)
                    : null;
            if (null == methodDeclaration) {
                // Mainly for error recovery (bad argument to method / method not declared)
                errorHook5p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "Script `", message.getText(),
                        "' not declared in class `", classObjectType.name() + "'.");
                return new ErrorExpression(null); // punt
            } else {
                methodSignature = methodDeclaration.signature();
            }
        } else {
            methodSignature = methodDeclaration.signature();
        }
    } else if (objectType instanceof InterfaceType) {
        final InterfaceType classObjectType = (InterfaceType) objectType;
        final ActualOrFormalParameterList argumentList = message.argumentList();
        final String methodSelectorName = message.selectorName();
        methodSignature = null != classObjectType
                ? classObjectType.lookupMethodSignature(methodSelectorName, argumentList)
                : null;
        if (null == methodSignature) {
            // Try again, ignoring type of this (e.g., for Interface types)
            methodSignature = null != classObjectType
                    ? classObjectType.lookupMethodSignatureWithConversionIgnoringParameter(
                            methodSelectorName, argumentList, "this")
                    : null;
            if (null == methodSignature) {
                // Mainly for error recovery (bad argument to method / method not declared)
                if (argumentList.isntError()) {
                    errorHook5p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "Script `",
                            methodSelectorName + argumentList.getText(), "' not declared in Interface `",
                            classObjectType.name() + "'.");
                }
            } else {
                isOKMethodSignature = true;
            }
        } else {
            isOKMethodSignature = true;
        }
    } else if (objectType.name().endsWith("_$array") && objectType instanceof ArrayType) {
        // This is part of the endeavor to add method invocations to
        // naked array object appearances (e.g., size())
        if (message.selectorName().equals("size")) {
            methodSignature = new MethodSignature(message.selectorName(),
                    StaticScope.globalScope().lookupTypeDeclaration("int"), AccessQualifier.PublicAccess,
                    (int) message.lineNumber(), false);
            methodSignature.setHasConstModifier(true);
        } else if (message.selectorName().equals("at")) {
            methodSignature = new MethodSignature(message.selectorName(), message.returnType(),
                    AccessQualifier.PublicAccess, (int) message.lineNumber(), false);
            methodSignature.setHasConstModifier(true);
        } else if (message.selectorName().equals("atPut")) {
            methodSignature = new MethodSignature(message.selectorName(),
                    StaticScope.globalScope().lookupTypeDeclaration("void"), AccessQualifier.PublicAccess,
                    (int) message.lineNumber(), false);
            methodSignature.setHasConstModifier(false);
        }
        isOKMethodSignature = true;
    }

    Type returnType = this.processReturnType(ctxGetStart, object, objectType, message);

    if (null != returnType && returnType instanceof TemplateParameterType) {
        // Is a template type. Change the return type into a bona fide type here
        final StaticScope objectScope = objectType.enclosedScope();
        final TemplateInstantiationInfo newTemplateInstantiationInfo = objectScope.templateInstantiationInfo();
        returnType = newTemplateInstantiationInfo.classSubstitionForTemplateTypeNamed(returnType.name());
    }

    if (objectType.name().equals(message.selectorName())) {
        errorHook5p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "Cannot 'call' constructor of ",
                objectType.name(), ". Use 'new' instead.", "");
    }

    assert (null != message); // just assuming...
    final String methodSelectorName = message.selectorName();

    if (null != methodDeclaration) {
        final List<String> invalidMethodSelectors = message.validInRunningEnviroment(methodDeclaration);
        if (0 < invalidMethodSelectors.size()) {
            errorHook5p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "The parameters to script `",
                    methodSelectorName + message.argumentList().selflessGetText(),
                    "' have scripts that are unavailable outside this Context, ",
                    "though some formal parameters of " + methodSelectorName
                            + " presume they are available (they are likely Role scripts):");
            for (final String badMethod : invalidMethodSelectors) {
                errorHook5p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "\t", badMethod, "", "");
            }
        }
    } else if (null == methodDeclaration && isOKMethodSignature == false) {
        if (message.argumentList().isntError()) {
            errorHook5p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "Script `",
                    methodSelectorName + message.argumentList().selflessGetText(), "' not declared in class ",
                    "classname (dubious error  see other messages)");
        }
    }

    assert null != returnType;
    assert null != object;
    assert null != message;

    message.setReturnType(returnType);

    retval = messageSendGenerateCall(ctxGetStart, object, methodDeclaration, message, returnType,
            methodSignature);

    return retval;
}

From source file:info.fulloo.trygve.parser.Pass2Listener.java

License:Open Source License

private void typeCheckHelperForRoleMismatches(final FormalParameterList formals,
        final ActualArgumentList actuals, final MethodDeclaration mdecl, final TypeDeclaration classdecl,
        final String parameterToIgnore, final Token ctxGetStart) {

    // This is for checking agreement with functions like assert

    int actualParameterIndex = 0, formalParameterIndex = 0;
    final int numberOfFormalParameters = formals.count(),
            numberOfActualParameters = (null == actuals) ? 0 : actuals.count();
    if (null == actuals) {
        if (numberOfActualParameters != 0) {
            errorHook5p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(),
                    "Number of arguments in enactment of script `", mdecl.name(),
                    "' does not match declaration of `", mdecl.name() + "'.");
            int lineNumber = mdecl.lineNumber();
            if (0 == lineNumber) {
                // e.g., for a built-in type
                lineNumber = ctxGetStart.getLine();
            }//  w  w  w . j  a  v a  2s  .co  m
            errorHook5p2(ErrorIncidenceType.Fatal, lineNumber, "\tMethod ", mdecl.name(), " is declared in ",
                    classdecl.name());
        }
    } else {
        // Strip off all the stuff up front
        String actualParameterName = actuals.nameOfParameterAtPosition(actualParameterIndex);
        while (actualParameterName.equals("this") || actualParameterName.equals("t$this")
                || actualParameterName.equals("current$context")
                || actualParameterName.equals("current$role")) {
            actualParameterIndex++;
            if (actualParameterIndex < numberOfActualParameters) {
                actualParameterName = actuals.nameOfParameterAtPosition(actualParameterIndex);
            } else {
                break;
            }
        }

        String formalParameterName = formals.nameOfParameterAtPosition(formalParameterIndex);
        while (formalParameterName.equals("this") || formalParameterName.equals("t$this")
                || formalParameterName.equals("current$context")
                || formalParameterName.equals("current$role")) {
            formalParameterIndex++;
            if (formalParameterIndex < numberOfFormalParameters) {
                formalParameterName = formals.nameOfParameterAtPosition(formalParameterIndex);
            } else {
                break;
            }
        }

        Expression actualParameter = null;
        Type actualParameterType = null;
        Declaration formalParameter = null;
        Type formalParameterType = null;

        while (formalParameterIndex < numberOfFormalParameters
                && actualParameterIndex < numberOfActualParameters) {
            boolean parametersMatch = true;

            final Object rawActualParameter = actuals.argumentAtPosition(actualParameterIndex);
            if (rawActualParameter == null || (rawActualParameter instanceof Expression) == false) {
                assert rawActualParameter != null && rawActualParameter instanceof Expression;
            }
            actualParameter = (Expression) rawActualParameter;
            actualParameterType = actualParameter.type();

            formalParameterName = formals.nameOfParameterAtPosition(formalParameterIndex);
            formalParameter = formals.parameterAtPosition(formalParameterIndex);
            assert formalParameter instanceof ObjectDeclaration || formalParameter.isError();
            formalParameterType = formalParameter.type();

            if (actualParameterType.enclosedScope() == formalParameterType.enclosedScope()) {
                actualParameterIndex++;
                formalParameterIndex++;
            } else if (actualParameterType.isBaseClassOf(formalParameterType)) {
                actualParameterIndex++;
                formalParameterIndex++;
            } else if (formalParameterType.canBeConvertedFrom(actualParameterType)) {
                actualParameterIndex++;
                formalParameterIndex++;
            } else {
                final Type enclosingType = Expression.nearestEnclosingMegaTypeOf(currentScope_);
                if (enclosingType instanceof TemplateType) {
                    // It could just work. This is just the template we're processing. Check things out
                    // later in the class instead.
                    actualParameterIndex++;
                    formalParameterIndex++;
                } else {
                    parametersMatch = false;
                }
            }

            if (false == parametersMatch && actualParameter.isntError() && formalParameter.isntError()) {
                final String actualParamMsg = actualParameter.getText() + "' (" + actualParameterType.name()
                        + ")";
                final String formalParamMsg = "`" + formalParameter.name() + "' (" + formalParameterType.name()
                        + " " + formalParameter.name() + ")";
                errorHook6p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "Type of actual parameter `",
                        actualParamMsg, " in call of `", mdecl.name(),
                        "' does not match type of formal parameter ", formalParamMsg);
            }
        }

        if (formalParameterIndex != numberOfFormalParameters
                || actualParameterIndex != numberOfActualParameters) {
            if (null != mdecl) {
                errorHook5p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(),
                        "Number of arguments in enactment of script `", mdecl.name(),
                        "' does not match declaration of `", mdecl.name() + "'.");
            }

            int lineNumber = null == mdecl ? 0 : mdecl.lineNumber();
            if (0 == lineNumber) {
                // e.g., for a built-in type
                lineNumber = ctxGetStart.getLine();
            }
            if (null != classdecl && null != mdecl) {
                errorHook5p2(ErrorIncidenceType.Fatal, lineNumber, "\tScript ", mdecl.name(),
                        " is declared in ", classdecl.name());
            }
        }
    }
}

From source file:info.fulloo.trygve.parser.Pass2Listener.java

License:Open Source License

protected void typeCheckIgnoringParameterNormal(final FormalParameterList formals,
        final ActualArgumentList actuals, final MethodDeclaration mdecl, final TypeDeclaration classdecl,
        final String parameterToIgnore, final Token ctxGetStart) {
    final long numberOfActualParameters = actuals.count();
    final long numberOfFormalParameters = formals.count();

    if (numberOfFormalParameters != numberOfActualParameters) {
        if (formals.containsVarargs()) {
            if (numberOfActualParameters < numberOfFormalParameters) {
                errorHook5p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(),
                        "Number of arguments in enactment of script `", mdecl.name(),
                        "' must be at least as many as in declaration of the script (",
                        String.format("%d", numberOfFormalParameters - 1) + ").");
            } else {
                ; // O.K.
            }/*from   w w w .  j a  va 2  s  .co  m*/
        } else {
            errorHook5p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(),
                    "Number of arguments in enactment of script `", mdecl.name(),
                    "' does not match declaration of `", mdecl.name() + "'.");
            int lineNumber = mdecl.lineNumber();
            if (0 == lineNumber) {
                // e.g., for a built-in type
                lineNumber = ctxGetStart.getLine();
            }
            if (null != classdecl) {
                errorHook5p2(ErrorIncidenceType.Fatal, lineNumber, "\tMethod ", mdecl.name(),
                        " is declared in ", classdecl.name());
            }
        }
    } else {

        for (int j = 0; j < numberOfActualParameters; j++) {
            final Object rawParameter = actuals.argumentAtPosition(j);
            assert rawParameter != null && rawParameter instanceof Expression;
            final Expression actualParameter = (Expression) rawParameter;
            final Type actualParameterType = actualParameter.type();

            final Declaration formalParameter = formals.parameterAtPosition(j);
            final Type formalParameterType = formalParameter.type();

            if (formalParameterType instanceof VarargsType) {
                break;
            } else if (null == formalParameterType) {
                ; // formalParameter is likely of ErrorDeclaration type  just skip it
            } else if (formalParameterType.canBeConvertedFrom(actualParameterType)) {
                continue;
            } else if (formalParameter.name().equals(parameterToIgnore)) {
                continue;
            } else {
                final Type enclosingType = Expression.nearestEnclosingMegaTypeOf(currentScope_);
                if (enclosingType instanceof TemplateType) {
                    // It could just work. This is just the template we're processing. Check things out
                    // later in the class instead.
                } else {
                    // See if it could be an interface of the class
                    boolean isOK = false;
                    if (actualParameterType instanceof ClassOrContextType) {
                        final List<InterfaceType> interfaceTypes = ((ClassOrContextType) actualParameterType)
                                .interfaceTypes();
                        for (final Type alternativeActualParameterType : interfaceTypes) {
                            if (formalParameterType.canBeConvertedFrom(alternativeActualParameterType)) {
                                isOK = true;
                                break;
                            }
                        }
                    }
                    if (false == isOK && actualParameter.isntError() && formalParameter.isntError()) {
                        final String actualParamMsg = actualParameter.getText() + "' ("
                                + actualParameterType.name() + ")";
                        final String formalParamMsg = "`" + formalParameter.name() + "' ("
                                + formalParameterType.name() + " " + formalParameter.name() + ")";
                        errorHook6p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(),
                                "Type of actual parameter `", actualParamMsg, " in call of `", mdecl.name(),
                                "' does not match type of formal parameter ", formalParamMsg);
                    }
                }
            }
        }
    }
}

From source file:info.fulloo.trygve.parser.Pass2Listener.java

License:Open Source License

@Override
public Expression idExpr(final TerminalNode ctxJAVA_ID, final Token ctxGetStart) {
    // | JAVA_ID// w w  w.  jav  a  2 s.  com
    // Special version for pass 2 and 3

    Type type = null;
    Expression retval = null;
    RoleDeclaration aRoleDecl = null;
    StaticScope declaringScope = null;
    final StaticScope globalScope = StaticScope.globalScope();
    final String idText = ctxJAVA_ID.getText();
    ObjectDeclaration objectDecl = null;

    final ObjectDeclaration objdecl = currentScope_.lookupObjectDeclarationRecursive(idText);
    if (null != objdecl) {
        type = objdecl.type();
        declaringScope = objdecl.enclosingScope();
        final Type enclosingMegaType = Expression.nearestEnclosingMegaTypeOf(currentScope_);
        StaticScope megaTypeScope = null;
        if (null != enclosingMegaType) {
            megaTypeScope = enclosingMegaType.enclosedScope();
        } else {
            megaTypeScope = globalScope;
        }

        if (declaringScope == megaTypeScope) {
            // Then it's a member of an object of the current class / context
            // Probably better to make it a qualified identifier
            final StaticScope enclosingMethodScope = Expression
                    .nearestEnclosingMethodScopeAround(currentScope_);
            final Declaration associatedDeclaration = declaringScope.associatedDeclaration();
            final IdentifierExpression self = new IdentifierExpression("this", associatedDeclaration.type(),
                    enclosingMethodScope, ctxGetStart.getLine());
            retval = new QualifiedIdentifierExpression(self, idText, type);

            // Further checks
            this.ensureNotDuplicatedInBaseClass(associatedDeclaration, idText, ctxGetStart.getLine());
        } else {
            retval = new IdentifierExpression(ctxJAVA_ID.getText(), type, declaringScope,
                    ctxGetStart.getLine());
        }

        // We don't want Role scope to be able to access symbols at
        // Context scope. Do a specific check for that and issue
        // a non-compliance warning

        final StaticScope currentProcScope = Expression.nearestEnclosingMethodScopeAround(currentScope_);
        if (null != currentProcScope) {
            final MethodDeclaration currentMethod = (MethodDeclaration) currentProcScope
                    .associatedDeclaration();

            // Is it a Role method?
            final StaticScope methodsEnclosingScope = currentMethod.enclosingScope();
            final Declaration enclosingMegaTypeDeclaration = methodsEnclosingScope.associatedDeclaration();
            if (enclosingMegaTypeDeclaration instanceof RoleDeclaration) {
                final Declaration symbolsEnclosingMegaType = declaringScope.associatedDeclaration();
                if (symbolsEnclosingMegaType instanceof ContextDeclaration) {
                    // Then there is code within the Role method accessing a symbol
                    // in the surrounding Context. Maybe a no-no.
                    errorHook6p2(ErrorIncidenceType.Noncompliant, ctxGetStart.getLine(),
                            "NONCOMPLIANT: Attempt to access Context member `", idText,
                            "' from within scope of Role script `",
                            enclosingMegaTypeDeclaration.name() + "." + currentMethod.name(),
                            "'. Roles may not directly access Context data. ",
                            " Consider binding the Context to one of its own Roles instead.");
                }
            }
        }

        assert null != retval;
    } else if (null != currentScope_.lookupClassDeclarationRecursive(idText)) {
        // Could be a reference to a class itself (like System)
        type = StaticScope.globalScope().lookupTypeDeclaration("Class");
        declaringScope = StaticScope.globalScope();
        retval = new IdentifierExpression(idText, type, declaringScope, ctxGetStart.getLine());
    } else if (null != (aRoleDecl = super.isRoleAssignmentWithinContext(idText))) {
        type = aRoleDecl.type();
        declaringScope = aRoleDecl.enclosingScope();
        retval = new IdentifierExpression(ctxJAVA_ID.getText(), type, declaringScope, ctxGetStart.getLine());
    } else if (null != Expression.nearestEnclosingMegaTypeOf(currentScope_)
            && null != Expression.nearestEnclosingMegaTypeOf(currentScope_).enclosedScope()
            && null != (objectDecl = Expression.nearestEnclosingMegaTypeOf(currentScope_).enclosedScope()
                    .lookupObjectDeclarationRecursive(idText))) {
        // done  get outta here
        final IdentifierExpression self = new IdentifierExpression("this", // name
                Expression.nearestEnclosingMegaTypeOf(currentScope_), // type of identifier
                Expression.nearestEnclosingMethodScopeAround(currentScope_), // scope where *declared*
                ctxGetStart.getLine());
        self.setResultIsConsumed(true);
        retval = new QualifiedIdentifierExpression(self, idText, objectDecl.type());
    } else if (null != Expression.nearestEnclosingMegaTypeOf(currentScope_)
            && null != Expression.nearestEnclosingMegaTypeOf(currentScope_).enclosedScope()
            && null != (aRoleDecl = Expression.nearestEnclosingMegaTypeOf(currentScope_).enclosedScope()
                    .lookupRoleOrStagePropDeclarationRecursive(idText))) {
        // done  get outta here
        final IdentifierExpression currentContext = new IdentifierExpression("current$context",
                Expression.nearestEnclosingMegaTypeOf(aRoleDecl.enclosedScope()),
                Expression.nearestEnclosingMethodScopeAround(currentScope_), ctxGetStart.getLine());
        currentContext.setResultIsConsumed(true);
        retval = new QualifiedIdentifierExpression(currentContext, idText, aRoleDecl.type());
    } else {
        final StaticScope possibleMethodScope = Expression.nearestEnclosingMethodScopeAround(currentScope_);
        final StaticScope possibleRoleScope = null == possibleMethodScope ? null
                : possibleMethodScope.parentScope();
        final StaticScope possibleContextScope = null == possibleRoleScope ? null
                : possibleRoleScope.parentScope();
        final Declaration associatedDeclaration = null == possibleContextScope ? null
                : possibleContextScope.associatedDeclaration();

        if (null != possibleRoleScope && (idText.equals("index") || idText.equals("lastIndex"))) {
            // It's O.K.
            final RoleDeclaration roleDeclaration = (RoleDeclaration) possibleRoleScope.associatedDeclaration();
            if (roleDeclaration.isArray()) {
                retval = idText.equals("index")
                        ? new IndexExpression(roleDeclaration, (ContextDeclaration) associatedDeclaration)
                        : new LastIndexExpression(roleDeclaration, (ContextDeclaration) associatedDeclaration);
            } else {
                retval = new ErrorExpression(null);
                errorHook5p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "The identifier `", idText,
                        "' may be invoked only from a method of an element of a Role vector.", "");
            }
        } else if (associatedDeclaration == currentContext_) {
            if (null != possibleContextScope) {
                final RoleDeclaration roleDecl = possibleContextScope.lookupRoleOrStagePropDeclaration(idText);
                if (null == roleDecl) {
                    // Check to see if it is a script invocation
                    if (null == (retval = canBeAScriptEnactment(possibleRoleScope, idText,
                            ctxGetStart.getLine()))) {
                        errorHook6p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "Object `", idText,
                                "' is not declared in scope `", currentScope_.name(), "'.", "");
                        type = new ErrorType();
                        retval = new ErrorExpression(null);
                    }
                } else {
                    // it's O.K. - maybe. Can be used as an L-value in an assignment. R-value, too, I guess
                    type = possibleContextScope.lookupTypeDeclaration(idText);
                    declaringScope = roleDecl.enclosingScope();
                    retval = new IdentifierExpression(ctxJAVA_ID.getText(), type, declaringScope,
                            ctxGetStart.getLine());
                }
            } else {
                errorHook6p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "Object `", idText,
                        "' is not declared in scope `", currentScope_.name(), "'.", "");
                type = new ErrorType();
                retval = new IdentifierExpression(ctxJAVA_ID.getText(), type, declaringScope,
                        ctxGetStart.getLine());
                retval = new ErrorExpression(retval);
            }
        } else {
            // Could be a base class reference
            retval = this.lookToBaseClassForHelp(idText, ctxGetStart.getLine(), currentScope_);

            // That was about the last chance
            if (null == retval) {
                // How about believing it could be a method call?
                retval = canBeAScriptEnactment(possibleContextScope, idText, ctxGetStart.getLine());
                if (null == retval) {
                    errorHook6p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "Object `", idText,
                            "' is not declared in scope `", currentScope_.name(), "'.", "");
                    type = new ErrorType();
                    retval = new ErrorExpression(null);
                }
            }
        }
    }
    return retval;
}

From source file:info.fulloo.trygve.parser.Pass2Listener.java

License:Open Source License

@Override
protected void checkForIncrementOpViolatingConstness(final ArrayIndexExpressionUnaryOp expression,
        final Token ctxGetStart) {
    final MethodDeclaration enclosingMethod = super.methodWithinWhichIAmDeclared(currentScope_);
    if (null != enclosingMethod && enclosingMethod.isConst()) {
        // We can have no idea where the array base is "pointing," so we have
        // to deny such expressions
        errorHook6p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "Modification of array ",
                expression.getText(), " from within const method ", enclosingMethod.name(),
                ", which violates the const modifier of the latter.", "");
    }// w w  w  .  jav a  2  s.  c  om
}

From source file:info.fulloo.trygve.parser.Pass2Listener.java

License:Open Source License

private void checkLhsForAssignmentViolatingConstness(final Expression assignee,
        final MethodDeclaration enclosingMethod, final Token ctxGetStart) {
    if (assignee instanceof IdentifierExpression) {
        final Declaration idDecl = currentScope_.lookupObjectDeclarationRecursiveWithinMethod(assignee.name());
        if (null == idDecl) {
            // Then it's not on the activation record
            errorHook5p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(),
                    "Assignment statement violates constness of declaration of ", enclosingMethod.name(), "",
                    "");
        }/*from w  w  w. j a  va  2  s.  c  o  m*/
    } else if (assignee instanceof QualifiedIdentifierExpression) {
        // We're assigning to something within "qualifier." That doesn't immediately
        // disqualify it - could be a locally created object.
        errorHook5p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(),
                "Assignment statement modifies a member object that could be shared; ",
                "that violates the constness of ", enclosingMethod.name(), "");
    } else if (assignee instanceof QualifiedClassMemberExpression) {
        // Certainly off-limits
        errorHook5p2(ErrorIncidenceType.Warning, ctxGetStart.getLine(),
                "WARNING: Assignment statement modifies a class member that could be shared; ",
                "that violates the constness of ", enclosingMethod.name(), "");
    } else if (assignee instanceof ArrayExpression) {
        // This is just an ArrayBase. In itself not a problem if it
        // is on the activation record of the method
        final ArrayExpression arrayExpression = (ArrayExpression) assignee;
        checkLhsForAssignmentViolatingConstness(arrayExpression.originalExpression(), enclosingMethod,
                ctxGetStart);
    } else if (assignee instanceof ArrayIndexExpression) {
        // Can't know without full dataflow analysis
        errorHook5p2(ErrorIncidenceType.Warning, ctxGetStart.getLine(),
                "WARNING: Assignment statement modifies an array member that could be shared; ",
                "that violates the constness of `", enclosingMethod.name(), "'.");
    }
}

From source file:info.fulloo.trygve.parser.Pass2Listener.java

License:Open Source License

protected void checkForMessageSendViolatingConstness(final MethodSignature signature, final Token ctxGetStart) {
    final MethodDeclaration enclosingMethod = super.methodWithinWhichIAmDeclared(currentScope_);
    if (null != enclosingMethod && enclosingMethod.isConst()) {
        if (signature.hasConstModifier()) {
            ; // it's O.K. - this is a const method
        } else {/* w w  w  .  j a  va  2s  .  co m*/
            errorHook6p2(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "Call of non-const method ",
                    signature.name(), " from within const method ", enclosingMethod.name(),
                    ", which violates the const modifier of the latter.", "");
        }
    }
}

From source file:info.fulloo.trygve.parser.Pass3Listener.java

License:Open Source License

@Override
protected <ExprType> Expression expressionFromReturnStatement(final ExprType ctxExpr,
        final RuleContext ctxParent, final Token ctxGetStart) {
    Expression expressionReturned = null;
    if (null != ctxExpr) {
        expressionReturned = parsingData_.popExpression();
    }//from  w  ww  . j a va2s .  c o m
    final MethodDeclaration methodDecl = (MethodDeclaration) findProperMethodScopeAround(ctxExpr, ctxParent,
            ctxGetStart);
    assert null == methodDecl || methodDecl instanceof MethodDeclaration;

    if (null == methodDecl) {
        expressionReturned = new ErrorExpression(null);
        ErrorLogger.error(ErrorIncidenceType.Fatal, ctxGetStart.getLine(),
                "Return statement must be within a method scope ", "", "", "");
    } else {
        if (methodDecl.returnType() == null || methodDecl.returnType().name().equals("void")) {
            if (null == expressionReturned || expressionReturned.type().name().equals("void")) {
                ;
            } else {
                ErrorLogger.error(ErrorIncidenceType.Fatal, ctxGetStart.getLine(), "Return expression `",
                        expressionReturned.getText(), "' of type ", expressionReturned.type().getText(),
                        " is incompatible with method that returns no value.", "");
                expressionReturned = new ErrorExpression(null);
            }
        } else if (methodDecl.returnType().canBeConvertedFrom(expressionReturned.type())) {
            ;
        } else {
            if (expressionReturned.isntError()) {
                ErrorLogger.error(ErrorIncidenceType.Fatal, ctxGetStart.getLine(),
                        "Return expression `" + expressionReturned.getText(), "`' of type `",
                        expressionReturned.type().getText(), "' is not compatible with declared return type `",
                        methodDecl.returnType().getText(), "'.");
                expressionReturned = new ErrorExpression(expressionReturned);
            }
        }
    }
    return expressionReturned;
}