private void printImports(PrintWriter out, ClassNode classNode) {
    List<String> imports = new ArrayList<String>();

    ModuleNode moduleNode = classNode.getModule();
    for (ImportNode importNode : moduleNode.getStarImports()) {
      imports.add(importNode.getPackageName());
    }

    for (ImportNode imp : moduleNode.getImports()) {
      if (imp.getAlias() == null) imports.add(imp.getType().getName());
    }

    imports.addAll(Arrays.asList(ResolveVisitor.DEFAULT_IMPORTS));

    for (String imp : imports) {
      String s =
          new StringBuilder()
              .append("import ")
              .append(imp)
              .append((imp.charAt(imp.length() - 1) == '.') ? "*;" : ";")
              .toString()
              .replace('$', '.');
      out.println(s);
    }
    out.println();
  }
 public void visitClass(ClassNode node) {
   visitAnnotations(node);
   visitPackage(node.getPackage());
   visitImports(node.getModule());
   node.visitContents(this);
   visitObjectInitializerStatements(node);
 }
  private Expression findStaticFieldOrPropAccessorImportFromModule(String name) {
    ModuleNode module = currentClass.getModule();
    if (module == null) return null;
    Map<String, ImportNode> importNodes = module.getStaticImports();
    Expression expression;
    String accessorName = getAccessorName(name);
    // look for one of these:
    //   import static MyClass.setProp [as setOtherProp]
    //   import static MyClass.getProp [as getOtherProp]
    // when resolving prop reference
    if (importNodes.containsKey(accessorName)) {
      ImportNode importNode = importNodes.get(accessorName);
      expression =
          findStaticPropertyAccessorByFullName(importNode.getType(), importNode.getFieldName());
      if (expression != null) return expression;
      expression =
          findStaticPropertyAccessor(
              importNode.getType(), getPropNameForAccessor(importNode.getFieldName()));
      if (expression != null) return expression;
    }
    if (accessorName.startsWith("get")) {
      accessorName = "is" + accessorName.substring(3);
      if (importNodes.containsKey(accessorName)) {
        ImportNode importNode = importNodes.get(accessorName);
        expression =
            findStaticPropertyAccessorByFullName(importNode.getType(), importNode.getFieldName());
        if (expression != null) return expression;
        expression =
            findStaticPropertyAccessor(
                importNode.getType(), getPropNameForAccessor(importNode.getFieldName()));
        if (expression != null) return expression;
      }
    }

    // look for one of these:
    //   import static MyClass.prop [as otherProp]
    // when resolving prop or field reference
    if (importNodes.containsKey(name)) {
      ImportNode importNode = importNodes.get(name);
      expression = findStaticPropertyAccessor(importNode.getType(), importNode.getFieldName());
      if (expression != null) return expression;
      expression = findStaticField(importNode.getType(), importNode.getFieldName());
      if (expression != null) return expression;
    }
    // look for one of these:
    //   import static MyClass.*
    // when resolving prop or field reference
    for (ImportNode importNode : module.getStaticStarImports().values()) {
      ClassNode node = importNode.getType();
      expression = findStaticPropertyAccessor(node, name);
      if (expression != null) return expression;
      expression = findStaticField(node, name);
      if (expression != null) return expression;
    }
    return null;
  }
  /**
   * A loop driver for applying operations to all primary ClassNodes in our AST. Automatically skips
   * units that have already been processed through the current phase.
   */
  public void applyToPrimaryClassNodes(PrimaryClassNodeOperation body)
      throws CompilationFailedException {
    // GRECLIPSE: start
    /*old{
    Iterator classNodes = getPrimaryClassNodes(body.needSortedInput()).iterator();
    }*/
    // newcode
    List primaryClassNodes = getPrimaryClassNodes(body.needSortedInput());
    Iterator classNodes = primaryClassNodes.iterator();
    // end
    while (classNodes.hasNext()) {
      SourceUnit context = null;
      try {
        ClassNode classNode = (ClassNode) classNodes.next();
        context = classNode.getModule().getContext();
        // GRECLIPSE get to the bottom of this - why are operations running multiple times that
        // should only run once?
        if (context == null
            || context.phase < phase
            || (context.phase == phase && !context.phaseComplete)) {

          int offset = 1;
          Iterator<InnerClassNode> iterator = classNode.getInnerClasses();
          while (iterator.hasNext()) {
            iterator.next();
            offset++;
          }
          body.call(context, new GeneratorContext(this.ast, offset), classNode);
        }
      } catch (CompilationFailedException e) {
        // fall through, getErrorReporter().failIfErrors() will trigger
      } catch (NullPointerException npe) {
        throw npe;
      } catch (GroovyBugError e) {
        changeBugText(e, context);
        throw e;
      } catch (Exception e) {
        // check the exception for a nested compilation exception
        ErrorCollector nestedCollector = null;
        for (Throwable next = e.getCause(); next != e && next != null; next = next.getCause()) {
          if (!(next instanceof MultipleCompilationErrorsException)) continue;
          MultipleCompilationErrorsException mcee = (MultipleCompilationErrorsException) next;
          nestedCollector = mcee.collector;
          break;
        }

        if (nestedCollector != null) {
          getErrorCollector().addCollectorContents(nestedCollector);
        } else {
          getErrorCollector().addError(new ExceptionMessage(e, configuration.getDebug(), this));
        }
      }
    }

    getErrorCollector().failIfErrors();
  }
 private void buildCommon(
     ClassNode buildee, AnnotationNode anno, List<FieldNode> fieldNodes, ClassNode builder) {
   String prefix = getMemberStringValue(anno, "prefix", "");
   String buildMethodName = getMemberStringValue(anno, "buildMethodName", "create");
   createBuilderConstructors(builder, buildee, fieldNodes);
   buildee.getModule().addClass(builder);
   String builderMethodName = getMemberStringValue(anno, "builderMethodName", "createInitializer");
   buildee.addMethod(
       createBuilderMethod(buildMethodName, builder, fieldNodes.size(), builderMethodName));
   for (int i = 0; i < fieldNodes.size(); i++) {
     builder.addMethod(createBuilderMethodForField(builder, fieldNodes, prefix, i));
   }
   builder.addMethod(createBuildMethod(builder, buildMethodName, fieldNodes));
 }
 private Expression transformMapEntryExpression(
     MapEntryExpression me, ClassNode constructorCallType) {
   Expression key = me.getKeyExpression();
   Expression value = me.getValueExpression();
   ModuleNode module = currentClass.getModule();
   if (module != null && key instanceof ConstantExpression) {
     Map<String, ImportNode> importNodes = module.getStaticImports();
     if (importNodes.containsKey(key.getText())) {
       ImportNode importNode = importNodes.get(key.getText());
       if (importNode.getType().equals(constructorCallType)) {
         String newKey = importNode.getFieldName();
         return new MapEntryExpression(
             new ConstantExpression(newKey), value.transformExpression(this));
       }
     }
   }
   return me;
 }
  // GroovyClassVisitor interface
  // -------------------------------------------------------------------------
  public void visitClass(ClassNode classNode) {
    try {
      this.classNode = classNode;
      this.internalClassName = BytecodeHelper.getClassInternalName(classNode);

      // System.out.println("Generating class: " + classNode.getName());

      this.internalBaseClassName = BytecodeHelper.getClassInternalName(classNode.getSuperClass());

      cv.visit(
          Opcodes.V1_3,
          classNode.getModifiers(),
          internalClassName,
          (String) null,
          internalBaseClassName,
          BytecodeHelper.getClassInternalNames(classNode.getInterfaces()));

      classNode.visitContents(this);

      for (Iterator iter = innerClasses.iterator(); iter.hasNext(); ) {
        ClassNode innerClass = (ClassNode) iter.next();
        ClassNode innerClassType = innerClass;
        String innerClassInternalName = BytecodeHelper.getClassInternalName(innerClassType);
        String outerClassName = internalClassName; // default for inner classes
        MethodNode enclosingMethod = innerClass.getEnclosingMethod();
        if (enclosingMethod != null) {
          // local inner classes do not specify the outer class name
          outerClassName = null;
        }
        cv.visitInnerClass(
            innerClassInternalName,
            outerClassName,
            innerClassType.getName(),
            innerClass.getModifiers());
      }
      cv.visitEnd();
    } catch (GroovyRuntimeException e) {
      e.setModule(classNode.getModule());
      throw e;
    }
  }
  /**
   * Loads the given class node returning the implementation Class.
   *
   * <p>WARNING: this compilation is not synchronized
   *
   * @param classNode
   * @return a class
   */
  public Class defineClass(ClassNode classNode, String file, String newCodeBase) {
    CodeSource codeSource = null;
    try {
      codeSource =
          new CodeSource(new URL("file", "", newCodeBase), (java.security.cert.Certificate[]) null);
    } catch (MalformedURLException e) {
      // swallow
    }

    CompilationUnit unit = createCompilationUnit(config, codeSource);
    ClassCollector collector = createCollector(unit, classNode.getModule().getContext());
    try {
      unit.addClassNode(classNode);
      unit.setClassgenCallback(collector);
      unit.compile(Phases.CLASS_GENERATION);
      definePackage(collector.generatedClass.getName());
      return collector.generatedClass;
    } catch (CompilationFailedException e) {
      throw new RuntimeException(e);
    }
  }
    protected Class createClass(byte[] code, ClassNode classNode) {
      BytecodeProcessor bytecodePostprocessor = unit.getConfiguration().getBytecodePostprocessor();
      byte[] fcode = code;
      if (bytecodePostprocessor != null) {
        fcode = bytecodePostprocessor.processBytecode(classNode.getName(), fcode);
      }
      GroovyClassLoader cl = getDefiningClassLoader();
      Class theClass =
          cl.defineClass(
              classNode.getName(), fcode, 0, fcode.length, unit.getAST().getCodeSource());
      this.loadedClasses.add(theClass);

      if (generatedClass == null) {
        ModuleNode mn = classNode.getModule();
        SourceUnit msu = null;
        if (mn != null) msu = mn.getContext();
        ClassNode main = null;
        if (mn != null) main = (ClassNode) mn.getClasses().get(0);
        if (msu == su && main == classNode) generatedClass = theClass;
      }

      return theClass;
    }
        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
        }
 private Expression findStaticMethodImportFromModule(Expression method, Expression args) {
   ModuleNode module = currentClass.getModule();
   if (module == null || !(method instanceof ConstantExpression)) return null;
   Map<String, ImportNode> importNodes = module.getStaticImports();
   ConstantExpression ce = (ConstantExpression) method;
   Expression expression;
   Object value = ce.getValue();
   // skip non-Strings, e.g. Integer
   if (!(value instanceof String)) return null;
   final String name = (String) value;
   // look for one of these:
   //   import static SomeClass.method [as otherName]
   // when resolving methodCall() or getProp() or setProp()
   if (importNodes.containsKey(name)) {
     ImportNode importNode = importNodes.get(name);
     expression = findStaticMethod(importNode.getType(), importNode.getFieldName(), args);
     if (expression != null) return expression;
     expression =
         findStaticPropertyAccessorGivenArgs(
             importNode.getType(), getPropNameForAccessor(importNode.getFieldName()), args);
     if (expression != null) {
       return new StaticMethodCallExpression(
           importNode.getType(), importNode.getFieldName(), args);
     }
   }
   // look for one of these:
   //   import static SomeClass.someProp [as otherName]
   // when resolving getProp() or setProp()
   if (validPropName(name)) {
     String propName = getPropNameForAccessor(name);
     if (importNodes.containsKey(propName)) {
       ImportNode importNode = importNodes.get(propName);
       expression =
           findStaticMethod(
               importNode.getType(), prefix(name) + capitalize(importNode.getFieldName()), args);
       if (expression != null) return expression;
       expression =
           findStaticPropertyAccessorGivenArgs(
               importNode.getType(), importNode.getFieldName(), args);
       if (expression != null) {
         return new StaticMethodCallExpression(
             importNode.getType(), prefix(name) + capitalize(importNode.getFieldName()), args);
       }
     }
   }
   Map<String, ImportNode> starImports = module.getStaticStarImports();
   ClassNode starImportType;
   if (currentClass.isEnum() && starImports.containsKey(currentClass.getName())) {
     ImportNode importNode = starImports.get(currentClass.getName());
     starImportType = importNode == null ? null : importNode.getType();
     expression = findStaticMethod(starImportType, name, args);
     if (expression != null) return expression;
   } else {
     for (ImportNode importNode : starImports.values()) {
       starImportType = importNode == null ? null : importNode.getType();
       expression = findStaticMethod(starImportType, name, args);
       if (expression != null) return expression;
       expression =
           findStaticPropertyAccessorGivenArgs(starImportType, getPropNameForAccessor(name), args);
       if (expression != null) {
         return new StaticMethodCallExpression(starImportType, name, args);
       }
     }
   }
   return null;
 }
  private void printClassContents(PrintWriter out, ClassNode classNode)
      throws FileNotFoundException {
    if (classNode instanceof InnerClassNode && ((InnerClassNode) classNode).isAnonymous()) {
      // if it is an anonymous inner class, don't generate the stub code for it.
      return;
    }
    try {
      Verifier verifier =
          new Verifier() {
            public void addCovariantMethods(ClassNode cn) {}

            protected void addTimeStamp(ClassNode node) {}

            protected void addInitialization(ClassNode node) {}

            protected void addPropertyMethod(MethodNode method) {
              doAddMethod(method);
            }

            protected void addReturnIfNeeded(MethodNode node) {}

            protected void addMethod(
                ClassNode node,
                boolean shouldBeSynthetic,
                String name,
                int modifiers,
                ClassNode returnType,
                Parameter[] parameters,
                ClassNode[] exceptions,
                Statement code) {
              doAddMethod(
                  new MethodNode(name, modifiers, returnType, parameters, exceptions, code));
            }

            protected void addConstructor(
                Parameter[] newParams, ConstructorNode ctor, Statement code, ClassNode node) {
              if (code instanceof ExpressionStatement) { // GROOVY-4508
                Statement temp = code;
                code = new BlockStatement();
                ((BlockStatement) code).addStatement(temp);
              }
              ConstructorNode ctrNode =
                  new ConstructorNode(ctor.getModifiers(), newParams, ctor.getExceptions(), code);
              ctrNode.setDeclaringClass(node);
              constructors.add(ctrNode);
            }

            protected void addDefaultParameters(DefaultArgsAction action, MethodNode method) {
              final Parameter[] parameters = method.getParameters();
              final Expression[] saved = new Expression[parameters.length];
              for (int i = 0; i < parameters.length; i++) {
                if (parameters[i].hasInitialExpression())
                  saved[i] = parameters[i].getInitialExpression();
              }
              super.addDefaultParameters(action, method);
              for (int i = 0; i < parameters.length; i++) {
                if (saved[i] != null) parameters[i].setInitialExpression(saved[i]);
              }
            }

            private void doAddMethod(MethodNode method) {
              String sig = method.getTypeDescriptor();

              if (propertyMethodsWithSigs.containsKey(sig)) return;

              propertyMethods.add(method);
              propertyMethodsWithSigs.put(sig, method);
            }

            @Override
            protected void addDefaultConstructor(ClassNode node) {
              // not required for stub generation
            }
          };
      verifier.visitClass(classNode);
      currentModule = classNode.getModule();

      boolean isInterface = classNode.isInterface();
      boolean isEnum = (classNode.getModifiers() & Opcodes.ACC_ENUM) != 0;
      boolean isAnnotationDefinition = classNode.isAnnotationDefinition();
      printAnnotations(out, classNode);
      printModifiers(
          out,
          classNode.getModifiers()
              & ~(isInterface ? Opcodes.ACC_ABSTRACT : 0)
              & ~(isEnum ? Opcodes.ACC_FINAL : 0));

      if (isInterface) {
        if (isAnnotationDefinition) {
          out.print("@");
        }
        out.print("interface ");
      } else if (isEnum) {
        out.print("enum ");
      } else {
        out.print("class ");
      }

      String className = classNode.getNameWithoutPackage();
      if (classNode instanceof InnerClassNode)
        className = className.substring(className.lastIndexOf("$") + 1);
      out.println(className);
      printGenericsBounds(out, classNode, true);

      ClassNode superClass = classNode.getUnresolvedSuperClass(false);

      if (!isInterface && !isEnum) {
        out.print("  extends ");
        printType(out, superClass);
      }

      ClassNode[] interfaces = classNode.getInterfaces();
      if (interfaces != null && interfaces.length > 0 && !isAnnotationDefinition) {
        if (isInterface) {
          out.println("  extends");
        } else {
          out.println("  implements");
        }
        for (int i = 0; i < interfaces.length - 1; ++i) {
          out.print("    ");
          printType(out, interfaces[i]);
          out.print(",");
        }
        out.print("    ");
        printType(out, interfaces[interfaces.length - 1]);
      }
      out.println(" {");

      printFields(out, classNode);
      printMethods(out, classNode, isEnum);

      for (Iterator<InnerClassNode> inner = classNode.getInnerClasses(); inner.hasNext(); ) {
        // GROOVY-4004: Clear the methods from the outer class so that they don't get duplicated in
        // inner ones
        propertyMethods.clear();
        propertyMethodsWithSigs.clear();
        constructors.clear();
        printClassContents(out, inner.next());
      }

      out.println("}");
    } finally {
      propertyMethods.clear();
      propertyMethodsWithSigs.clear();
      constructors.clear();
      currentModule = null;
    }
  }
 private String getPath(Class clazz) {
   CompilationUnit cu = getLocalData().get().cu;
   String name = clazz.getName();
   ClassNode classNode = cu.getClassNode(name);
   return classNode.getModule().getContext().getName();
 }
  private Expression findStaticFieldOrPropAccessorImportFromModule(String name) {
    ModuleNode module = currentClass.getModule();
    if (module == null) return null;
    Map<String, ImportNode> importNodes = module.getStaticImports();
    Expression expression = null;
    String accessorName = getAccessorName(name);
    // look for one of these:
    //   import static MyClass.setProp [as setOtherProp]
    //   import static MyClass.getProp [as getOtherProp]
    // when resolving prop reference
    if (importNodes.containsKey(accessorName)) {
      ImportNode importNode = importNodes.get(accessorName);
      expression =
          findStaticPropertyAccessorByFullName(importNode.getType(), importNode.getFieldName());
      if (expression != null) return expression;
      expression =
          findStaticPropertyAccessor(
              importNode.getType(), getPropNameForAccessor(importNode.getFieldName()));
      if (expression != null) return expression;
    }
    if (accessorName.startsWith("get")) {
      accessorName = "is" + accessorName.substring(3);
      if (importNodes.containsKey(accessorName)) {
        ImportNode importNode = importNodes.get(accessorName);
        expression =
            findStaticPropertyAccessorByFullName(importNode.getType(), importNode.getFieldName());
        if (expression != null) return expression;
        expression =
            findStaticPropertyAccessor(
                importNode.getType(), getPropNameForAccessor(importNode.getFieldName()));
        if (expression != null) return expression;
      }
    }

    // look for one of these:
    //   import static MyClass.prop [as otherProp]
    // when resolving prop or field reference
    if (importNodes.containsKey(name)) {
      ImportNode importNode = importNodes.get(name);
      // GRECLIPSE add
      try {
        if (!isReconcile) {
          // GRECLIPSE end
          expression = findStaticPropertyAccessor(importNode.getType(), importNode.getFieldName());
          if (expression != null) return expression;
          // GRECLIPSE add
        }
        // end
        expression = findStaticField(importNode.getType(), importNode.getFieldName());
        if (expression != null) return expression;
        // GRECLIPSE add
      } finally {
        // store the identifier to facilitate organizing static imports
        if (expression != null) expression.setNodeMetaData("static.import.alias", name);
      }
      // GRECLIPSE end
    }
    // look for one of these:
    //   import static MyClass.*
    // when resolving prop or field reference
    for (ImportNode importNode : module.getStaticStarImports().values()) {
      ClassNode node = importNode.getType();
      expression = findStaticPropertyAccessor(node, name);
      if (expression != null) return expression;
      expression = findStaticField(node, name);
      if (expression != null) return expression;
    }
    return null;
  }
 private void createBuilderFactoryMethod(
     AnnotationNode anno, ClassNode buildee, ClassNode builder) {
   buildee.getModule().addClass(builder);
   buildee.addMethod(createBuilderMethod(anno, builder));
 }