List of usage examples for org.antlr.v4.runtime Token getLine
int getLine();
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; }