public Expression CompileMethod(MethodNode parseTree, SmalltalkClass cls, Expression self, Expression executionContext, Expression[] arguments) { if (parseTree == null) { throw new ArgumentNullException("parseTree"); } if (cls == null) { throw new ArgumentNullException("cls"); } if (self == null) { throw new ArgumentNullException("self"); } if (arguments == null) { throw new ArgumentNullException("arguments"); } RootCompilationContext context = this.GetCompilationContext(parseTree, cls, self, executionContext, arguments); MethodVisitor visitor = new MethodVisitor(context); Expression code = parseTree.Accept(visitor); return(code); }
/// <summary> /// File-in and process the actions contained in the node. /// </summary> /// <param name="processor">Interchange format processor responsible for the processing context.</param> /// <param name="parseErrorSink">Error sink for reporting parse errors.</param> /// <param name="sourceCodeService">Source code service that can convert tokens to source code span and reports issues.</param> /// <returns>Return an interchange unit node for annotation, usually just self.</returns> public override InterchangeUnitNode FileIn(InterchangeFormatProcessor processor, IParseErrorSink parseErrorSink, ISourceCodeReferenceService sourceCodeService) { if (processor == null) { throw new ArgumentNullException("processor"); } if (parseErrorSink == null) { throw new ArgumentNullException("parseErrorSink"); } if (sourceCodeService == null) { throw new ArgumentNullException("sourceCodeService"); } // ALL instance vars must be set. If one is missing, then source code bug, and // InterchangeFormatParser.ParseInstance/ClassMethodDefinition() should have reported the error. if (this.ClassName == null) { return(this); } // <methodDefinition> ::= <className> ’method’ <elementSeparator> // <method definition> <elementSeparator> // <classMethodDefinition> ::= <className> ’classMethod’ <elementSeparator> // <method definition> <elementSeparator> // The methodSourceCodeService is used for translation positions inside the method body, // while the sourceCodeService is used for the method declaration (e.g. "Integer method"). // In reality, most bugs will be in the method source code and therefore report errors // via the methodSourceCodeService. ISourceCodeReferenceService methodSourceCodeService; MethodNode method = processor.ParseMethod(out methodSourceCodeService); if (method == null) { return(this); // Processor/Parser should have reported errors } if (!method.Accept(IronSmalltalk.Compiler.Visiting.ParseTreeValidatingVisitor.Current)) { // We expect the parser to have reported the errors. Just in case, we do it once more to the installer. // Bad practice here is to use the 'processor.SourcePosition', but we don't have anything better :-/ if (processor.ErrorSink != null) { processor.ErrorSink.AddInterchangeError(processor.SourcePosition, processor.SourcePosition, "Invalid method source code."); } return(this); } MethodDefinition definition = this.CreateDefinition(processor, sourceCodeService, methodSourceCodeService, method); this.Definfition = definition; // This may fail, but we don't care. If failed, it reported the error through its error sink. processor.FileInProcessor.FileInMethod(definition); return(this); }