protected void addError(String msg, ASTNode expr) {
   this.source
       .getErrorCollector()
       .addErrorAndContinue(
           new SyntaxErrorMessage(
               new SyntaxException(
                   msg + '\n',
                   expr.getLineNumber(),
                   expr.getColumnNumber(),
                   expr.getLastLineNumber(),
                   expr.getLastColumnNumber()),
               this.source));
 }
        public void call(SourceUnit source, GeneratorContext context, ClassNode classNode)
            throws CompilationFailedException {

          optimizer.visitClass(
              classNode, source); // GROOVY-4272: repositioned it here from staticImport

          if (!classNode.isSynthetic()) {
            GenericsVisitor genericsVisitor = new GenericsVisitor(source);
            genericsVisitor.visitClass(classNode);
          }
          //
          // Run the Verifier on the outer class
          //
          try {
            verifier.visitClass(classNode);
          } catch (GroovyRuntimeException rpe) {
            ASTNode node = rpe.getNode();
            getErrorCollector()
                .addError(
                    new SyntaxException(
                        rpe.getMessage(),
                        node.getLineNumber(),
                        node.getColumnNumber(),
                        node.getLastLineNumber(),
                        node.getLastColumnNumber()),
                    source);
          }

          LabelVerifier lv = new LabelVerifier(source);
          lv.visitClass(classNode);

          ClassCompletionVerifier completionVerifier = new ClassCompletionVerifier(source);
          completionVerifier.visitClass(classNode);

          ExtendedVerifier xverifier = new ExtendedVerifier(source);
          xverifier.visitClass(classNode);

          // because the class may be generated even if a error was found
          // and that class may have an invalid format we fail here if needed
          getErrorCollector().failIfErrors();

          //
          // Prep the generator machinery
          //
          ClassVisitor visitor = createClassVisitor();

          String sourceName =
              (source == null ? classNode.getModule().getDescription() : source.getName());
          // only show the file name and its extension like javac does in its stacktraces rather
          // than the full path
          // also takes care of both \ and / depending on the host compiling environment
          if (sourceName != null)
            sourceName =
                sourceName.substring(
                    Math.max(sourceName.lastIndexOf('\\'), sourceName.lastIndexOf('/')) + 1);
          AsmClassGenerator generator = new AsmClassGenerator(source, context, visitor, sourceName);

          //
          // Run the generation and create the class (if required)
          //
          // GRECLIPSE: if there are errors, don't generate code.
          // code gen can fail unexpectedly if there was an earlier error.
          if (!source.getErrorCollector().hasErrors()) {
            // end
            generator.visitClass(classNode);

            byte[] bytes = ((ClassWriter) visitor).toByteArray();
            /// GRECLIPSE: start: added classNode, sourceUnit
            /*old{
            generatedClasses.add(new GroovyClass(classNode.getName(), bytes));
            }*/
            // newcode
            generatedClasses.add(new GroovyClass(classNode.getName(), bytes, classNode, source));
            // end

            //
            // Handle any callback that's been set
            //
            if (CompilationUnit.this.classgenCallback != null) {
              classgenCallback.call(visitor, classNode);
            }

            //
            // Recurse for inner classes
            //
            LinkedList innerClasses = generator.getInnerClasses();
            while (!innerClasses.isEmpty()) {
              classgen.call(source, context, (ClassNode) innerClasses.removeFirst());
            }
            // GRECLIPSE: if there are errors, don't generate code
          }
          // end
        }