private static String getJvmInternalFQNameImpl(
      BindingTrace bindingTrace, DeclarationDescriptor descriptor) {
    if (descriptor instanceof FunctionDescriptor) {
      throw new IllegalStateException("requested fq name for function: " + descriptor);
    }

    if (descriptor.getContainingDeclaration() instanceof ModuleDescriptor
        || descriptor instanceof ScriptDescriptor) {
      return "";
    }

    if (descriptor instanceof ModuleDescriptor) {
      throw new IllegalStateException("missed something");
    }

    if (descriptor instanceof ClassDescriptor) {
      ClassDescriptor klass = (ClassDescriptor) descriptor;
      if (klass.getKind() == ClassKind.OBJECT || klass.getKind() == ClassKind.CLASS_OBJECT) {
        if (klass.getContainingDeclaration() instanceof ClassDescriptor) {
          ClassDescriptor containingKlass = (ClassDescriptor) klass.getContainingDeclaration();
          if (containingKlass.getKind() == ClassKind.ENUM_CLASS) {
            return getJvmInternalName(bindingTrace, containingKlass).getInternalName();
          } else {
            return getJvmInternalName(bindingTrace, containingKlass).getInternalName()
                + JvmAbi.CLASS_OBJECT_SUFFIX;
          }
        }
      }

      JvmClassName name = bindingTrace.getBindingContext().get(FQN, descriptor);
      if (name != null) {
        return name.getInternalName();
      }
    }

    DeclarationDescriptor container = descriptor.getContainingDeclaration();

    if (container == null) {
      throw new IllegalStateException("descriptor has no container: " + descriptor);
    }

    Name name = descriptor.getName();

    String baseName = getJvmInternalName(bindingTrace, container).getInternalName();
    if (!baseName.isEmpty()) {
      return baseName
          + (container instanceof NamespaceDescriptor ? "/" : "$")
          + name.getIdentifier();
    }

    return name.getIdentifier();
  }
  @Override
  public void visitClassObject(JetClassObject classObject) {
    ClassDescriptor classDescriptor = bindingContext.get(CLASS, classObject.getObjectDeclaration());
    assert classDescriptor != null;

    JvmClassName name =
        JvmClassName.byInternalName(peekFromStack(nameStack) + JvmAbi.CLASS_OBJECT_SUFFIX);
    recordClosure(
        bindingTrace, classObject, classDescriptor, peekFromStack(classStack), name, false);

    classStack.push(classDescriptor);
    nameStack.push(name.getInternalName());
    super.visitClassObject(classObject);
    nameStack.pop();
    classStack.pop();
  }
  @Override
  public void visitObjectLiteralExpression(JetObjectLiteralExpression expression) {
    ClassDescriptor classDescriptor = bindingContext.get(CLASS, expression.getObjectDeclaration());
    if (classDescriptor == null) {
      // working around a problem with shallow analysis
      super.visitObjectLiteralExpression(expression);
      return;
    }

    final String name = inventAnonymousClassName(expression.getObjectDeclaration());
    recordClosure(
        bindingTrace,
        expression.getObjectDeclaration(),
        classDescriptor,
        peekFromStack(classStack),
        JvmClassName.byInternalName(name),
        false);

    classStack.push(classDescriptor);
    //noinspection ConstantConditions
    nameStack.push(bindingContext.get(FQN, classDescriptor).getInternalName());
    super.visitObjectLiteralExpression(expression);
    nameStack.pop();
    classStack.pop();
  }
  @Override
  public void visitObjectDeclaration(JetObjectDeclaration declaration) {
    if (declaration.getParent() instanceof JetObjectLiteralExpression
        || declaration.getParent() instanceof JetClassObject) {
      super.visitObjectDeclaration(declaration);
    } else {
      ClassDescriptor classDescriptor = bindingContext.get(CLASS, declaration);
      // working around a problem with shallow analysis
      if (classDescriptor == null) return;

      String name = getName(classDescriptor);
      recordClosure(
          bindingTrace,
          declaration,
          classDescriptor,
          peekFromStack(classStack),
          JvmClassName.byInternalName(name),
          false);

      classStack.push(classDescriptor);
      nameStack.push(name);
      super.visitObjectDeclaration(declaration);
      nameStack.pop();
      classStack.pop();
    }
  }
Esempio n. 5
0
 private void invoke(InstructionAdapter v) {
   v.visitMethodInsn(
       getInvokeOpcode(),
       owner.getInternalName(),
       getSignature().getAsmMethod().getName(),
       getSignature().getAsmMethod().getDescriptor());
 }
Esempio n. 6
0
  private void invokeDefault(InstructionAdapter v, int mask) {
    if (defaultImplOwner == null || defaultImplParam == null) {
      throw new IllegalStateException();
    }

    v.iconst(mask);
    String desc = getSignature().getAsmMethod().getDescriptor().replace(")", "I)");
    if ("<init>".equals(getSignature().getAsmMethod().getName())) {
      v.visitMethodInsn(INVOKESPECIAL, defaultImplOwner.getInternalName(), "<init>", desc);
    } else {
      if (getInvokeOpcode() != INVOKESTATIC) {
        desc = desc.replace("(", "(" + defaultImplParam.getDescriptor());
      }
      v.visitMethodInsn(
          INVOKESTATIC,
          defaultImplOwner.getInternalName(),
          getSignature().getAsmMethod().getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX,
          desc);
    }
  }
  @NotNull
  public static JvmClassName getJvmInternalName(
      BindingTrace bindingTrace, @NotNull DeclarationDescriptor descriptor) {
    descriptor = descriptor.getOriginal();
    JvmClassName name = bindingTrace.getBindingContext().get(FQN, descriptor);
    if (name != null) {
      return name;
    }

    name = JvmClassName.byInternalName(getJvmInternalFQNameImpl(bindingTrace, descriptor));

    assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, descriptor, name);
    bindingTrace.record(FQN, descriptor, name);
    return name;
  }
Esempio n. 8
0
 private static void testSignatureName(
     String className,
     String innerClassName,
     String fqName,
     String outerClassName,
     List<String> innerClassNameList) {
   JvmClassName mapEntryName = JvmClassName.bySignatureName(className);
   assertEquals(innerClassName, mapEntryName.getInternalName());
   assertEquals(fqName, mapEntryName.getFqName().asString());
   assertEquals(outerClassName, mapEntryName.getOuterClassFqName().asString());
   assertEquals(innerClassNameList, mapEntryName.getInnerClassNameList());
 }
  @Override
  public void visitClass(JetClass klass) {
    ClassDescriptor classDescriptor = bindingContext.get(CLASS, klass);
    // working around a problem with shallow analysis
    if (classDescriptor == null) return;

    String name = getName(classDescriptor);
    recordClosure(
        bindingTrace,
        klass,
        classDescriptor,
        peekFromStack(classStack),
        JvmClassName.byInternalName(name),
        false);

    classStack.push(classDescriptor);
    nameStack.push(name);
    super.visitClass(klass);
    nameStack.pop();
    classStack.pop();
  }
  @Override
  public void visitNamedFunction(JetNamedFunction function) {
    FunctionDescriptor functionDescriptor =
        (FunctionDescriptor) bindingContext.get(DECLARATION_TO_DESCRIPTOR, function);
    // working around a problem with shallow analysis
    if (functionDescriptor == null) return;
    DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration();
    if (containingDeclaration instanceof ClassDescriptor) {
      nameStack.push(peekFromStack(nameStack) + '$' + function.getName());
      super.visitNamedFunction(function);
      nameStack.pop();
    } else if (containingDeclaration instanceof NamespaceDescriptor) {
      String peek = peekFromStack(nameStack);
      if (peek.isEmpty()) {
        peek = JvmAbi.PACKAGE_CLASS;
      } else {
        peek += "/" + JvmAbi.PACKAGE_CLASS;
      }
      nameStack.push(peek + '$' + function.getName());
      super.visitNamedFunction(function);
      nameStack.pop();
    } else {
      String name = inventAnonymousClassName(function);
      ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor);
      recordClosure(
          bindingTrace,
          function,
          classDescriptor,
          peekFromStack(classStack),
          JvmClassName.byInternalName(name),
          true);

      classStack.push(classDescriptor);
      nameStack.push(name);
      super.visitNamedFunction(function);
      nameStack.pop();
      classStack.pop();
    }
  }
  @Override
  public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) {
    FunctionDescriptor functionDescriptor =
        (FunctionDescriptor) bindingContext.get(DECLARATION_TO_DESCRIPTOR, expression);
    // working around a problem with shallow analysis
    if (functionDescriptor == null) return;

    String name = inventAnonymousClassName(expression);
    ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor);
    recordClosure(
        bindingTrace,
        expression,
        classDescriptor,
        peekFromStack(classStack),
        JvmClassName.byInternalName(name),
        true);

    classStack.push(classDescriptor);
    nameStack.push(name);
    super.visitFunctionLiteralExpression(expression);
    nameStack.pop();
    classStack.pop();
  }
 @NotNull
 private static JvmClassName classNameFromAsmDesc(@NotNull String desc) {
   assert desc.startsWith("L") && desc.endsWith(";") : "Not a JVM descriptor: " + desc;
   return JvmClassName.byInternalName(desc.substring(1, desc.length() - 1));
 }
Esempio n. 13
0
  @NotNull
  public LineResult eval(@NotNull String line) {
    ++lineNumber;

    FqName scriptFqName = new FqName("Line" + lineNumber);
    Type scriptClassType = asmTypeByFqNameWithoutInnerClasses(scriptFqName);

    StringBuilder fullText = new StringBuilder();
    for (String prevLine : previousIncompleteLines) {
      fullText.append(prevLine + "\n");
    }
    fullText.append(line);

    LightVirtualFile virtualFile =
        new LightVirtualFile(
            "line" + lineNumber + JetParserDefinition.STD_SCRIPT_EXT,
            JetLanguage.INSTANCE,
            fullText.toString());
    virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
    JetFile psiFile =
        (JetFile)
            ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject()))
                .trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);

    MessageCollectorToString errorCollector = new MessageCollectorToString();

    AnalyzerWithCompilerReport.SyntaxErrorReport syntaxErrorReport =
        AnalyzerWithCompilerReport.reportSyntaxErrors(psiFile, errorCollector);

    if (syntaxErrorReport.isOnlyErrorAtEof()) {
      previousIncompleteLines.add(line);
      return LineResult.incomplete();
    }

    previousIncompleteLines.clear();

    if (syntaxErrorReport.isHasErrors()) {
      return LineResult.error(errorCollector.getString());
    }

    prepareForTheNextReplLine(topDownAnalysisContext);
    trace.clearDiagnostics();

    psiFile.getScript().putUserData(ScriptHeaderResolver.PRIORITY_KEY, lineNumber);

    ScriptDescriptor scriptDescriptor = doAnalyze(psiFile, errorCollector);
    if (scriptDescriptor == null) {
      return LineResult.error(errorCollector.getString());
    }

    List<Pair<ScriptDescriptor, Type>> earlierScripts = Lists.newArrayList();

    for (EarlierLine earlierLine : earlierLines) {
      earlierScripts.add(
          Pair.create(earlierLine.getScriptDescriptor(), earlierLine.getClassType()));
    }

    BindingContext bindingContext =
        AnalyzeExhaust.success(trace.getBindingContext(), module).getBindingContext();
    GenerationState generationState =
        new GenerationState(
            psiFile.getProject(),
            ClassBuilderFactories.BINARIES,
            bindingContext,
            Collections.singletonList(psiFile),
            CompilerArgumentsUtil.DEFAULT_INLINE_FLAG);

    compileScript(
        psiFile.getScript(),
        scriptClassType,
        earlierScripts,
        generationState,
        CompilationErrorHandler.THROW_EXCEPTION);

    for (OutputFile outputFile : generationState.getFactory().asList()) {
      classLoader.addClass(
          JvmClassName.byInternalName(outputFile.getRelativePath().replaceFirst("\\.class$", "")),
          outputFile.asByteArray());
    }

    try {
      Class<?> scriptClass = classLoader.loadClass(scriptFqName.asString());

      Class<?>[] constructorParams = new Class<?>[earlierLines.size()];
      Object[] constructorArgs = new Object[earlierLines.size()];

      for (int i = 0; i < earlierLines.size(); ++i) {
        constructorParams[i] = earlierLines.get(i).getScriptClass();
        constructorArgs[i] = earlierLines.get(i).getScriptInstance();
      }

      Constructor<?> scriptInstanceConstructor = scriptClass.getConstructor(constructorParams);
      Object scriptInstance;
      try {
        scriptInstance = scriptInstanceConstructor.newInstance(constructorArgs);
      } catch (Throwable e) {
        return LineResult.error(Throwables.getStackTraceAsString(e));
      }
      Field rvField = scriptClass.getDeclaredField("rv");
      rvField.setAccessible(true);
      Object rv = rvField.get(scriptInstance);

      earlierLines.add(
          new EarlierLine(line, scriptDescriptor, scriptClass, scriptInstance, scriptClassType));

      return LineResult.successful(
          rv,
          KotlinBuiltIns.getInstance()
              .getUnitType()
              .equals(scriptDescriptor.getScriptCodeDescriptor().getReturnType()));
    } catch (Throwable e) {
      PrintWriter writer = new PrintWriter(System.err);
      classLoader.dumpClasses(writer);
      writer.flush();
      throw UtilsPackage.rethrow(e);
    }
  }
Esempio n. 14
0
 @NotNull
 public static JvmClassName bySignatureName(@NotNull String signatureName) {
   JvmClassName className = new JvmClassName(signatureNameToInternalName(signatureName));
   className.signatureName = signatureName;
   return className;
 }
Esempio n. 15
0
 /** WARNING: fq name cannot be uniquely mapped to JVM class name. */
 @NotNull
 public static JvmClassName byFqNameWithoutInnerClasses(@NotNull FqName fqName) {
   JvmClassName r = new JvmClassName(fqNameToInternalName(fqName));
   r.fqName = fqName;
   return r;
 }