Example #1
0
 public override void Exit(MethodDeclaration node)
 {
     int numReturnStatements = _returnTypes.Count;
     if (node.Symbol.Type == VoidType.GetInstance())
     {   // Void methods cannot have return statements
         // (because Mini-Java does not allow empty return statements).
         if (numReturnStatements > 0)
         {
             ReportError(
                 ErrorTypes.TypeError,
                 String.Format("Cannot return a value from a method whose result type is {0}.",
                 node.Symbol.Type.Name), node);
             _returnTypes.Clear();
         }
     }
     else if (numReturnStatements == 0 || !AllBranchesReturnAValue(node))
     {
         ReportError(
             ErrorTypes.TypeError,
             String.Format("Missing return statement in method {0}.",
             node.Symbol.Name), node);
     }
     // Return types can be checked even if some branches were missing
     // a return statement.
     CheckReturnTypes(node, node.Symbol);
 }
 public static MethodDeclaration CreateMainMethodDeclaration(List<IStatement> methodBody, int row, int col)
 {
     var method = new MethodDeclaration(MiniJavaInfo.MainMethodIdent, MiniJavaInfo.VoidType, false,
       new List<VariableDeclaration>(), methodBody, row, col, true);
     method.IsEntryPoint = true;
     return method;
 }
 public override void Visit(MethodDeclaration node)
 {
     if (_pass == 0)
     {
         CheckStatements(node.MethodBody);
     }
     else if (_pass == 1)
     {
         _currentLocalIdx = 0;
     }
 }
 public static ClassDeclaration CreateMainClassDeclaration(string name,
     MethodDeclaration mainMethod, int row, int col)
 {
     if (!mainMethod.IsEntryPoint)
     {
         throw new ArgumentException("Illegal main method declaration, the program has no entry point.");
     }
     var mainClass = new ClassDeclaration(name, null,
         new List<Declaration> { mainMethod }, row, col);
     mainClass.IsMainClass = true;
     return mainClass;
 }
 private static MethodAttributes GetMethodAttributes(MethodDeclaration node)
 {
     MethodAttributes attrs = MethodAttributes.Public; // all methods are public
     if (node.IsStatic)
     {
         attrs |= MethodAttributes.Static;
     }
     else
     {
         attrs |= MethodAttributes.Virtual;
     }
     return attrs;
 }
 private bool OverloadsSuperClassMethod(MethodDeclaration method,
     MethodDeclaration superClassMethod)
 {
     if (method.Formals.Count != superClassMethod.Formals.Count)
     {
         return true;
     }
     bool formalsEqual = true;
     for (int i = 0; i < method.Formals.Count && formalsEqual; i++)
     {
         var methodFormal = method.Formals[i].Type;
         var superFormal = superClassMethod.Formals[i].Type;
         // The method's formal parameter cannot be a subtype of the
         // superclass method's formal parameter type:
         // http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.2
         // (This would be overloading.)
         if (methodFormal != ErrorType.GetInstance() && superFormal != ErrorType.GetInstance())
         {
             formalsEqual = methodFormal.Equals(superFormal);
         }
     }
     return !formalsEqual;
 }
 private Type[] GetParameterTypes(MethodDeclaration node)
 {
     if (node.Formals.Count == 0) return Type.EmptyTypes;
     Type[] types = new Type[node.Formals.Count];
     for (int i = 0; i < node.Formals.Count; i++)
     {
         VariableDeclaration decl = node.Formals[i];
         types[i] = _parent.BuildType(decl.TypeName, decl.IsArray);
     }
     return types;
 }
Example #8
0
 public override void Visit(MethodDeclaration node)
 {
     // Check that the method does not overload a method in a superclass.
     // Only overriding is allowed.
     var classSymbol = node.DeclaringType;
     var superClassMethod = classSymbol.SuperClass == null ? null :
         classSymbol.SuperClass.Scope.ResolveMethod(node.Name);
     if (superClassMethod != null)
     {
         CheckForOverloading(node, classSymbol, superClassMethod);
     }
 }
        // Detects possible duplicate declaration of a method identifier.
        // A dummy scope is made to stand in for the method scope.
        public override void Visit(MethodDeclaration node)
        {
            Debug.Assert(CurrentScope is IMethodScope);

            node.Type = CheckDeclaredType(node);
            var methodScope = (IMethodScope) CurrentScope;

            // Note: the symbol is stored on the node even if the attempt
            // to define it fails. This feature can be used in the type
            // checking phase to e.g. check return types for even methods
            // that could not be defined due to a name clash.
            node.Symbol = new MethodSymbol(node.Name, node.Type, methodScope, node.IsStatic);
            IScope scope = node.Symbol.Scope;
            if (!methodScope.Define(node.Symbol))
            {
                ReportSymbolDefinitionError(node);
                scope = new ErrorScope(CurrentScope); // Make an error scope to stand in for the method scope for purposes of recovery.
            }                                         // (Both are IVariableScopes.)

            node.Symbol.Declaration = node;
            node.Scope = scope;

            EnterScope(scope);
        }
 public override void Exit(MethodDeclaration node)
 {
     ExitScope();
 }
 private bool AllBranchesReturnAValue(MethodDeclaration node)
 {
     return BlockAlwaysReturnsAValue(node.MethodBody);
 }
 private void ValidateCallParameterTypes(MethodInvocation node, MethodDeclaration methodDecl)
 {
     var callParamTypes = node.CallParameters.Select<IExpression, IType>((expr) => expr.Type).ToList();
     for (int i = 0; i < methodDecl.Formals.Count; i++)
     {
         var callParamType = callParamTypes[i];
         var formalParamType = methodDecl.Formals[i].Type;
         if (!callParamType.IsAssignableTo(formalParamType))
         {
             var msg = String.Format(
                 "Wrong type of argument to method {0}. Expected {1} but found {2}.",
                 node.MethodName, formalParamType.Name, callParamType.Name);
             ReportError(ErrorTypes.TypeError, msg, node);
         }
     }
 }
            public override void Visit(MethodDeclaration node)
            {
                MethodBuilder methodBuilder = _currentType.DefineMethod(node.Name, GetMethodAttributes(node));
                if (node.IsEntryPoint)
                {
                    _parent._asmBuilder.SetEntryPoint(methodBuilder, PEFileKinds.ConsoleApplication);
                }

                methodBuilder.SetReturnType(GetReturnType(node));
                methodBuilder.SetParameters(GetParameterTypes(node));

                var sym = node.Scope.ResolveMethod(node.Name);
                _parent._methods[sym] = methodBuilder;

                _currentMethod = methodBuilder;
            }
 private void CheckReturnTypes(MethodDeclaration node, MethodSymbol method)
 {
     while (_returnTypes.Count > 0)
     {
         var returnType = _returnTypes.Pop();
         if (!returnType.IsAssignableTo(method.Type))
         {   // The type of object returned by the return statement
             // must match the method's declared return type.
             ReportError(ErrorTypes.TypeError,
                 String.Format("Cannot convert expression of type {0} to {1}.",
                 returnType.Name, method.Type.Name), node);
         }
     }
 }
            private void CheckForOverloading(MethodDeclaration node,
                TypeSymbol classSymbol, MethodSymbol superClassMethod)
            {
                var superClassMethodDeclaration = (MethodDeclaration)superClassMethod.Declaration;
                if (OverloadsSuperClassMethod(node, superClassMethodDeclaration))
                {
                    var msg = String.Format("Method {0} in class {1} overloads a method in class {2}. Overloading is not allowed.",
                        node.Name, classSymbol.Name, classSymbol.SuperClass.Name);
                    ReportError(ErrorTypes.InvalidOverride, msg, node);
                }

                // Subclass methods CANNOT have covariant return types with respect to overridden
                // superclass methods, though this is allowed in Java. This is because the .NET runtime
                // does not natively support them. (Reference link can be found in tests and docs.)
                if (node.Type != superClassMethodDeclaration.Type)
                {
                    var msg = String.Format(
                        "Method {0} in class {1} has a different return type from overridden method in class {2}.",
                        node.Name, classSymbol.Name, classSymbol.SuperClass.Name);
                    ReportError(ErrorTypes.InvalidOverride, msg, node);
                }
            }
 public override void Exit(MethodDeclaration node)
 {
     _currentMethod = null;
 }
 private Type GetReturnType(MethodDeclaration node)
 {
     return _parent.BuildType(node.TypeName, node.IsArray);
 }