KotlinLightClassBuilderFactory, LightClassBuilder: refactor, clarify
This commit is contained in:
-60
@@ -1,60 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.asJava.builder;
|
|
||||||
|
|
||||||
import com.intellij.psi.stubs.StubElement;
|
|
||||||
import com.intellij.util.containers.Stack;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.kotlin.codegen.ClassBuilder;
|
|
||||||
import org.jetbrains.kotlin.codegen.ClassBuilderFactory;
|
|
||||||
import org.jetbrains.kotlin.codegen.ClassBuilderMode;
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
|
||||||
|
|
||||||
/*package*/ class KotlinLightClassBuilderFactory implements ClassBuilderFactory {
|
|
||||||
private final Stack<StubElement> stubStack;
|
|
||||||
|
|
||||||
public KotlinLightClassBuilderFactory(Stack<StubElement> stubStack) {
|
|
||||||
this.stubStack = stubStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public ClassBuilderMode getClassBuilderMode() {
|
|
||||||
return ClassBuilderMode.LIGHT_CLASSES;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public ClassBuilder newClassBuilder(@NotNull JvmDeclarationOrigin origin) {
|
|
||||||
return new StubClassBuilder(stubStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String asText(ClassBuilder builder) {
|
|
||||||
throw new UnsupportedOperationException("asText is not implemented"); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] asBytes(ClassBuilder builder) {
|
|
||||||
throw new UnsupportedOperationException("asBytes is not implemented"); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.asJava.builder
|
||||||
|
|
||||||
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
|
||||||
|
import com.intellij.psi.stubs.StubElement
|
||||||
|
import com.intellij.util.containers.Stack
|
||||||
|
import org.jetbrains.kotlin.codegen.ClassBuilder
|
||||||
|
import org.jetbrains.kotlin.codegen.ClassBuilderFactory
|
||||||
|
import org.jetbrains.kotlin.codegen.ClassBuilderMode
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||||
|
|
||||||
|
class KotlinLightClassBuilderFactory(private val javaFileStub: PsiJavaFileStub) : ClassBuilderFactory {
|
||||||
|
private val stubStack = Stack<StubElement<PsiElement>>().apply {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
push(javaFileStub as StubElement<PsiElement>)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getClassBuilderMode(): ClassBuilderMode = ClassBuilderMode.LIGHT_CLASSES
|
||||||
|
override fun newClassBuilder(origin: JvmDeclarationOrigin) = StubClassBuilder(stubStack, javaFileStub)
|
||||||
|
|
||||||
|
override fun asText(builder: ClassBuilder) = throw UnsupportedOperationException("asText is not implemented")
|
||||||
|
override fun asBytes(builder: ClassBuilder) = throw UnsupportedOperationException("asBytes is not implemented")
|
||||||
|
override fun close() {}
|
||||||
|
|
||||||
|
fun result(): PsiJavaFileStub {
|
||||||
|
val pop = stubStack.pop()
|
||||||
|
if (pop !== javaFileStub) {
|
||||||
|
LOG.error("Unbalanced stack operations: " + pop)
|
||||||
|
}
|
||||||
|
return javaFileStub
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val LOG = Logger.getInstance(KotlinLightClassBuilderFactory::class.java)
|
||||||
+5
-21
@@ -23,13 +23,10 @@ import com.intellij.openapi.project.Project
|
|||||||
import com.intellij.openapi.util.SystemInfo
|
import com.intellij.openapi.util.SystemInfo
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.ClassFileViewProvider
|
import com.intellij.psi.ClassFileViewProvider
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import com.intellij.psi.PsiManager
|
import com.intellij.psi.PsiManager
|
||||||
import com.intellij.psi.impl.compiled.ClsFileImpl
|
import com.intellij.psi.impl.compiled.ClsFileImpl
|
||||||
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
|
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
|
||||||
import com.intellij.psi.impl.java.stubs.impl.PsiJavaFileStubImpl
|
import com.intellij.psi.impl.java.stubs.impl.PsiJavaFileStubImpl
|
||||||
import com.intellij.psi.stubs.StubElement
|
|
||||||
import com.intellij.util.containers.Stack
|
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -47,20 +44,12 @@ fun buildLightClass(
|
|||||||
generate: (state: GenerationState, files: Collection<KtFile>) -> Unit
|
generate: (state: GenerationState, files: Collection<KtFile>) -> Unit
|
||||||
): LightClassBuilderResult {
|
): LightClassBuilderResult {
|
||||||
val project = files.first().project
|
val project = files.first().project
|
||||||
val javaFileStub = createJavaFileStub(project, packageFqName, files)
|
|
||||||
val bindingContext: BindingContext
|
|
||||||
|
|
||||||
val state: GenerationState
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val stubStack = Stack<StubElement<PsiElement>>()
|
val classBuilderFactory = KotlinLightClassBuilderFactory(createJavaFileStub(project, packageFqName, files))
|
||||||
|
val state = GenerationState(
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
stubStack.push(javaFileStub as StubElement<PsiElement>)
|
|
||||||
|
|
||||||
state = GenerationState(
|
|
||||||
project,
|
project,
|
||||||
KotlinLightClassBuilderFactory(stubStack),
|
classBuilderFactory,
|
||||||
context.module,
|
context.module,
|
||||||
context.bindingContext,
|
context.bindingContext,
|
||||||
files.toList(),
|
files.toList(),
|
||||||
@@ -70,17 +59,12 @@ fun buildLightClass(
|
|||||||
)
|
)
|
||||||
state.beforeCompile()
|
state.beforeCompile()
|
||||||
|
|
||||||
bindingContext = state.bindingContext
|
|
||||||
|
|
||||||
generate(state, files)
|
generate(state, files)
|
||||||
|
|
||||||
val pop = stubStack.pop()
|
val javaFileStub = classBuilderFactory.result()
|
||||||
if (pop !== javaFileStub) {
|
|
||||||
LOG.error("Unbalanced stack operations: " + pop)
|
|
||||||
}
|
|
||||||
|
|
||||||
ServiceManager.getService(project, StubComputationTracker::class.java)?.onStubComputed(javaFileStub, context)
|
ServiceManager.getService(project, StubComputationTracker::class.java)?.onStubComputed(javaFileStub, context)
|
||||||
return LightClassBuilderResult(javaFileStub, bindingContext, state.collectedExtraJvmDiagnostics)
|
return LightClassBuilderResult(javaFileStub, context.bindingContext, state.collectedExtraJvmDiagnostics)
|
||||||
}
|
}
|
||||||
catch (e: ProcessCanceledException) {
|
catch (e: ProcessCanceledException) {
|
||||||
throw e
|
throw e
|
||||||
|
|||||||
+6
-5
@@ -50,14 +50,16 @@ public class StubClassBuilder extends AbstractClassBuilder {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
private final StubElement parent;
|
private final StubElement parent;
|
||||||
|
private final PsiJavaFileStub fileStub;
|
||||||
private StubBuildingVisitor v;
|
private StubBuildingVisitor v;
|
||||||
private final Stack<StubElement> parentStack;
|
private final Stack<StubElement> parentStack;
|
||||||
private boolean isPackageClass = false;
|
private boolean isPackageClass = false;
|
||||||
private int memberIndex = 0;
|
private int memberIndex = 0;
|
||||||
|
|
||||||
public StubClassBuilder(@NotNull Stack<StubElement> parentStack) {
|
public StubClassBuilder(@NotNull Stack<StubElement> parentStack, @NotNull PsiJavaFileStub fileStub) {
|
||||||
this.parentStack = parentStack;
|
this.parentStack = parentStack;
|
||||||
this.parent = parentStack.peek();
|
this.parent = parentStack.peek();
|
||||||
|
this.fileStub = fileStub;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -102,7 +104,8 @@ public class StubClassBuilder extends AbstractClassBuilder {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private String calculateShortName(@NotNull String internalName) {
|
private String calculateShortName(@NotNull String internalName) {
|
||||||
if (parent instanceof PsiJavaFileStub) {
|
if (parent instanceof PsiJavaFileStub) {
|
||||||
String packagePrefix = getPackageInternalNamePrefix((PsiJavaFileStub) parent);
|
assert parent == fileStub;
|
||||||
|
String packagePrefix = getPackageInternalNamePrefix();
|
||||||
assert internalName.startsWith(packagePrefix) : internalName + " : " + packagePrefix;
|
assert internalName.startsWith(packagePrefix) : internalName + " : " + packagePrefix;
|
||||||
return internalName.substring(packagePrefix.length());
|
return internalName.substring(packagePrefix.length());
|
||||||
}
|
}
|
||||||
@@ -118,8 +121,6 @@ public class StubClassBuilder extends AbstractClassBuilder {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private String getClassInternalNamePrefix(@NotNull PsiClassStub classStub) {
|
private String getClassInternalNamePrefix(@NotNull PsiClassStub classStub) {
|
||||||
PsiJavaFileStub fileStub = (PsiJavaFileStub) parentStack.get(0);
|
|
||||||
|
|
||||||
String packageName = fileStub.getPackageName();
|
String packageName = fileStub.getPackageName();
|
||||||
|
|
||||||
String classStubQualifiedName = classStub.getQualifiedName();
|
String classStubQualifiedName = classStub.getQualifiedName();
|
||||||
@@ -135,7 +136,7 @@ public class StubClassBuilder extends AbstractClassBuilder {
|
|||||||
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static String getPackageInternalNamePrefix(@NotNull PsiJavaFileStub fileStub) {
|
private String getPackageInternalNamePrefix() {
|
||||||
String packageName = fileStub.getPackageName();
|
String packageName = fileStub.getPackageName();
|
||||||
if (packageName.isEmpty()) {
|
if (packageName.isEmpty()) {
|
||||||
return "";
|
return "";
|
||||||
|
|||||||
Reference in New Issue
Block a user