public static void genNotNullAssertionsForParameters( @NotNull InstructionAdapter v, @NotNull GenerationState state, @NotNull FunctionDescriptor descriptor, @NotNull FrameMap frameMap) { if (!state.isGenerateNotNullParamAssertions()) return; // Private method is not accessible from other classes, no assertions needed if (getVisibilityAccessFlag(descriptor) == ACC_PRIVATE) return; for (ValueParameterDescriptor parameter : descriptor.getValueParameters()) { JetType type = parameter.getReturnType(); if (type == null || isNullableType(type)) continue; int index = frameMap.getIndex(parameter); Type asmType = state.getTypeMapper().mapReturnType(type); if (asmType.getSort() == Type.OBJECT || asmType.getSort() == Type.ARRAY) { v.load(index, asmType); v.visitLdcInsn(descriptor.getName().asString()); v.invokestatic( "jet/runtime/Intrinsics", "checkParameterIsNotNull", "(Ljava/lang/Object;Ljava/lang/String;)V"); } } }
@NotNull public static ClassFileFactory generateFiles( @NotNull JetCoreEnvironment environment, @NotNull CodegenTestFiles files) { AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegrationAndCheckForErrors( environment.getProject(), files.getPsiFiles(), files.getScriptParameterTypes(), Predicates.<PsiFile>alwaysTrue()); analyzeExhaust.throwIfError(); AnalyzingUtils.throwExceptionOnErrors(analyzeExhaust.getBindingContext()); CompilerConfiguration configuration = environment.getConfiguration(); GenerationState state = new GenerationState( environment.getProject(), ClassBuilderFactories.TEST, Progress.DEAF, analyzeExhaust.getBindingContext(), files.getPsiFiles(), configuration.get(JVMConfigurationKeys.GENERATE_NOT_NULL_ASSERTIONS, true), configuration.get(JVMConfigurationKeys.GENERATE_NOT_NULL_PARAMETER_ASSERTIONS, true), /*generateDeclaredClasses = */ true, configuration.get( JVMConfigurationKeys.ENABLE_INLINE, InlineUtil.DEFAULT_INLINE_FLAG_FOR_TEST)); KotlinCodegenFacade.compileCorrectFiles(state, CompilationErrorHandler.THROW_EXCEPTION); return state.getFactory(); }
@Override public StackValue innerValue( DeclarationDescriptor d, LocalLookup localLookup, GenerationState state, MutableClosure closure, Type classType) { VariableDescriptor vd = (VariableDescriptor) d; boolean idx = localLookup != null && localLookup.lookupLocal(vd); if (!idx) return null; Type sharedVarType = state.getTypeMapper().getSharedVarType(vd); Type localType = state.getTypeMapper().mapType(vd); Type type = sharedVarType != null ? sharedVarType : localType; String fieldName = "$" + vd.getName(); StackValue innerValue = sharedVarType != null ? StackValue.fieldForSharedVar(localType, classType, fieldName) : StackValue.field(type, classType, fieldName, false); closure.recordField(fieldName, type); closure.captureVariable(new EnclosedValueDescriptor(fieldName, d, innerValue, type)); return innerValue; }
public static void genClassOrObject( @NotNull CodegenContext parentContext, @NotNull JetClassOrObject aClass, @NotNull GenerationState state, @Nullable MemberCodegen<?> parentCodegen) { ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass); if (descriptor == null || ErrorUtils.isError(descriptor)) { badDescriptor(descriptor, state.getClassBuilderMode()); return; } if (descriptor.getName().equals(SpecialNames.NO_NAME_PROVIDED)) { badDescriptor(descriptor, state.getClassBuilderMode()); } ClassBuilder classBuilder = state.getFactory().forClassImplementation(descriptor, aClass.getContainingFile()); ClassContext classContext = parentContext.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state); new ImplementationBodyCodegen(aClass, classContext, classBuilder, state, parentCodegen) .generate(); if (aClass instanceof JetClass && ((JetClass) aClass).isTrait()) { ClassBuilder traitImplBuilder = state.getFactory().forTraitImplementation(descriptor, state, aClass.getContainingFile()); ClassContext traitImplContext = parentContext.intoClass(descriptor, OwnerKind.TRAIT_IMPL, state); new TraitImplBodyCodegen(aClass, traitImplContext, traitImplBuilder, state, parentCodegen) .generate(); } }
private static void registerEarlierScripts( @NotNull GenerationState state, @NotNull List<Pair<ScriptDescriptor, Type>> earlierScripts) { for (Pair<ScriptDescriptor, Type> t : earlierScripts) { ScriptDescriptor earlierDescriptor = t.first; Type earlierClassType = t.second; registerClassNameForScript(state.getBindingTrace(), earlierDescriptor, earlierClassType); } List<ScriptDescriptor> earlierScriptDescriptors = Lists.newArrayList(); for (Pair<ScriptDescriptor, Type> t : earlierScripts) { ScriptDescriptor earlierDescriptor = t.first; earlierScriptDescriptors.add(earlierDescriptor); } state.setEarlierScriptsForReplInterpreter(earlierScriptDescriptors); }
@Override public StackValue innerValue( DeclarationDescriptor d, LocalLookup localLookup, GenerationState state, MutableClosure closure, Type classType) { FunctionDescriptor vd = (FunctionDescriptor) d; boolean idx = localLookup != null && localLookup.lookupLocal(vd); if (!idx) return null; BindingContext bindingContext = state.getBindingContext(); Type localType = asmTypeForAnonymousClass(bindingContext, vd); MutableClosure localFunClosure = bindingContext.get(CLOSURE, bindingContext.get(CLASS_FOR_FUNCTION, vd)); if (localFunClosure != null && JvmCodegenUtil.isConst(localFunClosure)) { // This is an optimization: we can obtain an instance of a const closure simply by // GETSTATIC ...$instance // (instead of passing this instance to the constructor and storing as a field) return StackValue.field(localType, localType, JvmAbi.INSTANCE_FIELD, true); } String fieldName = "$" + vd.getName(); StackValue innerValue = StackValue.field(localType, classType, fieldName, false); closure.recordField(fieldName, localType); closure.captureVariable(new EnclosedValueDescriptor(fieldName, d, innerValue, localType)); return innerValue; }
public static void compileScript( @NotNull JetScript script, @NotNull Type classType, @NotNull List<Pair<ScriptDescriptor, Type>> earlierScripts, @NotNull GenerationState state, @NotNull CompilationErrorHandler errorHandler) { registerEarlierScripts(state, earlierScripts); registerClassNameForScript(state.getBindingTrace(), script, classType); state.beforeCompile(); KotlinCodegenFacade.generatePackage( state, script.getContainingJetFile().getPackageFqName(), Collections.singleton(script.getContainingJetFile()), errorHandler); }
protected ClassBodyCodegen( JetClassOrObject aClass, CodegenContext context, ClassBuilder v, GenerationState state) { super(state); descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass); myClass = aClass; this.context = context; this.kind = context.getContextKind(); this.v = v; }
@NotNull @Override protected String processRequest(@NotNull Location location) { JetFile jetFile = location.getJetFile(); assert jetFile != null; GenerationState state; try { AnalyzeExhaust exhaust = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile); if (exhaust.isError()) { return printStackTraceToString(exhaust.getError()); } state = new GenerationState( jetFile.getProject(), ClassBuilderFactories.TEST, Progress.DEAF, exhaust.getBindingContext(), Collections.singletonList(jetFile), true, true, GenerationState.GenerateClassFilter.GENERATE_ALL, enableInline.isSelected()); KotlinCodegenFacade.compileCorrectFiles(state, CompilationErrorHandler.THROW_EXCEPTION); } catch (ProcessCanceledException e) { throw e; } catch (Exception e) { return printStackTraceToString(e); } StringBuilder answer = new StringBuilder(); OutputFileCollection outputFiles = state.getFactory(); for (OutputFile outputFile : outputFiles.asList()) { answer.append("// ================"); answer.append(outputFile.getRelativePath()); answer.append(" =================\n"); answer.append(outputFile.asText()).append("\n\n"); } return answer.toString(); }
public void testNoAssertionsForKotlinFromBinary() throws Exception { CompilerConfiguration configuration = JetTestUtils.compilerConfigurationForTests( ConfigurationKind.JDK_ONLY, TestJdkKind.MOCK_JDK); JetCoreEnvironment tmpEnvironment = new JetCoreEnvironment(getTestRootDisposable(), configuration); GenerationState state = generateCommon( ClassBuilderFactories.TEST, tmpEnvironment, CodegenTestFiles.create( tmpEnvironment.getProject(), new String[] {"notNullAssertions/noAssertionsForKotlin.kt"})); File compiledDirectory = new File(FileUtil.getTempDirectory(), "kotlin-classes"); CompileEnvironmentUtil.writeToOutputDirectory(state.getFactory(), compiledDirectory); setUpEnvironment(true, false, compiledDirectory); loadFile("notNullAssertions/noAssertionsForKotlinMain.kt"); assertNoIntrinsicsMethodIsCalled(PackageClassUtils.getPackageClassName(FqName.ROOT)); }
@Override public StackValue generate( ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { final CallableMethod callableMethod = state.getTypeMapper().mapToCallableMethod(method, false, OwnerKind.IMPLEMENTATION); codegen.invokeMethodWithArguments(callableMethod, (JetCallExpression) element, receiver); return StackValue.onStack(callableMethod.getSignature().getAsmMethod().getReturnType()); }
private static void genNotNullAssertion( @NotNull InstructionAdapter v, @NotNull GenerationState state, @NotNull CallableDescriptor descriptor, @NotNull String assertMethodToCall) { if (!state.isGenerateNotNullAssertions()) return; if (!isDeclaredInJava(descriptor, state.getBindingContext())) return; JetType type = descriptor.getReturnType(); if (type == null || isNullableType(type)) return; Type asmType = state.getTypeMapper().mapReturnType(type); if (asmType.getSort() == Type.OBJECT || asmType.getSort() == Type.ARRAY) { v.dup(); v.visitLdcInsn(descriptor.getContainingDeclaration().getName().asString()); v.visitLdcInsn(descriptor.getName().asString()); v.invokestatic( "jet/runtime/Intrinsics", assertMethodToCall, "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V"); } }
@Override public final void generateBody( @NotNull MethodVisitor mv, @NotNull JvmMethodSignature signature, @NotNull MethodContext context, @Nullable MemberCodegen<?> parentCodegen) { ExpressionCodegen codegen = new ExpressionCodegen( mv, getFrameMap(state.getTypeMapper(), context), signature.getReturnType(), context, state, parentCodegen); doGenerateBody(codegen, signature); }
@Override public StackValue innerValue( DeclarationDescriptor d, LocalLookup enclosingLocalLookup, GenerationState state, MutableClosure closure, Type classType) { if (closure.getEnclosingReceiverDescriptor() != d) return null; JetType receiverType = ((CallableDescriptor) d).getReceiverParameter().getType(); Type type = state.getTypeMapper().mapType(receiverType); StackValue innerValue = StackValue.field(type, classType, CAPTURED_RECEIVER_FIELD, false); closure.setCaptureReceiver(); return innerValue; }
@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); } }